How I can check whether a page is loaded completely or not in web driver?

前端 未结 9 1813
走了就别回头了
走了就别回头了 2020-12-01 01:33

I am writing some Java Webdriver code to automate my application. How can I correctly check whether the page has been loaded or not? The application has some Ajax calls, too

相关标签:
9条回答
  • 2020-12-01 02:04

    I know this post is old. But after gathering all code from above I made a nice method (solution) to handle ajax running and regular pages. The code is made for C# only (since Selenium is definitely a best fit for C# Visual Studio after a year of messing around).

    The method is used as an extension method, which means to put it simple; that you can add more functionality (methods) in this case, to the object IWebDriver. Important is that you have to define: 'this' in the parameters to make use of it.

    The timeout variable is the amount of seconds for the webdriver to wait, if the page is not responding. Using 'Selenium' and 'Selenium.Support.UI' namespaces it is possible to execute a piece of javascript that returns a boolean, whether the document is ready (complete) and if jQuery is loaded. If the page does not have jQuery then the method will throw an exception. This exception is 'catched' by error handling. In the catch state the document will only be checked for it's ready state, without checking for jQuery.

    public static void WaitUntilDocumentIsReady(this IWebDriver driver, int timeoutInSeconds) {
        var javaScriptExecutor = driver as IJavaScriptExecutor;
        var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSeconds));
    
        try {
            Func<IWebDriver, bool> readyCondition = webDriver => (bool)javaScriptExecutor.ExecuteScript("return (document.readyState == 'complete' && jQuery.active == 0)");
            wait.Until(readyCondition);
        } catch(InvalidOperationException) {
            wait.Until(wd => javaScriptExecutor.ExecuteScript("return document.readyState").ToString() == "complete");
        }
    }
    
    0 讨论(0)
  • 2020-12-01 02:04

    Recently, when I was dealing with an AJAX application/RIA, I was having the same issue! And I used implicit wait, with a time of around 90 seconds. It waits, till the element is available...So, what we can do to make sure, that page gets loaded completely is,

    add a boolean statement, checking for whether the condition(a particular part of the element), is present and assign it to a variable, check for the condition and only when it is true, " do the necessary actions!"...In this way, I figured out, both waits could be used...

    Ex:

    @Before
    
    { implicit wait statement}
    
    @Test
    
    {
    
    boolean tr1=Driver.findElement(By.xpath("xx")).isEnabled/isDisplayed;
    
    if (tr1==true && ____)//as many conditions, to make sure, the page is loaded
    
    {
    
    //do the necessary set of actions...
    driver.findElement(By.xpath("yy")).click();
    
    }
    
    }
    

    Hope this helps!! It is in implementation stage, for me too...

    0 讨论(0)
  • 2020-12-01 02:05

    Selenium does it for you. Or at least it tries its best. Sometimes it falls short, and you must help it a little bit. The usual solution is Implicit Wait which solves most of the problems.

    If you really know what you're doing, and why you're doing it, you could try to write a generic method which would check whether the page is completely loaded. However, it can't be done for every web and for every situation.


    Related question: Selenium WebDriver : Wait for complex page with JavaScript(JS) to load, see my answer there.

    Shorter version: You'll never be sure.

    The "normal" load is easy - document.readyState. This one is implemented by Selenium, of course. The problematic thing are asynchronous requests, AJAX, because you can never tell whether it's done for good or not. Most of today's webpages have scripts that run forever and poll the server all the time.

    The various things you could do are under the link above. Or, like 95% of other people, use Implicit Wait implicity and Explicit Wait + ExpectedConditions where needed.

    E.g. after a click, some element on the page should become visible and you need to wait for it:

    WebDriverWait wait = new WebDriverWait(driver, 10);  // you can reuse this one
    
    WebElement elem = driver.findElement(By.id("myInvisibleElement"));
    elem.click();
    wait.until(ExpectedConditions.visibilityOf(elem));
    
    0 讨论(0)
  • 2020-12-01 02:09

    You can set a JavaScript variable in your WepPage that gets set once it's been loaded. You could put it anywhere, but if you're using jQuery, $(document).onReady isn't a bad place to start. If not, then you can put it in a <script> tag at the bottom of the page.

    The advantage of this method as opposed to checking for element visibility is that you know the exact state of the page after the wait statement executes.

    MyWebPage.html

    ... All my page content ...
    <script> window.TestReady = true; </script></body></html>
    

    And in your test (C# example):

    // The timespan determines how long to wait for any 'condition' to return a value
    // If it is exceeded an exception is thrown.
    WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5.0));
    
    // Set the 'condition' as an anonymous function returning a boolean
    wait.Until<Boolean>(delegate(IWebDriver d)
    {
        // Check if our global variable is initialized by running a little JS
        return (Boolean)((IJavaScriptExecutor)d).ExecuteScript("return typeof(window.TestReady) !== 'undefined' && window.TestReady === true");
    });
    
    0 讨论(0)
  • 2020-12-01 02:11

    You can take a screenshot and save the rendered page in a location and you can check the screenshot if the page loaded completely without broken images

    0 讨论(0)
  • 2020-12-01 02:16

    Simple ready2use snippet, working perfectly for me

    static void waitForPageLoad(WebDriver wdriver) {
        WebDriverWait wait = new WebDriverWait(wdriver, 60);
    
        Predicate<WebDriver> pageLoaded = new Predicate<WebDriver>() {
    
            @Override
            public boolean apply(WebDriver input) {
                return ((JavascriptExecutor) input).executeScript("return document.readyState").equals("complete");
            }
    
        };
        wait.until(pageLoaded);
    }
    
    0 讨论(0)
提交回复
热议问题