Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# C Selenium WebDriverWait.IgnoreExceptionTypes不起作用_C#_Selenium Webdriver_Webdriver_Selenium Chromedriver - Fatal编程技术网

C# C Selenium WebDriverWait.IgnoreExceptionTypes不起作用

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

我试图使用SeleniumWebDriverWait类型,在检查元素是否存在之前,等待页面完全加载。我尝试了两种不同的方法

第一个方法使用IgnoreExceptionTypes,然后在Until方法内调用FindElement。这会立即抛出NoTouchElementException,而无需等待。我希望这会继续尝试查找元素,直到超时,同时忽略NosTouchElementException。它似乎不是这样工作的。为什么方法1不起作用

第二个方法使用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)));

回答重新措辞的问题

所以我一直都这样。我使用页面对象模型来编写自动化,因此这很好地解决了这一问题,但即使不使用页面对象模型,您仍然可以使用它

基本概念是。。。找到最后加载的元素并等待该元素。此时,您知道页面已完成加载,您的脚本可以继续,而不用担心与页面上尚未完成加载的某些元素交互

警告。。。我怎么知道最后加载哪个元素?我不知道。你基本上是做一个猜测,然后使用它直到失败。如果您的页面不是非常动态,那么只需选择任意元素即可。如果页面中有一部分加载延迟,请在该部分页面中选择一个元素

这是我的典型做法。我为某个页面编写一个页面对象。我在页面上选择一个唯一的元素,并通过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"));