46

When I am using a proxy in webdriver like FirefoxDriver, if the proxy is bad then the get method will block forever. I set some timeout parameters, but this did not work out.

This is my code:

FirefoxProfile profile = new FirefoxProfile();
profile.setPreference("general.useragent.override", ua);    
Proxy p = new Proxy();
p.setHttpProxy(proxy);
profile.setProxyPreferences(p);
profile.setEnableNativeEvents(true);

// create a driver
WebDriver driver = new FirefoxDriver(profile);
driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);
driver.manage().timeouts().setScriptTimeout(30, TimeUnit.SECONDS);
driver.get("www.sina.com.cn")

The call to driver.get will block for ever, but I want it to wait for 30 seconds and if the page is not loaded then throw an exception.

David Rogers
  • 2,601
  • 4
  • 39
  • 84
福气鱼
  • 1,189
  • 2
  • 10
  • 13

8 Answers8

42

Try this:

 driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
Fujiao Liu
  • 2,195
  • 2
  • 24
  • 28
  • 4
    As I write, this answer is accepted as correct. However, as zhongting [mentions below](http://stackoverflow.com/a/10827070/705157), this solution seems to block the load for a very long time. I think the actual answer should be [user1102631's](http://stackoverflow.com/a/12915015/705157). – Steve HHH Oct 02 '13 at 18:26
  • 2
    Agreed, this answer will add a delay of 30 seconds to every command that selenium runs. Arbitrary delays like this are a very expensive and generally unreliable way to make tests work. Its usually better to set the implicit wait to 0 and use explicit waits for the results of each action. This is more reliable and generally faster as you only wait until the action happens rather than for the full time limit every time. – ajsutton Jan 20 '14 at 22:26
  • @ajsutton how do you explicitly wait? – Thufir Oct 14 '14 at 06:48
  • It is bad to use implicitlyWait. It's better to use ExplicitWait – Ripon Al Wasim Feb 09 '15 at 12:11
  • @Thufir I wanted to ask the same question - how? Folks mentioned It's better to use this not that but they just didn't say how. Here's how WebDriverWait wait = new WebDriverWait(, waitTimeInSeconds); wait.until(ExpectedConditions.visibilityOf(elementToWaitFor)); – Niks Mar 05 '15 at 08:20
  • 5
    @ajsutton how will it add 30 sec delay to each command? implictwait **polls** the DOM for the given time until the element/s are avaialable. If they are available before 30 secs it will break the wait and continue the execution. – Vivek Singh Mar 25 '15 at 07:04
  • How to do that in JS, can't do that in JS – Zeeshan Ahmad Khalil Sep 08 '22 at 13:50
30

The timeouts() methods are not implemented in some drivers and are very unreliable in general.
I use a separate thread for the timeouts (passing the url to access as the thread name):

Thread t = new Thread(new Runnable() {
    public void run() {
        driver.get(Thread.currentThread().getName());
    }
}, url);
t.start();
try {
    t.join(YOUR_TIMEOUT_HERE_IN_MS);
} catch (InterruptedException e) { // ignore
}
if (t.isAlive()) { // Thread still alive, we need to abort
    logger.warning("Timeout on loading page " + url);
    t.interrupt();
}

This seems to work most of the time, however it might happen that the driver is really stuck and any subsequent call to driver will be blocked (I experience that with Chrome driver on Windows). Even something as innocuous as a driver.findElements() call could end up being blocked. Unfortunately I have no solutions for blocked drivers.

Jason Law
  • 965
  • 1
  • 9
  • 21
user1102631
  • 534
  • 6
  • 7
  • 1
    If u mix selenium with userscripts (via extension and saving profile back) you can still fire javascript code into the browser, even if selenium is blocked waiting for load. This way you can add a simple javascript `setTimeout(function(){window.stop();}, 5000)` with desired time in ms then stop page from loading. Once you stop loading, the control is sent back to selenium (simple run a test then press ESC key when load). This way allows you to load just 5 secs of webpage and get the common web elements. – m3nda Nov 08 '15 at 17:54
18

try

driver.executeScript("window.location.href='http://www.sina.com.cn'")

If you have set pageLoadStrategy to none, this statement will return immediately.

And after that , you can add a WebDriverWait with timeout to check if the page title or any element is ok.

Hope this will help you.

P i
  • 29,020
  • 36
  • 159
  • 267
JasonYou
  • 181
  • 1
  • 4
  • 3
    This was the easiest working solution for me using ChromeDriver, since it doesn't support the pageLoadTimeout stuff. Works in python too (execute_script). – chris838 Dec 22 '16 at 17:28
  • 2
    Nice! Great way to resolve my fighting against socket.timeout exceptions (python). I prefer to deal with selenium's TimeoutException. – Donn Lee Feb 01 '17 at 20:28
  • 1
    Yes! This is what I was looking for too. I had a `get()` and then `WebDriverWait` in a try catch with a time out of 3 second. But this block sometimes took 300 seconds without terminating due to the wait happening in `get` instead of `WebDriverWait`. Using `execute_script` (I am in python) instead of `get()` solved the issue. – Hashimoto Jul 02 '20 at 20:43
  • @JasonYou I've edited your answer by inserting the text "If you have set pageLoadStrategy to none,". By my tests, if it's `eager` I have a several-second wait before reaching the next line of code. – P i Aug 03 '22 at 11:04
8

I had the same problem and thanks to this forum and some other found the answer. Initially I also thought of separate thread but it complicates the code a bit. So I tried to find an answer that aligns with my principle "elegance and simplicity".

Please have a look at such forum: https://sqa.stackexchange.com/questions/2606/what-is-seleniums-default-timeout-for-page-loading

#

SOLUTION: In the code, before the line with 'get' method you can use for example:

driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);
#

One thing is that it throws timeoutException so you have to encapsulate it in the try catch block or wrap in some method.

I haven't found the getter for the pageLoadTimeout so I don't know what is the default value, but probably very high since my script was frozen for many hours and nothing moved forward.

#

NOTICE: 'pageLoadTimeout' is NOT implemented for Chrome driver and thus causes exception. I saw by users comments that there are plans to make it.

Community
  • 1
  • 1
Lukasz
  • 368
  • 4
  • 9
  • OP tried `pageLoadTimeout` and did not work for his/her case.. – Packard CPW Oct 05 '19 at 03:51
  • I actually used this in the latest ChromeDriver version 101.0.4951.41 and the timeout worked. I set it at 5 seconds, and while it seemed like it took longer than 5 seconds to timeout, the driver reported around 4.98 seconds elapsed. I didn't want to resort to using threads either, so this was a nice simple solution for my purposes. – Dave May 02 '22 at 13:41
2

You can set the timeout on the HTTP Client like this

int connectionTimeout=5000;
int socketTimeout=15000;
ApacheHttpClient.Factory clientFactory = new ApacheHttpClient.Factory(new HttpClientFactory(connectionTimeout, socketTimeout));
HttpCommandExecutor executor =
      new HttpCommandExecutor(new HashMap<String, CommandInfo>(), new URL(seleniumServerUrl), clientFactory);
RemoteWebDriver driver = new RemoteWebDriver(executor, capabilities);
flob
  • 116
  • 5
1

The solution of driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS) will work on the pages with synch loading. This does not solve, however, the problem on pages loading stuff in async, then the tests will fail all the time if we set the pageLoadTimeOut.

GustavoIP
  • 873
  • 2
  • 8
  • 25
sou
  • 21
  • 3
0

I find that the timeout calls are not reliable enough in real life, particularly for internet explorer , however the following solutions may be of help:

  1. You can timeout the complete test by using @Test(timeout=10000) in the junit test that you are running the selenium process from. This will free up the main thread for executing the other tests, instead of blocking up the whole show. However even this does not work at times.

  2. Anyway by timing out you do not intend to salvage the test case, because timing out even a single operation might leave the entire test sequence in inconsistent state. You might just want to proceed with the other testcases without blocking (or perhaps retry the same test again). In such a case a fool-proof method would be to write a poller that polls processes of Webdriver (eg. IEDriverServer.exe, Phantomjs.exe) running for more than say 10 min and kill them. An example could be found at Automatically identify (and kill) processes with long processing time

Community
  • 1
  • 1
premganz
  • 399
  • 2
  • 7
-1

Used below code in similar situation

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

and embedded driver.get code in a try catch, which solved the issue of loading pages which were taking more than 1 minute.

alexander.polomodov
  • 5,396
  • 14
  • 39
  • 46