I'm starting to automate a test suite for a mobile app coded in NativeScript (it used to be a hybrid Cordova app) and it's proving difficult to locate some elements.
I'm trying to locate a TextView widget that's outside of the visible screen space (AKA viewport) using UiSelector:
#AndroidFindBy(uiAutomator = "new UiSelector().textContains(\"CFT\")")
private MobileElement labelCFT;
When I try to interact with such element, the result is the following message:
org.openqa.selenium.NoSuchElementException: Can't locate an element
by this strategy: By.chained({By.AndroidUIAutomator:
new UiSelector().textContains("CFT")})
The logic conclusion would be that the element does not exist or my locator strategy is faulty. But here is the thing, when I change the text to find for that of an element that's inside the visible space/viewport, the locator works flawlessly. Example:
#AndroidFindBy(uiAutomator = "new UiSelector().textContains(\"loans\")")
private MobileElement labelCFT;
And then:
public void whatText() {
System.out.println("Text of the label: " + labelCFT.getText());
}
I get the correct "Text of the label: These are your loans".
Apparently, it's a limitation of the UiSelector or at least the way Appium works with it.
The only option I imagine is to scroll the whole screen and then trigger #AndroidFindBy, then repeat until there's no scroll left.
Is this suppose to be how UiSelector and textContains() work?
Is it another solution for this?
Many thanks.
I have faced similar type of problems in automation. The only way around I found was to scroll up or down till the element is visible on screen and then access the element by "name". you can use the following command for scrolling.
driver.findElementByAndroidUIAutomator("new UiScrollable(new UiSelector()).scrollIntoView(text(\"Your Element\"));");
After your desired element is visible on the screen you can access that element easily.
Thanks
In Android App you can only click or do any actions on the elements which are visible on the screen if you want to perform any actions on element which are not visible you can use touch action method where you need to specify x and y cordinated i think this might help you in my case this works
TouchAction ta = new TouchAction(driver);
ta.press(PointOption.point(207, 582)).moveTo(PointOption.point(8, -360)).release().perform();
Related
As you can see in this picture, I can't locate the Id or XPath of the details I want to click. I'm using AndroidDriver.
I had tried the following codes:
AndroidElement searchView = androidDriver.FindElementByAndroidUIAutomator("new UiScrollable(new UiSelector()).scrollIntoView(text(\"Tribology Testing\"));");
but I still can't get the Tribology Testing being select.
We cannot help you to come up with the correct element locator without seeing your application layout, screenshot doesn't help at all.
You can see the layout by invoking AndroidDriver.getPageSource() function - it will print all the UI hierarchy of the current screen and you will be able to create the corresponding selector.
Another options are:
Android Device Monitor (part of Android SDK)
Layout Inspector (part of Android Studio)
XPath Feature of the Appium Studio
As, you can see in the above snippet, when i try to locate value e.g.. '16' in this case or i would like to scroll to select any other value. I am unable to select or scroll from this window. Is it possible to select value using robot framework with appium library. suggestions are most welcome.
One approach you can follow to do this is as follows:
First get the position of the element which is visible(In your case 16).
If you want to scroll down click on the element above 16 by substracting some pixels from the location you get in step 1.Verify for the element you want is highlighted or not.
I am working to automate an android app which have some screen of webview too. I am unable to click the right element through xpath class, with index or even with giving name text.
If you see these screenshots it is visible that when I inspect element i get link to somewhere else. i tried using getlocation and then pass it for click but it also getting me wrong click.
I tried touchaction class methods but they are not working. My code get pass through appium but the methods tap or press nothing.
I tried this way too but no luck.
WebElement Quiz1 = (new WebDriverWait(driver , 20))
.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//android.view.View[contains(#content-desc,'Die Wish App')]")));
Quiz1.click();
Any help would be appreciated. Also how can I use webview rather than webelement? and which one is preferable?
You can click on the element which you have highlighted in the screenshot.Below is the locator to identify that element
By.accessibilityId("Die Wish App")
I have UITableViewCell which has Subject,Name,Description,time. When I am testing this on Appium the xpath changed for UIElement for Subject line only.
xpath:-subject line: //UIAApplication[1]/UIAWindow[1]/UIATableView[1]/UIATableCell[3]**/UIAStaticText[2]**
after changes
xpath:-subject line: //UIAApplication[1]/UIAWindow[1]/UIATableView[1]/UIATableCell[3]**/UIAStaticText[3]**
Which is giving another UI element details, which fails the testing. How to handle this from Appium, or do I need to fix it from Xcode?
Basing on xpaths is not a really good idea.
But sometimes it is the only way to develop your scripts if there are no static ids nor accessibility labels available.
Your element that was previously set as: UIAStaticText[2], so as I suppose it was second element available at current screen. Now looks like UIAStaticText[3] - it is marked as third. If you are not able to see changes on the screen that you are automating, that can be caused because of an element that is under in the background it can be hidden.
The best approach will be with using static resource id's in your scripts or accessibility labels which you have mentioned in comment you've them already set and available.
We're using Appium with iOS Simulator and test functions written in Java.
We have an iOS App with screen 1 containing a UICollection view, and tell Appium to click on one of its elements.
This opens screen 2 (and the scrolling animation takes about 500 ms), which also contains an UICollection view. I want to find out the size of the UICollection view of the second screen with Appium.
The problem is that Appium is too fast and executes the findElements() method directly after the click, which causes it to find the UICollection view of the first screen.
clickOnElementOnFirstScreen();
webDriver.findElements( By.className( "UIACollectionCell" ) ).size();
// is supposed to find the UICollection view on the second screen,
// but actually finds the UICollection view on the first screen
Appium provides several waiting functions. However as far as I can see all of them are intended to be used in this fashion:
"wait until element at location X / with name X becomes visible"
If I try to use these waiting functions, they don't wait at all because they immediately find the UICollection view of the first screen, which has the same location and name as the one on the second screen.
The only solution I have found is to use Thread.sleep:
Thread.sleep(1000);
webDriver.findElements( By.className( "UIACollectionCell" ) ).size();
But we don't want to use Thread.sleep in code that will run on the client's server on hundreds of tests.
We might be able to modify the App and enter metadata into the views so that Appium is able to distinguish them, but this situation occurs in several places and the App is being programmed by the client, so we want to avoid this too.
What is a simple and safe way to wait for the new screen to appear, without modifying the code of the iOS App?
I have found only dirty workaround for this issue.
static waitFor(Duration duration) {
try {
def WebDriverWait wait = new WebDriverWait(mobileDriver, duration.standardSeconds)
wait.until(visibilityOfElementLocated(By.xpath("//Fail")))
//Wait until false case is visible to ensure proper timeout
} catch (Exception e) {
}
}
Another workaround/solution that has been posted on the Appium forums is:
First search for some other element that distinguishes the 2. screen from the 1. screen; once that is visible, it's safe to search for the originally desired element.