Intellipaat Back

Explore Courses Blog Tutorials Interview Questions
0 votes
2 views
in DevOps and Agile by (19.7k points)

I was reading the SeleniumHQ documentation and came across the following statements.

"WARNING: Do not mix implicit and explicit waits. Doing so can cause unpredictable wait times. For example, setting an implicit wait of 10s and an explicit wait of 15 seconds could cause a timeout to occur after 20 seconds."

For some reason, I cannot get this to make sense. The total timeout 20s is the main confusion point for me. Can anyone explain if I am missing something?

EDIT

My question is not about the implementation/consequences of mixing those waits. It's entirely about the statements and calculation of timeout on the doc.

2nd Edit

Looks like the doc is correct according to the tests below. I still need the explanation though.

Just Implicit wait
using System;
using System.Diagnostics;
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
namespace Test
{
    [TestFixture]
    public class Test
    {
        private IWebDriver _webDriver;
        [Test]
        public void ExplicitVsImplicitWaitTest()
        {
            _webDriver = new ChromeDriver();
            _webDriver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));
            _webDriver.Navigate().GoToUrl("https://www.google.com/");
            _webDriver.Manage().Window.Maximize();
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            try
            {
                //new WebDriverWait(_webDriver, TimeSpan.FromSeconds(15)).Until(
                //ExpectedConditions.ElementExists(By.CssSelector("Should Fail")));
                _webDriver.FindElement(By.CssSelector("Should Fail"));
            }
            catch ( NoSuchElementException exception)
            //catch ( OpenQA.Selenium.WebDriverTimeoutException)
            {
                stopwatch.Stop();
                Console.WriteLine(stopwatch.Elapsed);
            }
            _webDriver.Quit();
        }
    }
}
Time in second: 00:00:10.0167290
Just Explicit wait
using System;
using System.Diagnostics;
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;
namespace Test
{
    [TestFixture]
    public class Test
    {
        private IWebDriver _webDriver;
        [Test]
        public void ExplicitVsImplicitWaitTest()
        {
            _webDriver = new ChromeDriver();
            //_webDriver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));
            _webDriver.Navigate().GoToUrl("https://www.google.com/");
            _webDriver.Manage().Window.Maximize();
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            try
            {
                new WebDriverWait(_webDriver, TimeSpan.FromSeconds(15)).Until(
                ExpectedConditions.ElementExists(By.CssSelector("Should Fail")));
                _webDriver.FindElement(By.CssSelector("Should Fail"));
            }
            //catch ( NoSuchElementException exception)
            catch ( OpenQA.Selenium.WebDriverTimeoutException)
            {
                stopwatch.Stop();
                Console.WriteLine(stopwatch.Elapsed);
            }
            _webDriver.Quit();
        }
    }
}Time in second: 00:00:15.2463079

Mixed, Explicit and Implicit both

using System;

using System.Diagnostics;

using NUnit.Framework;

using OpenQA.Selenium;

using OpenQA.Selenium.Chrome;

using OpenQA.Selenium.Support.UI;

namespace Test

{

    [TestFixture]

    public class Test

    {

        private IWebDriver _webDriver;

        [Test]

        public void ExplicitVsImplicitWaitTest()

        {

            _webDriver = new ChromeDriver();

            _webDriver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));

            _webDriver.Navigate().GoToUrl("https://www.google.com/");

            _webDriver.Manage().Window.Maximize();

            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();

            try

            {

                new WebDriverWait(_webDriver, TimeSpan.FromSeconds(15)).Until(

                ExpectedConditions.ElementExists(By.CssSelector("Should Fail")));

                _webDriver.FindElement(By.CssSelector("Should Fail"));

            }

            //catch ( NoSuchElementException exception)

            catch ( OpenQA.Selenium.WebDriverTimeoutException)

            {

                stopwatch.Stop();

                Console.WriteLine(stopwatch.Elapsed);

            }

            _webDriver.Quit();

        }

    }

}

Time in second: 00:00:20.5771817

1 Answer

0 votes
by (62.9k points)

But you have to know how they're implemented to form a sense of what's happening. Here is what happens with your mixture of the two kinds of waits. I am kipping over those steps that aren't necessary for the discussion. 

Your script sets an implicit wait. Your script starts an explicit wait checking whether or not the part exists. the explicit wait works by polling. therefore it sends a command to the browser to examine for the existence of the element. Because of the implicit wait already set, the command sent to the browser takes ten seconds to come back a failure. 

Your explicit wait checks whether or not it's reached its time limit which is 15s. it's presently at 10s (+ a small amount of time taken to execute the script, network latency, etc.) into the wait, that is less than 15s. so it's not done waiting and reissues the same command as in step 2 above.

Because of the implicit wait, the command sent to the browser takes ten seconds to return a failure. 

When the explicit wait checks again for its own timeout, more than 15s have elapsed, so it times out. 

So the explicit wait polls twice, and each time takes ten seconds that mean twenty seconds total (plus a tiny amount of time to account for the bookkeeping).

An explicit wait does not do anything to detect and compensate for an implicit wait that has been set. And it does not continue running in parallel to the commands it sends to the browser. while a browser command executes, the explicit wait isn't doing any bookkeeping or able to a day out. it's to wait for the browser command to complete before checking whether or not it should time out.

31k questions

32.8k answers

501 comments

693 users

Browse Categories

...