如何在java中使用selenium wait.until和anchor元素

时间:2014-03-19 17:37:47

标签: c# java selenium-webdriver

我有用c#编写的selenium项目,我想将它迁移到java,但我有一个问题,我自己无法解决。 假设我有一个webElement elem1,我希望找到另一个使用elem2作为锚点的元素elem1。 所以在java中,我可以这样做:

WebElement elem1 = wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("div.uiContextualLayer.uiContextualLayerBelowLeft"))) ;

WebElement elem2 = elem1.findElement(By.tagName("li"));

现在,我的问题开始时我想要同样但wait.until() elem2。问题是elem1总是出现在DOM中,但elem2只会在一段时间后出现在DOM中(它取决于与此问题无关的一些代码),所以使用上面的代码将抛出异常。 在c#中我使用了lambda表达式,它非常简单:

IWebElement elem1 = wait.Until((d) => { return d.FindElement(By.CssSelector("div.uiContextualLayer.uiContextualLayerBelowLeft")); });

IWebElement elem2= wait.Until((d) => { return **elem1**.FindElement(By.TagName("li")); });

在java中我无法找到一种方法来wait.until并使用elem1作为findElement函数的锚点。 这是我正在处理的html示例:

<div class="uiContextualLayer uiContextualLayerBelowLeft">
      <div style="width: 240px;">
          <div class="uiTypeaheadView uiContextualTypeaheadView">
              <ul id="typeahead_list_u_jsonp_2_2" class="search" role="listbox">
                  <li id="js_2" class="user" aria-label="whatEver" role="option" aria-selected="false">
                      <a href="someLink" rel="ignore" target=""> … </a>
                        </li>
                    </ul>
                </div>
            </div>
        </div>
    </div>  
</div>

我不希望将所有具有“li”tagName的元素放入列表中,而是遍历每个元素以找到我需要的元素。我很确定我错过了一些非常基本的东西,并且会感谢任何建议/解释。

1 个答案:

答案 0 :(得分:0)

最Java风格的方法是使用返回定位器的方法并编写使用这些方法的内联ExpectedCondition

public By getElem1Locator() {
    return By.cssSelector(....);
}
public By getElem2Locator() {
    return By.tagName(....);
}

...

    WebElement elem2 = wait.until(new ExpectedCondition<WebElement>() {
        public WebElement apply(WebDriver driver) {
            try {
                return driver.findElement(getElem1Locator()).findElement(getElem2Locator());
        } catch (NoSuchElementException e) {
            return null;
        }
    });

...

我们想要使用定位器而不是最终WebElement实例的原因是,如果在我们等待时DOM发生变化,WebElement可能会变得陈旧。

快速而肮脏的解决方案是为第二个元素使用单个Xpath选择器

WebElement elem2 = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//div[contains(concat(' ',normalize-space(@class),' '),' uiContextualLayer ') and contains(concat(' ',normalize-space(@class),' '),' uiContextualLayerBelowLeft ')]//li"));

您还应该查看Page Factory