【问题标题】:WebDriver does not reliably click links or buttonsWebDriver 不能可靠地单击链接或按钮
【发布时间】:2011-07-04 21:14:29
【问题描述】:

我一直在拼命想让 WebDriver 可靠地单击按钮或链接,但它就是不想合作。我尝试了不同的方法,从设置隐式超时到下面的代码,假设单击并等待元素出现。

下面的 sn-p 代码是在 Internet 上的某个地方找到的,它是我最接近可靠地获得单击按钮或链接的方法。除了它在调试模式下的工作方式与我在夜间回归测试期间执行时的工作方式不同。

有谁知道在浏览器中单击按钮或链接的另一种方法?或者我应该使用 Selenium 1 而不是 WebDriver,因为它太新而无法可靠使用。

public void waitAndClick(WebDriver driver, By by) {
    WebDriverWait wait = new WebDriverWait(driver, 10000, 2000);
    Function<WebDriver, Boolean> waitForElement = new waitForElement(by);
    wait.until(waitForElement);

    Actions builder = new Actions(driver);
    builder.click(driver.findElement(by))
            .perform();
}

private class waitForElement implements Function<WebDriver, Boolean> {
    private final By by;

    private String text = null;

    public waitForElement(By by) {
        this.by = by;
    }

    public waitForElement(By by, String text) {
        this.by = by;
        this.text = text;
    }

    @Override
    public Boolean apply(WebDriver from) {
        if (this.text != null) {
            for (WebElement e : from.findElements(this.by)) {
                if (e.getText().equals(this.text)) {
                    return Boolean.TRUE;
                }
            }

            return Boolean.FALSE;
        } else {
            try {
                driver.switchTo().defaultContent().switchTo().frame("top");
                from.findElement(this.by);
            } catch (Exception e) {
                logger.error("Unable to find \"" + this.by.toString() + "\". Retrying....");
                return Boolean.FALSE;
            }
            logger.info("Found \"" + this.by.toString() + "\".");
            return Boolean.TRUE;
        }
    }
}

在 Eclipse 调试模式下控制台输出:

16:07:08,109 INFO  WebDriverUtility: apply Found "By.linkText: Classes".
16:07:10,514 INFO  WebDriverUtility: apply Found "By.linkText: Reports".
16:07:17,028 ERROR WebDriverUtility: apply Unable to find "By.linkText: Users". Retrying....
16:07:26,369 INFO  WebDriverUtility: apply Found "By.linkText: Users".
16:07:38,272 ERROR WebDriverUtility: apply Unable to find "By.linkText: System". Retrying....
16:07:41,334 INFO  WebDriverUtility: apply Found "By.linkText: System".
16:07:47,722 ERROR WebDriverUtility: apply Unable to find "By.linkText: Schools". Retrying....
16:07:50,565 INFO  WebDriverUtility: apply Found "By.linkText: Schools".

从 Eclipse 运行时控制台退出:

16:14:04,179 INFO  WebDriverUtility: apply Found "By.linkText: Classes".
16:14:04,726 INFO  WebDriverUtility: apply Found "By.linkText: Reports".
16:14:09,771 INFO  PageAPITesting: login org.openqa.selenium.NoSuchElementException: Unable to find element with link text == Reports (WARNING: The server did not provide any stacktrace information)
For documentation on this error, please visit: http://seleniumhq.org/exceptions/no_such_element.html
Build info: version: '2.0rc3', revision: '12536', time: '2011-06-20 18:19:52'
System info: os.name: 'Windows XP', os.arch: 'x86', os.version: '5.1', java.version: '1.6.0_24'
Driver info: driver.version: RemoteWebDriver
16:14:09,865 INFO  PageAPITesting: login current tabs is Classes
16:14:09,958 INFO  WebDriverUtility: apply Found "By.linkText: Schools".
16:14:10,240 INFO  PageAPITesting: login java.lang.IllegalStateException: Unable to navigate to the ca.schoolspecialty.qa.api.pages.schools.MenuSchoolPage page

【问题讨论】:

  • 我遇到了同样的问题,我尝试过使用隐式/显式方法,但一直没有工作,所以我开始使用Thread.Sleep,似乎它对我有用,我一直在挣扎像你一样,即使在使用 thread.sleep 之后,我仍然没有看到 100% 的脚本点击,但至少它的工作率为 90%

标签: java automated-tests webdriver


【解决方案1】:

我没有看到任何奇怪的行为,

wait.until 方法,它的作用是在函数上调用apply 方法,直到它返回一些东西或者有一个Time Out。

如果元素尚未创建,则有时会收到 NotFoundExceptions,实际上,如果您查看代码,您会看到:

 while (clock.isNowBefore(end)) {
  try {
    T value = isTrue.apply(driver);

    if (value != null && Boolean.class.equals(value.getClass())) {
      if (Boolean.TRUE.equals(value)) {
        return value;
      }
    } else if (value != null) {
      return value;
    }
  } catch (NotFoundException e) {
    // Common case in many conditions, so swallow here, but be ready to
    // rethrow if it the element never appears.
    lastException = e;
  }
  sleep();

它捕获异常并且什么都不做,问题是您覆盖了应用程序以捕获并记录该异常,所以您看到的是预期的行为,没有其他方法可以检查元素是否已创建不断地要求它。

我自己正在将这段代码用于函数生成器:

public static Function<WebDriver, WebElement> presenceOfElementLocated(
        final By locator) {
    return new Function<WebDriver, WebElement>() {
        @Override
        public WebElement apply(WebDriver driver) {
            return driver.findElement(locator);
        }
    };
}

更简单,您可以用于任何定位器

【讨论】:

  • 感谢 relpy jasalguero。我经常看到的另一个问题是,当我在成功等待后立即重新搜索相同的元素时,会抛出 StaleElementReferenceException 或 ElementNotVisibleException。我不明白为什么在之前找到元素后会抛出这些异常。我试过忽略异常,但这可能不是最好的做法。
  • 因为找到一个元素并不意味着WebDriver可以与之交互。例如,如果元素被隐藏,WebDriver 将抛出 ElementNotVisibleException。这样做是为了模拟用户与 web 应用程序的交互,如果您有一个不可见的元素或在其他层下用户无法对其执行任何操作
  • 我经常看到的是,一旦我使用WebDriverWait()类在DOM中找到一个元素,然后立即等待该元素被isDisplayed(),再次使用WebDriverWait()类,我一尝试点击就会抛出 StaleElementReferenceException 异常。
猜你喜欢
  • 2021-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多