How to make Selenium to wait for DOM to load completely before performing next action

848 views
Skip to first unread message

Nagendra Kuppala

unread,
Jun 18, 2018, 2:55:14 AM6/18/18
to Selenium Users
Hi Guys,

Is there a way to make the selenium to wait for DOM to completely load before performing next action ?
My test cases work as expected 90% of the time. But whenever the application had a patch, application loads bit slow for the first attempt making my test cases fail randomly. I tried using pause for 1min where ever I feel like the application slows down.

I know about implicit and explicit waits, which I don't prefer for this case.

I want to make my code to check DOM loaded complete before executing next step.

Thanks in advance.

Greg Martz

unread,
Jun 18, 2018, 9:33:05 AM6/18/18
to seleniu...@googlegroups.com
I wish there were a way to 100% reliably tell when all the page, with all javascript execution, with everything complete.  Unfortunately, there isn't.  The best I've found is:

    /**
     * isLoaded method is used to check whether Home page is loaded successfully.
     *
     * @return boolean - This method returns boolean value true if the element is visible else false
     * @see HomePage#isLoaded()
     **/
    public boolean isLoaded()
    {
        Log.info("Entering method HomePage::isLoaded()");
        boolean bFlag = false;
        Wait<WebDriver> wait = new WebDriverWait(wDriver, 60);
        wait.until(wDriver -> String.valueOf(((JavascriptExecutor) wDriver).executeScript("return document.readyState")).equals("complete"));
        Utility.waitForJavascript(5000, 500, wDriver);
        bFlag = Utility.isElementDisplayed(homepageCarousel, wDriver, 60);
        Log.info("Exiting the method HomePage::isLoaded() with return value: '" + bFlag + "'");
        return bFlag;
    }


This works about 97% of the time.


Thanks!
Greg

Greg Martz
Test Analyst III - eBusiness Lead QA Automation Analyst  |  (425)416-5039  |  gma...@Costco.com 

"Confidentiality Notice:  This e-mail message, including any attachments, is for the sole use to the intended recipient(s) and may contain confidential and privileged information.  Any unauthorized review, use, disclosure or distribution is prohibited.  If you are not the intended recipient, please contact the sender by reply e-mail and destroy all copies of the original message."


--
You received this message because you are subscribed to the Google Groups "Selenium Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to selenium-users+unsubscribe@googlegroups.com.
To post to this group, send email to seleniu...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/selenium-users/c5d75f09-d2b7-4fee-8ebc-8abf15d3b362%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

⇜Krishnan Mahadevan⇝

unread,
Jun 18, 2018, 10:42:19 AM6/18/18
to seleniu...@googlegroups.com
Greg 

I think this is the same logic selenium employs under the hood as well when dealing with blocking calls such as url load or click etc. 

On Mon 18 Jun, 2018, 19:03 Greg Martz, <gma...@costco.com> wrote:
I wish there were a way to 100% reliably tell when all the page, with all javascript execution, with everything complete.  Unfortunately, there isn't.  The best I've found is:

    /**
     * isLoaded method is used to check whether Home page is loaded successfully.
     *
     * @return boolean - This method returns boolean value true if the element is visible else false
     * @see HomePage#isLoaded()
     **/
    public boolean isLoaded()
    {
        Log.info("Entering method HomePage::isLoaded()");
        boolean bFlag = false;
        Wait<WebDriver> wait = new WebDriverWait(wDriver, 60);
        wait.until(wDriver -> String.valueOf(((JavascriptExecutor) wDriver).executeScript("return document.readyState")).equals("complete"));
        Utility.waitForJavascript(5000, 500, wDriver);
        bFlag = Utility.isElementDisplayed(homepageCarousel, wDriver, 60);
        Log.info("Exiting the method HomePage::isLoaded() with return value: '" + bFlag + "'");
        return bFlag;
    }


This works about 97% of the time.


Thanks!
Greg

Greg Martz
Test Analyst III - eBusiness Lead QA Automation Analyst  |  (425)416-5039  |  gma...@Costco.com 

"Confidentiality Notice:  This e-mail message, including any attachments, is for the sole use to the intended recipient(s) and may contain confidential and privileged information.  Any unauthorized review, use, disclosure or distribution is prohibited.  If you are not the intended recipient, please contact the sender by reply e-mail and destroy all copies of the original message."


