Appium + Selenium Android: ListView element not clicked without Thread.sleep

I hate using "sleepers" (Thread.sleep(millis) ) in tests, but without sleepers some tests fail.

I have a ListView in my Android application and I want to use the first item in the list (SAUDI ARABIA in our case).

ListView Countries

  public AndroidDriver androidDriver; ... androidDriver = new AndroidDriver(serverAddress, capabilities); androidDriver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS); driverWait = new WebDriverWait(androidDriver, 30); // at this moment everything is initialized and working properly, // Appium server is up and running driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.id("com.###.debug:id/countries_list_view"))); WebElement countriesList = driver.findElement(By.id("com.###.debug:id/countries_list_view")); List<WebElement> countries = countriesList.findElements(By.id("com.###.debug:id/list_item_container")); WebElement country = countries.get(0); // country isn't null, and it corresponds to a real ListView row driverWait.until(ExpectedConditions.elementToBeClickable(country)); Thread.sleep(1000); // <---- country isn't clicked without this country.click(); 

The same problem exists in Calabash/Cucumber tests (an explicit wait is required).

I tried different ways of waiting for the item to click

  • driverWait.until(ExpectedConditions.visibilityOfElementLocated(By));
  • driverWait.until(ExpectedConditions.visibilityOf(WebElement));
  • driverWait.until(ExpectedConditions.elementToBeClickable(By));
  • driverWait.until(ExpectedConditions.presenceOfElementLocated(By));

and no one works. At the moment when I try to click on the 1st item in the ListView , the ListView exists and all the list items are on the screen.

I tried to find ListView 1st row by getting an XPath list row using the Appium Inspector . The result is the same - the view is not clicked without Thread.sleep .

Using Thread.sleep in tests is really bad practice and makes my tests unstable. In this case, I can’t rely on the test results, as they can fail even if the application works correctly. There's an article about using "wait" and "sleep" in Selenium tests ( Selenium WebDriver is waiting ).

  • How to fix such problems in tests?
  • How often are Thread.sleep calls used in the automation world? (I'm mainly an Android developer, not one that has mobile automation experience).

UPDATE: I tried not to mix implicit and explicit expectations, as mentioned by JeffC , and that didn't help.

Here is my test:

 @Test public void selectCountryLanguageAndStartApplication() throws Exception { countryLanguagePage.loaded(); countryLanguagePage.selectFirstCountry(); countryLanguagePage.pleaseSelectCountryTextIsHidden(); countryLanguagePage.startClick(); } ... /** * Verify the page has loaded */ public static void loaded() { driver.findElement(By.id("com.###.debug:id/countries_list_view")); } 

I check if the page is loaded in each test. If I use only implicit expectations, the test fails from time to time; if I use only explicit expectations - this is the same, the test fails from time to time.

I found in the Appium tutorial that they use implicit in combination with explicit 1 , 2 . It looks weird according to the docs .

Working solution: I slightly modified the loaded method

 public static void loaded() { driver.findElement(By.id("com.###.debug:id/countries_list_view")); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } 

Having this dream brings β€œstability” to test, and I can find the elements and click on them with or without explicit expectation.

Does this mean I have to add "sleep" when a new Activity running (the only working solution for me)? Or am I waiting for activity initialization to go wrong?

+5
source share
1 answer

You can try the following:

  WebDriverWait wait = new WebDriverWait(driver, 30); wait.until(ExpectedConditions.elementToBeClickable(By)); 

or

 while(!driver.findElement(By).isDisplayed()) { //Thread.sleep(10); } 

I think that Thread.sleep calls are suitable for use (and almost necessary if your testing involves synchronization), but for the most part there are better ways to handle most of the things for which they will be used.

Hope this helps,

Liam

0
source

Source: https://habr.com/ru/post/1235550/


All Articles