简体   繁体   English

等待 Selenium 中的页面加载

[英]Wait for page load in Selenium

你如何让Selenium 2.0 等待页面加载?

You can also check pageloaded using following code您还可以使用以下代码检查页面加载

IWait<IWebDriver> wait = new OpenQA.Selenium.Support.UI.WebDriverWait(driver, TimeSpan.FromSeconds(30.00));

 wait.Until(driver1 => ((IJavaScriptExecutor)driver).ExecuteScript("return document.readyState").Equals("complete"));

Use class WebDriverWait使用类WebDriverWait

Also see here另见此处

You can expect to show some element.您可以期望显示一些元素。 something like in C#:像在 C# 中的东西:

WebDriver _driver = new WebDriver();
WebDriverWait _wait = new WebDriverWait(_driver, new TimeSpan(0, 1, 0));

_wait.Until(d => d.FindElement(By.Id("Id_Your_UIElement"));

If you set the implicit wait of the driver, then call the findElement method on an element you expect to be on the loaded page, the WebDriver will poll for that element until it finds the element or reaches the time out value.如果您设置了驱动程序的隐式等待,然后在您希望位于加载页面上的元素上调用findElement方法,WebDriver 将轮询该元素,直到它找到该元素或达到超时值。

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

source: implicit-waits来源: 隐式等待

In general, with Selenium 2.0 the web driver should only return control to the calling code once it has determined that the page has loaded.通常,在 Selenium 2.0 中,Web 驱动程序应该只在确定页面已加载后将控制权返回给调用代码。 If it does not, you can call waitforelemement , which cycles round calling findelement until it is found or times out (time out can be set).如果没有,您可以调用waitforelemement ,它会循环调用findelement直到找到它或超时(可以设置超时)。

Ruby implementation:红宝石实现:

wait = Selenium::WebDriver::Wait.new(:timeout => 10)
wait.until {
    @driver.execute_script("return document.readyState;") == "complete" 
}

You may remove the System.out line.您可以删除System.out行。 It is added for debug purposes.添加它是为了调试目的。

WebDriver driver_;

public void waitForPageLoad() {

    Wait<WebDriver> wait = new WebDriverWait(driver_, 30);
    wait.until(new Function<WebDriver, Boolean>() {
        public Boolean apply(WebDriver driver) {
            System.out.println("Current Window State       : "
                + String.valueOf(((JavascriptExecutor) driver).executeScript("return document.readyState")));
            return String
                .valueOf(((JavascriptExecutor) driver).executeScript("return document.readyState"))
                .equals("complete");
        }
    });
}

All of these solutions are OK for specific cases, but they suffer from at least one of a couple of possible problems:所有这些解决方案都适用于特定情况,但它们至少会遇到以下几个可能问题中的一个:

  1. They are not generic enough -- they want you to know, ahead of time, that some specific condition will be true of the page you are going to (eg some element will be displayed)它们不够通用——它们希望您提前知道,您将要访问的页面的某些特定条件将成立(例如,将显示某些元素)

  2. They are open to a race condition where you use an element that is actually present on the old page as well as the new page.它们对竞争条件持开放态度,您可以使用旧页面和新页面上实际存在的元素。

Here's my attempt at a generic solution that avoids this problem (in Python):这是我对避免此问题的通用解决方案的尝试(在 Python 中):

First, a generic "wait" function (use a WebDriverWait if you like, I find them ugly):首先,一个通用的“等待”函数(如果你愿意,可以使用 WebDriverWait,我觉得它们很丑):

def wait_for(condition_function):
    start_time = time.time()
    while time.time() < start_time + 3:
        if condition_function():
            return True
        else:
            time.sleep(0.1)
    raise Exception('Timeout waiting for {}'.format(condition_function.__name__))

Next, the solution relies on the fact that selenium records an (internal) id-number for all elements on a page, including the top-level <html> element.接下来,该解决方案依赖于这样一个事实,即 selenium 为页面上的所有元素记录一个(内部)id-number,包括顶级<html>元素。 When a page refreshes or loads, it gets a new html element with a new ID.当页面刷新或加载时,它会获得一个带有新 ID 的新 html 元素。

So, assuming you want to click on a link with text "my link" for example:因此,假设您要单击带有文本“我的链接”的链接,例如:

old_page = browser.find_element_by_tag_name('html')

browser.find_element_by_link_text('my link').click()

def page_has_loaded():
    new_page = browser.find_element_by_tag_name('html')
    return new_page.id != old_page.id

wait_for(page_has_loaded)

For more Pythonic, reusable, generic helper, you can make a context manager:对于更多 Pythonic、可重用、通用的帮助器,您可以创建一个上下文管理器:

from contextlib import contextmanager

@contextmanager
def wait_for_page_load(browser):
    old_page = browser.find_element_by_tag_name('html')

    yield

    def page_has_loaded():
        new_page = browser.find_element_by_tag_name('html')
        return new_page.id != old_page.id

    wait_for(page_has_loaded)

And then you can use it on pretty much any selenium interaction:然后你几乎可以在任何硒交互中使用它:

with wait_for_page_load(browser):
    browser.find_element_by_link_text('my link').click()

I reckon that's bulletproof!我认为这是防弹的! What do you think?你怎么认为?

More info in a blog post about it here 博客文章中有关它的更多信息here

Imran's answer rehashed for Java 7: Imran 对 Java 7 的回答:

    WebDriverWait wait = new WebDriverWait(driver, 30);

    wait.until(new ExpectedCondition<Boolean>() {
        public Boolean apply(WebDriver wdriver) {
            return ((JavascriptExecutor) driver).executeScript(
                "return document.readyState"
            ).equals("complete");
        }
    });

You can also use the class: ExpectedConditions to explicitly wait for an element to show up on the webpage before you can take any action further actions您还可以使用类: ExpectedConditions显式等待元素显示在网页上,然后才能采取任何进一步的操作

You can use the ExpectedConditions class to determine if an element is visible:您可以使用ExpectedConditions类来确定元素是否可见:

WebElement element = (new WebDriverWait(getDriver(), 10)).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("input#houseName")));

