Change Default Timeout and Wait Time of Capybara

One of the biggest challenge for automation is handling timeout problem. Most of the time, timeout is 60 seconds but it may sometimes not enough if you have badly designed asynchronous calls or the third party ajax calls. This makes handling timeout more complex.
set large enough to tolerate network related problems. For Selenium based automation frameworks, like Capybara, default Webdriver timeout is set to
 Net::ReadTimeout (Net::ReadTimeout)

Changing ReadTimeout

If you have timeout problem for Capybara, it gives an error like above. This means that the page is not fully loaded in given timeout period. Even you can see that page is loaded correctly but webdriver wait until the Ajax calls finish.
  class BufferedIO   #:nodoc: internal use only
    def initialize(io)
      @io = io
      @read_timeout = 60
      @continue_timeout = nil
      @debug_output = nil
      @rbuf = ''
    end
    .
    .
    ...

    def rbuf_fill
      begin
        @rbuf << @io.read_nonblock(BUFSIZE)
      rescue IO::WaitReadable
        if IO.select([@io], nil, nil, @read_timeout)
          retry
        else
          raise Net::ReadTimeout
        end
      rescue IO::WaitWritable
        # OpenSSL::Buffering#read_nonblock may fail with IO::WaitWritable.
        # http://www.openssl.org/support/faq.html#PROG10
        if IO.select(nil, [@io], nil, @read_timeout)
          retry
        else
          raise Net::ReadTimeout
        end
      end
    end

end


If you need more or less time than predefined time 60 seconds you can change the read_timeout variable in the source code from the following module as in the shown above source code.
/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/net/protocol.rb

Editing source code may be dangerous, which may let you do unnecessary changing and the update may be overwritten by incoming source code update. Instead of doing this, you can simply set this value by overriding creating new instance of driver. The followings are new instances for Chrome and Firefox:
# Firefox instance with timeout is set to 100 seconds
Capybara.register_driver :firefox_timeout do |app| client = Selenium::WebDriver::Remote::Http::Default.new client.timeout = 100 Capybara::Selenium::Driver.new(app, :browser => :firefox, :http_client => client) end # Chrome instance with timeout is set to 100 seconds Capybara.register_driver :chrome_timeout do |app| client = Selenium::WebDriver::Remote::Http::Default.new client.timeout = 100 Capybara::Selenium::Driver.new(app, :browser => :chrome, :http_client => client) end

You also need to use one of these driver instance, to do this change the following lines in your features/support/env.rb:

#Capybara.default_driver = :firefox_timeout
Capybara.default_driver = :chrome_timeout

If you still have problem with loading test pages you get the following error:

Net::ReadTimeout: Net::ReadTimeout
 from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/net/protocol.rb:158:in `rescue in rbuf_fill'
 from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/net/protocol.rb:152:in `rbuf_fill'
 from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/net/protocol.rb:134:in `readuntil'
 from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/net/protocol.rb:144:in `readline'
 from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/net/http/response.rb:39:in `read_status_line'
 from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/net/http/response.rb:28:in `read_new'
 from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/net/http.rb:1412:in `block in transport_request'
 from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/net/http.rb:1409:in `catch'
 from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/net/http.rb:1409:in `transport_request'
 from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/net/http.rb:1382:in `request'
 from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/net/http.rb:1375:in `block in request'
 from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/net/http.rb:852:in `start'
 from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/net/http.rb:1373:in `request'
 from /Library/Ruby/Gems/2.0.0/gems/selenium-webdriver-2.52.0/lib/selenium/webdriver/remote/http/default.rb:107:in `response_for'
 from /Library/Ruby/Gems/2.0.0/gems/selenium-webdriver-2.52.0/lib/selenium/webdriver/remote/http/default.rb:58:in `request'
 from /Library/Ruby/Gems/2.0.0/gems/selenium-webdriver-2.52.0/lib/selenium/webdriver/remote/http/common.rb:59:in `call'
 from /Library/Ruby/Gems/2.0.0/gems/selenium-webdriver-2.52.0/lib/selenium/webdriver/remote/bridge.rb:645:in `raw_execute'
 from /Library/Ruby/Gems/2.0.0/gems/selenium-webdriver-2.52.0/lib/selenium/webdriver/remote/bridge.rb:623:in `execute'
 from /Library/Ruby/Gems/2.0.0/gems/selenium-webdriver-2.52.0/lib/selenium/webdriver/remote/bridge.rb:134:in `get'
 from /Library/Ruby/Gems/2.0.0/gems/selenium-webdriver-2.52.0/lib/selenium/webdriver/common/navigation.rb:33:in `to'
 from /Library/Ruby/Gems/2.0.0/gems/capybara-2.6.2/lib/capybara/selenium/driver.rb:45:in `visit'
 from /Library/Ruby/Gems/2.0.0/gems/capybara-2.6.2/lib/capybara/session.rb:232:in `visit'
 from /Library/Ruby/Gems/2.0.0/gems/capybara-2.6.2/lib/capybara/dsl.rb:51:in `block (2 levels) in <module:DSL>'

Changing Wait Time

If you are searching an element on the page, Capybara is clever enough to search element  repeatedly with given parameters until the Capybara.default_max_wait_time (before Capybara version 2.5.0, it is Capybara.default_wait_time) finishes.  In such a case you need more or less time for finding an element you can Capybara.using_wait_time that is added with Capybara version 2.1. It requires time paremeter and a block of what you want. See the example below:
Capybara.using_wait_time 5 do 
  find("#password").set("12qw34")
end

Capybara.using_wait_time 5 do 
  page.has_css? "#comment"
end


Comments

  1. Merhaba mesut bey sizi buradan rahatsız ediyorum zira hicbir kontakt verisi bulamadım sizin ile iletişime geçmek için, acilen turkce online quick test pro eğitimi veren bir kaynak bulmalıyım. Sizin bu konudaki iki bölümlük girişten başka hicbir kaynak bulamadım. Rica etsem bildiğiniz bir kaynak bağlantısını iletebilir misiniz?

    ReplyDelete
    Replies
    1. Merhaba QTP dökümanları genelde ingilizce bu yüzden Türkçe arıyorsan bulamayabilirsin. Alttaki kaynaklar çok iyi diyebilirim:

      http://www.qtptutorial.net/qtpuft-course-syllabus/

      https://plus.google.com/109752377664334439839

      http://www.tutorialspoint.com/qtp/qtp_tutorial.pdf

      http://www.automationrepository.com/wordpress/download-code/qtp-framework-pdf-ebook.pdf

      Delete
  2. Teşekkür ederim. Oz3l bir kurstan İngilizce eğitimini alacağım ama dilim yeterli olmayacağı için türkçe kaynak ihtiyacım var, peki siz ücreti mukabilinde danışmanlık yapmaz misiniz?

    ReplyDelete
  3. Teşekkür ederim. Oz3l bir kurstan İngilizce eğitimini alacağım ama dilim yeterli olmayacağı için türkçe kaynak ihtiyacım var, peki siz ücreti mukabilinde danışmanlık yapmaz misiniz?

    ReplyDelete
    Replies
    1. Merhaba tam olarak ne istedigini mail yazabilir misin? gunesmes@gmail.com

      Delete

Post a Comment

Popular posts from this blog

Selenium Error "Element is not currently interactable and may not be manipulated"

Performance Testing on CI: Locust is running on Jenkins

How to Set Shared Preferences in Espresso Test for Kotlin and Java

Performance Testing on CI: Integration of Locust and Jenkins