如何在Selenium C#中防止PageFactory中的StaleElementReferenceException? [英] How to prevent StaleElementReferenceException in PageFactory in Selenium C#?

查看:134
本文介绍了如何在Selenium C#中防止PageFactory中的StaleElementReferenceException?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在C#6中有一个Selenium WebDriver页面对象模型.我在尝试单击加载了ajax的导航栏元素时遇到了StaleElementReferenceException s.这很令人困惑,因为我使用的是PageFactory,没有任何[CacheLookup].

I have a Selenium WebDriver Page Object Model in C# 6. I am experiencing StaleElementReferenceExceptions while trying to click on ajax-loaded nav bar elements. This is confusing, because I'm using PageFactory, without any [CacheLookup]s.

这是有问题的代码.我试图简化为重要的部分. (实际上,我绕过了Driver,包装了IWebDriver.)MenuBar.SelectEnglish<T>()引发了异常.

Here's the code in question. I've tried to simplify to just the important parts. (I actually pass around a Driver, a wrapper around IWebDriver.) MenuBar.SelectEnglish<T>() throws the exception.

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)));
    }

    // ...
}

是什么导致此错误?我该怎么办?

What is causing this error? What can I do about it?

推荐答案

从文档中陈旧元素引用异常

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完成,然后再获取受影响的元素.

Since you mentioned the element is loaded using Ajax, most likely the element changed after your page object fetched it. Just fetch it again or wait for the Ajax to complete before fetching the affected elements.

编辑1

这里有一些示例代码,展示了即使在使用PageFactory的情况下也可以使用一种方法来获取元素.

Here's some sample code to show how you can fetch an element using a method even while using 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;
        }
    }
}

这篇关于如何在Selenium C#中防止PageFactory中的StaleElementReferenceException?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