TouchAction deprecated in Selenium 4 - mobile

Here is my code to bring the Keyboard on the real ipad devices. Since Touch actions is been deprecated in Selenium 4. Can anyone help with the new solution?
public void tapOnElementToBringKeyboard(By locator) {
TeasyElement element = element(locator);
clickActions(locator);
int fromX = element.getLocation().getX();
int fromY = element.getLocation().getY();
TouchAction touchAction = new TouchAction((IOSDriver<?>) getDriver());
touchAction.tap(PointOption.point(fromX, fromY)).release().perform().tap(PointOption.point(fromX, fromY)) .release().perform();
}
Dont have any solution

Related

Unable to Zoom Out of screen using Selenium WebDriver

Am trying to zoom out of my current page as some of the monitors are quite small there our application is not loading properly.
Selenium 3.141.59
Java 1.8
This is my sample code:
public class ScreenResolutionCheck {
static WebDriver driver = null;
public static void main(String[] args) {
int width = 1512, height = 982; //Default Macbook Pro Size
WebDriverManager webDriverManager = WebDriverManager.chromedriver().browserInDocker().enableVnc().linux().dockerScreenResolution(width + "x" + height +"x24").timeout(100);
driver = webDriverManager.create();
BaseFunctions.logInfoWithOutScreenShot("VNC Url",webDriverManager.getDockerNoVncUrl().toString());
driver.get("https://opensource-demo.orangehrmlive.com/");
driver.findElement(By.tagName("body")).sendKeys(Keys.chord(Keys.COMMAND, Keys.SUBTRACT));
findElement(By.id("txtUsername")).sendKeys("Admin");
findElement(By.id("txtPassword")).sendKeys("admin123");
findElement(By.id("btnLogin")).click();
findElement(By.id("menu_admin_viewAdminModule")).click();
findElement(By.id("tableWrapper"));
driver.quit();
webDriverManager.quit();
}
public static WebElement findElement(By by) {
WebElement we = new WebDriverWait(driver, 30).until(d -> d.findElement(by));
return we;
}
}
I tried the following:
driver.findElement(By.tagName("body")).sendKeys(Keys.chord(Keys.COMMAND,Keys.SUBTRACT));
driver.findElement(By.tagName("body")).sendKeys(Keys.chord(Keys.COMMAND,Keys.SHIFT,Keys.SUBTRACT));
driver.findElement(By.tagName("body")).sendKeys(Keys.chord(Keys.COMMAND,"-"));
new Actions(driver).sendKeys(driver.findElement(By.tagName("body"),Keys.chord(Keys.COMMAND,Keys.SUBTRACT)).build().perform();
js.executeScript("arguments[0].dispatchEvent(new KeyboardEvent('keydown',{'key':'Meta'}))",we);
js.executeScript("arguments[0].dispatchEvent(new KeyboardEvent('keydown',{'key':'+'}))",we);
js.executeScript("arguments[0].dispatchEvent(new KeyboardEvent('keyup',{'key':'Meta'}))",we);
js.executeScript("arguments[0].dispatchEvent(new KeyboardEvent('keyup',{'key':'+'}))",we);
options.addArguments("force-device-scale-factor=0.75");
options.addArguments("high-dpi-support=0.75");
WebDriver driver = new ChromeDriver(options);
Only this one worked but its not optimal as the moment I navigate to next screen, the zoom gets resetted.
js.executeScript("document.body.style.zoom='80%'");
I followed all these links but none worked for me. Any help would be much appreciated.
StackOverflowQuestion
Also Robot class doesn't suit me as I had to run in different OSes.

How to take a screenshot of a scrollable in Selenium using Java?

I am a beginner in Selenium.
I have very long scroll-able form which will automation script will fill, is there a way where I can take screenshot when the page is scrolled down every time (web-driver scrolls to fill the form, I haven't scripted to scroll down as web-driver takes care of it), so that the entire form can be captured in multiple screenshots.
Here is how I would do it. On every swipe You can take screenshot, like as step screenshot.
Here is part of code for screenshot take:
public static String takeScreenshot(WebDriver driver) {
driver.get("http://www.google.com/");
File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
// Now you can do whatever you need to do with it, for example copy somewhere
File dest = new File("c:\\tmp\\screenshot.png");
FileUtils.copyFile(scrFile, dest);
return dest.getAbsolutePath();
}
And here is the code for vertical swipe:
public static void swipeVertical(WebDriver driver) {
Dimension size = driver.manage().window().getSize();
System.out.println(size);
int starty = (int) (size.height * 0.70);
int endy = (int) (size.height * 0.30);
int startx = size.width / 2;
new TouchAction(driver)
.press(startx, starty)
.waitAction(Duration.ofMillis(1000))
.moveTo(startx, endy)
.release()
.perform();
}
so my pseudo code would look like this:
WebDriver driver = initDriver();
load page and elements
inputText(text);
takScreenShot(driver);
swipe(driver);
...
repeat until end...
You can capture as many screenshots as you want. After fill in each column, after fill in each third column, whatever.
Or you can let the webdriver fill in the whole form and scroll up/down using press pgup/pgdn simulation:
import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.KeyEvent;
Robot rob = new Robot();
rob.keyPress(KeyEvent.VK_PAGE_DOWN);
rob.keyRelease(KeyEvent.VK_PAGE_DOWN);

AutoCompleteTextField does not respect minimum length on load

On load, when I focus or select the AutoCompleteTextField , the suggestions are showed right away eventhough I set the minimumLength to 4.
This is what is going on:
1) On load , all suggestions are shown in this example
2) Only after I start typing the suggestions behave correctly and they wouldn't show until we meet the 4 character criteria.
You can recreate this issue with the code below from a barebone hello world.
public void start() {
if (current != null) {
current.show();
return;
}
Form hi = new Form("Hi World");
ListModel<String> suggestionsModel = new DefaultListModel<String>();
suggestionsModel.addItem("Apple");
suggestionsModel.addItem("Banana");
suggestionsModel.addItem("Chocolate");
suggestionsModel.addItem("Elk");
suggestionsModel.addItem("Fish");
AutoCompleteTextField search = new AutoCompleteTextField(suggestionsModel);
search.setMinimumLength(4);
suggestionsModel.addSelectionListener(new SelectionListener() {
#Override
public void selectionChanged(int oldSelected, int newSelected) {
System.out.println("SUGGESTION SELECTED"+suggestionsModel.getSelectedIndex());
}
});
hi.add(search);
hi.show();
}
That is a bug on Codename One side... I experienced the same thing. Here is a link for you to file an issue and it will be fixed
https://github.com/codenameone/CodenameOne/issues/new
EDIT:
According to Shai's answer to your previous question, I doubt if the behavior will be changed due to other actions that rely on it.

