我在C#6中有一个Selenium WebDriver页面对象模型。我在尝试点击加载了ajax的导航栏元素时遇到了StaleElementReferenceException
。这很令人困惑,因为我使用PageFactory
,没有任何[CacheLookup]
s。
这是有问题的代码。我试图简化到重要的部分。 (我实际上传递Driver
,IWebDriver
周围的包装。)MenuBar.SelectEnglish<T>()
抛出异常。
public class Tests
{
[Test]
public void SelectEnglishTest()
{
homePage
.MenuBar.SelectEnglish<HomePage>();
}
// ...
}
public class MenuBar : PageObject
{
[FindsBy(How = How.CssSelector, Using = "...")]
private IWebElement Language { get; set; }
[FindsBy(How = How.CssSelector, Using = "...")]
private IWebElement English { get; set; }
public T SelectEnglish<T>() where T : Page
{
Language.Click();
IWait<IWebDriver> wait = new WebDriverWait(Driver, TimeSpan.FromSeconds(5));
wait.Until(ExpectedConditions.ElementToBeClickable(English));
English.Click();
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("en-US");
return (T)Activator.CreateInstance(typeof(T), Driver);
}
// ...
}
public class HomePage : PageObject
{
public MenuBar MenuBar { get; private set; }
// ...
}
public class PageObject
{
protected IWebDriver Driver { get; }
protected PageObject(IWebDriver driver)
{
Driver = driver;
PageFactory.InitElements(this, new RetryingElementLocator(Driver, TimeSpan.FromSeconds(20)));
}
// ...
}
导致此错误的原因是什么?我该怎么办呢?
答案 0 :(得分:0)
来自文档Stale Element Reference Exception
A stale element reference exception is thrown in one of two cases, the first being more common than the second:
- The element has been deleted entirely.
- The element is no longer attached to the DOM.
由于您提到使用Ajax加载元素,因此很可能在页面对象获取元素后更改了元素。在获取受影响的元素之前,只需再次获取它或等待Ajax完成。
编辑1
这里有一些示例代码,展示了即使在使用PageFactory时如何使用方法获取元素。
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Support.PageObjects;
using System;
namespace C_Sharp_Selenium_Test
{
class Program
{
static void Main(string[] args)
{
FirefoxDriver driver = new FirefoxDriver();
driver.Navigate().GoToUrl("http://www.google.com");
HomePage homePage = new HomePage(driver);
PageFactory.InitElements(driver, homePage);
homePage.search("stack overflow");
homePage.getSearchBox().Clear();
homePage.getSearchBox().SendKeys("c# pagefactory");
homePage.getSearchButton().Click();
}
}
public class HomePage
{
private By searchBox = By.Id("lst-ib");
private By searchButton = By.Name("btnG");
// add other elements in here that use FindsBy() to be loaded using PageFactory.InitElements()
private IWebDriver driver;
public void search(String s)
{
getSearchBox().SendKeys(s);
getSearchButton().Click();
}
public IWebElement getSearchBox()
{
return driver.FindElement(searchBox);
}
public IWebElement getSearchButton()
{
return driver.FindElement(searchButton);
}
public HomePage(IWebDriver driver)
{
this.driver = driver;
}
}
}