【问题标题】:Selenium java, wait for element by xpath and matching text in case of xpath matching multiple elementsSelenium java,在xpath匹配多个元素的情况下等待xpath元素和匹配文本
【发布时间】:2020-09-17 16:50:38
【问题描述】:

我正在尝试等待具有特定 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();

上面的 sn-p 有时会错过满足 CSS 但在 selenium 检查时没有加载的缩进元素。这导致我在第二部分没有匹配的元素。

我尝试使用 textMatches 和定位器

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

但我认为上面的 sn-p 正在选择它可以找到匹配 CSS 的第一个元素并等待其文本为 TARGET_TEXT,这不是我的意图。

在多个元素匹配定位器的情况下等待文本匹配的任何建议?

【问题讨论】:

    标签: java selenium selenium-webdriver webdriver webdriverwait


    【解决方案1】:

    您需要为visibilityOfAllElementsLocatedBy() 诱导WebDriverWait 而不是presenceOfAllElementsLocatedBy(),您可以使用以下Locator Strategy:

    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();
    

    【讨论】:

    • 虽然这是一个不错的方法。我有标签布局。因此,某些与定位器匹配的元素可能不在活动选项卡中,因此不可见。抱歉,我没有在问题中提到这一点。我会更新它。但当一切都在屏幕上时,这是一个很好的解决方案,因为它不需要任何自定义期望。谢谢
    • @NagendraGupta 讽刺的是,Selenium 的核心功能是与屏幕上可见的WebElements 进行交互。其他选项卡中的元素以及不可见的元素需要以不同的方式处理。
    【解决方案2】:

    您可以编写自己的预期条件方法,这里是 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;
            }
        };
    }
    

    【讨论】:

    • 在上面的 sn-p 中,直接返回第一个不匹配会失败,对吧?说我有两个匹配定位器的元素。第一个与文本模式不匹配。在这种情况下,sn-p 不会总是失败吗?虽然我明白了,但我可以跟踪匹配的并返回它们是非空的,否则为空。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多