在Selenium WebDriver中导航后如何可靠地检查当前页面?

时间:2013-06-17 15:00:13

标签: selenium-webdriver

在使用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中导航后如何可靠地检查当前页面?有一个好的模式有效吗?

2 个答案:

答案 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出现,它将继续到下一行代码并执行断言。虽然它并不完美,但确实使我的测试更加稳定。