I can't make swipe gesture work for me in Appium using Java

I can't made Swipe action work. I did browsed through the web for a few days and found many similar questions but there is no working answer. Also I have tried TouchAction class, doesn't work as well.
I have Appium Version 1.4.13 (Draco) and using Java, TestNG framework.
btw I made scrolling work using (you can use the same logic as a pull to refresh) here is code sample.
public void scrollUp() {
JavascriptExecutor js = (JavascriptExecutor) getDriver();
HashMap<String, String> scrollObject = new HashMap<String,String();
scrollObject.put("direction", "up");
scrollObject.put("element", listElements.get(1).getText());
js.executeScript("mobile: scroll", scrollObject);
}
//Method names explain themselves. I hope it works.
public static void swipeFromRightToLeftMultipleTimes(int howManySwipes) {
JavascriptExecutor js = (JavascriptExecutor) iosDriver;
for(int counter=0; counter < howManySwipes; counter++){
HashMap<String, Integer> swipeObject = new HashMap<String, Integer>();
swipeObject.put("startX", getScreenWidth());
swipeObject.put("startY", getScreenHeight());
swipeObject.put("endX", getScreenWidth()/4);
swipeObject.put("endY", getScreenHeight());
swipeObject.put("duration", 2);
js.executeScript("mobile: swipe", swipeObject);
}
}
public static void swipeFromLeftToRightMultipleTimes(int howManySwipes) {
JavascriptExecutor js = (JavascriptExecutor) iosDriver;
for(int counter=0; counter < howManySwipes; counter++){
HashMap<String, Integer> swipeObject = new HashMap<String, Integer>();
swipeObject.put("startX", getScreenWidth()/4);
swipeObject.put("startY", getScreenHeight());
swipeObject.put("endX", getScreenWidth());
swipeObject.put("endY", getScreenHeight());
swipeObject.put("duration", 2);
js.executeScript("mobile: swipe", swipeObject);
}
}
Is this swipe issue in iOS or Android? Further, is it in real devices or simulators. I couldn't find a solution for iOS simulator for Xcode 7.0.1 with iOS 8.x / 9.0. Please let me know if it works for you.
However, Following is the solution perfectly work in Android real device as well in Android Simulator.
When calling swipeElement method provide element as MobileElement. use like this.. this.swipeElement(driver, MobileElement, 200, 3000); If the scroll length is positive then it scrolls to down, negative then scrolls up.
public void swipeElement(AndroidDriver driver, WebElement element, int scrollLength, int duration){
driver.context("NATIVE_APP");
int bottomY = element.getLocation().getY()+scrollLength;
((AppiumDriver)driver).swipe(element.getLocation().getX(), element.getLocation().getY(), element.getLocation().getX(), bottomY, duration);
}
This solution works in iOS simulator with Appium 1.4.13; Java-Client 3.2.0; Xcode 7.0.1; iOS 8.x / 9.0;
Provide 'elementName' where scroll happens to the element.
JavascriptExecutor js = (JavascriptExecutor) iosDriv;
HashMap<String, String> scrollObject = new HashMap<String, String>();
scrollObject.put("element", ((RemoteWebElement) iosDriv.findElement(By.name("elementName"))).getId());
js.executeScript("mobile: scroll", scrollObject);
driver.context("NATIVE_APP");
Dimension size = driver.manage().window().getSize();
int startx = (int) (size.width * 0.8);
int endx = (int) (size.width * 0.20);
int starty = size.height / 2;
driver.swipe(startx, starty, endx, starty, 1000);
Use above code. Change startx to starty if you wish to swipe in opposite direction.
driver.swipe(startingXCoordinate,StartingYCoordinate,EndXCoordinate,EndYCoordinate,timeForSwipe);
Ex: driver.swipe(100,200,450,200,2000);
here, you are swipe from 100th X coordinate to 450th X coordinate.that is why Y coordinates are same for starting and ending points(200 and 200). The last parameter 2 indicates, swipe action will performs 2 seconds.
Actually we have to mention 2000 milliseconds for 2 seconds.