On Sun, Jun 17, 2018 at 11:55 PM, Nagendra Kuppala <nagendraku...@gmail.com> wrote:
Hi Guys,

Is there a way to make the selenium to wait for DOM to completely load before performing next action ?
My test cases work as expected 90% of the time. But whenever the application had a patch, application loads bit slow for the first attempt making my test cases fail randomly. I tried using pause for 1min where ever I feel like the application slows down.

I know about implicit and explicit waits, which I don't prefer for this case.

I want to make my code to check DOM loaded complete before executing next step.

Thanks in advance.

--
You received this message because you are subscribed to the Google Groups "Selenium Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to selenium-user...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Selenium Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to selenium-user...@googlegroups.com.

To post to this group, send email to seleniu...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.
--

Thanks & Regards
Krishnan Mahadevan

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"
My Scribblings @ http://wakened-cognition.blogspot.com/

My Technical Scribbings @ http://rationaleemotions.wordpress.com/

Greg Martz

unread,
Jun 18, 2018, 11:37:19 AM6/18/18
to seleniu...@googlegroups.com
Interesting!  I know that I went from about a 35% failure rate to less than 3% after adding that in our isLoaded() class.  I so wish that the webdriver would give us a method that would guarantee that the full page has been loaded.


Thanks!
Greg

Greg Martz
Test Analyst III - eBusiness Lead QA Automation Analyst  |  (425)416-5039  |  gma...@Costco.com 

"Confidentiality Notice:  This e-mail message, including any attachments, is for the sole use to the intended recipient(s) and may contain confidential and privileged information.  Any unauthorized review, use, disclosure or distribution is prohibited.  If you are not the intended recipient, please contact the sender by reply e-mail and destroy all copies of the original message."


Greg 

To unsubscribe from this group and stop receiving emails from it, send an email to selenium-users+unsubscribe@googlegroups.com.
To post to this group, send email to selenium-users@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Selenium Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to selenium-users+unsubscribe@googlegroups.com.
To post to this group, send email to selenium-users@googlegroups.com.
--

Thanks & Regards
Krishnan Mahadevan

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"
My Scribblings @ http://wakened-cognition.blogspot.com/

My Technical Scribbings @ http://rationaleemotions.wordpress.com/

--
You received this message because you are subscribed to the Google Groups "Selenium Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to selenium-users+unsubscribe@googlegroups.com.
To post to this group, send email to selenium-users@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/selenium-users/CANikZLmLuRbsBt22oU8nqUmTFgSBF4BYL17Wz67yOYd%3DiwzC7w%40mail.gmail.com.

Ankit Gupta

unread,
Jun 18, 2018, 11:52:29 AM6/18/18
to seleniu...@googlegroups.com
document.readyState it would only work when the application is in JavaScript.

On Mon, Jun 18, 2018 at 9:06 PM, Greg Martz <gma...@costco.com> wrote:
Interesting!  I know that I went from about a 35% failure rate to less than 3% after adding that in our isLoaded() class.  I so wish that the webdriver would give us a method that would guarantee that the full page has been loaded.


Thanks!
Greg

Greg Martz
Test Analyst III - eBusiness Lead QA Automation Analyst  |  (425)416-5039  |  gma...@Costco.com 

"Confidentiality Notice:  This e-mail message, including any attachments, is for the sole use to the intended recipient(s) and may contain confidential and privileged information.  Any unauthorized review, use, disclosure or distribution is prohibited.  If you are not the intended recipient, please contact the sender by reply e-mail and destroy all copies of the original message."


Greg 

To post to this group, send email to seleniu...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Selenium Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to selenium-users+unsubscribe@googlegroups.com.
To post to this group, send email to seleniu...@googlegroups.com.
--

Thanks & Regards
Krishnan Mahadevan

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"
My Scribblings @ http://wakened-cognition.blogspot.com/

My Technical Scribbings @ http://rationaleemotions.wordpress.com/

--
You received this message because you are subscribed to the Google Groups "Selenium Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to selenium-users+unsubscribe@googlegroups.com.
To post to this group, send email to seleniu...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Selenium Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to selenium-users+unsubscribe@googlegroups.com.
To post to this group, send email to selenium-users@googlegroups.com.

