Selenium自動化測試網頁等待的技巧 (Java 範例)
這篇文章主要說明一個網頁自動化致命傷,網頁載入的時間快慢常會導致自動化測試程式失敗,
因此要達到穩定的自動化測試結果,就必須要處理網頁與網路的時間快慢因素,
也就是讓程式”等待”網頁完成相關的動作之後在繼續接下來的程式動作。
我們會討論幾種不同的等待方式與Java範例程式。
Implicit Wait
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS); |
Selenium 會先檢查該元件是否存在,接著等待所指定時間(例如30秒)並且在 retry
當30秒過後還是找不到時就會回傳 Exception.
PageLoadTimeout
driver.manage().timeouts().pageLoadTimeout(20, TimeUnit.SECONDS); |
設定 Selenium 等網頁載入時間
Explicit Wait
當有特定網頁元載入時間明顯會慢於其他原件或是網頁載入時就會使用 Explicit Wait.通常用在 Ajax動態網頁原件上。
例如這個範例針對 name-id的網頁元件等待 30 sec
[pastacode lang=”markup” message=”” highlight=”” provider=”manual”]
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("name-id")));
[/pastacode]
Fluent Wait
什麼是 Fluent Wait 呢
Fluent wait = Explicit Wait + retry 的頻率 + Exception 處理方式
[pastacode lang=”java” message=”” highlight=”” provider=”manual”]
public static boolean untilElementAppears(Element obj, long maxTimeout){
FluentWait<Element> fluentWait = new FluentWait<Element>(obj);
fluentWait.pollingEvery(100, TimeUnit.MILLISECONDS);
fluentWait.withTimeout(maxTimeout, TimeUnit.MILLISECONDS);
try{
fluentWait.until(new Predicate<Element>() {
public boolean apply(Element obj) {
try {
return obj.isDisplayed();
} catch (NoSuchElementException | StaleElementReferenceException e) {
return false;
}
}
});
if(obj instanceof ExtElement){
}
return obj.isDisplayed();
}catch (NoSuchElementException | StaleElementReferenceException | TimeoutException e){
return false;
}
}
[/pastacode]
[pastacode lang=”java” message=”” highlight=”” provider=”manual”]
ublic class Fluent_Wait {
public static void webDriverWait(WebDriver driver, String wElement) {
FluentWait fWait = new FluentWait(driver);
fWait.withTimeout(100, TimeUnit.SECONDS);
fWait.pollingEvery(4, TimeUnit.SECONDS);
WebElement loginTBox = (WebElement) fWait.until(ExpectedConditions.presenceOfElementLocated(By.xpath(wElement)));
//System.out.println("Inside webDriverWait...");
}
}
[/pastacode]
Sleep
Thread. Sleep (30000); |
綜合 Wait Class 範例
[pastacode lang=”java” message=”” highlight=”” provider=”manual”]
public class Wait {
public static boolean untilElementAppears(Element obj){
long maxTimeout = 5000;
return untilElementAppears(obj, maxTimeout);
}
public static boolean untilElementDisappears(Element obj){
long maxTimeout = 5000;
return untilElementDisappears(obj, maxTimeout);
}
public static boolean untilElementAppears(Element obj, long maxTimeout){
FluentWait<Element> fluentWait = new FluentWait<Element>(obj);
fluentWait.pollingEvery(100, TimeUnit.MILLISECONDS);
fluentWait.withTimeout(maxTimeout, TimeUnit.MILLISECONDS);
try{
fluentWait.until(new Predicate<Element>() {
public boolean apply(Element obj) {
try {
return obj.isDisplayed();
} catch (NoSuchElementException | StaleElementReferenceException e) {
return false;
}
}
});
if(obj instanceof ExtElement){
}
return obj.isDisplayed();
}catch (NoSuchElementException | StaleElementReferenceException | TimeoutException e){
return false;
}
}
public static boolean untilElementDisappears(Element obj, long maxTimeout){
FluentWait<Element> fluentWait = new FluentWait<Element>(obj);
fluentWait.pollingEvery(100, TimeUnit.MILLISECONDS);
fluentWait.withTimeout(maxTimeout, TimeUnit.MILLISECONDS);
try{
fluentWait.until(new Predicate<Element>() {
public boolean apply(Element obj) {
try {
return !obj.isDisplayed();
} catch (NoSuchElementException | StaleElementReferenceException e) {
return true;
}
}
});
//Wait.sleep(1000);
return !obj.isDisplayed();
}catch (NoSuchElementException | StaleElementReferenceException | TimeoutException e){
return true;
}
}
public static boolean untilElementIsEnabled(Element obj){
long maxTimeout = 3000;
return untilElementIsEnabled(obj, maxTimeout);
}
public static boolean untilElementIsDisabled(Element obj){
long maxTimeout = 3000;
return untilElementIsDisabled(obj, maxTimeout);
}
public static boolean untilElementIsEnabled(Element obj, long maxTimeout){
boolean enabled = false;
for (int i = 0; i < (maxTimeout/1000); i++) {
if(obj.isEnabled()){
enabled = true;
break;
}
sleep(1000);
}
return enabled;
}
public static boolean untilElementIsDisabled(Element obj, long maxTimeout){
boolean disabled = false;
for (int i = 0; i < (maxTimeout/1000); i++) {
if(!obj.isEnabled()){
disabled = true;
break;
}
sleep(1000);
}
return disabled;
}
public static void sleep(long millis){
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
[/pastacode]