当前位置: 首页 > 知识库问答 >
问题:

Selenium java SafariDriver:单击后等待页面加载

罗祺
2023-03-14

当我运行以下代码时,执行会突然结束,除非我取消对Thread.sleep()的注释。因此,我在撤回url servlet中的代码不会被执行。单击是一个提交按钮单击,加载另一个页面。

        EventFiringWebDriver webDriver = new EventFiringWebDriver(new SafariDriver());
        try {
            webDriver.get("http://localhost:9988");
            webDriver.findElement(By.id("amount")).sendKeys(new StringBuffer().append(amount.getRupees()).append('.').append(amount.getPaise()).toString());
            webDriver.findElement(By.id("withdraw")).click();
            //Thread.sleep(10000);
        } finally {
            webDriver.close();
        }

让硒等到页面加载的正确方法是什么?

我正在使用以下selenium版本

<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-server</artifactId>
<version>3.11.0</version>

共有1个答案

澹台权
2023-03-14

听起来,显式等待可能是您所需要的。在< code>ExpectedConditions类中有一个现成可用的条件集合(更多信息请参见https://www.seleniumhq.org/docs/04_webdriver_advanced.jsp)。但是一旦你理解了它们是如何工作的,制作你自己的就相当简单了。这些方法的美妙之处在于,与Thread.sleep()不同,一旦条件满足,它会立即停止等待。

我写了一些我过去用来等待“页面加载”的具体例子,然后稍微了解一下如何制作你自己的,以防它对你有用:

如果您的页面在ajax内容上很轻,并且加载了一次静态内容,您可以实现一个显式的等待条件来检查DOM的readyState属性

// this could benefit being static so it doesn't create new classpath defs every invocation
public ExpectedCondition<Boolean> readyStateIsComplete() {

    return new ExpectedCondition<Boolean>() {
        @Override
        public Boolean apply(WebDriver webDriver) {
            String readyState = (String) ((JavascriptExecutor) webDriver)
                    .executeScript("return document.readyState");

            return readyState.equals("complete");
        }

        public String toString() {
            return "page document's readyState flag to be complete";
        }
    };
}

只有当所有静态内容都完成加载后,该属性才是“完整的”。使用它可能就像:

// prepare me like this
WebDriverWait wait = new WebDriverWait(driver, maxSecondsToWait);

// Use me like this
wait.until(readyStateIsComplete());

上面的例子适用于第一次在所有内容完成之前加载页面。如果您的页面有大量的ajax内容,那么您可以尝试等待ajax队列到达零,这可以在已经加载了ajax工作的页面上完成。

public ExpectedCondition<Boolean> activeQueuesToFinish() {

    return new ExpectedCondition<Boolean>() {

        public Boolean apply(WebDriver driver) {

            // This is just a formatted javascript block with in-string indenting
            String jScript = "if (A4J.AJAX) {" +
                    "            with (A4J.AJAX) {" +
                    "                var queues = A4J.AJAX.EventQueue.getQueues();" +
                    "                    for (var queueNames in queues) {" +
                    "                        return A4J.AJAX.EventQueue.getQueue(queueNames).getSize() <= 0;" +
                    "                    }" +
                    "                }" +
                    "            }" +
                    "        return true;";
            try {
                return (Boolean) ((JavascriptExecutor) driver).executeScript(jScript);
            } catch (WebDriverException e) {
                return true;
            }
        }

        public String toString() {
            return "active queues to finish.";
        }
    };

如果你使用jquery,你可以尝试这样做,让当前的ajax工作完成:

public ExpectedCondition<Boolean> allAjaxRequestsFinish() {
    return new ExpectedCondition<Boolean>() {
        public Boolean apply(WebDriver driver) {
            try {
                return (Boolean) ((JavascriptExecutor) driver).executeScript("return jQuery.active == 0");
            } catch (Exception e) {
                return true;
            }
        }

        public String toString() {
            return "all ajax requests to finish.";
        }
    };
}

所有这些条件或您在此模板中创建的任何条件都可以以相同的方式用于动态等待:

wait.until(activeQueuesToFinish());
wait.until(allAjaxRequestsFinish());

编辑:

我的意思是“模板”是一个具有这种形式的函数:

public ExpectedCondition<Boolean> myCustomCondition(/* some arguments from the outside */) {
    return new ExpectedCondition<Boolean>() {
        public Boolean apply(WebDriver driver) {
            // Check something on the page and return either true or false,
            // this method will be run repeatedly until either the time
            // limit is exceeded, or true is returned
        }

        public String toString() {
            return "a description of what this is waiting for";
        }
    };
}

下面是一个示例,说明如何执行此操作以等待可能阻止页面的特定元素:

public ExpectedCondition<Boolean> waitForElementToHaveText(final WebElement element, final String expectedText) {
    return new ExpectedCondition<Boolean>() {
        public Boolean apply(WebDriver driver) {
            try {
                return element.getText().equals(expectedText);
            } catch (Exception e) {
                return false; // catchall fail case
            }
        }

        public String toString() {
            return "an element to have specific text";
        }
    };
}
 类似资料:
  • 问题内容: 有人知道如何等待页面加载吗?我尝试了在网上找到的所有可能的变体,但根本无法正常工作。 触发click()命令后,我需要等待,Web服务器上存在一些内部脚本,这些脚本会愚弄检查,例如(我排除了导入所需模块并使用标准命名约定的代码): 要么 要么 上述所有检查均无效,从某种意义上来说,即使页面仍在加载中,它们也会返回True。这会导致我正在阅读的文本不完整,因为click()命令后页面未完

  • 我想在点击后获取页面的页面源。然后使用browser.back()函数返回。但是Selenium不会让页面在点击后完全加载,并且由JavaScript生成的内容不包含在该页面的页面源中。

  • 我正在尝试使用selenium/python从印度中央污染控制委员会读取数据表。这是一个输出示例。我基本上遵循此处介绍的方法:https://github.com/RachitKamdar/Python-Scraper. 多亏了@Prophet,我才能够从第一页读取数据(使用Python的XPATH选择元素?)但我无法让selenium在切换到第2页时等待数据表重新加载。我试图添加webdrive

  • 我试图创建一个等待加载页面的方法,但我出现了一个错误。可能我没有正确使用这个方法。 错误是:

  • 本文向大家介绍jQuery EasyUI 页面加载等待及页面等待层,包括了jQuery EasyUI 页面加载等待及页面等待层的使用技巧和注意事项,需要的朋友参考一下 下面一个代码片段是 easyUI 页面加载等待,代码如下所示: 下面看个工具类 基于easyui的页面等待提示层,即mask 效果图: 以上所述是小编给大家介绍的jQuery EasyUI 页面加载等待及页面等待层,希望对大家有所帮

  • 问题内容: 我编写了一个脚本,该脚本从页面中获取数据,但是有时页面需要花费一些时间来加载,因此当将html拉到汤对象中时,有时它什么也不会拉,因为页面仍然需要完成。 我编写了以下代码以等待页面完成。 有用 但是调用函数时出现以下错误; 问题答案: 我认为您应该这样使用: 如手册所述。