学过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 {[url=home.php?mod=space&uid=26824]@link[/url] FluentWait} that uses WebDriver instances.
- */
- public class AndroidDriverWait extends FluentWait<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)
- */
- public AndroidDriverWait(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)
- */
- public AndroidDriverWait(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.
- */
- public AndroidDriverWait(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"));
- }
- });
复制代码
|