Synchronization in tests with appium

Implicit Wait in Appium

  1. We can set implicit wait timeout for entire session of the driver
  2. If we set the implicit wait as say 10 seconds, Appium will wait for 10 seconds before throwing Element not found exception
  3. The problem with implicit wait is that it will wait for 10 seconds for each element. But Application does not behave that way. Let us say application is dependent on 2 third party services. One service takes say 10 seconds and other takes 20 seconds to respond. In this case, Appium test will pass when verifying the first service but will fail in verifying second service

Page load timeout in Appium

  1. We can set Page load timeout for entire session of the driver
  2. If we set the page load timeout as say 20 seconds, Appium will wait for 20 seconds for new page to load
  3. The problem with page load time out is that it will wait for 20 seconds for each page load. But Application does not behave that way. Each page may take different amount of time to load.

Webdriver Wait (Explicit wait) in Appium

  1. We can set Webdriver wait for specific element. That's the beauty of the Webdriver Wait
  2. Let us say application is dependent on 2 third party services. One service takes say 10 seconds and other takes 20 seconds to respond. In this case, We can set the Webdriver wait of 10 seconds for first service while 20 seconds for second service. This way tests will not be flaky. That's why I recommend that automation testers should use Explicit wait. When you are using explicit wait, You must not use page load timeout and implicit wait in same session.

Webdriver Wait (Explicit wait) example in Appium


package org.softpost.android.simulator;

import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.AndroidElement;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.net.URL;
import java.time.Duration;
import java.util.NoSuchElementException;
import java.util.concurrent.TimeUnit;

/**
 * Created by Sagar on 10-07-2016.
 */
public class SynchWaitTest {
    WebDriver driver;
    private  String securityText = "//android.widget.TextView[@text='Security']";
    private  String touchSensorText = "//android.widget.TextView[@text='Touch the sensor']";
    private  String doneText = "//android.widget.Button[@text='DONE']";

    @Test
    public void test1() throws Exception{
        DesiredCapabilities caps = new DesiredCapabilities();
        caps.setCapability("platformName", "android");

        caps.setCapability("deviceName", "Pixel 9");
        caps.setCapability("appPackage", "com.android.settings");
        caps.setCapability("appActivity","com.android.settings.Settings");
        caps.setCapability("automationName","uiautomator2");

        try {
            driver = new AndroidDriver<AndroidElement>(new URL("http://0.0.0.0:4723/wd/hub"), caps);
            //driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
            //driver.manage().timeouts().pageLoadTimeout(20,TimeUnit.SECONDS);

            //If element is not found within 10 seconds, below code will throw exception
            WebDriverWait wait = new WebDriverWait(driver,10);
            WebElement e = wait.ignoring(NoSuchElementException.class)
                .pollingEvery(Duration.ofSeconds(1))
                .until(ExpectedConditions.visibilityOfElementLocated(By.id("xyz")));
            e.click();

            //below is the custom method
            WaitUntilElementIsDisplayed(By.xpath("//input"),10).click();

        }catch (Exception ex) {
            ex.printStackTrace();
            System.out.println(driver.getPageSource());

        }finally {

            driver.quit();
        }
    }


    protected WebElement WaitUntilElementIsDisplayed(By by, int seconds)
    {
        try
        {
            WebDriverWait wait = new WebDriverWait(driver,10);
            return wait.ignoring(NoSuchElementException.class)
                    .pollingEvery(Duration.ofSeconds(1))
                    .until(ExpectedConditions.visibilityOfElementLocated(by));
        }
        catch (Exception ex)
        {
            System.out.println("Exception while waiting {ex.Message}" + ex.getMessage());
            return null;
        }
    }
}

Web development and Automation testing

solutions delivered!!