2

I would like to wait for MobilElement, not sure what is the correct way.

Using Appium, Selenium and Java to create some automation tests, but running all using emulator and sometimes I need to wait little bit for element, I would like to use something what I use in webElement. Reason why I use find by class is in application there are no ids and I can not change it.

public static MobileElement myButton(AndroidDriver driver, int index) {
    List<MobileElement> button = driver.findElements(By.className("android.widget.Button"));

    return  button.get(index);
}

Emulator is slow for me so I would like to use something like waitForElement method

Alexey Usharovski
  • 1,404
  • 13
  • 31
Karol
  • 165
  • 2
  • 6
  • 19

3 Answers3

0

You can implement an Implicit wait. Which is basically waiting for a certain amount of time before throwing an exception that it cannot find the element on the page.

WebDriver driver => new FirefoxDriver();

 driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

 driver.get("http://url_that_delays_loading");

 WebElement myDynamicElement = driver.findElement(By.id("myDynamicElement"));

Another way is to use Expected Conditions wait to evaluate that something is neither null nor false.

 WebDriverWait wait = new WebDriverWait(driver, 10);

 WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id(>someid>)));

To wait for the page to load to set the amount of time to wait for a page load to complete before throwing an error. If the timeout is negative, page loads can be indefinite.

driver.manage().timeouts().pageLoadTimeout(100, SECONDS);

Thread.Sleep also can be used, but it's not an ideal wait declaration.

 thread.sleep(1000);
Nata Sturza
  • 311
  • 3
  • 4
  • Hi, thank you for your answer, but in my case I don't want to define Webdriver, I want to use Android driver. I don't test app in any browser, I am testing mobile application and all tests are done there. Using atm thread.sleep but I want to change for wait for element etc – Karol Aug 28 '19 at 07:34
0

UPDATE

Try use visibilityOf, like this:

public static MobileElement myButton(AndroidDriver driver, int index) {
    List<MobileElement> button = driver.findElements(By.className("android.widget.Button"));

    //update here
    new WebDriverWait(driver, 30).until(ExpectedConditions.visibilityOf(button.get(index)));
    return  button.get(index);
}

30 in second.

frianH
  • 7,295
  • 6
  • 20
  • 45
  • Thank you for your answer, if I use this code I can see . The method visibilityOfAllElements(WebElement...) in the type ExpectedConditions is not applicable for the arguments (List). So I was trying with something like this. new WebDriverWait(driver, 30).until(ExpectedConditions.visibilityOfAllElementsLocatedBy((By) enrollKeyboard)); but then I can this java.util.ArrayList cannot be cast to org.openqa.selenium.By :( – Karol Aug 28 '19 at 09:00
  • Thank you very much, code is correct now, but I don't think is is actually waits :( I set wait for 2 minutes "new WebDriverWait(driver, 120)" but is fails without waits 2 minutes – Karol Aug 28 '19 at 10:21
0

Sure you can, just change this line:

List<MobileElement> button = driver.findElements(By.className("android.widget.Button"));

to this assuming WebDriverWait class usage for Explicit Wait implementation :

List<MobileElement> button = new WebDriverWait(driver, 10)
        .until(ExpectedConditions.presenceOfAllElementsLocatedBy(By.className("android.widget.Button")))
        .stream()
        .map(element -> (MobileElement) element)
        .collect(Collectors.toList());    

Going forward you can consider implementing Page Object Model design pattern and use @AndroidFindBy annotation, check out https://github.com/appium/java-client/blob/master/docs/Page-objects.md for example code.

Dmitri T
  • 159,985
  • 5
  • 83
  • 133