问题描述
我使用Selenium 2来测试使用InternetExplorerDriver一个asp.net web窗体页和我遇到一个StaleElementReferenceException。该页面包含一个(自动回传)下拉列表中,其中我从选择不同的值
I am using Selenium 2 to test an asp.net web forms page using the InternetExplorerDriver and am encountering a StaleElementReferenceException. The page contains a (auto-postback) drop down list, which I am selecting different values from.
示例代码:
页:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebApplication.WebForm1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:DropDownList ID="ddl" runat="server" AutoPostBack="true">
<asp:ListItem Text="one"></asp:ListItem>
<asp:ListItem Text="two"></asp:ListItem>
</asp:DropDownList>
</div>
</form>
</body>
</html>
(代码隐藏文件中包含什么比在Visual Studio自动创建的东西更多。)
(The code-behind file contains nothing more than the Visual Studio auto-created stuff.)
测试夹具代码:
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.IE;
namespace IntegrationTests
{
[TestFixture]
public class WebForm1TestFixture
{
[Test]
public void ShouldSelectItemOneThenItemTwo()
{
IWebDriver driver = new InternetExplorerDriver(); // Using ChromeDriver causes test to pass...
driver.Navigate().GoToUrl("http://localhost/<my-virtual-directory-name>/WebForm1.aspx");
IWebElement list = driver.FindElement(By.Id("ddl"));
IWebElement itemOne = list.FindElement(By.XPath("option[1]"));
itemOne.Select();
list = driver.FindElement(By.Id("ddl"));
IWebElement itemTwo = list.FindElement(By.XPath("option[2]"));
itemTwo.Select();
list = driver.FindElement(By.Id("ddl"));
itemOne = list.FindElement(By.XPath("option[1]"));// This line causes the StaleElementReferenceException to occur
itemOne.Select();
// Some assertion would go here
}
}
}
当我运行测试,我得到以下错误:
When I run the test I get the following error:
OpenQA.Selenium.StaleElementReferenceException: Element is no longer valid
at OpenQA.Selenium.Remote.RemoteWebDriver.UnpackAndThrowOnError(Response errorResponse) in e:\Projects\WebDriver\trunk\remote\client\src\csharp\webdriver-remote-client\RemoteWebDriver.cs: line 883
at OpenQA.Selenium.Remote.RemoteWebDriver.Execute(DriverCommand driverCommandToExecute, Dictionary`2 parameters) in e:\Projects\WebDriver\trunk\remote\client\src\csharp\webdriver-remote-client\RemoteWebDriver.cs: line 727
at OpenQA.Selenium.Remote.RemoteWebElement.FindElement(String mechanism, String value) in e:\Projects\WebDriver\trunk\remote\client\src\csharp\webdriver-remote-client\RemoteWebElement.cs: line 570
at OpenQA.Selenium.Remote.RemoteWebElement.FindElementByXPath(String xpath) in e:\Projects\WebDriver\trunk\remote\client\src\csharp\webdriver-remote-client\RemoteWebElement.cs: line 458
at OpenQA.Selenium.By.<>c__DisplayClasse.<XPath>b__c(ISearchContext context) in e:\Projects\WebDriver\trunk\common\src\csharp\webdriver-common\By.cs: line 119
at OpenQA.Selenium.By.FindElement(ISearchContext context) in e:\Projects\WebDriver\trunk\common\src\csharp\webdriver-common\By.cs: line 227
at OpenQA.Selenium.Remote.RemoteWebElement.FindElement(By by) in e:\Projects\WebDriver\trunk\remote\client\src\csharp\webdriver-remote-client\RemoteWebElement.cs: line 267
at IntegrationTests.WebForm1TestFixture.ShouldSelectItemOneThenItemTwo() in WebForm1TestFixture.cs: line 25
如果我更改测试使用ChromeDriver,则测试通过。在我看来,这样意味着它可以是一个与InternetExplorerDriver或Internet Explorer浏览器本身的问题。有谁知道,如果有什么我可以做的就是这一轮(该网站将在IE由最终用户使用,因此更改浏览器是不可能的,不幸的是)?
If I change the test to use a ChromeDriver then the test passes. It seems to me like this means it is either a problem with the InternetExplorerDriver or the Internet Explorer browser itself. Does anybody know which and if there's anything I can do to get round this (the site will be used in IE by the end users, so changing browsers isn't possible, unfortunately)?
编辑:目前的变通,我用的就是把一个 Thread.sleep代码()
列表中已被选中之后;这个工作,但显然不是一个理想的解决方案。
The current work-around that I am using is to put a Thread.Sleep()
after the list has been selected; this works but obviously isn't an ideal solution.
推荐答案
下面是我最终落实的格局。
Below is the pattern I ended up implementing.
每个项目*。选择()
我已经实现了一个等待后:
After each item*.Select()
I've implemented a wait:
IWait<IWebDriver> wait = new MyCustomWebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until(driver => <some-condition-to-wait-for>);
其中<有的条件到等待换>是确定该项目的选择已经完成(例如,通过检查页面上的其他控制已被更新,例如
Where <some-condition-to-wait-for> is a way of determining that the item selection has finished (for example, by checking that another control on the page has been updated, e.g.
wait.Until(driver => driver.FindElement(By.Id("someLabelId")).Text == "expectedValue")`.
MyCustomWebDriverWait
是一个类实现 IWAIT< IWebDriver>
,是几乎相同的类,只抓到 StaleElementReferenceException
以及 NotFoundException
(这意味着改变<$ C类型$ C> lastException 从 NotFoundException
到 WebDriverException
。
MyCustomWebDriverWait
is a class that implements IWait<IWebDriver>
and is almost identical to the WebDriverWait class, only it catches StaleElementReferenceException
as well as NotFoundException
(which meant changing the type of lastException
from NotFoundException
to WebDriverException
.
您可以阅读我是如何在指向这个方向由丹尼尔·瓦格纳厅硒,谷歌用户群的。
You can read how I was pointed in this direction by Daniel Wagner-Hall on the Selenium-users google group here.
这篇关于硒2 StaleElementReferenceException使用的DropDownList当的AutoPostBack随着InternetExplorerDriver的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!