1. 程式人生 > >appium三種等待元素的方法

appium三種等待元素的方法

學過selenium的都知道,一般等待元素載入有三種辦法:

  • (1)sleep                  強制等待。示例:Thread.sleep(60000)
  • (2)implicitlyWait   隱式等待。全域性等待30s不管元素是否已經載入
    示例:driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
  • (3)WebDriverWait     顯示等待,這個需要增加一定等待時間,顯示等待時間可以通過WebDriverWait 和util來決定,比如這個timeOut是60,如果該元素60s以內出現就不在等待
WebDriverWait wait = new
WebDriverWait(driver, 60); WebElement e= wait.until(new ExpectedCondition<WebElement>() { @Override public WebElement apply(WebDriver d){ return d.findElement(By.id("q")); } })

  以上三種方法中,只用WebDriverWait是selenium所特有,在java-client中也找不到相應的,如果想使用這種方法怎麼辦?

改造輪子,首先新增AndroidDriverWait.java, 其實是將WebDriverWait的型別改成AndroidDriverWait

具體程式碼如下:

 import org.openqa.selenium.NotFoundException;
 import org.openqa.selenium.TimeoutException;
 import org.openqa.selenium.WebDriver;
 import org.openqa.selenium.WebDriverException;
 import org.openqa.selenium.remote.RemoteWebDriver;
 import
org.openqa.selenium.support.ui.Clock; import org.openqa.selenium.support.ui.FluentWait; import org.openqa.selenium.support.ui.Sleeper; import org.openqa.selenium.support.ui.SystemClock; import io.appium.java_client.android.AndroidDriver; import java.util.concurrent.TimeUnit; /** * A specialization of {@link FluentWait} that uses WebDriver instances. */ public classAndroidDriverWaitextendsFluentWait<AndroidDriver> { public final static long DEFAULT_SLEEP_TIMEOUT = 500; private final WebDriver driver; /** * Wait will ignore instances of NotFoundException that are encountered (thrown) by default in * the 'until' condition, and immediately propagate all others. You can add more to the ignore * list by calling ignoring(exceptions to add). * * @param driver The WebDriver instance to pass to the expected conditions * @param timeOutInSeconds The timeout in seconds when an expectation is called * @see AndroidDriverWait#ignoring(java.lang.Class) */ publicAndroidDriverWait(AndroidDriver driver, long timeOutInSeconds){ this(driver, new SystemClock(), Sleeper.SYSTEM_SLEEPER, timeOutInSeconds, DEFAULT_SLEEP_TIMEOUT); } /** * Wait will ignore instances of NotFoundException that are encountered (thrown) by default in * the 'until' condition, and immediately propagate all others. You can add more to the ignore * list by calling ignoring(exceptions to add). * * @param driver The WebDriver instance to pass to the expected conditions * @param timeOutInSeconds The timeout in seconds when an expectation is called * @param sleepInMillis The duration in milliseconds to sleep between polls. * @see AndroidDriverWait#ignoring(java.lang.Class) */ publicAndroidDriverWait(AndroidDriver driver, long timeOutInSeconds, long sleepInMillis){ this(driver, new SystemClock(), Sleeper.SYSTEM_SLEEPER, timeOutInSeconds, sleepInMillis); } /** * @param driver The WebDriver instance to pass to the expected conditions * @param clock The clock to use when measuring the timeout * @param sleeper Object used to make the current thread go to sleep. * @param timeOutInSeconds The timeout in seconds when an expectation is * @param sleepTimeOut The timeout used whilst sleeping. Defaults to 500ms called. */ publicAndroidDriverWait(AndroidDriver driver, Clock clock, Sleeper sleeper, long timeOutInSeconds, long sleepTimeOut){ super(driver, clock, sleeper); withTimeout(timeOutInSeconds, TimeUnit.SECONDS); pollingEvery(sleepTimeOut, TimeUnit.MILLISECONDS); ignoring(NotFoundException.class); this.driver = driver; } @Override protected RuntimeException timeoutException(String message, Throwable lastException){ TimeoutException ex = new TimeoutException(message, lastException); ex.addInfo(WebDriverException.DRIVER_INFO, driver.getClass().getName()); if (driver instanceof RemoteWebDriver) { RemoteWebDriver remote = (RemoteWebDriver) driver; if (remote.getSessionId() != null) { ex.addInfo(WebDriverException.SESSION_ID, remote.getSessionId().toString()); } if (remote.getCapabilities() != null) { ex.addInfo("Capabilities", remote.getCapabilities().toString()); } } throw ex; } }

接著需要修改介面:ExpectedCondition,將其WebDriver的型別替換為AndroidDriver

具體程式碼:

public interface ExpectedCondition<T> extends Function<AndroidDriver, T> {}

經過修改之後,就可以在appium中直接使用:

        //wait for 60s if WebElemnt show up less than 60s , then return , until 60s
        WebElement showClose = new AndroidDriverWait(driver, 60)
                .until(new ExpectedCondition<WebElement>() {
                    public WebElement apply(AndroidDriver d) {
                        return d.findElement(By
                                .id("com.zhihu.android:id/showcase_close"));
                    }

                });