有没有办法扩展WebElement的.click方法?
我想为它添加一些代码来解决我们在内部网站上遇到的一些问题。
我想补充一下:
WebDriverWait wait = new WebDriverWait(driver, 5);
wait.until(ExpectedConditions.elementToBeClickable(pageElement));
现在我知道有些人可能会说只是使用隐式等待。我已经考虑过了,但我编写的一些页面需要10-30秒才能加载。有些页面加载速度非常快,但是显示的按钮是基于点击其他按钮的条件,我进入了一个我知道按钮应该在5秒内加载的情况。我宁愿不在每个按钮上等待30秒。这可能会发生几百次,我不希望脚本花费那么长时间。
有没有办法为点击事件添加显式等待?
答案 0 :(得分:0)
尝试FluentWait,这将每5秒检查一次元素。
Wait wait = new FluentWait(driver).withTimeout(30, TimeUnit.SECONDS).pollingEvery(5, TimeUnit.SECONDS).ignoring(NoSuchElementException.class);
答案 1 :(得分:0)
实际上并不需要覆盖.click()
,正如@lauda在评论中所述,这不是一个好习惯。您不需要添加大量代码来等待元素可点击,因此声称它将添加数千行代码是不正确的。您可以使用一行代码轻松完成此操作...因此无需额外的代码行。话虽如此......你应该少关注它会添加和考虑的代码行数:
代表性按钮的示例点击方法
public void clickButtonX()
{
new WebDriverWait(driver, timeOutInSeconds).until(ExpectedConditions.elementToBeClickable(buttonXLocator)).click();
}
你在课堂顶部声明了这些
private By buttonXLocator = By.id("buttonXId");
private int timeOutInSeconds = 10;
话虽如此......我不认为这是正确的做法。使用页面对象模型,您应该让每个页面类句柄等待页面完成加载...然后您不必在单击它们之前等待按钮加载。在动态加载按钮的情况下,触发动态加载的操作应等待加载完成。
package sandbox;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import common.Functions;
public class _PageTemplate
{
private WebDriver driver;
private By dynamicPageLoadLocator = By.id("someId");
private By buttonXLocator = By.id("buttonXId");
private By dynamicLinkLocator = By.id("dynamicLinkId");
private By dynamicSectionElementLocator = By.id("dynamicSectionId");
public _PageTemplate(WebDriver webDriver) throws IllegalStateException
{
Functions.waitForPageLoad(driver);
// see if we're on the right page
if (!driver.getCurrentUrl().contains("samplePage.jsp"))
{
throw new IllegalStateException("This is not the XXXX Sample page. Current URL: " + driver.getCurrentUrl());
}
// for dynamic pages, wait for a specific element to signal the dynamic load is complete
new WebDriverWait(driver, 10).until(ExpectedConditions.presenceOfElementLocated(dynamicPageLoadLocator));
}
public void clickButtonX()
{
// no wait needed here
driver.findElement(buttonXLocator).click();
}
public void clickDynamicLink()
{
// clicking this link triggers part of the page to change, reload, etc. ...
driver.findElement(dynamicLinkLocator).click();
// ... so after the click, we wait for the dynamic part of the page to finish by locating an element that is inside the dynamically
// loaded portion and wait for it to be visible
new WebDriverWait(driver, 10).until(ExpectedConditions.visibilityOfElementLocated(dynamicSectionElementLocator));
}
}
这是在某些Utils类或其他任何内容中声明的。
/**
* Waits for the browser to signal that the DOM is loaded. For dynamic pages, an extra wait may be necessary.
*/
public static void waitForPageLoad(WebDriver driver)
{
new WebDriverWait(driver, 30).until(new ExpectedCondition<Boolean>()
{
public Boolean apply(WebDriver webDriver)
{
return ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("complete");
}
});
}
现在有了这个框架,我们不再需要为每个按钮添加代码,以确保在点击之前它可用。我建议你采用这种方法来处理所有代码。只在需要的地方等待,而不是到处等待。
如果你只是做这两件事,你只会在非常特定的地方等待而不需要它们(在调试时减少复杂性和混乱等)。