Java 在 Selenium 中避免 NoSuchElementException 的最佳方法是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19536954/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the best way to avoid NoSuchElementException in Selenium?
提问by Parminder Singh
I have written few test cases in Selenium WebDriver using Java and execute them on grid (hub and multiple nodes). I have noticed that a few test cases fail due to NoSuchElementException
. What is the best and robust way to avoid NoSuchElementException
and ensure the element is always found?
我使用 Java 在 Selenium WebDriver 中编写了一些测试用例,并在网格(集线器和多个节点)上执行它们。我注意到一些测试用例由于NoSuchElementException
. 避免NoSuchElementException
和确保始终找到元素的最佳和可靠方法是什么?
采纳答案by Petr Mensik
You can never be sure that element will be found, actually this is purpose of functional tests - to tell you if anything changed on your page. But one thing which definitely helps is to add waits for the elements which are often causing NoSuchElementException
like
您永远无法确定会找到该元素,实际上这是功能测试的目的 - 告诉您页面上是否有任何更改。但是绝对有帮助的一件事是添加等待元素,这些元素通常会导致NoSuchElementException
像
WebDriverWait wait = new WebDriverWait(webDriver, timeoutInSeconds);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id<locator>));
回答by Amith
you can also use FluentWait
,
你也可以使用FluentWait
,
Each FluentWait
instance defines the maximum amount of time to wait for a condition, as well as the frequency with which to check the condition.
每个FluentWait
实例定义等待条件的最长时间,以及检查条件的频率。
Furthermore, the user may configure the wait to ignore specific types of exceptions whilst waiting, such as NoSuchElementExceptions
when searching for an element on the page.
此外,用户可以将等待配置为在等待时忽略特定类型的异常,例如NoSuchElementExceptions
在页面上搜索元素时。
// Waiting 30 seconds for an element to be present on the page, checking
// for its presence once every 5 seconds.
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(30, SECONDS)
.pollingEvery(5, SECONDS)
.ignoring(NoSuchElementException.class);
WebElement foo = wait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(By.id("foo"));
}
});
回答by eugene.polschikov
I completely agree to Petr Mensik above. The matter you can never say whether element is present. You should clearly understand why when it happens. From my experience I should say that it happens due to the following reasons:
我完全同意上面的 Petr Mensik。你永远不能说元素是否存在。当它发生时,您应该清楚地了解原因。根据我的经验,我应该说它的发生是由于以下原因:
- 1) The page is still being rendered and you've already finished your element search and obtain no element exception.
- 2) The second reason is AJAX has not returned yet and you've already
obtain
NoSuchElementException
- 3) The third is most obvious: The element is really not on the page whenever.
- 1)页面仍在渲染中,您已经完成了元素搜索并且没有获得元素异常。
- 2)第二个原因是AJAX还没有返回,你已经获取了
NoSuchElementException
- 3)第三个是最明显的:该元素真的不在页面上。
so the most robust IMHO way to handle all these three conditions using one function call is to use fluentWait
as Amith003 suggested.
所以使用一个函数调用来处理所有这三个条件的最健壮的恕我直言的方法是使用fluentWait
Amith003 建议。
so the code be the following:
所以代码如下:
let ur element has the locator:
让你的元素有定位器:
String elLocXpath= "..blablabla";
WebElement myButton= fluentWait(By.xpath(elLocXpath));
myButton.click();
public WebElement fluentWait(final By locator){
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(30, TimeUnit.SECONDS)
.pollingEvery(5, TimeUnit.SECONDS)
.ignoring(org.openqa.selenium.NoSuchElementException.class);
WebElement foo = wait.until(
new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(locator);
}
}
);
return foo;
};
Also if your purpose is robust code wrap fluentWait()
with a try{} catch{}
block.
此外,如果您的目的是fluentWait()
使用try{} catch{}
块进行健壮的代码包装。
Also don't forget about
也不要忘记
public boolean isElementPresent(By selector)
{
return driver.findElements(selector).size()>0;
}
that is also useful.
这也很有用。
So to conclude all the mentioned if you want to avoid NoElement
exception just handle it properly as nobody can ensure in the element presence on the page.
所以总结所有提到的,如果你想避免NoElement
异常,只需正确处理它,因为没有人可以确保页面上的元素存在。
Hope now it is more clear to you. Regards
希望现在你更清楚了。问候
回答by Satish
WebDriverWait wait = new WebDriverWait(webDriver, timeoutInSeconds);
wait.until(ExpectedConditions.elementToBeClickable(By.id<locator>));
elementToBeClickablewaits for Enableand Visibleof an Element
elementToBeClickable等待元素的启用和可见
回答by Ashwini
public WebElement fluientWaitforElement(WebElement element, int timoutSec, int pollingSec) {
FluentWait<WebDriver> fWait = new FluentWait<WebDriver>(driver).withTimeout(timoutSec, TimeUnit.SECONDS)
.pollingEvery(pollingSec, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class, TimeoutException.class);
for (int i = 0; i < 2; i++) {
try {
//fWait.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("//*[@id='reportmanager-wrapper']/div[1]/div[2]/ul/li/span[3]/i[@data-original--title='We are processing through trillions of data events, this insight may take more than 15 minutes to complete.']")));
fWait.until(ExpectedConditions.visibilityOf(element));
fWait.until(ExpectedConditions.elementToBeClickable(element));
}
catch (Exception e) {
System.out.println("Element Not found trying again - " + element.toString().substring(70));
e.printStackTrace();
}
}
return element;
}
回答by Chetu19
I usually use this line in the main function
我通常在主函数中使用这一行
public static void main(String[] args) throws ParseException {
driver= new ChromeDriver();
driver.manage().window().maximize();
**driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);**
Hope this helps.
希望这可以帮助。
回答by Ankit Vijay
We can apply below codes to remove this exception condition
我们可以应用以下代码来删除此异常条件
By applying WebDriverWait, webdriver object wait for a specific time (in second) of an element for its visibility.
WebDriverWait wait = new WebDriverWait(driver, 10); wait.until(ExpectedConditions.visibilityOf(link));
We can handle NoSuchElementException through try-catch block inside Generic method
public boolean isElementPresent(By by) { boolean isPresent = true; try { driver.findElement(by); } catch (NoSuchElementException e) { isPresent = false; } return isPresent }
通过应用 WebDriverWait,webdriver 对象等待元素的特定时间(以秒为单位)以使其可见。
WebDriverWait wait = new WebDriverWait(driver, 10); wait.until(ExpectedConditions.visibilityOf(link));
我们可以通过泛型方法中的 try-catch 块处理 NoSuchElementException
public boolean isElementPresent(By by) { boolean isPresent = true; try { driver.findElement(by); } catch (NoSuchElementException e) { isPresent = false; } return isPresent }
http://selenium-code.blogspot.in/2017/08/selenium-exception-nosuchelementexcepti.html
http://selenium-code.blogspot.in/2017/08/selenium-exception-nosuchelementexcepti.html
回答by Blay Wille
Sometimes it is possible to wait for the download of the desired item.
有时可以等待所需项目的下载。
driver.get("https://zzzzzzzzz.market/items/mirage_prime_set")
WebDriverWait(driver, 20)
.until(
EC.visibility_of_element_located(
(By.XPATH, ('//div[@class="orders-row__element order__price sell_color"]')
)))
Sometimes you need to do something so that the UI framework loads the data. For example scroll page
有时您需要做一些事情以便 UI 框架加载数据。例如滚动页面
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
And then get the necessary data
然后得到必要的数据
responsetext=driver.page_source
from lxml import html
parsed_body = html.fromstring(responsetext)
obj1 = parsed_body.xpath('.//div[@class="orders-row__element order__price sell_color"]/span[1]')
print(len(obj1))