Yogesh Khachane

unread,
Jun 18, 2018, 12:12:20 PM6/18/18
to seleniu...@googlegroups.com
Hi Nagendra,

You can use fluent wait for this kind of application, what happens fluent wait pulling DOM till element is not present in DOM also you can ignore multiple exception in fluent wiat and whenever get element it will perform action and move to next action, So your test case will not failed randomly it will work as per functionality. Also you can add minwait,midwait,and maxwait in your framework.



-- 
With Best Regards,
Yogesh  Khachane
Framework Developer
+91-9764953754


--
You received this message because you are subscribed to the Google Groups "Selenium Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to selenium-users+unsubscribe@googlegroups.com.
To post to this group, send email to selenium-users@googlegroups.com.

Greg Martz

unread,
Jun 19, 2018, 11:10:19 AM6/19/18
to seleniu...@googlegroups.com
Please explain.


Thanks!
Greg

Greg Martz
Test Analyst III - eBusiness Lead QA Automation Analyst  |  (425)416-5039  |  gma...@Costco.com 

"Confidentiality Notice:  This e-mail message, including any attachments, is for the sole use to the intended recipient(s) and may contain confidential and privileged information.  Any unauthorized review, use, disclosure or distribution is prohibited.  If you are not the intended recipient, please contact the sender by reply e-mail and destroy all copies of the original message."


--
You received this message because you are subscribed to the Google Groups "Selenium Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to selenium-users+unsubscribe@googlegroups.com.
To post to this group, send email to selenium-users@googlegroups.com.

Mike Hetzer

unread,
Jun 19, 2018, 11:28:06 AM6/19/18
to Selenium Users
Ideally, you want to handle it in the constructor of your Page Object.
Example "HomePage":
                private HomePage(IWebDriver driver) : base(driver)
{
this.driver = driver;
WaitForPageLoadToComplete(300);
WaitForAjax();
PageFactory.InitElements(this.driver, this);
}

These methods are on my "BasePage":
                public void WaitForPageLoadToComplete(int intTimeOutFromSeconds = 120)
{
WebDriverWait wait = new WebDriverWait(baseWebDriver, TimeSpan.FromSeconds(intTimeOutFromSeconds));
wait.Until(d => ((IJavaScriptExecutor)baseWebDriver).ExecuteScript("return document.readyState").Equals("complete"));
}

                public void WaitForAjax()
{
IJavaScriptExecutor executor = (IJavaScriptExecutor)baseWebDriver;
if ((Boolean)executor.ExecuteScript("return window.jQuery != undefined"))
{
while (!(Boolean)executor.ExecuteScript("return jQuery.active == 0"))
{
Thread.Sleep(1000);
}
}
}



For some more problematic Pages, you could also put additional wait calls in the constructor before it return the Page Object, where you would wait for an IWebElement or a By to be present.
Using a method like so (we use extension methods):
                public static bool xtWaitUntilExists(this By by, IWebDriver driver, int timeoutInSeconds = 30)
{
try
{
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSeconds));
wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementExists(by));
return true;
}
catch (Exception ex)
{
return false;
}

}

or

                public static void xtWaitUntilVisible(this By by, IWebDriver driver, int timeoutInSeconds = 30)
{
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSeconds));
wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementIsVisible(by));
}

.
.

Greg Martz

unread,
Jun 19, 2018, 12:30:13 PM6/19/18
to seleniu...@googlegroups.com
That's some interesting code!  Would like to try and add it.  I have a base PageObject class, where I initialize the driver and init the elements.  Couple of questions:

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

Where is d identified?  Where is IJavaScriptExecutor identified?

var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSeconds));

What is TimeSpan?

Here's what I am looking at:

Sample HomePage object (HomePage.java)

public class HomePage extends PageObject
{
.
.
.
    public HomePage(WebDriver wDriver)
    {
        super(wDriver);
        Utility.scrollToTopOfPage(wDriver);
    }
.
.
.
}


PageObject.java

