Please help! Unable to select dynamic elements

I’m currently trying to find & click on each element present on a screen. Currently there are 5 elements but they are dynamic and the number of elements on the screen will vary from time to time.

I would like to try and automate them one by one, whatever is present on the screen.

I have been searching around on how to generate dynamic xpaths for appium/mobile devices but haven’t found anything. There is alot of material online about web stuff but not mobile. Therefore i tried generating my own “dynamic” xpath which i included in the code below.

Here’s the code i wrote:

@When("^I click on the present ctas$")
public void i_click_on_the_present_ctas() throws Throwable {
wait.until(ExpectedConditions.visibilityOf(destinationDetailsScreen.Back_Btn));
driver.swipe(325, 1016, 305, 291, 3000);

    List<MobileElement> linkSearch = driver.findElements(By.xpath("//android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.view.View[1]/android.view.View[1]/android.widget.ScrollView[1]/android.view.View[1]/android.view.View["));
    int checkLink = linkSearch.size();
    if (checkLink != 0) {
        driver.findElement(By.xpath("//android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.view.View[1]/android.view.View[1]/android.widget.ScrollView[1]/android.view.View[1]/android.view.View[")).click();


    }
}

}

The xpath used in the code above was the part of the xpath which is static and i removed the rest. Please find below the default xpaths per element (4 elements) as captured via appium inspector:

//android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.view.View[1]/android.view.View[1]/android.widget.ScrollView[1]/android.view.View[1]/android.view.View[3]/android.view.View[1]/android.view.View[1]/android.widget.Button[1]
//android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.view.View[1]/android.view.View[1]/android.widget.ScrollView[1]/android.view.View[1]/android.view.View[3]/android.view.View[2]/android.view.View[1]/android.widget.Button[1]
//android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.view.View[1]/android.view.View[1]/android.widget.ScrollView[1]/android.view.View[1]/android.view.View[2]/android.view.View[3]/android.view.View[1]/android.widget.Button[1]
//android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.view.View[1]/android.view.View[1]/android.widget.ScrollView[1]/android.view.View[1]/android.view.View[2]/android.view.View[4]/android.view.View[1]/android.widget.Button[1]

Here’s the error logs when i run the above method:

Scenario: test the destination journey Time elapsed: 0.007 sec <<< ERROR!
org.openqa.selenium.InvalidSelectorException: Argument was an invalid selector (e.g. XPath/CSS). (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 21 milliseconds
For documentation on this error, please visit: http://seleniumhq.org/exceptions/invalid_selector_exception.html
Build info: version: ‘2.46.0’, revision: ‘61506a4624b13675f24581e453592342b7485d71’, time: ‘2015-06-04 10:22:50’
System info: host: ‘Parids-MacBook-Pro-2.local’, ip: ‘192.168.15.28’, os.name: ‘Mac OS X’, os.arch: ‘x86_64’, os.version: ‘10.11.6’, java.version: ‘1.8.0_101’
Driver info: io.appium.java_client.android.AndroidDriver
Capabilities [{app=/Users/paridbego/Documents/appium_native1/builds/dev/MeineTUI.apk, networkConnectionEnabled=true, warnings={}, databaseEnabled=false, deviceName=TA06802DPO, platform=LINUX, desired={app=/Users/paridbego/Documents/appium_native1/builds/dev/MeineTUI.apk, platformName=Android, deviceName=TA06802DPO}, platformVersion=5.1, webStorageEnabled=false, locationContextEnabled=false, browserName=Android, takesScreenshot=true, javascriptEnabled=true, platformName=Android}]
Session ID: ff77b245-e329-4b8c-95ae-c0334701e538
*** Element info: {Using=xpath, value=//android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.view.View[1]/android.view.View[1]/android.widget.ScrollView[1]/android.view.View[1]/android.view.View[}
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:204)
at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:156)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:605)
at io.appium.java_client.DefaultGenericMobileDriver.execute(DefaultGenericMobileDriver.java:27)
at io.appium.java_client.AppiumDriver.execute(AppiumDriver.java:1)
at io.appium.java_client.android.AndroidDriver.execute(AndroidDriver.java:1)
at org.openqa.selenium.remote.RemoteWebDriver.findElements(RemoteWebDriver.java:383)
at org.openqa.selenium.remote.RemoteWebDriver.findElementsByXPath(RemoteWebDriver.java:459)
at io.appium.java_client.DefaultGenericMobileDriver.findElementsByXPath(DefaultGenericMobileDriver.java:103)
at io.appium.java_client.AppiumDriver.findElementsByXPath(AppiumDriver.java:159)
at org.openqa.selenium.By$ByXPath.findElements(By.java:353)
at org.openqa.selenium.remote.RemoteWebDriver.findElements(RemoteWebDriver.java:346)
at io.appium.java_client.DefaultGenericMobileDriver.findElements(DefaultGenericMobileDriver.java:32)
at io.appium.java_client.AppiumDriver.findElements(AppiumDriver.java:126)
at com.tui.steps.DestinationDetailsSteps.i_click_on_the_present_ctas(DestinationDetailsSteps.java:36)
at ✽.And I click on the present ctas(EndtoEnd.feature:16)

Results :

Tests in error:
And I click on the present ctas(Scenario: test the destination journey): Argument was an invalid selector (e.g. XPath/CSS). (WARNING: The server did not provide any stacktrace information)(…)
Scenario: test the destination journey: Argument was an invalid selector (e.g. XPath/CSS). (WARNING: The server did not provide any stacktrace information)(…)

Tests run: 9, Failures: 0, Errors: 2, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:19 min
[INFO] Finished at: 2016-08-25T12:50:39+01:00
[INFO] Final Memory: 20M/246M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test (default-test) on project native: There are test failures.
[ERROR]
[ERROR] Please refer to /Users/paridbego/Documents/appium_native1/target/surefire-reports for the individual test results.
[ERROR] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException
Parids-MacBook-Pro-2:appium_native1 paridbego$

Thanks in advance for your help!!!

your xpath is not properly terminated. no closure clamp at the end. Alternatively, try to remove the clamp opening at the end of xpath.
Maybe try find elements by resource-id?

Hello there

Thanks for your reply, much appreciated. The app is based on Appcelerator Titanium framework and apparently you cannot assign resource-id’s which is super frustrating. Since my initial post here I tried various ways of formating the xpath but with little success so far. I will try an xpath using the content description and see if that works.

Maybe the loop. First gets the page and then click elements. Next again gets page and equals a first one. If the page are different click elements. if not ends loop

Hi ,

Yes i did partially fix the issue. However i can’t seem to find a way to scroll to all elements and click on each one. Currently i scroll up and down the page and click on most of the elements and not all. Any ideas on how i can click on all elements present in the screen? Here’s the code i’m currently using:

driver.scrollTo(“destinationCTA”);

   List<MobileElement> linkSearch = driver.findElements(By.xpath("//android.widget.Button[@content-desc='destinationCTA.']"));

    for (int i=1; i<=linkSearch.size(); i++)
    {
        linkSearch = driver.findElements(By.xpath("//android.widget.Button[@content-desc='destinationCTA.']"));
        wait.until(ExpectedConditions.visibilityOf(linkSearch.get(i-1)));
        linkSearch.get(i-1).click();
        destinationDetailsScreen.Back_Btn.click();
    }

Thanks in advance for your help!