42

I am using Selenium 2.20 WebDriver to create and manage a firefox browser with C#. To visit a page, i use the following code, setting the driver timeouts before visiting the URL:

driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(5)); // Set implicit wait timeouts to 5 secs
driver.Manage().Timeouts().SetScriptTimeout(new TimeSpan(0, 0, 0, 5));  // Set script timeouts to 5 secs
driver.Navigate().GoToUrl(myUrl);   // Goto page url

The problem is that sometimes pages take forever to load, and it appears that the default timeout for a page to load using the selenium WebDriver is 30 seconds, which is too long. And i don't believe the timeouts i am setting apply to the loading of a page using the GoToUrl() method.

So I am trying to figure out how to set a timeout for a page to load, however, i cannot find any property or method that actually works. The default 30 second timeout also seems to apply to when i click an element.

Is there a way to set the page load timeout to a specific value so that when i call the GoToUrl() method it will only wait my specified time before continuing?

Nakilon
  • 34,866
  • 14
  • 107
  • 142
KabanaSoft
  • 1,591
  • 2
  • 13
  • 13
  • Are you sure `GoToUrl()` waits for the page to load? My experience is that it doesn't. But that's just a feeling, not a fact. – Torbjörn Kalin May 15 '12 at 18:51
  • yes, i am 100% sure that calling GoToUrl() blocks execution until the page is completely done loading, and i have measured a default timeout of 30 seconds for calling this method, after 30 seconds execution will continue, and i'm trying to reduce that default timeout of 30 seconds somehow. – KabanaSoft May 15 '12 at 19:11
  • i have posted similar question: http://stackoverflow.com/questions/11958701/what-is-the-best-approach-for-timeout-using-selenium-using-webdriver – Nick Kahn Aug 15 '12 at 15:06
  • @TorbjörnKalin It does block until the page loads as far as the onReady event is thrown by the browser. If theres post js and ajax ... that "page loaded" knowlege doesn't mean anything. – AnthonyJClink Mar 11 '16 at 18:53

9 Answers9

47
driver.Manage().Timeouts().PageLoad = TimeSpan.FromSeconds(5);

Note: driver.Manage().Timeouts().SetPageLoadTimeout(TimeSpan.FromSeconds(5)) is now deprecated.

Josh
  • 2,142
  • 2
  • 23
  • 20
32

In case this helps anyone still looking for the answer to this, the C# WebDriver API now contains the appropriate method.

driver.Manage().Timeouts().SetPageLoadTimeout(timespan)
Josh
  • 2,142
  • 2
  • 23
  • 20
ktam33
  • 1,217
  • 12
  • 22
  • 3
    I just wish someone had a clear description of how page load timeout differs from the implicit wait. When exactly does a page load but an element not? – JasonCoder Mar 20 '13 at 17:47
  • 9
    From the C# intellisense `ImplicitlyWait` is the amount of time searching for an element on the page, `SetPageLoadTimeout` is the amount of time waiting for a URL to load, and `SetScriptTimeout` is the amount of time waiting for async JS to load. – jpvantuyl Apr 10 '15 at 16:26
6

With this you should be able to declare a wait explicitly.

WebDriverWait wait = new WebDriverWait(browser, new TimeSpan(time in seconds));
wait.until(Your condition)

you could also change the implicit wait time

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

I think that is the syntax in C#. (not to sure)

In ruby it is

@driver.manage.timeouts.implicit_wait = 30
@wait = Selenium::WebDriver::Wait.new(:timeout => 30)
Amey
  • 8,470
  • 9
  • 44
  • 63
  • 1
    this will not work because execution is blocked by the GoToUrl() method, so i cannot execute any code until that method is done or times out, which be default seems to be 30 seconds. Thanks for the response though. – KabanaSoft May 15 '12 at 19:12
  • 2
    so you need to change your implicit wait time - `driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(5));` decrease the 5 seconds to how ever less you want. That will affect your wait time on the gotourl. – Amey May 15 '12 at 19:16
  • 1
    you could also try `wait.until (driver.Navigate().GoToUrl(myUrl)); // Goto page url` where your explicitly defining the time to wait for the gotoURL command to be executed – Amey May 15 '12 at 19:20
  • 1
    @seleniumnewbie: I don't know why there's upvote for `wait.until (driver.Navigate().GoToUrl(myUrl)); // Goto page url`, but from the results I got this does not work at all. – Shane May 25 '12 at 07:32
4

