6

I have a page that sometimes loads in over a minute. Assume this is the expected behavior and wont change. In these cases, I get Net::ReadTimeout.

Note that this is after navigating to a page by clicking a button on the previous page, not an ajax request. Therefore Capybara.using_wait_time doesn't help.

I have tried a number of radical things (some of which I knew wouldn't work) like:

  • Setting page.driver.browser.manage.timeouts's implicit_wait, script_timeout and page_load.
  • Looping through the entire object space and setting all Selenium::WebDriver::Remote::Http::Default's timeout value.
  • Looping through the entire object space and setting all Net::HTTP's read_timeout.
  • page.driver.browser.send(:bridge).http.instance_variable_get(:@http).read_timeout=

None seem to work. This should be very trivial, still I couldn't find a way to do it.

If you know of a webdriver agnostic solution that would be great. If not - I am using selenium.

ndnenkov
  • 35,425
  • 9
  • 72
  • 104
  • my 2 cents: automation is all about quick feedback, if your app takes more than a min to load, increasing the page timeout is not the answer, bring your apps load time down is what you should be focusing at... – Pippo Jul 13 '15 at 15:32
  • @user3087106, I completely agree. However, in the current case this is not applicable. Assume I am testing someone else's live project and they are not willing to invest the resources needed to optimize the operation/put it in a background process or whatever. – ndnenkov Jul 13 '15 at 16:35
  • Have you tried increasing Capybara.default_max_wait_time (default is 2 seconds), along with an assert for an element that is only available on the new page ? – Sam Jul 14 '15 at 00:24
  • @Sam, yes. In fact, `using_wait_time` is internally calling `default_max_wait_time` as seen in the docs: http://www.rubydoc.info/github/jnicklas/capybara/Capybara.using_wait_time It's idea is if you have some modifications to the dom that you know will happen via some javascript, you should wait for some amount of time instead of instantly declaring 'no, it is not there!'. But this is wait before an action. The case here is different - I just don't what to timeout when a page is loading for some long amount of time. – ndnenkov Jul 14 '15 at 06:12

1 Answers1

13

Selenium has a lot of different timeout settings, some of which can be changed at runtime, others which have to be set when the driver is initialized. You are most likely running into the Http::Default timeout which defaults to 60 seconds. You can override this by passing your own instance into the Selenium driver as http_client

Capybara.register_driver :slow_selenium do |app|
  client = Selenium::WebDriver::Remote::Http::Default.new
  client.timeout = 120
  Capybara::Selenium::Driver.new(app, http_client: client)
end

and then use the :slow_selenium driver for tests which will take over a minute to load the page

Thomas Walpole
  • 48,548
  • 5
  • 64
  • 78
  • 1
    Just to clarify for anyone's future reference - you can tell Capybara to use the new driver for some of your specs by adding the `driver: :slow_selenium` tag. – ndnenkov Jul 20 '15 at 06:52