如何将明确等待的条件缩小到给定的 SearchContext?
How do I narrow down the condition of an explicit wait to a given SearchContext?
我想等到特定视图消失。一般来说,我可以用下面的代码来完成:
val wait = WebDriverWait(driver, Duration.ofSeconds(3)) // where driver is e.g. WebDriver
val condition = ExpectedConditions.invisibilityOfElementLocated(
By.id("my.app:id/someId") // or another locator, e.g. XPath
)
wait.until(condition)
但是,这种方式不是很精确。
想象一个场景,两个不同的视图匹配同一个谓词(定位器)。在下面的示例中,我使用了“按 ID”定位器,但它也可以是其他任何东西。
在下图中,有 3 个视图:
- 查看与我的谓词匹配的“A”(“按 ID”)
- 包含视图“C”的视图“B”
- 查看与我的谓词匹配的“C”(“按 ID”)
当我只想找到视图“C”时,例如为了点击它,我可以这样做:
driver.findElement(By.id("anotherId")).findElement("someId").click()
所以当我知道它包含视图“C”时,我可以通过首先搜索视图“B”来缩小视图“C”的搜索范围。
这是可能的,因为 findElement
方法返回的 WebElement
实现了 SearchContext
接口,就像 WebDriver
一样。因此,我可以选择是要在整个屏幕上还是在特定的 WebElement
.
内搜索
如何在等待视图消失的情况下缩小搜索范围?
理想情况下,我希望是这样的:
ExpectedConditions.invisibilityOfElementLocated(
searchContext, // either a driver or WebElement
By.id(...) // the locator
)
但我还没有找到类似的东西。
我看过 org.openqa.selenium.support.ui.ExpectedConditions
方法..
还有一些类似的方法:
visibilityOfNestedElementsLocatedBy(final By parent, final By childLocator)
visibilityOfNestedElementsLocatedBy(final WebElement element, final By childLocator)
但 invisibility
没有相同的方法。
所以,我建议实施自定义的:
import org.openqa.selenium.support.ui.ExpectedCondition
import org.openqa.selenium.support.ui.ExpectedConditions
public static ExpectedCondition<Boolean> invisibilityOfNestedElementLocated(WebElement parent, By nested) {
return new ExpectedCondition<Boolean>() {
private boolean wasFound = false;
@Override
public Boolean apply(WebDriver driver) {
wasFound = ExpectedConditions.invisibilityOfAllElements(parent.findElements(nested)).apply(driver);
return wasFound;
}
@Override
public String toString() {
return String.format("element \"%s\" from parent \"%s\", found: \"%b\"", nested.toString(), parent.toString(), wasFound);
}
};
}
举个例子:
WebElement searchContext = driver.findElement(By.id("anotherId");
new WebDriverWait(driver, Duration.ofSeconds(10)).until(
invisibilityOfNestedElementLocated(searchContext, By.id('someId'))
)
我想等到特定视图消失。一般来说,我可以用下面的代码来完成:
val wait = WebDriverWait(driver, Duration.ofSeconds(3)) // where driver is e.g. WebDriver
val condition = ExpectedConditions.invisibilityOfElementLocated(
By.id("my.app:id/someId") // or another locator, e.g. XPath
)
wait.until(condition)
但是,这种方式不是很精确。
想象一个场景,两个不同的视图匹配同一个谓词(定位器)。在下面的示例中,我使用了“按 ID”定位器,但它也可以是其他任何东西。
在下图中,有 3 个视图:
- 查看与我的谓词匹配的“A”(“按 ID”)
- 包含视图“C”的视图“B”
- 查看与我的谓词匹配的“C”(“按 ID”)
当我只想找到视图“C”时,例如为了点击它,我可以这样做:
driver.findElement(By.id("anotherId")).findElement("someId").click()
所以当我知道它包含视图“C”时,我可以通过首先搜索视图“B”来缩小视图“C”的搜索范围。
这是可能的,因为 findElement
方法返回的 WebElement
实现了 SearchContext
接口,就像 WebDriver
一样。因此,我可以选择是要在整个屏幕上还是在特定的 WebElement
.
如何在等待视图消失的情况下缩小搜索范围?
理想情况下,我希望是这样的:
ExpectedConditions.invisibilityOfElementLocated(
searchContext, // either a driver or WebElement
By.id(...) // the locator
)
但我还没有找到类似的东西。
我看过 org.openqa.selenium.support.ui.ExpectedConditions
方法..
还有一些类似的方法:
visibilityOfNestedElementsLocatedBy(final By parent, final By childLocator)
visibilityOfNestedElementsLocatedBy(final WebElement element, final By childLocator)
但 invisibility
没有相同的方法。
所以,我建议实施自定义的:
import org.openqa.selenium.support.ui.ExpectedCondition
import org.openqa.selenium.support.ui.ExpectedConditions
public static ExpectedCondition<Boolean> invisibilityOfNestedElementLocated(WebElement parent, By nested) {
return new ExpectedCondition<Boolean>() {
private boolean wasFound = false;
@Override
public Boolean apply(WebDriver driver) {
wasFound = ExpectedConditions.invisibilityOfAllElements(parent.findElements(nested)).apply(driver);
return wasFound;
}
@Override
public String toString() {
return String.format("element \"%s\" from parent \"%s\", found: \"%b\"", nested.toString(), parent.toString(), wasFound);
}
};
}
举个例子:
WebElement searchContext = driver.findElement(By.id("anotherId");
new WebDriverWait(driver, Duration.ofSeconds(10)).until(
invisibilityOfNestedElementLocated(searchContext, By.id('someId'))
)