selenium Wait.Until(ExspectedConditions.visibilityOf Element1或Element2)

qgelzfjb  于 2022-11-10  发布在  其他
关注(0)|答案(9)|浏览(177)

我想使用带有两个元素的wait.until(ExpectedConditions)。我正在运行一个测试,我需要WebDriver来等待Element1或Element2出现。那我就得去接谁先到。我试过了:

WebDriverWait wait = new WebDriverWait(driver, 60); 
    wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//h2[@class='....']"))) || wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//h3[@class='... ']"))); 

        // Then I would need:

String result = driver.findElement(By.xpath("...")).getText() || driver.findElement(By.xpath("...")).getText();

总而言之,我需要等到这两个元素中的任何一个出现。然后接任何出现的人(他们不能同时出现)请帮帮忙。

nhhxz33t

nhhxz33t1#

现在有一个本机解决方案,or方法,请查看文档。
您可以这样使用它:

driverWait.until(ExpectedConditions.or(
    ExpectedConditions.presenceOfElementLocated(By.cssSelector("div.something")),
    ExpectedConditions.presenceOfElementLocated(By.cssSelector("div.anything"))));
yfjy0ee7

yfjy0ee72#

这是我在我的Helper类中声明的方法,它的工作方式非常出色。只需创建您自己的ExpectedCondition并使其返回定位器找到的任何元素:

public static ExpectedCondition<WebElement> oneOfElementsLocatedVisible(By... args)
{
    final List<By> byes = Arrays.asList(args);
    return new ExpectedCondition<WebElement>()
    {
        @Override
        public Boolean apply(WebDriver driver)
        {
            for (By by : byes)
            {
                WebElement el;
                try {el = driver.findElement(by);} catch (Exception r) {continue;}
                if (el.isDisplayed()) return el;
            }
            return false;
        }
    };
}

然后你可以这样使用它:

Wait wait = new WebDriverWait(driver, Timeouts.WAIT_FOR_PAGE_TO_LOAD_TIMEOUT);
WebElement webElement = (WebElement) wait.until(
        Helper.oneOfElementsLocatedVisible(
                By.xpath(SERVICE_TITLE_LOCATOR), 
                By.xpath(ATTENTION_REQUEST_ALREADY_PRESENTS_WINDOW_LOCATOR)
        )
);

这里的SERVICE_TITLE_LOCATORATTENTION_REQUEST_ALREADY_PRESENTS_WINDOW_LOCATOR是页面的两个静态定位器。

aydmsdu9

aydmsdu93#

我认为如果将“OR”放入XPath中,您的问题就有一个简单的解决方案。

WebDriverWait wait = new WebDriverWait(driver, 60); 
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//h2[@class='....'] | //h3[@class='... ']")));

然后,要打印结果,请使用以下命令:

if(driver.findElements(By.xpath("//h2[@class='....']")).size()>0){
       driver.findElement(By.xpath("//h2[@class='....']")).getText();
}else{
       driver.findElement(By.xpath("//h3[@class='....']")).getText();
}
x3naxklr

x3naxklr4#

您还可以使用如下所示的CSSSelector:

wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("h2.someClass, h3.otherClass")));

用您在[...]中拥有的内容替换某些类和其他类在XPath中。

mqxuamgl

mqxuamgl5#

不幸的是,没有这样的命令。您可以通过尝试和捕捉来克服这个问题,或者我最好推荐您使用开放源码的Ruby库Watir

4ngedf3f

4ngedf3f6#

还有一种等待的替代方法,但它没有使用预期的条件,而是使用了lambda表达式。

wait.Until(x => driver.FindElements(By.Xpath("//h3[@class='... ']")).Count > 0 || driver.FindElements(By.Xpath("//h2[@class='... ']")).Count > 0);
7cjasjjr

7cjasjjr7#

如果要满足的条件数量可变,则可以利用泛型列表,如here所示的Java的ArrayList<>,然后执行以下操作:

//My example is waiting for any one of a list of URLs (code is java)

    public void waitUntilUrls(List<String> urls) {
        if(null != urls && urls.size() > 0) {
            System.out.println("Waiting at " + _driver.getCurrentUrl() + " for " + urls.size() + " urls");
            List<ExpectedCondition<Boolean>> conditions = new ArrayList<>();
            for (String url : urls) {
                conditions.add(ExpectedConditions.urlContains(url));
            }

            WebDriverWait wait = new WebDriverWait(_driver, 30);
            ExpectedCondition<Boolean>[] x = new ExpectedCondition[conditions.size()];
            x = conditions.toArray(x);
            wait.until(ExpectedConditions.or(x)); // "OR" selects from among your ExpectedCondition<Boolean> array
        }
    }
uqxowvwt

uqxowvwt8#

wait.until(
            ExpectedConditions.or(
                    ExpectedConditions.elementToBeClickable(By.xpath("yourXpath"),
                    ExpectedConditions.elementToBeClickable(By.xpath("yourAnotherXpath")
            )
    );
uqjltbpv

uqjltbpv9#

对此有一个简单的解决方案,使用显式等待:

wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//*[@id='FirstElement' or @id='SecondElement']")));

在此之前,我尝试使用wait.until(ExpectedConditions.or(...,它与2.53.0之前的Selify版本不兼容。

相关问题