Selenium Java,按照 XPath 等待元素,如果 XPath 匹配多个元素,则匹配文本。

huangapple go评论76阅读模式
英文:

Selenium java, wait for element by xpath and matching text in case of xpath matching multiple elements

问题

我正在尝试等待具有特定CSS和内部文本的元素。
我有多个满足CSS条件的元素(元素可以是可见/不可见的),而Selenium的ExpectedConditions的行为不是我想要的方式。

如果我先尝试通过CSS查找元素,然后自行筛选,有时可能会错过预期的元素,因为某些元素可能尚未加载。

By cssBy = By.css("CSS_HERE");
wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(cssBy);
List<WebElement> tabs = driver.findElements(cssBy);
WebElement element =
        tabs.stream().filter(tab -> tab.getText().contains("TARGET_TEXT")).findAny().get();

上面的代码片段有时会错过满足CSS但在Selenium检查时尚未加载的预期元素。这导致在第二部分中找不到匹配的元素。

我尝试过使用textMatches和locator

By cssBy = By.css("CSS_HERE");
wait.until(ExpectedConditions.textMatches(cssBy, "TARGET_TEXT");
....

但我认为上面的代码片段会选择找到的第一个匹配CSS的元素,并等待其文本变为“TARGET_TEXT”,这不是我的意图。

有任何建议在多个匹配定位器的元素中等待文本匹配吗?

英文:

I'm trying to wait for an element with certain css and inner text.
I have multiple elements satisfying the css condition (element could be visible/invisible) and selenium ExpectedConditions is not behaving the way I want.

If I try to find elements by css first and then filter out myself, I sometimes miss the intended element because some elements might not have loaded.

By cssBy = By.css(&quot;CSS_HERE&quot;);
wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(cssBy);
List&lt;WebElement&gt; tabs = driver.findElements(cssBy);
WebElement element =
        tabs.stream().filter(tab -&gt; tab.getText().contains(&quot;TARGET_TEXT&quot;)).findAny().get();

the above snippet sometimes misses the indented elements which satisfy the CSS but have not loaded when selenium checked for it. This results in me getting no matching element in second part.

I tried with textMatches and locator

By cssBy = By.css(&quot;CSS_HERE&quot;);
wait.until(ExpectedConditions.textMatches(cssBy, &quot;TARGET_TEXT&quot;);
....

But I think the above snippet is selecting the first element it can find matching CSS and waits for its text to be TARGET_TEXT which is not my intention.

Any suggestions to wait for text match in case of multiple elements matching the locator?

答案1

得分: 1

替代 presenceOfAllElementsLocatedBy(),您需要使用 WebDriverWait 来等待 visibilityOfAllElementsLocatedBy(),并且您可以使用以下 定位策略:

By cssBy = By.css("CSS_HERE");
wait.until(ExpectedConditions.visibilityOfAllElementsLocatedBy(cssBy));
List<WebElement> tabs = driver.findElements(cssBy);
WebElement element =
    tabs.stream().filter(tab -> tab.getText().contains("TARGET_TEXT")).findAny().get();
英文:

Instead of presenceOfAllElementsLocatedBy() you need to induce WebDriverWait for the visibilityOfAllElementsLocatedBy() and you can use the following Locator Strategy:

By cssBy = By.css(&quot;CSS_HERE&quot;);
wait.until(ExpectedConditions.visibilityOfAllElementsLocatedBy(cssBy);
List&lt;WebElement&gt; tabs = driver.findElements(cssBy);
WebElement element =
	tabs.stream().filter(tab -&gt; tab.getText().contains(&quot;TARGET_TEXT&quot;)).findAny().get();

答案2

得分: 0

你可以在这里编写自己的预期条件方法,以下是textMatches()的示例代码:

public static ExpectedCondition<List<WebElement>> textMatches(final By locator, final Pattern pattern) {
    return new ExpectedCondition<List<WebElement>>() {
        @Override
        public List<WebElement> apply(WebDriver driver) {
            String currentValue;
            List<WebElement> elements = driver.findElements(locator);
            List<WebElement> matchingElements = new ArrayList();

            for (WebElement element : elements) {
                currentValue = element.getText();
                if (pattern.matcher(currentValue).find()) {
                    matchingElements.add(element);
                }
            }
            return matchingElements;
        }

        @Override
        public String toString() {
            return "matching elements for " + locator;
        }
    };
}
英文:

You could write your own Expected Conditions method here is an example for textMatches()

  public static ExpectedCondition&lt;List&lt;WebElement&gt;&gt; textMatches(final By locator, final Pattern pattern) {
    return new ExpectedCondition&lt;List&lt;WebElement&gt;&gt;() {
        @Override
        public List&lt;WebElement&gt; apply(WebDriver driver) {
            String currentValue;
            List&lt;WebElement&gt; elements = driver.findElements(locator);
            List&lt;WebElement&gt; matchingElements = new ArrayList();


            for(WebElement element : elements){
                currentValue = element.getText();
                if (pattern.matcher(currentValue).find()){
                    matchingElements.add(element);
                }
            }
            return matchingElements;
        }

        @Override
        public String toString() {
            return &quot;matching elements for  &quot; + locator;
        }
    };
}

huangapple
  • 本文由 发表于 2020年9月18日 00:50:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/63942739.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定