See ExpectedConditions class Javadoc for list of all conditions you are able to check.有关您可以检查的所有条件的列表,请参阅ExpectedConditions class Javadoc

This seems to be a serious limitation of WebDriver.这似乎是 WebDriver 的一个严重限制。 Obviously waiting for an element will not imply the page being loaded, in particular the DOM can be fully build (onready state) whereby JS is still executing and CSS and images are still loading.显然,等待元素并不意味着页面正在加载,特别是 DOM 可以完全构建(onready 状态),此时 JS 仍在执行并且 CSS 和图像仍在加载。

I believe the simplest solution is to set a JS variable upon the onload event after everything is initialized and check and wait for this JS variable in Selenium.我相信最简单的解决方案是在一切都初始化后在 onload 事件上设置一个 JS 变量,并在 Selenium 中检查并等待这个 JS 变量。

Here is a Java 8 version of the currently most upvoted answer :这是当前最受好评的答案的 Java 8 版本:

WebDriverWait wait = new WebDriverWait(myDriver, 15);
wait.until(webDriver -> ((JavascriptExecutor) myDriver).executeScript("return document.readyState").toString().equals("complete"));

Where myDriver is a WebDriver object (declared earlier).其中myDriver是一个WebDriver对象(之前声明过)。

Note : Be aware that this method ( document.readyState ) only checks the DOM.注意:请注意,此方法 ( document.readyState ) 仅检查 DOM。

If you want to wait for a specific element to load, you can use the isDisplayed() method on a RenderedWebElement :如果要等待特定元素加载,可以在RenderedWebElement上使用isDisplayed()方法:

// Sleep until the div we want is visible or 5 seconds is over
long end = System.currentTimeMillis() + 5000;
while (System.currentTimeMillis() < end) {
    // Browsers which render content (such as Firefox and IE) return "RenderedWebElements"
    RenderedWebElement resultsDiv = (RenderedWebElement) driver.findElement(By.className("gac_m"));

    // If results have been returned, the results are displayed in a drop down.
    if (resultsDiv.isDisplayed()) {
      break;
    }
}

(Example from The 5 Minute Getting Started Guide ) 5 分钟入门指南中的示例)

Explicitly wait or conditional wait in this wait until given this condition.在此等待中显式等待或有条件等待,直到给出此条件。

WebDriverWait wait = new WebDriverWait(wb, 60);
wait.until(ExpectedConditions.elementToBeClickable(By.name("value")));

This will wait for every web element for 60 seconds.这将等待每个 web 元素 60 秒。

Use implicitly wait for wait of every element on page till that given time.使用隐式等待页面上的每个元素直到给定时间。

driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);

This will wait for every web element for 60 seconds.这将等待每个 web 元素 60 秒。

Man all these answers require too much code.男人所有这些答案都需要太多的代码。 This should be a simple thing as its pretty common.这应该是一件简单的事情,因为它很常见。

Why not just inject some simple Javascript with the webdriver and check.为什么不直接在 webdriver 中注入一些简单的 Javascript 并检查。 This is the method I use in my webscraper class.这是我在 webscraper 类中使用的方法。 The Javascript is pretty basic even if you don't know it. Javascript 是非常基础的,即使你不知道。

def js_get_page_state(self):        
    """
    Javascript for getting document.readyState
    :return: Pages state.
    
    More Info: https://developer.mozilla.org/en-US/docs/Web/API/Document/readyState
    """
    ready_state = self.driver.execute_script('return document.readyState')
    if ready_state == 'loading':
        self.logger.info("Loading Page...")
    elif ready_state == 'interactive':
        self.logger.info("Page is interactive")
    elif ready_state == 'complete':
        self.logger.info("The page is fully loaded!")
    return ready_state

I'm surprised that predicates weren't the first choice as you typically know what element(s) you will next interact with on the page you're waiting to load.我很惊讶谓词不是首选,因为您通常知道接下来将在等待加载的页面上与哪些元素进行交互。 My approach has always been to build out predicates/functions like waitForElementByID(String id) and waitForElemetVisibleByClass(String className) , etc. and then use and reuse these wherever I need them, be it for a page load or page content change I'm waiting on.我的方法一直是构建谓词/函数,如waitForElementByID(String id)waitForElemetVisibleByClass(String className)等,然后在我需要的任何地方使用和重用它们,无论是页面加载还是页面内容更改等待。

For example,例如,

In my test class:在我的测试课中:

driverWait.until(textIsPresent("expectedText");

In my test class parent:在我的测试班父母中:

protected Predicate<WebDriver> textIsPresent(String text){
    final String t = text;
    return new Predicate<WebDriver>(){
        public boolean apply(WebDriver driver){
            return isTextPresent(t);
        }
    };
}

protected boolean isTextPresent(String text){
    return driver.getPageSource().contains(text);
}

Though this seems like a lot, it takes care of checking repeatedly for you and the interval for how often to check can be set along with the ultimate wait time before timing out.尽管这看起来很多,但它会为您反复检查,并且可以设置检查频率的间隔以及超时前的最终等待时间。 Also, you will reuse such methods.此外,您将重用此类方法。

In this example, the parent class defined and initiated the WebDriver driver and the WebDriverWait driverWait .在这个例子中,父类定义并启动了WebDriver driverWebDriverWait driverWait

I hope this helps.我希望这有帮助。

Use implicitly wait for wait of every element on page till given time.使用隐式等待页面上的每个元素直到给定时间。

driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);

this wait for every element on page for 30 sec.这将等待页面上的每个元素 30 秒。

Another wait is Explicitly wait or conditional wait in this wait until given condition.另一个等待是在此等待中显式等待或有条件等待,直到给定条件。

WebDriverWait wait = new WebDriverWait(driver, 40);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("someid")));

In id give static element id which is diffidently display on the page, as soon as page is load.在 id 中给出静态元素 id,它会在页面加载后立即显示在页面上。

The best way to wait for page loads when using the Java bindings for WebDriver is to use the Page Object design pattern with PageFactory.使用 WebDriver 的 Java 绑定时等待页面加载的最佳方法是将页面对象设计模式与 PageFactory 一起使用。 This allows you to utilize the AjaxElementLocatorFactory which to put it simply acts as a global wait for all of your elements.这允许您利用AjaxElementLocatorFactory将其简单地用作所有元素的全局等待。 It has limitations on elements such as drop-boxes or complex javascript transitions but it will drastically reduce the amount of code needed and speed up test times.它对下拉框或复杂的 javascript 转换等元素有限制,但它将大大减少所需的代码量并加快测试时间。 A good example can be found in this blogpost.在这篇博文中可以找到一个很好的例子。 Basic understanding of Core Java is assumed.假设对 Core Java 有基本的了解。

http://startingwithseleniumwebdriver.blogspot.ro/2015/02/wait-in-page-factory.html http://startingwithseleniumwebdriver.blogspot.ro/2015/02/wait-in-page-factory.html

NodeJS Solution: NodeJS解决方案:

In Nodejs you can get it via promises...Nodejs 中,你可以通过 promises 获得它......

If you write this code, you can be sure that the page is fully loaded when you get to the then...如果你写了这段代码,你可以确定当你到达 then 时页面是完全加载的...

driver.get('www.sidanmor.com').then(()=> {
    // here the page is fully loaded!!!
    // do your stuff...
}).catch(console.log.bind(console));

If you write this code, you will navigate, and selenium will wait 3 seconds...如果你写这段代码,你会导航,而selenium会等待3秒...

driver.get('www.sidanmor.com');
driver.sleep(3000);
// you can't be sure that the page is fully loaded!!!
// do your stuff... hope it will be OK...

From Selenium Documentation (Nodejs) :来自Selenium 文档(Nodejs)

 this.get( url ) → Thenable<undefined>

Schedules a command to navigate to the given URL.调度命令以导航到给定的 URL。

Returns a promise that will be resolved when the document has finished loading .返回将在文档完成加载后解决的承诺。

You can use the below existing method to set the pageLoadTimeout .您可以使用以下现有方法来设置pageLoadTimeout In below example if the page is taking more than 20 seconds to load, then it will throw an exception of page reload:在下面的示例中,如果页面加载时间超过 20 秒,则会引发页面重新加载异常:

WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().pageLoadTimeout(20, TimeUnit.SECONDS);

Call below Function in your script , this will wait till page is not loaded using javascript在脚本中调用下面的函数,这将等到页面未使用 javascript 加载

public static boolean isloadComplete(WebDriver driver)
{
    return ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("loaded")
            || ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("complete");
}

SeleniumWaiter :硒服务员

import com.google.common.base.Function;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

public class SeleniumWaiter {

      private WebDriver driver;

      public SeleniumWaiter(WebDriver driver) {
           this.driver = driver;
      }

      public WebElement waitForMe(By locatorname, int timeout){
           WebDriverWait wait = new WebDriverWait(driver, timeout);
           return wait.until(SeleniumWaiter.presenceOfElementLocated(locatorname));
      }

      public static Function<WebDriver, WebElement> presenceOfElementLocated(final By locator) {
            // TODO Auto-generated method stub
            return new Function<WebDriver, WebElement>() {
                 @Override
                 public WebElement apply(WebDriver driver) {
                      return driver.findElement(locator);
                 }
            };
      }
 }

And to you use it :而你使用它

_waiter = new SeleniumWaiter(_driver);

try {
   _waiter.waitForMe(By.xpath("//..."), 10);
} 
catch (Exception e) {
   // Error
}
/**
 * Call this method before an event that will change the page.
 */
private void beforePageLoad() {
    JavascriptExecutor js = (JavascriptExecutor) driver;
    js.executeScript("document.mpPageReloaded='notYet';");
}

/**
 * Call this method after an event that will change the page.
 * 
 * @see #beforePageLoad
 * 
 *      Waits for the previous page to disappear.
 */
private void afterPageLoad() throws Exception {
    (new WebDriverWait(driver, 10)).until(new Predicate<WebDriver>() {

        @Override
        public boolean apply(WebDriver driver) {
            JavascriptExecutor js = (JavascriptExecutor) driver;
            Object obj = js.executeScript("return document.mpPageReloaded;");
            if (obj == null) {
                return true;
            }
            String str = (String) obj;
            if (!str.equals("notYet")) {
                return true;
            }
            return false;
        }
    });
}

You can change from the document to an element, in the case of where only part of a document is being changed.在仅更改文档的一部分的情况下,您可以将文档更改为元素。

This technique was inspired by the answer from sincebasic.这项技术的灵感来自于来自 sincebasic 的回答。

My simple way:我的简单方法:

long timeOut = 5000;
    long end = System.currentTimeMillis() + timeOut;

        while (System.currentTimeMillis() < end) {

            if (String.valueOf(
                    ((JavascriptExecutor) driver)
                            .executeScript("return document.readyState"))
                    .equals("complete")) {
                break;
            }
        }

The best way I've seen is to utilize the stalenessOf ExpectedCondition, to wait for the old page to become stale.我见过的最好的方法是利用stalenessOf ExpectedCondition,等待旧页面变得陈旧。

Example:例子:

WebDriver driver = new FirefoxDriver();
WebDriverWait wait = new WebDriverWait(driver, 10);

WebElement oldHtml = driver.findElement(By.tagName("html"));
wait.until(ExpectedConditions.stalenessOf(oldHtml));

It'll wait for ten seconds for the old HTML tag to become stale, and then throw an exception if it doesn't happen.它会等待 10 秒钟让旧的 HTML 标签变得陈旧,如果没有发生,则抛出异常。

I use node + selenium-webdriver(which version is 3.5.0 now).我使用 node + selenium-webdriver(现在版本是 3.5.0)。 what I do for this is:我为此做的是:

var webdriver = require('selenium-webdriver'),
    driver = new webdriver.Builder().forBrowser('chrome').build();
;
driver.wait(driver.executeScript("return document.readyState").then(state => {
  return state === 'complete';
}))

You can use wait.您可以使用等待。 there are basically 2 types of wait in selenium硒中基本上有两种类型的等待

  • Implicit wait隐式等待
  • Explicit wait显式等待

- Implicit wait - 隐式等待

This is very simple please see syntax below:这非常简单,请参见下面的语法:

driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);

- Explicit wait - 显式等待

Explicitly wait or conditional wait in this wait until given condition is occurred.在此等待中显式等待或有条件等待,直到出现给定条件。

WebDriverWait wait = new WebDriverWait(driver, 40);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("someid")));

You can use other properties like visblityOf() , visblityOfElement()您可以使用其他属性,如visblityOf()visblityOfElement()

If someone uses selenide:如果有人使用硒化物:

public static final Long SHORT_WAIT = 5000L; // 5 seconds
$("some_css_selector").waitUntil(Condition.appear, SHORT_WAIT);

More Conditions can be found here: http://selenide.org/javadoc/3.0/com/codeborne/selenide/Condition.html更多条件可以在这里找到: http : //selenide.org/javadoc/3.0/com/codeborne/selenide/Condition.html

In my case , I used the following to know the page load status.就我而言,我使用以下内容来了解​​页面加载状态。 In our application loading gif(s) are present and, I listen to them as follows to eliminate unwanted wait time in the script.在我们的应用程序中加载 gif(s) 是存在的,我听他们如下以消除脚本中不需要的等待时间。

public static void processing(){ 
    WebDriverWait wait = new WebDriverWait(driver, 30);
    wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[@id='Msgpanel']/div/div/img")));
    wait.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("//div[@id='Msgpanel']/div/div/img")));
}

Where the xpath locates the gif in the HTML DOM. xpath 在 HTML DOM 中定位 gif 的位置。 After this, You may also implement your action methods Click.在此之后,您还可以实现您的操作方法 Click。

public static void click(WebElement elementToBeClicked){
    WebDriverWait wait = new WebDriverWait(driver, 45);
    wait.until(ExpectedConditions.visibilityOf(element));
    wait.until(ExpectedConditions.elementToBeClickable(element)); 
    wait.ignoring(NoSuchElementException.class).ignoring(StaleElementReferenceException.class); elementToBeClicked.click(); 
 }

You can explicitly wait for an element to show up on the webpage before you can take any action (like element.click() ):您可以在执行任何操作(例如element.click() )之前明确等待某个元素出现在网页上:

driver.get("http://somedomain/url_that_delays_loading");
WebElement myDynamicElement = (new WebDriverWait(driver, 10))
    .until(new ExpectedCondition<WebElement>() {
        @Override
        public WebElement apply(WebDriver d) {
            return d.findElement(By.id("myDynamicElement"));
        }
    }
);

This is what I used for a similar scenario and it works fine.这是我用于类似场景的方法,并且效果很好。

How to get Selenium to wait for page load after a click provides the following interesting approach: 单击后如何让 Selenium 等待页面加载提供了以下有趣的方法:

  1. Store a reference to a WebElement from the old page.从旧页面存储对WebElement的引用。
  2. Click the link.单击链接。
  3. Keep on invoking operations on the WebElement until StaleElementReferenceException is thrown.继续调用WebElement上的操作,直到抛出StaleElementReferenceException

Sample code:示例代码:

WebElement link = ...;
link.click();
new WebDriverWait(webDriver, timeout).until((org.openqa.selenium.WebDriver input) ->
{
    try
    {
        link.isDisplayed();
        return false;
    }
    catch (StaleElementReferenceException unused)
    {
        return true;
    }
});

You can use this snippet of code for the page to load: 您可以使用此代码段来加载页面:

    IWait wait = new OpenQA.Selenium.Support.UI.WebDriverWait(driver,TimeSpan.FromSeconds(30.00));
    wait.Until(driver1 => ((IJavaScriptExecutor)driver).ExecuteScript("return document.readyState").Equals("complete"));

Or you can use waiter for any element to be loaded and become visible/clickable on that page, most probably which is going to be load at the end of loading like: 或者,您可以使用waiter来加载任何元素,并使其在该页面上可见/可单击,最有可能在加载结束时进行加载,例如:

    Wait.Until(ExpectedConditions.ElementToBeClickable(By.XPath(xpathOfElement));
    var element = GlobalDriver.FindElement(By.XPath(xpathOfElement));
    var isSucceededed = element != null;
driver.asserts().assertElementFound("Page was not loaded",
By.xpath("//div[@id='actionsContainer']"),Constants.LOOKUP_TIMEOUT);

The easiest way is just wait for some element which will appear on loaded page. 最简单的方法是等待一些元素出现在加载的页面上。

If you would like to click on some button already after page is loaded you could use await and click: 如果您想在页面加载后单击某个按钮,可以使用等待并单击:

await().until().at.most(20, TimeUnit.Seconds).some_element.isDisplayed(); // or another condition
getDriver().find(some_element).click;
  1. WebDriver driver = new ff / chrome / anyDriverYouWish(); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); Waits maximum of 10 Seconds.最多等待 10 秒。

  2. WebDriverWait wait = new WebDriverWait(driver, 10); wait.until(ExpectedConditions.visibilityOf(WebElement element));

  3. FluentWait<Driver> fluentWait; fluentWait = new FluentWait<>(driver).withTimeout(30, TimeUnit.SECONDS) .pollingEvery(200, TimeUnit.MILLISECONDS) .ignoring(NoSuchElementException.class);

The advantage of the last option is that you can include exception to be expected, so that your execution continues.最后一个选项的优点是您可以包含预期的异常,以便您的执行继续。

use a if condition and for any of the element present使用 if 条件和任何存在的元素

try {
    Thread.sleep(1000);
} catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

