简体   繁体   English

如何在硒中使用硒wait.until与锚元素

[英]how to use selenium wait.until with anchor element in java

i have selenium project written in c# and i want to migrate it to java, but i have a problem that i could not solve by myself. 我有用C#编写的硒项目,我想将其迁移到Java,但是我有一个我自己无法解决的问题。 lets say i have a webElement elem1 and i want to find another element elem2 using elem1 as the anchor. 可以说我有一个webElement elem1 ,我想使用elem1作为锚点找到另一个元素elem2 so in java i can do it like that: 所以在Java中我可以这样做:

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

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

now, my problem starts when i want to do the same but with wait.until() for elem2 . 现在,当我想要做相同,但与我的问题开始wait.until()elem2 the thing is that elem1 is always appear in the DOM, but elem2 will appear in the DOM only after some time (it depends on some code that is not relevant for this issue), so using the above code will throw an exception. 事实是elem1总是出现在DOM中,但是elem2仅在一段时间后才会出现在DOM中(这取决于与此问题无关的某些代码),因此使用上述代码将引发异常。 in c# i used lambda expression and it was very simple: 在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")); });

in java i cant find a way to do the wait.until AND use elem1 as the anchor for the findElement function. 在Java中,我无法找到一种方法来执行wait.until ,并使用elem1作为findElement函数的锚点。 here is a sample of the html i'm working on: 这是我正在处理的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>

i don't want to get all the elements that has the "li" tagName into a list and than go over each element to find the element i need. 我不想将具有“ li” tagName的所有元素都放入列表中,而不是遍历每个元素以查找所需的元素。 i'm pretty sure i'm missing something which is very basic, and would appreciate any suggestion/explanation. 我很确定我缺少一些非常基本的东西,并且希望您提出任何建议/解释。

The most Java-style way is to have methods that return locators and write your own inline ExpectedCondition that uses these methods. 最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;
        }
    });

...

The reason why we want to use locators and not final WebElement instances is that if DOM changes while we are waiting, the WebElement can become stale. 之所以要使用定位器而不是最终的WebElement实例,是因为如果在等待时DOM发生更改,则WebElement可能会过时。

A quick and dirty solution is to use a single Xpath selector for the second element 一种快速而肮脏的解决方案是对第二个元素使用单个Xpath选择器

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

You should also take a look at Page Factory 您还应该看看Page Factory

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM