如何等到 Selenium 中不再存在元素
Posted
技术标签:
【中文标题】如何等到 Selenium 中不再存在元素【英文标题】:How to wait until an element no longer exists in Selenium 【发布时间】:2015-05-18 22:10:04 【问题描述】:我正在测试用户单击删除按钮和表格条目消失的 UI。因此,我希望能够检查表条目是否不再存在。
我曾尝试使用ExpectedConditions.not()
反转ExpectedConditions.presenceOfElementLocated()
,希望这意味着“期望不存在指定元素”。我的代码是这样的:
browser.navigate().to("http://***.com");
new WebDriverWait(browser, 1).until(
ExpectedConditions.not(
ExpectedConditions.presenceOfElementLocated(By.id("foo"))));
但是,我发现即使这样做,我也会收到由 NoSuchElementException
引起的 TimeoutExpcetion
,表示元素“foo”不存在。当然,没有这样的元素是我想要的,但我不希望抛出异常。
那么我怎样才能等到一个元素不再存在呢?如果可能的话,我更喜欢一个不依赖于捕获异常的示例(据我所知,应该为异常行为抛出异常)。
【问题讨论】:
【参考方案1】:你也可以使用 -
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;
【讨论】:
上述代码中出现奇怪的语法错误:语法错误,插入“;”完成 BlockStatements【参考方案2】:该解决方案仍将依赖于异常处理。这非常好,即使 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;
;
【讨论】:
您的答案效果很好,但我决定接受另一个答案,因为似乎有一个内置版本可以完全满足我的要求。不过,您的回答是一个很好的指导方针! @Thunderforge 谢谢,我知道这个方法。尽管我假设您需要等待 DOM 中不存在的元素而不是变得不可见。无论如何,很高兴它解决了! 我发现该方法还可以处理它在 DOM 中不存在的情况,而不仅仅是在它不可见的情况下。由于前者是我的用例,而我不关心后者,因此它对我有用,并且节省了我自己的工作量。【参考方案3】:您为什么不简单地找到elements
的大小。如果 element 不存在,我们知道元素的 size 集合将为 0。
if(driver.findElements(By.id("foo").size() > 0 )
//It should fail
else
//pass
【讨论】:
不幸的是,这个解决方案不会等待元素不再存在;它只检查一次。 @VivekSingh 的解决方案是不重新发明***的最佳 imo,但如果情况略有不同,此解决方案将与预期条件相结合。看起来像这样:(new WebDriverWait(driver, 30)).withMessage("element was still displayed after timeout").until((ExpectedCondition<Boolean>) d -> d.findElements(By.id("foo").size() > 0));
【参考方案4】:
我不知道为什么,但 ExpectedConditions.invisibilityOf(element)
是我唯一的工作,而 ExpectedConditions.invisibilityOfElementLocated(By)
、!ExpectedConditions.presenceOfElementLocated(By)
... 不是。试试吧!
希望对您有所帮助!
【讨论】:
【参考方案5】:// 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 上引发异常。所以我使用 findelements 实现。请随时根据您的需要更正和使用它。
【讨论】:
【参考方案6】:我找到了一种解决方法,可以有效地为我解决此问题,使用以下 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;
【讨论】:
【参考方案7】:好消息,它现在已经内置了(我在 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);
【讨论】:
这个函数的描述是:Creates a condition that will wait for the given element to be in the DOM, yet not visible to the user.
这不是大多数人在这里寻找的。我自己,可能还有其他人正在寻找一种方法来断言元素不在 dom 中,而不是在 dom 中,而只是不可见以上是关于如何等到 Selenium 中不再存在元素的主要内容,如果未能解决你的问题,请参考以下文章
Selenium - 等到元素存在、可见且可交互,即使在 C# 中的可滚动模式上也是如此