在使用Selenium WebDriver和IEDriverServer.exe 2.32.3.0的Web测试中,我需要在导航到某个URL后检查当前页面的标题。这是代码:
_webDriver.Navigate().GoToUrl("...");
Assert.That(_webDriver.Title, Is.EqualTo("..."));
这有时会起作用,但偶尔会中断 - 标题不符合预期(但仍然是之前页面中的标题)。
我已经在StackOverflow(C# Webdriver - Page Title assert fails before page loads)上读到IWebDriver.Title
属性没有自动等待导航完成(为什么不等?),而是你需要手动等待使用WebDriverWait
API。
我实施了手动等待标题:
var wait = new WebDriverWait(_webDriver, TimeSpan.FromSeconds (3.0));
wait.Until(d => d.Title == expectedTitle);
然而,这有时等待3秒钟,然后抛出WebDriverTimeoutException
。运行代码的构建代理非常快,我正在测试的网站是微不足道的(刚刚开始开发),所以我很确定它不能真正花费3秒钟来导航。我注意到在另一个StackOverflow问题上,原始海报也得到了WebDriverTimeoutException
,只是抓住并忽略了它。
我发现解决方案有点不稳定,所以我尝试了不同的解决方法。我在我的HTML中为<title>
属性提供了一个ID,并使用了IWebDriver.FindElement,它应该等待页面完成:
Assert.That(_webDriver.FindElement(By.Id(ViewIDs.Shared._Layout.Title)).Text, Is.EqualTo(page.ExpectedTitle));
起初,这似乎有效。但是,它不可靠,它有时会抛出:
OpenQA.Selenium.NoSuchElementException : Unable to find element with id == _Layout-title
at OpenQA.Selenium.Remote.RemoteWebDriver.UnpackAndThrowOnError(Response errorResponse)
at OpenQA.Selenium.Remote.RemoteWebDriver.Execute(String driverCommandToExecute, Dictionary`2 parameters)
at OpenQA.Selenium.Remote.RemoteWebDriver.FindElement(String mechanism, String value)
at OpenQA.Selenium.By.FindElement(ISearchContext context)
at ...
(我也尝试升级到WebDriver / IEDriverServer 2.33.0.0;但在该版本中,<title>
标签的文本始终为空...)
因此我的问题。在Selenium WebDriver中导航后如何可靠地检查当前页面?有一个好的模式有效吗?
答案 0 :(得分:2)
我刚刚用CodeProject上找到的东西解析了它:
private void WaitUntilLoaded()
{
var wait = new OpenQA.Selenium.Support.UI.WebDriverWait(driver, TimeSpan.FromSeconds(%));
wait.Until(x =>
{
return ((IJavaScriptExecutor)this.driver)
.ExecuteScript("return document.readyState").Equals("complete");
});
}
根据w3schools,它适用于大多数流行的浏览器。
正如我目前在Firefox上测试一样,我最终在Mozilla's own page上了解了如何将页面识别为已加载。恕我直言,值得避免龙。
那给了我
wait.Until(p => p.FindElement(
By.Id("somethingThatIsDisplayedWhenMyAsyncronousStuffIsFinished")
).Displayed);
这节省了我的一天。
答案 1 :(得分:0)
我遇到过非常类似的问题。我仍然无法告诉原因,但是如果你尝试使用一个元素而不进行isElementPresent检查,它偶尔会失败。我的解决方案略显“昂贵”,但我还没有找到可靠的替代方案。
我的例子是在java中,不应该很难翻译,但我没有库。
waitForElement("_Layout-title", 45);
然后继续使用您的代码
Assert.That(_webDriver.FindElement(By.Id(ViewIDs.Shared._Layout.Title)).Text, Is.EqualTo(page.ExpectedTitle));
这会尝试设定次数(在本例中为45)来查找元素。一旦id = _Layout-title出现,它将继续到下一行代码并执行断言。虽然它并不完美,但确实使我的测试更加稳定。