i found the solution this this issue. When creating a new FirefoxDriver, there are overloads in the constructor that allow you to specify a command timeout which is the maximum time to wait for each command, and it seems to be working when calling the GoToUrl() method:

driver = new FirefoxDriver(new FirefoxBinary(), profile, new TimeSpan(0, 0, 0, timeoutSeconds));

link to FirefoxDriver constructor documentation for reference: http://selenium.googlecode.com/svn/trunk/docs/api/dotnet/html/M_OpenQA_Selenium_Firefox_FirefoxDriver__ctor_2.htm

Hope this helps someone else who runs into this problem.

KabanaSoft
  • 1,591
  • 2
  • 13
  • 13
  • i have posted similar question: http://stackoverflow.com/questions/11958701/what-is-the-best-approach-for-timeout-using-selenium-using-webdriver – Nick Kahn Aug 15 '12 at 15:07
3

We brazilians have a word for crappy workarounds "Gambiarra"... Well... at least they do the job... Here is mine:

var url = "www.your.url.here"
try {
    DRIVER.Navigate().GoToUrl(url);
} catch {
    // Here you can freely use the Selenium's By class:
    WaitElement(By.Id("element_id_or_class_or_whatever_to_be_waited"), 60);
}
// rest of your application

What my WaitElement(By, int) does:

/// <summary>
/// Waits until an element of the type <paramref name="element"/> to show in the screen.
/// </summary>
/// <param name="element">Element to be waited for.</param>
/// <param name="timeout">How long (in seconds) it should be waited for.</param>
/// <returns>
/// False: Never found the element. 
/// True: Element found.
/// </returns>
private bool WaitElement(By element, int timeout)
{
    try {
        Console.WriteLine($" - Waiting for the element {element.ToString()}");
        int timesToWait = timeout * 4; // Times to wait for 1/4 of a second.
        int waitedTimes = 0; // Times waited.
        // This setup timesout at 7 seconds. you can change the code to pass the 

        do {
            waitedTimes++;
            if (waitedTimes >= timesToWait) {
                Console.WriteLine($" -- Element not found within (" +
                $"{(timesToWait * 0.25)} seconds). Canceling section...");
                return false;
            }
            Thread.Sleep(250);
        } while (!ExistsElement(element));

        Console.WriteLine($" -- Element found. Continuing...");
    //  Thread.Sleep(1000); // may apply here
        return true;
    } catch { throw; }
}

After this, you can play with timeout...

Make By the things you notice that loads last in the page (like javascript elements and captchas) remembering: it will start working the // rest of your application before the page fully loads, therefore may be nice to put a Thread.Sleep(1000) at the end just to be sure...

Also notice that this method will be called AFTER the 60 seconds standard timeout from Selenium's DRIVER.Navigate().GoToUrl(url);

Not the best, but... as I said: A good gambiarra gets the job done...

2

Page load timeouts are not implemented in the .NET bindings yet. Hopefully they will be soon.

JimEvans
  • 27,201
  • 7
  • 83
  • 108
  • Any update on this? After 9 years, it seems they still have not been implemented. My system still times out after 10 seconds regardless of the timeouts I set on ImplicitWait, AsynchronousJavaScript, or PageLoad. – John Chesshir Jan 31 '22 at 21:43
2

As of 2018: Besides these:

driver.Manage().Timeouts().ImplicitWait.Add(System.TimeSpan.FromSeconds(5));      
driver.Manage().Timeouts().PageLoad.Add(System.TimeSpan.FromSeconds(5));
driver.Manage().Timeouts().AsynchronousJavaScript.Add(timespan));

wait for searching for an item, loading a page, and waiting for script respectively. There is:

WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
Ywapom
  • 601
  • 5
  • 18
1

For anyone who wants the opposite effect: setting timeout longer than 60s.

You need both use:

new FirefoxDriver(FirefoxDriverService.CreateDefaultService(), new FirefoxOptions(), TimeSpan.FromSeconds(120))

and

driver.Manage().Timeouts().PageLoad = TimeSpan.FromSeconds(120);

The new FirefoxDriver(binary, profile, timeSpan) has been obsolete.

imba-tjd
  • 491
  • 4
  • 11
0
driver.Manage().Timeouts().SetPageLoadTimeout(timespan) 

does not work.

This works. Use a property setter syntax.

driver.Manage().Timeouts().PageLoad = TimeSpan.FromSeconds(15);
T. Muir
  • 11
  • 2