MVC5 DisplayModeProvider registration problems

so I have an mvc 5 application with 3 display modes, desktop (default), mobile, and tablet. I'm using WURFL to figure out devices. Here's the code called from global.cs to register:
public static void RegisterDisplayModes(IList<IDisplayMode> displayModes){
var datafile = HttpContext.Current.Server.MapPath(WurflDataFilePath);
var configurer = new InMemoryConfigurer().MainFile(datafile);
var manager = WURFLManagerBuilder.Build(configurer);
HttpContext.Current.Cache[WURFLMANAGER_CACHE_KEY] = manager;
bool mobileEnabled = ConfigurationManager.AppSettings["EnableMobileSite"] == "true";
bool tabletEnabled = ConfigurationManager.AppSettings["EnableTabletSite"] == "true";
var modeDesktop = new DefaultDisplayMode("") {
ContextCondition = (c => c.Request.IsDesktop())
};
var modeMobile = new DefaultDisplayMode("mobile"){
ContextCondition = (c => c.Request.IsMobile())
};
var modeTablet = new DefaultDisplayMode("tablet"){
ContextCondition = (c => c.Request.IsTablet())
};
displayModes.Clear();
if (mobileEnabled) displayModes.Add(modeMobile);
if (tabletEnabled) displayModes.Add(modeTablet);
displayModes.Add(modeDesktop);
}
I'm using some extension methods to HttpRequestBase, as discussed in http://msdn.microsoft.com/en-us/magazine/dn296507.aspx:
public static bool IsDesktop(this HttpRequestBase request){
return true;
}
public static bool IsMobile(this HttpRequestBase request) {
return IsMobileInternal(request.UserAgent) && !IsForcedDesktop(request);
}
public static bool IsTablet(this HttpRequestBase request) {
return IsTabletInternal(request.UserAgent) && !IsForcedDesktop(request);
}
public static void OverrideBrowser(this HttpRequestBase request, bool forceDesktop){
request.RequestContext.HttpContext.Cache[OVERRIDE_BROWSER_CACHE_KEY] = forceDesktop;
}
public static bool IsForcedDesktop(this HttpRequestBase request){
var isForced = request.RequestContext.HttpContext.Cache[OVERRIDE_BROWSER_CACHE_KEY];
return isForced != null ? isForced.ToString().ToBool() : false;
}
private static bool IsMobileInternal(string userAgent) {
var device = WURFLManagerBuilder.Instance.GetDeviceForRequest(userAgent);
if (device.IsTablet() == true) {
return false;
} else {
return device.IsMobile();
}
}
private static bool IsTabletInternal(string userAgent) {
var device = WURFLManagerBuilder.Instance.GetDeviceForRequest(userAgent);
return device.IsTablet();
}
It all works fine for a while, but then after an hour or so, mobile and tablet devices start displaying the desktop views, and the desktop view starts showing the ViewSwitcher shared view (I assume most people are familiar with it, it just allows you to show the desktop view from a mobile device). It's almost like that caching bug in mvc4. I have tried removing my code to register the display modes, and just went with the default mvc mobile support, and it works fine it has the same issue! So clearly there's a problem in here somewhere... can anyone see anything obvious? Almost impossible to debug cause problems only start coming up after a long time, and even then only on the live system really! Any ideas?
Thanks heaps... been on this issue for way too long now...
Cheers
Andy
EDIT: even stripping it right back to the default implementations creates the issue. I added some debugging code to make sure I'm actually running mvc5, but it appears I am. I've also tried the initially recommended workaround for the issue on mvc4 by disabling the cache, still no joy. Is there really no one with info on this?
So I finally figured it out. Very simple as usual. For some reason I used RequestContext.HttpContext.Cache to save the status when someone wants the full view as opposed to the mobile view. I've never used HttpContext.Cache, I'm pretty sure I would have taken that from a blog somewhere - can't find it anymore though. So all that happened was that it would switch the view for everyone, not just the one person. Can't believe it took weeks to figure that out. Hope it helps someone else at some point.

Resources