繁体   English   中英

C#Selenium WebDriverWait.IgnoreExceptionTypes不起作用

[英]C# Selenium WebDriverWait.IgnoreExceptionTypes does not work

我正在尝试使用Selenium WebDriverWait类型来等待页面完全加载,然后再检查是否存在元素。 我尝试过两种不同的方式。

第一个方法使用IgnoreExceptionTypes,然后在直到方法中调用FindElement。 这将立即引发NoSuchElementException,而无需等待。 我希望这会继续尝试找到直到超时的元素,同时忽略NoSuchElementException。 它似乎无法以这种方式工作。 为什么Method1不起作用?

第二种方法使用ExpectedConditions.ElementExists,似乎可以正确等待。

driver.Navigate().GoToUrl("http://www.google.com");
var myId = "myId";

//Method 1
var wait1 = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait1.IgnoreExceptionTypes(typeof(NoSuchElementException));

//Does not wait. Immediately throws NoSuchElementException
var result1 = wait1.Until(x => x.FindElement(By.Id(myId)));

//Method 2    - works as expected
var wait2= new WebDriverWait(driver,TimeSpan.FromSeconds(10))
    .Until(ExpectedConditions.ElementExists(By.Id(myId)));

回答新改写的问题...

所以我一直都这样做。 我使用页面对象模型来编写自动化,因此可以很好地实现自动化,但是即使您没有使用页面对象模型,您仍然可以使用它。

基本概念是……您找到一个最后加载的元素,然后等待该元素。 到那时,您知道页面已完成加载,并且脚本可以继续运行而不必担心与页面上尚未完成加载的某些元素进行交互。

请注意...在世界上我怎么知道最后加载哪个元素? 我不知道。 您基本上会进行猜测(希望是经过深思熟虑的猜测)并使用它直到失败。 如果您的页面不是动态的,那么只需选择任何元素。 如果页面的一部分加载较晚,请在页面的该部分内选择一个元素。

这通常适合我。 我为某个页面写一个页面对象。 我在页面上选择一个唯一元素,并将其声明为By waitForLocator 现在,当我要等待页面加载完成时,我致电

By waitForLocator = By.Id("myId");
new WebDriverWait(Driver, TimeSpan.FromSeconds(10)).Until(ExpectedConditions.ElementIsVisible(waitForLocator));

现在,我(完全)有信心完成页面的加载,然后开始为页面对象编写方法,依此类推。 我编写了一个脚本,该脚本使用了该页面对象,并根据测试用例与该页面进行交互,然后运行该脚本。 希望我很好地选择了waitForLocator 如果还没有,那么在脚本运行期间的某个时候,我会得到一些异常,因为某些元素没有完全加载(在我选择的元素之后加载)。 因此,我将waitForElement更改为刚刚与之交互的元素,从而引发了异常,现在我应该对最后一个加载元素有一个更好的猜测。 您基本上会重复此过程,直到没有更多的例外为止。

您可能会说,这是一种非常随意的方法。 这似乎比实际要更加随意。 如果您知道自己的网站和页面,则将做出一个很好的第一个猜测。 我必须更改一次猜测是非常罕见的,而且我必须多次更改它,这非常罕见。 也就是说,更改它确实很容易。 您已经有了引发异常的元素的定位器,只需将其粘贴到waitForLocator的声明中就可以了。

因此,您可能会遇到的一个例外情况是,如果您已经正确选择了waitForLocator并且页面加载后,单击页面上的某个元素即可动态加载页面的其他部分。 这种情况超出了等待页面加载的范围。 在这种情况下,您将必须建立另一个等待,该等待在执行单击后等待页面的新加载部分完成加载。 它不会影响页面加载机制。


附加评论

返回并阅读完您的问题后,这里有一些其他信息,可以使您的生活更轻松。

您最初的问题所采用的方法已在下面进行了简化/修改,以证明这一原理

public void ClickElementById(RemoteWebDriver driver, string id)
{
    driver.FindElement(By.Id(id)).Click();
}

编写此方法的方式是,您必须自己为每种定位器类型,ID,名称,CSS选择器,XPath等创建方法。与其传递字符串,不传递字符串,而是传递By定位器。

public void ClickElement(RemoteWebDriver driver, By locator)
{
    driver.FindElement(locator).Click();
}

现在有了这种新方法,它就变得完全灵活。 您可以传入任何定位符类型,它将起作用。 要称呼它,您可以使用类似

ClickElement(driver, By.Id("someId"));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM