appium三種等待元素的方法
阿新 • • 發佈:2019-01-27
學過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"));
}
});