在特定的IWebElement上使用webdriverwait

时间:2013-04-04 07:21:41

标签: c# selenium webdriver selenium-webdriver

我将selenium webdriverwait方法应用于特定的IWebElement,以便在它们可用时获取此IWebElement的一些子元素。这是我的代码......

WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
IList<IWebElement> elementsA = wait.Until<IList<IWebElement>>((d) =>
{
     return driver.FindElements(By.XPath("//table[@class='boxVerde']"));
});

foreach (IWebElement iwe in elementsA)
{
      wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
      IList<IWebElement> elementsB = wait.Until<IList<IWebElement>>((d) =>
      {
            return iwe.FindElements(By.XPath("tr/td/div/a"));
            //trying to fetch the anchor tags from the element
       });
}

它一直给我一个错误,说'元素不再附加到DOM'......我认为webdriver等待根本不起作用。我做错了什么人吗?非常感谢提前

4 个答案:

答案 0 :(得分:3)

听起来你正遭受陈旧元素的困扰。

Selenium发现的每个WebElement实际上都是对DOM内部元素的引用

有时在网站上使用的JavaScript会破坏并重新创建一个元素,当这种情况发生时你的现有引用变得陈旧,你会看到一个StaleElementReferenceException(至少那是它在Java土地中调用的东西,你应该看到非常相似的东西) 。

因此,如果您看到StaleElementReferenceException或指出“元素不再附加到DOM”的消息,则意味着您以前对DOM中元素的引用不再有效,因为您拥有的元素引用已被破坏。

这在视觉上并不总是很明显,因为原始元素可能已被破坏,然后重新创建了相同的元素,但它是一个新元素,因此您需要创建一个新的引用来与它进行交互。

创建新引用的方法是再次找到该元素。

从您的问题中并不完全清楚,但我假设您在找到表格后迭代锚元素列表时遇到问题。如果是这种情况,则表明该表已被破坏并在您找到表元素的点之间重新创建,然后开始迭代表中的锚元素。

如果是这种情况,您需要再次找到该表,一个有用的技巧是在您尝试再次找到它之前等待该表变为陈旧。通过这种方式,您可以合理地确信页面上任何破坏表然后重新创建它的JavaScript都已完成处理。 .NET ExpectedConditions class并不像Java ExpectedConditions class那样成熟。我建议看看一些Java并将它们移植到.NET(它应该相当简单,结构非常相似),特别感兴趣的是等待元素变得陈旧的Java。 / p>

答案 1 :(得分:1)

我相信该页面已删除了部分表格。查看页面上的事件会很有用。您应该使用//table[@class='boxVerde']/tr/td/div/a xpath而不是在元素内搜索。

答案 2 :(得分:0)

在轮询时间结束之前,您必须定义Webdriver等待忽略异常。以下java方法轮询元素util 60秒,如果加载则返回,否则将抛出Timeout Exception。请根据需要将其转换为您的语言。(对不起,我是一名javaist)

public WebElement fluentWait(final By locator, WebDriver driver) {
    Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
    .withTimeout(60, TimeUnit.SECONDS)
    .pollingEvery(1, TimeUnit.SECONDS)
    .ignoring(StaleElementReferenceException.class)
    .ignoring(NoSuchElementException.class);
    WebElement foo = wait.until(
    new Function<WebDriver, WebElement>() {
    public WebElement apply(WebDriver driver) {
    return driver.findElement(locator);
    }
         }  );
    return foo;}

除此之外,如果您要查找单个锚标记元素,请使用xpath作为

       iwe.FindElements(By.XPath(" //a[text()='anchor tag text']"));

或通过By.linkText(“锚标记文本”)找到您的元素;

       iwe.FindElements(By.linkText("anchor tag text"));

答案 3 :(得分:-1)

尝试使用此功能。它等待元素出现在页面中。

static void ForElementsArePresent(IWebDriver wd, double waitForSeconds, By by)
        {
            try
            {
                WebDriverWait wait = new WebDriverWait(wd, TimeSpan.FromSeconds(waitForSeconds));
                wait.Until(x => (x.FindElements(by).Count > 0));
            }
            catch (WebDriverTimeoutException)
            {
                Console.WriteLine("Waiting for element " + by + " to disappear timed out after " + waitForSeconds + " seconds.");
                throw;
            }                       
        }