C# C Selenium WebDriverWait.IgnoreExceptionTypes不起作用
我试图使用SeleniumWebDriverWait类型,在检查元素是否存在之前,等待页面完全加载。我尝试了两种不同的方法 第一个方法使用IgnoreExceptionTypes,然后在Until方法内调用FindElement。这会立即抛出NoTouchElementException,而无需等待。我希望这会继续尝试查找元素,直到超时,同时忽略NosTouchElementException。它似乎不是这样工作的。为什么方法1不起作用 第二个方法使用ExpectedConditions.ElementExists,并且似乎正确等待C# C Selenium WebDriverWait.IgnoreExceptionTypes不起作用,c#,selenium-webdriver,webdriver,selenium-chromedriver,C#,Selenium Webdriver,Webdriver,Selenium Chromedriver,我试图使用SeleniumWebDriverWait类型,在检查元素是否存在之前,等待页面完全加载。我尝试了两种不同的方法 第一个方法使用IgnoreExceptionTypes,然后在Until方法内调用FindElement。这会立即抛出NoTouchElementException,而无需等待。我希望这会继续尝试查找元素,直到超时,同时忽略NosTouchElementException。它似乎不是这样工作的。为什么方法1不起作用 第二个方法使用ExpectedConditions.Ele
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)));
回答重新措辞的问题 所以我一直都这样。我使用页面对象模型来编写自动化,因此这很好地解决了这一问题,但即使不使用页面对象模型,您仍然可以使用它 基本概念是。。。找到最后加载的元素并等待该元素。此时,您知道页面已完成加载,您的脚本可以继续,而不用担心与页面上尚未完成加载的某些元素交互 警告。。。我怎么知道最后加载哪个元素?我不知道。你基本上是做一个猜测,然后使用它直到失败。如果您的页面不是非常动态,那么只需选择任意元素即可。如果页面中有一部分加载延迟,请在该部分页面中选择一个元素 这是我的典型做法。我为某个页面编写一个页面对象。我在页面上选择一个唯一的元素,并通过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定位器
现在有了这个新方法,它是完全灵活的。您可以传入任何定位器类型,它都可以工作。你可以用这样的词来称呼它
ClickElement(driver, By.Id("someId"));
我很困惑。您发布的方法将driver和id作为参数,但您所讨论的是自定义等待时间和现有元素。你可能需要澄清你的问题,你实际上在做什么,因为它似乎与你在这里问的问题不同。根据新的信息更新了我的答案你在使用页面对象模型吗?我不这么认为。我的问题有所有的代码,除了创建驱动程序
ClickElement(driver, By.Id("someId"));