For implicit wait you can use something like following:对于隐式等待,您可以使用以下内容:

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS)

In order for webpage to wait for a specific object to be visible or cerntain condition to be true.为了让网页等待特定对象可见或某些条件为真。 You can use wait feather of web driver.您可以使用 Web 驱动程序的等待羽毛。

//120 is maximum number of seconds to wait.
WebDriverWait wait = new WebDriverWait(driver,120);  
wait.until(ExpectedConditions.elementToBeClickable("CONDITITON"));

In Java , another option is to sleep the thread for specific time.Java 中,另一种选择是让线程休眠特定时间。

Thread.sleep(numberOfSeconds*1000); 
//This line will cause thread to sleep for seconds as variable

I created a method to simplify thread.sleep method我创建了一个方法来简化 thread.sleep 方法

public static void wait_time(int seconds){
    try {
        Thread.sleep(seconds*1000);
        }catch (InterruptedException e) {
        // TODO Auto-generated catch block
            e.printStackTrace();
        }
}

Use the method as wait_time(10);使用方法为wait_time(10); The thread will sleep for 10 seconds.该线程将休眠 10 秒。

You can try this code to let the page load completely until element is found.您可以尝试使用此代码让页面完全加载,直到找到元素。

public void waitForBrowserToLoadCompletely() {
    String state = null;
    String oldstate = null;
    try {
        System.out.print("Waiting for browser loading to complete");

        int i = 0;
        while (i < 5) {
            Thread.sleep(1000);
            state = ((JavascriptExecutor) driver).executeScript("return document.readyState;").toString();
            System.out.print("." + Character.toUpperCase(state.charAt(0)) + ".");
            if (state.equals("interactive") || state.equals("loading"))
                break;
            /*
             * If browser in 'complete' state since last X seconds. Return.
             */

            if (i == 1 && state.equals("complete")) {
                System.out.println();
                return;
            }
            i++;
        }
        i = 0;
        oldstate = null;
        Thread.sleep(2000);

        /*
         * Now wait for state to become complete
         */
        while (true) {
            state = ((JavascriptExecutor) driver).executeScript("return document.readyState;").toString();
            System.out.print("." + state.charAt(0) + ".");
            if (state.equals("complete"))
                break;

            if (state.equals(oldstate))
                i++;
            else
                i = 0;
            /*
             * If browser state is same (loading/interactive) since last 60
             * secs. Refresh the page.
             */
            if (i == 15 && state.equals("loading")) {
                System.out.println("\nBrowser in " + state + " state since last 60 secs. So refreshing browser.");
                driver.navigate().refresh();
                System.out.print("Waiting for browser loading to complete");
                i = 0;
            } else if (i == 6 && state.equals("interactive")) {
                System.out.println(
                        "\nBrowser in " + state + " state since last 30 secs. So starting with execution.");
                return;
            }

            Thread.sleep(4000);
            oldstate = state;

        }
        System.out.println();

    } catch (InterruptedException ie) {
        ie.printStackTrace();
    }
}
private static void checkPageIsReady(WebDriver driver) {
    JavascriptExecutor js = (JavascriptExecutor) driver;

    // Initially bellow given if condition will check ready state of page.
    if (js.executeScript("return document.readyState").toString().equals("complete")) {
        System.out.println("Page Is loaded.");
        return;
    }

    // This loop will rotate for 25 times to check If page Is ready after
    // every 1 second.
    // You can replace your value with 25 If you wants to Increase or
    // decrease wait time.
    for (int i = 0; i < 25; i++) {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
        }
        // To check page ready state.
        if (js.executeScript("return document.readyState").toString().equals("complete")) {
            break;
        }
    }
}

use following code it's very easy and simple for page load.使用以下代码,页面加载非常容易和简单。

public void PageLoad(IWebDriver driver, By by)
{
    try
    {
        Console.WriteLine("PageLoad" + by);
        WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30));
        wait.Until(ExpectedConditions.ElementIsVisible(by));
        wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30)); // 30 seconds wait until element not found. 
        wait.Until(ExpectedConditions.ElementToBeClickable(by));


    }
    catch (Exception ex)
    {

        Console.WriteLine(ex.Message);
        Assert.Fail("Element not found!")
    }
}