Public class PageObject
{
    protected WebDriver wDriver = null;
    
    public PageObject(WebDriver wDriver)
    {
        this.wDriver = wDriver;
WaitForPageLoadToComplete(300);
WaitForAjax();
        PageFactory.initElements(wDriver, this);
    }

    public void WaitForPageLoadToComplete(int intTimeOutFromSeconds = 120)
    {
  WebDriverWait wait = new WebDriverWait(wDriver, TimeSpan.FromSeconds(intTimeOutFromSeconds));
  wait.Until(d => ((IJavaScriptExecutor)wDriver).ExecuteScript("return document.readyState").Equals("complete"));
  }

    public void WaitForAjax()
  {
  IJavaScriptExecutor executor = (IJavaScriptExecutor)baseWebDriver;
  if ((Boolean)executor.ExecuteScript("return window.jQuery != undefined"))
  {
  while (!(Boolean)executor.ExecuteScript("return jQuery.active == 0"))
  {
  Thread.Sleep(1000);
  }
  }
  }
}





Thanks!
Greg

Greg Martz
Test Analyst III - eBusiness Lead QA Automation Analyst  |  (425)416-5039  |  gma...@Costco.com 

"Confidentiality Notice:  This e-mail message, including any attachments, is for the sole use to the intended recipient(s) and may contain confidential and privileged information.  Any unauthorized review, use, disclosure or distribution is prohibited.  If you are not the intended recipient, please contact the sender by reply e-mail and destroy all copies of the original message."


--
You received this message because you are subscribed to the Google Groups "Selenium Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to selenium-users+unsubscribe@googlegroups.com.
To post to this group, send email to selenium-users@googlegroups.com.

⇜Krishnan Mahadevan⇝

unread,
Jun 19, 2018, 12:35:06 PM6/19/18
to seleniu...@googlegroups.com
Greg 

The code you are looking at is C# and I am guessing things such as "d" are lambda expressions. 

Since u are using page factory you could very well use a custom invocation handler which essentially waits for element to be present etc after a page load action has occurred. 



To unsubscribe from this group and stop receiving emails from it, send an email to selenium-user...@googlegroups.com.
To post to this group, send email to seleniu...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Selenium Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to selenium-user...@googlegroups.com.
To post to this group, send email to seleniu...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/selenium-users/CAJ5e%3Deg%2BKewpeb5iEoPw6Jubb-ehHZ%2BPu-KSr_ChW6tZdx9M0Q%40mail.gmail.com.

For more options, visit https://groups.google.com/d/optout.

Mike Hetzer

unread,
Jun 19, 2018, 12:49:06 PM6/19/18
to seleniu...@googlegroups.com
Lol, sorry I should note our project is in C# so will likely have to modify some of that for java.
Principles are the same though.

1. "d" is just an arbitrary name defined for the lambda expression
2. "TimeSpan" is c# related - you probably would just use something like [WebDriverWait wait = new WebDriverWait(driver, 30);] for java


To post to this group, send email to seleniu...@googlegroups.com.

--
You received this message because you are subscribed to a topic in the Google Groups "Selenium Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/selenium-users/Ewbvaeb68GM/unsubscribe.
To unsubscribe from this group and all its topics, send an email to selenium-users+unsubscribe@googlegroups.com.

To post to this group, send email to selenium-users@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
____________________________________________

Mike Hetzer

Greg Martz

unread,
Jun 20, 2018, 9:09:51 AM6/20/18
to seleniu...@googlegroups.com
That's what we are trying to get around.  You shouldn't need to wait for an element to be available on a page to determine that the page has been loaded.  We are trying to determine that "the page is loaded" with all elements, all javascript, all ajax completed.


Thanks!
Greg

Greg Martz
Test Analyst III - eBusiness Lead QA Automation Analyst  |  (425)416-5039  |  gma...@Costco.com 

"Confidentiality Notice:  This e-mail message, including any attachments, is for the sole use to the intended recipient(s) and may contain confidential and privileged information.  Any unauthorized review, use, disclosure or distribution is prohibited.  If you are not the intended recipient, please contact the sender by reply e-mail and destroy all copies of the original message."


To unsubscribe from this group and stop receiving emails from it, send an email to selenium-users+unsubscribe@googlegroups.com.
To post to this group, send email to selenium-users@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Selenium Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to selenium-users+unsubscribe@googlegroups.com.
To post to this group, send email to selenium-users@googlegroups.com.
--

