【问题标题】:Can I extend the .click method of a WebElement?我可以扩展 WebElement 的 .click 方法吗?
【发布时间】:2016-11-15 22:50:32
【问题描述】:

有没有办法扩展 WebElement 的 .click 方法?

我想添加几行代码来解决我们在内部网站上遇到的一些问题。

我想补充:

WebDriverWait wait = new WebDriverWait(driver, 5);
wait.until(ExpectedConditions.elementToBeClickable(pageElement));

现在我知道你们中的一些人可能会说只使用隐式等待。我已经考虑过了,但是我编写的一些页面需要 10-30 秒才能加载。一些页面加载速度非常快,但随后显示的按钮是基于单击其他按钮的条件,我遇到了我知道按钮应该在 5 秒内加载的情况。我宁愿不要在每个按钮上等待 30 秒。这可能会发生数百次,我不希望脚本花那么长时间。

有没有办法为点击事件添加显式等待?

【问题讨论】:

  • 在 C# 中我只会覆盖该方法,但我不知道如何在 Java 中做到这一点。
  • 你为什么不创建一个静态实用方法,用你想要的附加功能包装 click()。
  • 您不应该自定义解决特定问题的通用方法,这不是一个好习惯。使用页面对象并在这些特定操作中处理您遇到的问题。
  • @lauda 通常我会同意你的观点,但在这种情况下,为每个按钮添加代码(有数百个)实际上会添加数千行代码。我创建了一个类,然后将元素传递给它,然后做我需要做的事情,但是代码不像我希望的那样可读。
  • @Grasshopper 你能举个例子吗?

标签: java selenium


【解决方案1】:

真的不需要覆盖.click(),正如@lauda 在 cmets 中所说,这不是一个好习惯。您不需要添加大量代码来等待元素可点击,因此声称它将添加数千行代码的说法是不正确的。您可以使用一行代码轻松完成此操作......因此无需额外的代码行。话虽如此...您应该少关注它将添加和考虑多少行代码:

  1. 维护起来有多容易?
  2. 我是否在我的代码库中增加了不必要的复杂性?
  3. 它会变得更具可读性吗?
  4. ...等等...

代表按钮的示例点击方法

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");
        }
    });
}

现在有了这个框架,我们不再需要向每个按钮添加代码来确保它在点击之前可用。我建议您对所有代码都采用这种方法。只在需要的地方等待,而不是到处等待。

  1. 等待页面加载
  2. 触发动态换页后,等待换页完成

如果你只做这两件事,你只会在非常特定的地方等待,而不是到处都需要它们(减少调试时的复杂性和混乱等)。

【讨论】:

    【解决方案2】:

    试试 FluentWait,这将每 5 秒检查一次元素。

    Wait wait = new FluentWait(driver).withTimeout(30, TimeUnit.SECONDS).pollingEvery(5, TimeUnit.SECONDS).ignoring(NoSuchElementException.class);
    

    【讨论】:

      猜你喜欢
      • 2011-11-21
      • 2021-12-25
      • 2018-08-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-20
      • 2019-06-27
      相关资源
      最近更新 更多