如何在没有 By 定位器的情况下使用 WebDriverWait.until?
How to use WebDriverWait.until without a By locator?
我正在使用通过框架 (Cucumber) 实现的 Selenium WebDriver,但在执行操作之前等待元素加载时遇到了问题。
最初,我想使用隐式等待,但如果一个元素没有立即加载,它就会等待超时。通常情况下,它使我的测试时间比我想要的要长。
然后,我想使用 Explicit wait 使每种情况的等待时间尽可能短。
问题是 WebDriverWait.until 中的大多数 ExpectedConditions 正在寻找由 By 定位器定位的元素(它们是 ClassName、CssSelector、Id、LinkText、Name、PartialLinkText、Tagname 或 XPath)。
我在用于单击网络元素的通用函数中使用 WebDriverWait.until。
我正在测试的网站上的 Webelements 是由 dojo 生成的,没有静态 ID。它们并不总是有其他类型的定位器,或者它们不是静态的。
然后,开发人员向网络元素添加了一个名为 data-automation-id 的附加属性。我想在显式等待中使用此属性,但找不到方法。
我尝试使用以下代码来使用 xpath :
public void clickOnDataAutomationId(String dataautomationid) {
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//" + findDataAutomationId(dataautomationid).getAttribute("tagName") + "[contains(@data-automation-id, '" + dataautomationid + "')]")));
findDataAutomationId(dataautomationid).click();
}
findDataAutomationId() 是一个函数,它返回第一个包含 data-automation-id 作为 FluentWebElement 的网络元素。
问题是如果没有立即加载网络元素,findDataAutomationId 会失败,这使得 WebDriverWait.until 变得毫无意义。您是否看到另一种无需重构网站即可解决“按定位器”问题的方法?
使用 "presenceOfElementLocated" 方法代替 "elementToBeClickable"。此更改可能会帮助您
与其使用方法findDataAutomationId检索webelement,不如直接找到webelement,然后点击如下图:
public void clickOnDataAutomationId(String dataautomationid) {
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[contains(@data-automation-id, '" + dataautomationid + "')]")));
element.click();
}
或者,如果data-automation-id是一个完整的文本而不是一个部分,那么你可以使用下面的代码:
public void clickOnDataAutomationId(String dataautomationid) {
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[@data-automation-id, '" + dataautomationid + "')]")));
element.click();
}
你下面的解决方案。它不会 return 直到 apply() 为真或直到等待超时
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(new Function<WebDriver, Object>() {
@Nullable
public Object apply(@Nullable WebDriver input) {
//add any condition or check your data-automation-id is visible/clickable
return true;
}
});
}
我正在使用通过框架 (Cucumber) 实现的 Selenium WebDriver,但在执行操作之前等待元素加载时遇到了问题。
最初,我想使用隐式等待,但如果一个元素没有立即加载,它就会等待超时。通常情况下,它使我的测试时间比我想要的要长。
然后,我想使用 Explicit wait 使每种情况的等待时间尽可能短。 问题是 WebDriverWait.until 中的大多数 ExpectedConditions 正在寻找由 By 定位器定位的元素(它们是 ClassName、CssSelector、Id、LinkText、Name、PartialLinkText、Tagname 或 XPath)。 我在用于单击网络元素的通用函数中使用 WebDriverWait.until。 我正在测试的网站上的 Webelements 是由 dojo 生成的,没有静态 ID。它们并不总是有其他类型的定位器,或者它们不是静态的。 然后,开发人员向网络元素添加了一个名为 data-automation-id 的附加属性。我想在显式等待中使用此属性,但找不到方法。
我尝试使用以下代码来使用 xpath :
public void clickOnDataAutomationId(String dataautomationid) {
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//" + findDataAutomationId(dataautomationid).getAttribute("tagName") + "[contains(@data-automation-id, '" + dataautomationid + "')]")));
findDataAutomationId(dataautomationid).click();
}
findDataAutomationId() 是一个函数,它返回第一个包含 data-automation-id 作为 FluentWebElement 的网络元素。
问题是如果没有立即加载网络元素,findDataAutomationId 会失败,这使得 WebDriverWait.until 变得毫无意义。您是否看到另一种无需重构网站即可解决“按定位器”问题的方法?
使用 "presenceOfElementLocated" 方法代替 "elementToBeClickable"。此更改可能会帮助您
与其使用方法findDataAutomationId检索webelement,不如直接找到webelement,然后点击如下图:
public void clickOnDataAutomationId(String dataautomationid) {
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[contains(@data-automation-id, '" + dataautomationid + "')]")));
element.click();
}
或者,如果data-automation-id是一个完整的文本而不是一个部分,那么你可以使用下面的代码:
public void clickOnDataAutomationId(String dataautomationid) {
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[@data-automation-id, '" + dataautomationid + "')]")));
element.click();
}
你下面的解决方案。它不会 return 直到 apply() 为真或直到等待超时
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(new Function<WebDriver, Object>() {
@Nullable
public Object apply(@Nullable WebDriver input) {
//add any condition or check your data-automation-id is visible/clickable
return true;
}
});
}