![](/img/trans.png)
[英]Selenium - Difference between WebDriver.findElement() and WebElement.findElement()
[英]Selenium WebDriver: wait for element to be present when locating with WebDriver.findElement is impossible
等待WebElement
與WebDriverWait
和ExpectedConditions
一起出現是很方便的。
問題是, 如果WebElement.findElment
是唯一可能找到元素的方法,那該怎么辦?因為它沒有id,沒有名字,沒有唯一的類?
WebDriverWait
的構造函數只接受WebDriver
作為參數,而不接受WebElement
。
我已經設置了implicitlyWait
等待時間,所以使用try{} catch(NoSuchElementException e){}
似乎不是一個好主意,因為我不想等待這個元素的那么長時間。
這是場景:
有一個網頁,其中包含一個包含許多input
標簽的表單。 每個input
標簽都有格式要求。
當不滿足格式要求時,在此input
標記之后將存在動態div
標記。
由於有很多input
標簽,我創建了一個通用的方法,如:
public WebElement txtBox(String name) {
return driver.findElement(By.name(name));
}
而不是為每個input
標簽創建數據成員。
然后我創建一個方法isValid
來檢查某些input
中的用戶輸入是否有效。 我在isValid
應該做的就是檢查inputboxToCheck
之后是否存在div
標簽,代碼如下:
public boolean isValid(WebElement inputboxToCheck) {
WebElementWait wait = new WebElementWait(inputboxToCheck, 1);
try {
wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("./following-sibling::div")));
return false;
} catch (TimeOutException e) {
return true;
}
}
WebElementWait
是一個虛構的(不存在的)類,其工作方式與WebDriverWait
相同。
上面提到的WebElementWait類:
package org.openqa.selenium.support.ui;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.NotFoundException;
import org.openqa.selenium.WebElement;
public class WebElementWait extends FluentWait<WebElement> {
public final static long DEFAULT_SLEEP_TIMEOUT = 500;
public WebElementWait(WebElement element, long timeOutInSeconds) {
this(element, new SystemClock(), Sleeper.SYSTEM_SLEEPER, timeOutInSeconds, DEFAULT_SLEEP_TIMEOUT);
}
public WebElementWait(WebElement element, long timeOutInSeconds, long sleepInMillis) {
this(element, new SystemClock(), Sleeper.SYSTEM_SLEEPER, timeOutInSeconds, sleepInMillis);
}
protected WebElementWait(WebElement element, Clock clock, Sleeper sleeper, long timeOutInSeconds,
long sleepTimeOut) {
super(element, clock, sleeper);
withTimeout(timeOutInSeconds, TimeUnit.SECONDS);
pollingEvery(sleepTimeOut, TimeUnit.MILLISECONDS);
ignoring(NotFoundException.class);
}
}
它與WebDriverWait相同,只是WebDriver
參數被WebElement
替換。
然后,isValid方法:
//import com.google.common.base.Function;
//import org.openqa.selenium.TimeoutException;
public boolean isValid(WebElement e) {
try {
WebElementWait wait = new WebElementWait(e, 1);
//@SuppressWarnings("unused")
//WebElement icon =
wait.until(new Function<WebElement, WebElement>() {
public WebElement apply(WebElement d) {
return d.findElement(By
.xpath("./following-sibling::div[class='invalid-icon']"));
}
});
return false;
} catch (TimeoutException exception) {
return true;
}
}
我不知道這是否對你有所幫助,但它允許等待元素你想要多少時間。
public WebElement findDynamicElement(By by, int timeOut) {
WebDriverWait wait = new WebDriverWait(driver, timeOut);
WebElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(by));
return element;
}
findDynamicElement(By.xpath("//body") , 30);
user2432405解決方案的一個更通用的變體是使用SearchContext類型而不是WebElement:
public class SearchContextWait extends FluentWait<SearchContext> {
...
這允許在WebDriver和WebElement上進行等待,就像SearchContext接口是WebDriver和WebElement的祖先一樣。 isValid方法也需要調整:
...
WebElement icon = wait
.until(new Function<SearchContext, WebElement>() {
public WebElement apply(SearchContext d) {
...
不幸的是,當你在內部使用WebDriver接口時,你失去了ExpectedConditions.xxxx()方法的所有便利。
我發現這個博客:檢查一個元素 - 存在?,可見?,存在? - https://jkotests.wordpress.com/2012/11/02/checking-for-an-element-exists-visible-present/
它帶來了存在,可見和現在之間的差異。
- 存在? - 返回此元素是否確實存在。
- 當下? - 如果元素存在且在頁面上可見,則返回true
- 可見? - 如果任何父元素不可見,那么我們就不能寫入元素。 確定這一點的唯一可靠方法是迭代DOM元素樹,檢查每個元素以確保它
可見。
存在將告訴您,您正在搜索的內容是否在DOM中的任何位置; 但是, WebDriver
似乎沒有內置的方法來檢查元素是否存在,類似於普通的driver.findElement(By.name(name))
。
而且,正如博客中所解釋的, Exists與Present不同 。 所以我不能使用ExpectedConditions.presenceOfAllElementLocatedBy(By.cssSelector(cssSelector)
我的解決方案:(在這里尋找反饋:)
public WebElement waitForElementExists(String selector, String timeout) {
Wait<WebDriver> wait = new WebDriverWait(driver, timeout);
WebElement element = wait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(By.cssSelector(selector));
}
});
return element;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.