Thanks & Regards
Krishnan Mahadevan

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"
My Scribblings @ http://wakened-cognition.blogspot.com/

My Technical Scribbings @ http://rationaleemotions.wordpress.com/

--
You received this message because you are subscribed to the Google Groups "Selenium Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to selenium-users+unsubscribe@googlegroups.com.
To post to this group, send email to selenium-users@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/selenium-users/CANikZLkHp137ebk1yv_vUYT4o6pqmOtav%3DvEtHu5dE9QUtTfAA%40mail.gmail.com.

Greg Martz

unread,
Jun 20, 2018, 9:10:53 AM6/20/18
to seleniu...@googlegroups.com
Aha!  I should have noticed it was C#.  I guess I've been in the Java world for so long it's affected my brain :)  Will go based off that knowledge.


Thanks!
Greg

Greg Martz
Test Analyst III - eBusiness Lead QA Automation Analyst  |  (425)416-5039  |  gma...@Costco.com 

"Confidentiality Notice:  This e-mail message, including any attachments, is for the sole use to the intended recipient(s) and may contain confidential and privileged information.  Any unauthorized review, use, disclosure or distribution is prohibited.  If you are not the intended recipient, please contact the sender by reply e-mail and destroy all copies of the original message."





--
____________________________________________

Mike Hetzer

--
You received this message because you are subscribed to the Google Groups "Selenium Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to selenium-users+unsubscribe@googlegroups.com.
To post to this group, send email to selenium-users@googlegroups.com.

Roger Cook

unread,
Jun 20, 2018, 1:51:44 PM6/20/18
to Selenium Users
Here's what I use. It relies on JavaScript's document.readyState. It's in C#.

    public static void WaitForDocumentReady(this IWebDriver driver)
   
{
       
Console.WriteLine("Waiting for five instances of document.readyState returning 'complete' at 100ms intervals.");
       
IJavaScriptExecutor jse = (IJavaScriptExecutor)driver;
       
int i = 0; // Count of (document.readyState === complete) && (ae.isProcessing === false)
       
int j = 0; // Count of iterations in the while() loop.
       
int k = 0; // Count of times i was reset to 0.
       
bool readyState = false;
       
while (i < 5)
       
{
           
System.Threading.Thread.Sleep(100);
           
string scriptText = "return (document.readyState === 'complete')";
            readyState
= (bool)jse.ExecuteScript(scriptText);
           
if (readyState) { i++; }
           
else
           
{
                i
= 0;
                k
++;
           
}
            j
++;
           
if (j > 300) { throw new TimeoutException("Timeout waiting for document.readyState to be complete."); }
       
}
        j
*= 100;
       
Console.WriteLine("Waited " + j.ToString() + " milliseconds. There were " + k + " resets.");
   
}


The idea is to check for document.readyState === true for an entire half-second before proceeding. If it's still loading, it should come back false. That said, like others have said, there's no good way to do this. There are too many variables with Ajax and other frameworks that keep running in the background.

roger

Jim Evans

unread,
Jun 20, 2018, 4:17:36 PM6/20/18
to Selenium Users
I realize your wish is “that the webdriver would give us a method that would guarantee that the full page has been loaded.” However, there is no one-size-fits-all solution to that desire. You say “all elements present,” but what about elements that are added dynamically to the DOM via JavaScript? You say “all JavaScript complete,” but what about JavaScript that defers execution by using setTimeout or othe mechanisms. You say “all AJAX complete,” but how do you measure that when there are a ton of AJAX libraries, all of which indicate their completeness in different ways? Also, WebDriver can’t play favorites among libraries, since just because one is the most popular today has no bearing on which will be popular tomorrow. A far better approach, from the point of view of WebDriver and Selenium, is to let the user define for themselves what it means for “the page is fully loaded.”

I understand we may disagree on this, but I can think of no way to get the answer right for every page and every user. And make no mistake, it would have to be right 100% of the time, or the users for whom the result is wrong would loudly complain about it. But I’m willing to e proven wrong. What’s your solution that works for every web page that exists now or will ever exist, and works across all supported browsers?
Reply all
Reply to author
Forward
0 new messages