我希望将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();
总而言之,我需要等到两个元素中的任何一个出现。然后挑选出现的人(他们不能同时出现) 请帮助。
答案 0 :(得分:16)
现在有一个原生的解决方案,or
方法,check the doc。
你这样使用它:
driverWait.until(ExpectedConditions.or(
ExpectedConditions.presenceOfElementLocated(By.cssSelector("div.something")),
ExpectedConditions.presenceOfElementLocated(By.cssSelector("div.anything"))));
答案 1 :(得分:7)
这是我在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_LOCATOR
和ATTENTION_REQUEST_ALREADY_PRESENTS_WINDOW_LOCATOR
是页面的两个静态定位器。
答案 2 :(得分:2)
如果您将“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();
}
答案 3 :(得分:1)
不幸的是,没有这样的命令。您可以通过try和catch来克服这个问题,或者我建议您使用开源Ruby库Watir。
答案 4 :(得分:1)
你也可以使用这样的CSSSelector:
wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("h2.someClass, h3.otherClass")));
将someClass和otherClass替换为xpath中[...]中的内容。
答案 5 :(得分:0)
有另一种方法可以等待,但它不是使用预期条件而是使用lambda表达式而不是..
Do
[(0, 6)]
0
2 Do
36 Do Sevif vjrKylhtgvmgLslj ypjgZollw?
Do
Sevif vjrKylhtgvmgLslj ypjgZollw?
S
No shift match found, closest match:
[]
Do
答案 6 :(得分:0)
如果要满足的条件数量不定,则可以利用通用列表,例如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
}
}
答案 7 :(得分:-1)
有一个简单的解决方案,使用显式等待:
wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//*[@id='FirstElement' or @id='SecondElement']")));
在此之前,我尝试使用wait.until(ExpectedConditions.or(...
,这与2.53.0之前的硒版本不兼容。