c# - 如何防止 Selenium C# 中 PageFactory 中的 StaleElementReferenceException?

标签 c# ajax selenium selenium-webdriver pageobjects

我有一个 C# 6 中的 Selenium WebDriver 页面对象模型。我正在经历 StaleElementReferenceException尝试单击 ajax 加载的导航栏元素时。这很令人困惑,因为我正在使用 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)));
    }

    // ...
}

是什么导致了这个错误?我能做什么呢?

最佳答案

来自文档,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;
        }
    }
}

关于c# - 如何防止 Selenium C# 中 PageFactory 中的 StaleElementReferenceException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32209199/

相关文章:

c# - 构建动态表达式树时出现问题

php - 有什么方法可以用 JS 和 PHP 来实现 "backend media queries"吗?

jquery - 地理定位和 jQuery - 无法使用 ajax 发布结果

python - 使用 Selenium Web 驱动程序提取我想要的值时遇到问题

c# - 如何在控制台应用程序中与ConfigureAwait(true) 进行工作交互?

c# - ZXing Barcode ImageView不显示生成的条形码Xamarin Forms

c# - StreamReader 和读取 XML 文件

PHP Post 变量有重复的、已修改的数据

php - 在 Codeception 测试 (webdriver) 中创建可点击节点(Web 元素)列表

android - 使用 Selenium 在 Kobiton 设备上滑动