8

I run nearly 30-40 test cases twice a day. And everytime some test case fails due to page load time. Infact i have explicitly mentioned Thread.sleep("2000"); wherever i feel it takes more time to load. But still some 5-6 testCases fails. How can i make my selenium to wait until the page loads ?? And what would the below code do ? driver.manage().timeouts().implicitlyWait(4000, TimeUnit.SECONDS); Will it wait for 4 seconds everytime or it sets the maximum time limit to 4 secs . I even tried this but it really slowed my test execution. I need some help.

  • I was facing the same problem .After entering UN and PWD ,click on Login button every input I entered got vanished.Loading time was more and finally It was not getting loggedin also. As per advice of one of my friend at work I changed that URL i was automating.and Finally everything worked fine. – user35992 Dec 5 '18 at 8:28

10 Answers 10

9

Look at the Wait commands rather than sleep - a search on this site or Google will give you lots of examples

  • 1
    The single most helpful method for avoiding problems like the OP has is to use a "waitForPageToLoad" method. Totally worth it. – joshin4colours Oct 10 '13 at 11:35
8

You can use WebDriverWait to synch with page load. Something like the following might help

WebDriverWait wait = new WebDriverWait(driver, 15); //you can play with the time integer  to wait for longer than 15 seconds.`
wait.until(ExpectedConditions.titleContains("title")); //if you want to wait for a particular title to show up

OR

wait.until(ExpectedConditions.presenseOfElementLocated(ByLocator)); //in case you want to wait for a particular element to appear on the page.`
4

A Sleep method is almost always the least acceptable way to synchronize an automated test. A better approach might be to register an event and check the event is raised when in the desired state, or use a polling loop which will can enable the test to proceed when the system is ready (e.g. an element id appears), or a timeout occurs if it takes more than a pre-determined max wait time. (See Sleepy Automated Tests)

  • 1
    This link doesn't have any details. Says it is for sale. – ilm Feb 6 '16 at 9:11
3

Don't ever use sleep in your test. Every sleep you have indicates to a bad test design. Let's say you have a sleep of 1000ms, but it takes 1002ms to load something - your test will break. If it takes 996ms, you are wasting time. That been said, I just answered pretty much the same question in stackoverflow - https://stackoverflow.com/questions/18843581/wait-for-elment-webdriver-pageobject-pattern/18844275#18844275

  • I think you have a point . But for page load can we use WaitForPageLoad() ? . Some times due to slow network my application becomes slow or page load time gets slower . How to handle selenium in those situations ?? – kittudk Sep 26 '13 at 5:55
  • 1
    There is no such thing has "page has finised loading" unless you are serving static html. nowadays stuff getting loaded async all the time and this conception does not exist anymore. you as a tester must know when some specific stuff happens and wait for that very thing to happen before you continue. So you rather wait for (for example) a submit button to be visible and assume the page in a state so you can continue. If you run your tests thru a proxy, the browsermob has something like WaitForNetworkTrafficToStop, but i would go with WebDriverWait. – Erki M. Sep 27 '13 at 7:50
1

This code tells Selenium to search up to 60 seconds for id-of-element to appear on the page. Once it finds the element, you can interact with it. If the element is not found within 60 seconds, a java.lang.AssertionError will be thrown with the reason being "timeout".

for (int second = 0;; second++){
        if (second >= 60)
            fail("timeout");
        try{
            if (1 == driver.findElements(By.xpath("//a[@id=\"id-of-element"]")).size()){
                driver.findElement(By.xpath("//a[@id=\"id-of-element")).click();                    
                break;
            }
        } catch (Exception e){
      }
}

As per Kate's comment, this code will not produce a wait time of 60 seconds.

To wait for an element to appear, I would use an implicit wait:

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

This means that whenever you call WaitForElement() or WaitForElements(), the driver will wait up to 60 seconds for the specified element or elements to appear. See http://docs.seleniumhq.org/docs/04_webdriver_advanced.jsp#implicit-waits and http://www.bizalgo.com/2012/01/14/timing-races-selenium-2-implicit-waits-explicit-waits/.

  • I don't think this is going to give you a 60 second fuse - all it's going to give is 60 iterations which take whatever time they take - to do something like this you really need to include an explicit wait call for 1 second. – Kate Paulk Sep 17 '13 at 18:33
  • This is the best answer IMO, except you should wait for a certain date (i.e not + 60 seconds) rather than 60 counts as mentioned, and you could refactor this to a method to take the By selector and any root element or default to the driver to be able to use it as an extension method on IWebDriver or IWebElement so your driver always tries waiting for any element it accessed to be visible. – chrisc Jun 18 '15 at 16:41
0

driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS); is the correct and cleanest way of doing this in my experience. Call it once after instantiating the driver, and all subsequent calls will correctly wait for whatever timespan specified (60 seconds in this case)

It is better to be generous in timeframes for explicit waits, as lower environments can have skewed loading times, especially when it is the first couple calls to a fresh environment. That being said, 60 seconds is still on the high end for web apps.

  • Why not use the explicit waits and wait for a custom condition? – demouser123 Feb 6 '16 at 19:41
0

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);
}
  • This thread seems active since long. @kituudk - Resolved your query of page load time? – NarendraC Jul 6 '16 at 6:45
0

Although document.readyState works most of the time, rather than relying on document.readyState, I would suggest observing which element on the page loads last. You can base the further processing on the loading of that final element

  • can you expand on that answer a little? Why is the other solution better? Can you give an example on implementation in the answer? – ECiurleo Sep 7 '17 at 8:23
  • For example, say you have an HTML table that loads last on the page, take the id of that table say table1 WebDriverWait wait1 = new WebDriverWait(driver,20); wait1.until(ExpectedConditions.visibilityOf(driver.findElement(By.Id("table1"))); You can perform rest of the processing based on this. – Pinakin Chaubal Oct 17 '17 at 8:20
0

As in previous responses, using static "sleeps" is not good idea. WebDriver Wait(...) should be best option for you.

However you need to be extra careful about the condition, as some elements are loading in different order. In my case bests results came with asking JS is everything is in place already :) Method that perform validation:

 return ((string)Driver.ExecuteScript("return document.readyState")).Equals("complete");

Of course Driver class is a wrapper around original WebDriver's driver and to execute script I'm using:

 public object ExecuteScript(string javascriptCode, params object[] args)
        {
            return ((IJavaScriptExecutor)DriverInstanceInstance).ExecuteScript(javascriptCode, args);
        }
-1
synchronized(driver) {
      driver.wait(4000);
}
  • 3
    Welcome to SQA, Raman. Could you elaborate on this? As a rule of thumb, a snippet of code is less helpful than the accompanying explanation. – corsiKa Aug 19 '13 at 14:56

protected by Community Dec 5 '18 at 13:24

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.