Selenium2 Webdriver C#.Click()List - 陈旧引用异常

时间:2011-09-19 16:32:19

标签: c# selenium-webdriver

我需要一些帮助,因为当我尝试解析要点击的标签列表时,我一直收到StaleElementReference。

我所做的是在页面上我遍历页面并生成一个对象List<>与所有标签

    private List<IWebElement> _pageLinks;
    public List<IWebElement> pageLinks
    {
        get
        {
            if (_pageLinks == null)
            {
                _pageLinks = InfoDriver.FindElements(By.TagName("a")).ToList();
            }
            return _pageLinks;
        }
    }

然后我想解析这个列表,然后单击每个列表,然后返回它所引用的页面。

    private static SeleniumInformation si = new SeleniumInformation(ffDriver);

        si.pageLinks.ForEach(i =>
        {
            i.Click();
            System.Threading.Thread.Sleep(1000);
            ffDriver.Navigate().Back();
        });

在第一次点击后,它会进入新页面,然后返回到起始页面,但无法获得下一个链接。我已经尝试将它设置为一个静态元素,设置一个支持字段,以便它检查是否有数据已经​​存在,但是看起来点击IwebElement会丢失列表并且它不会重建列表所以我得到未处理StaleElementReference异常且缓存中找不到元素。

这是Selenium中带有IWebElement类的错误还是我做错了什么?任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:1)

这是预期的行为。你离开了元素所在的页面。当您向后导航时,它是一个新页面,该元素不再在其上。

为了解决这个问题,如果可以的话,我建议改为绕过Bys。假设您的锚链接都具有唯一的href,您可以生成如下列表(java代码,但应转换为c#):

private static List<By> getLinks(WebDriver driver)
{
    List<By> anchorLinkBys = new ArrayList<By>();
    List<WebElement> elements = driver.findElements(By.tagName("a"));
    for(WebElement e : elements)
    {
        anchorLinkBys.add(By.cssSelector("a[href=\"" + e.getAttribute("href") + "\"]"));
        //could also use another attribute such as id.
    }
    return anchorLinkBys;
}

我不知道您网页的构成,所以我不知道是否可以动态生成By,以唯一标识您想要的元素。例如,如果所有元素具有相同的父元素,则可以使用css level 3选择器nth-child(n)。希望你从上面的代码中得到一些想法。

答案 1 :(得分:1)

    private void YourTest()
    {
        IWebDriver browserDriver = new FirefoxDriver();
        browserDriver.Navigate().GoToUrl(pageUrl);
        int linkCount= browserDriver.FindElements(By.TagName("a")).Count;

        for (int i = 0; i <= linkCount-1; i++ )
        {
            List<IWebElement> linksToClick = browserDriver.FindElements(By.TagName("a")).ToList();
            linksToClick[i].Click();
            System.Threading.Thread.Sleep(4000);
            if(some boolean check)
            {
              //Do something here for validation
            }
            browserDriver.Navigate().Back();
        }
        broswerDriver.Quit();
    }