i hope this helps you.我希望这可以帮助你。

public static int counter = 0;

public void stepGeneralWait() {

    boolean breakIt = true;

    while (true) {
        breakIt = true;
        try {

            do{
                // here put e.g. your spinner ID
                Controller.driver.findElement(By.xpath("//*[@id='static']/div[8]/img")).click();
                Thread.sleep(10000);

                counter++;

                if (counter > 3){
                    breakIt = false;

                }
            }
            while (breakIt);



        } catch (Exception e) {
            if (e.getMessage().contains("element is not attached")) {
                breakIt = false;
            }
        }
        if (breakIt) {
            break;
        }

    }

    try {
        Thread.sleep(12000);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

For Programmers using java 8 onward can use below code to wait for page load using explicit wait.对于使用 java 8 以后的程序员,可以使用以下代码使用显式等待来等待页面加载。

JavascriptExecutor js = (JavascriptExecutor) driver;  
new WebDriverWait(driver, 10).until(webDriver ->
(js).executeScript("return document.readyState;").equals("complete"));

Note: In my above code Lambda Expression is used, which is only available in java 8 onward version.注意:在我上面的代码中使用了 Lambda 表达式,它只在 java 8 以后的版本中可用。

For Programmers using lower version of Java ie below Java 8 can use:对于使用较低版本 Java 即低于 Java 8 的程序员可以使用:

ExpectedCondition<Boolean> cond = new ExpectedCondition<Boolean>() {
    @Override
    public Boolean apply(WebDriver input) {
        JavascriptExecutor js = (JavascriptExecutor) driver; 
        return js.executeScript("return document.readyState;").equals("complete");
            }
        };
         
    new WebDriverWait(driver, 100).until(cond);

Use this function使用这个功能

public void waitForPageLoad(ChromeDriver d){
        String s="";
        while(!s.equals("complete")){
        s=(String) d.executeScript("return document.readyState");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        }

    }

Use:用:

driver.manage().timeOuts().implicitlyWait(10, TimeUnit.SECONDS);

Which means any search for the elements on the web page could take time to load.这意味着对网页上元素的任何搜索都可能需要时间来加载。 The implicitlyWait is set before throwing an exception.在抛出异常之前设置了implicitlyWait The TimeUnit displays whichever way you want to wait in (seconds, minutes, hours and days). TimeUnit显示您想要等待的任何方式(秒、分钟、小时和天)。

There are 2 types of waits available in Webdriver/Selenium 2 software testing tool. Webdriver/Selenium 2 软件测试工具中有两种类型的等待可用。 One of them is Implicit wait and another one is explicit wait.其中一种是隐式等待,另一种是显式等待。 Both (Implicit wait and explicit wait) are useful for waiting in WebDriver.两者(隐式等待和显式等待)对于 WebDriver 中的等待都很有用。 Using waits, we are telling WebDriver to wait for a certain amount of time before going to next step.You can use implicit wait for page load waiting.使用等待,我们告诉 WebDriver 在进入下一步之前等待一定的时间。您可以使用隐式等待来等待页面加载。

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

I don't think an implicit wait is what you want.我不认为隐式等待是你想要的。 Try this:尝试这个:

driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);

More information in the documentation 文档中的更多信息

This code will wait until all the elements on the page are loaded in the DOM.此代码将等到页面上的所有元素都加载到 DOM 中。

WebDriver driver = new WebDriver();
WebDriverWait wait = new WebDriverWait(driver, timeout);

wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*")));

在python中,您可以简单地使用:

driver.implicitly_wait(30)

Implicit and explicit wait is better.隐式和显式等待更好。

But if you are handling an exception in Java, then you can use this for waiting for a page to reload:但是如果您正在处理 Java 中的异常,那么您可以使用它来等待页面重新加载:

Thead.sleep(1000);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM