如何等到元素不再存在于 Selenium 中
How to wait until an element no longer exists in Selenium
我正在测试一个 UI,其中用户单击删除按钮后 table 条目消失。因此,我希望能够检查 table 条目是否不再存在。
我已经尝试使用 ExpectedConditions.not()
来反转 ExpectedConditions.presenceOfElementLocated()
,希望这意味着 "expect that there is not a presence of the specified element"。我的代码是这样的:
browser.navigate().to("http://whosebug.com");
new WebDriverWait(browser, 1).until(
ExpectedConditions.not(
ExpectedConditions.presenceOfElementLocated(By.id("foo"))));
但是,我发现即使这样做,我也会得到一个由 NoSuchElementException
引起的 TimeoutExpcetion
,表示元素 "foo" 不存在。当然,没有这个元素是我想要的,但我不想抛出异常。
那么我如何才能等到某个元素不再存在呢?如果可能的话,我更喜欢一个不依赖于捕获异常的示例(据我所知,应该为异常行为抛出异常)。
解决方案仍然依赖于异常处理。这很好,甚至 standard Expected Conditions 依赖于 findElement()
.
抛出的异常
想法是创建一个自定义预期条件:
public static ExpectedCondition<Boolean> absenceOfElementLocated(
final By locator) {
return new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver driver) {
try {
driver.findElement(locator);
return false;
} catch (NoSuchElementException e) {
return true;
} catch (StaleElementReferenceException e) {
return true;
}
}
@Override
public String toString() {
return "element to not being present: " + locator;
}
};
}
为什么不简单地求 elements
的大小呢?我们知道如果 element 不存在,元素集合的 size 将是 0。
if(driver.findElements(By.id("foo").size() > 0 ){
//It should fail
}else{
//pass
}
您也可以使用 -
new WebDriverWait(driver, 10).until(ExpectedConditions.invisibilityOfElementLocated(locator));
如果您查看其中的 the source,您可以看到 NoSuchElementException
和 staleElementReferenceException
都已处理。
/**
* An expectation for checking that an element is either invisible or not
* present on the DOM.
*
* @param locator used to find the element
*/
public static ExpectedCondition<Boolean> invisibilityOfElementLocated(
final By locator) {
return new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver driver) {
try {
return !(findElement(locator, driver).isDisplayed());
} catch (NoSuchElementException e) {
// Returns true because the element is not present in DOM. The
// try block checks if the element is present but is invisible.
return true;
} catch (StaleElementReferenceException e) {
// Returns true because stale element reference implies that element
// is no longer visible.
return true;
}
}
// pseudo code
public Fun<driver,webelement> ElemtDisappear(locator)
{
webelement element=null;
iList<webelement> elemt =null;
return driver=>
{
try
{
elemt = driver.findelements(By.locator);
if(elemt.count!=0)
{
element=driver.findelement(By.locator);
}
}
catch(Exception e)
{
}
return(elemnt==0)?element:null;
};
// call function
public void waitforelemDiappear(driver,locator)
{
webdriverwaiter wait = new webdriverwaiter(driver,time);
try
{
wait.until(ElemtDisappear(locator));
}
catch(Exception e)
{
}
}
由于 findelement 在元素上抛出异常 unaviability.so 我使用 findelements 实现。请随时根据您的需要进行更正和使用。
我找到了一种有效解决此问题的解决方法,使用以下 C# 代码来处理此问题,您可以将其转换为 Java
public bool WaitForElementDisapper(By element)
{
try
{
while (true)
{
try
{
if (driver.FindElement(element).Displayed)
Thread.Sleep(2000);
}
catch (NoSuchElementException)
{
break;
}
}
return true;
}
catch (Exception e)
{
logger.Error(e.Message);
return false;
}
}
我不知道为什么,但 ExpectedConditions.invisibilityOf(element)
是我唯一的作品,而 ExpectedConditions.invisibilityOfElementLocated(By)
、!ExpectedConditions.presenceOfElementLocated(By)
... 不是。试试吧!
希望对您有所帮助!
好消息,现在内置了(我在2021年使用Node.js)
看起来 elementIsNotVisible
已添加到 until
之前的答案给出后。我正在使用 selenium webdriver 4.0.0-beta.3
查看:
const timeout = 60 * 1000; // 60 seconds
const element = await driver.findElement(By.id(elementId));
// this is the important line
await driver.wait(until.elementIsNotVisible(element), timeout);
我正在测试一个 UI,其中用户单击删除按钮后 table 条目消失。因此,我希望能够检查 table 条目是否不再存在。
我已经尝试使用 ExpectedConditions.not()
来反转 ExpectedConditions.presenceOfElementLocated()
,希望这意味着 "expect that there is not a presence of the specified element"。我的代码是这样的:
browser.navigate().to("http://whosebug.com");
new WebDriverWait(browser, 1).until(
ExpectedConditions.not(
ExpectedConditions.presenceOfElementLocated(By.id("foo"))));
但是,我发现即使这样做,我也会得到一个由 NoSuchElementException
引起的 TimeoutExpcetion
,表示元素 "foo" 不存在。当然,没有这个元素是我想要的,但我不想抛出异常。
那么我如何才能等到某个元素不再存在呢?如果可能的话,我更喜欢一个不依赖于捕获异常的示例(据我所知,应该为异常行为抛出异常)。
解决方案仍然依赖于异常处理。这很好,甚至 standard Expected Conditions 依赖于 findElement()
.
想法是创建一个自定义预期条件:
public static ExpectedCondition<Boolean> absenceOfElementLocated(
final By locator) {
return new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver driver) {
try {
driver.findElement(locator);
return false;
} catch (NoSuchElementException e) {
return true;
} catch (StaleElementReferenceException e) {
return true;
}
}
@Override
public String toString() {
return "element to not being present: " + locator;
}
};
}
为什么不简单地求 elements
的大小呢?我们知道如果 element 不存在,元素集合的 size 将是 0。
if(driver.findElements(By.id("foo").size() > 0 ){
//It should fail
}else{
//pass
}
您也可以使用 -
new WebDriverWait(driver, 10).until(ExpectedConditions.invisibilityOfElementLocated(locator));
如果您查看其中的 the source,您可以看到 NoSuchElementException
和 staleElementReferenceException
都已处理。
/**
* An expectation for checking that an element is either invisible or not
* present on the DOM.
*
* @param locator used to find the element
*/
public static ExpectedCondition<Boolean> invisibilityOfElementLocated(
final By locator) {
return new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver driver) {
try {
return !(findElement(locator, driver).isDisplayed());
} catch (NoSuchElementException e) {
// Returns true because the element is not present in DOM. The
// try block checks if the element is present but is invisible.
return true;
} catch (StaleElementReferenceException e) {
// Returns true because stale element reference implies that element
// is no longer visible.
return true;
}
}
// pseudo code
public Fun<driver,webelement> ElemtDisappear(locator)
{
webelement element=null;
iList<webelement> elemt =null;
return driver=>
{
try
{
elemt = driver.findelements(By.locator);
if(elemt.count!=0)
{
element=driver.findelement(By.locator);
}
}
catch(Exception e)
{
}
return(elemnt==0)?element:null;
};
// call function
public void waitforelemDiappear(driver,locator)
{
webdriverwaiter wait = new webdriverwaiter(driver,time);
try
{
wait.until(ElemtDisappear(locator));
}
catch(Exception e)
{
}
}
由于 findelement 在元素上抛出异常 unaviability.so 我使用 findelements 实现。请随时根据您的需要进行更正和使用。
我找到了一种有效解决此问题的解决方法,使用以下 C# 代码来处理此问题,您可以将其转换为 Java
public bool WaitForElementDisapper(By element)
{
try
{
while (true)
{
try
{
if (driver.FindElement(element).Displayed)
Thread.Sleep(2000);
}
catch (NoSuchElementException)
{
break;
}
}
return true;
}
catch (Exception e)
{
logger.Error(e.Message);
return false;
}
}
我不知道为什么,但 ExpectedConditions.invisibilityOf(element)
是我唯一的作品,而 ExpectedConditions.invisibilityOfElementLocated(By)
、!ExpectedConditions.presenceOfElementLocated(By)
... 不是。试试吧!
希望对您有所帮助!
好消息,现在内置了(我在2021年使用Node.js)
看起来 elementIsNotVisible
已添加到 until
之前的答案给出后。我正在使用 selenium webdriver 4.0.0-beta.3
查看:
const timeout = 60 * 1000; // 60 seconds
const element = await driver.findElement(By.id(elementId));
// this is the important line
await driver.wait(until.elementIsNotVisible(element), timeout);