學過selenium的都知道,通常等待元素加載有三種辦法:java
示例:driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
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中也找不到相應的,若是想使用這種方法怎麼辦?android
改造輪子,首先添加AndroidDriverWait.java, 實際上是將WebDriverWait的類型改爲AndroidDriverWaitapp
具體代碼以下:less
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 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的類型替換爲AndroidDriveride
具體代碼:ui
public interface ExpectedCondition<T> extends Function<AndroidDriver, T> {}this
通過修改以後,就能夠在appium中直接使用:spa
//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")); } });