Net::ReadTimeout: Net::ReadTimeout using selenium-webdriver with Ruby - ruby

I use selenium-webdriver gem, Ruby 2.4.4, Rails 4.2 to run Jasmine tests using Firefox.
But unfortunately in most cases I have this error : Net::ReadTimeout: Net::ReadTimeout.
Logs from Selenium show me that test run, but then there is a huge delay after running tests before closing browser.
Could you please advise how to fix that? Or maybe someone had the same issue?
Maybe I can add some code fix this in jasmine_helper.rb ?

The above error was thrown when the page load time exceeds 60 seconds so write the following code for page load
client = Selenium::WebDriver::Remote::Http::Default.new
client.read_timeout = 120 # seconds
driver = Selenium::WebDriver.for :firefox,http_client: client
Now your code would wait for 120 seconds for any page load which has been caused by #click and also wait to load the url by goto method.

Related

The test hangs for a decent amount of time and crashes with an error Net::ReadTimeout (Net::ReadTimeout)

When running tests, a Net::ReadTimeout (Net::ReadTimeout) error occurs.
The error occurs only in situations of switching to a new window.
At the same time, the problem is not even in the exception itself, but in the consequences. The fact is that when a problem occurs, the test does not fall, and a decent time (up to 10 minutes) waits before is crashed.
At the same time, there are no exceptions in the server console and browser console.
I use Capybara (selenium), chromediver 102.0.5005.61 and chrome .
client = Selenium::WebDriver::Remote::Http::Default.new
client.read_timeout = 80
options = Selenium::WebDriver::Chrome::Options.new
options.add_preference('profile.content_settings.exceptions.automatic_downloads', {
'*': {'setting': 1}
})
Capybara::Selenium::Driver.new(app, :browser => :chrome, http_client: client, options: options)
It is code to switch to new window
window_last = page.driver.browser.window_handles.last
log window_last
page.driver.browser.switch_to.window(window_last)
There is a hook that should work, it seems to work, but for some reason it does not interrupt the test
After do |scenario|
if scenario.failed?
filename = scenario.location.file.split('/').pop.split('.').shift
path = "#{ENV['ROOTDIR']}/06_Reports/error/#{filename}#{scenario.id}.png"
p path
page.save_screenshot path
end
page.driver.browser.close
page.driver.quit()
end
Video record
It seems to me that it started after updating chrome and chromedriver - but I'm not sure. It is not possible to repeat it manually, it is possible to run the autotest, and far from the first attempt.
Any idea what it is, where to dig? How to prevent such freezes? They greatly increase the run time.
Thank you!
If it started after updating chrome/chromedriver then it's likely a bug in chromedriver. Try rolling back to a previous version of chrome and seeing if the issue goes away. One thing to note is that by switching windows directly on the driver you are preventing Capybara from knowing about the window switch which can lead to issues. You should instead use the Capybara::Session#switch_to_window or within_window methods to do window switching.

How to extract JS rendered HTML using Selenium-webdriver and nokogiri?

Consider two webpages one and two. Site number two is easy to scrape using nokogiri because it doesn't use JS. Site number one however cannot be scraped using just nokogiri. I googled and searched far and wide and found that if I loaded the page with an automated web browser I could scrape the the rendered HTML. I have the following code right below:
# creates an instance
driver = Selenium::WebDriver.for :chrome
# opens an existing webpage
driver.get 'http://www.bigstub.com/search.aspx'
# wait is used to let the webpage load up and let the JS render
wait = Selenium::WebDriver::Wait.new(:timeout => 5)
My question is that I am trying to let the page load up an close immediately once I get my desired class. An example is that if I adjust the time out to 10 seconds until I can find the class .title-holder how would I write this code?
Pusedo code:
rendered_source_page will time out if .include?("title-holder"). I just don't know how to write it.
UPDATE:
In regards to the headless question, selenium has an option or configuration in where you can add in a headless option. This is done by the code below:
options = Selenium::WebDriver::Chrome::Options.new
options.add_argument('--headless')
driver = Selenium::WebDriver.for :chrome, options: options
For my next question in order for the site to fully scrape the JS rendered HTML I set my timeout variable to 5 seconds:
wait = Selenium::WebDriver::Wait.new(:timeout => 5)
wait.until { /title-holder/.match(driver.page_source) }
wait.until pretty much means wait 5 seconds until I find a title-holder class inside of the page_source or rendered HTML. This pretty much solved all my questions.
I am assuming you are running selenium on a server. So first install Xvfb
sudo apt-get install xvfb
Install firefox
sudo apt-get install firefox
Add the following two gems to your gemfile. You will need headless because you want to run the selenium webdriver on your server. Headless will start and stop Xvfb for you.
#gemfile
gem 'selenium-webdriver'
gem 'headless'
Code for scraping
headless = Headless.new
headless.start
driver = Selenium::WebDriver.for :firefox
driver.navigate.to example.com
wait = Selenium::WebDriver::Wait.new(:timeout => 30)
#scraping code comes here
Housekeeping so that you don't run out of memory.
driver.quit
headless.destroy
Hope this helps.
In regards to the headless question, selenium has an option or configuration in where you can add in a headless option. This is done by the code below:
options = Selenium::WebDriver::Chrome::Options.new
options.add_argument('--headless')
driver = Selenium::WebDriver.for :chrome, options: options
For my next question in order for the site to fully scrape the JS rendered HTML I set my timeout variable to 5 seconds:
wait = Selenium::WebDriver::Wait.new(:timeout => 5)
wait.until { /title-holder/.match(driver.page_source) }
wait.until pretty much means wait 5 seconds until I find a title-holder class inside of the page_source or rendered HTML. This pretty much solved all my questions.

save_and_show_page does not show page if test ends too quickly

Capybara, a web testing library for Ruby, has a method Capybara::Session.save_and_show_page that brings up the current web page in the browser. This appears to work asynchronously--the web page is shown some time after the call is made. That's fine, but if the test ends too quickly after the call to #save_and_show_page, then no web page is shown.
Problem code
Given this Gemfile:
source "https://rubygems.org"
gem "launchy"
gem "poltergeist"
Then this code does not display a web page:
require "capybara/poltergeist"
session = Capybara::Session.new(:poltergeist)
session.visit("http://www.google.com")
session.save_and_open_page
Workaround
Adding a brief sleep at the end of the code causes the web page to be displayed, as desired:
require "capybara/poltergeist"
session = Capybara::Session.new(:poltergeist)
session.visit("http://www.google.com")
session.save_and_open_page
sleep 1
# => Opening "/home/wayne/homesmart/franchise-manager-qa/capybara-201610141504469160970532.html" with Google Chrome (text/html)
# => [10253:10281:1014/150446:ERROR:nss_util.cc(809)] After loading Root Certs, loaded==false: NSS error code: -8018
# => Created new window in existing browser session.
How can I cause Capybara's #save_and_open_page method to always display a page, without having to insert a sleep after calling the method?
Versions
Ruby 2.3.1p112
capybara 2.10.1
launchy 2.4.3
poltergeist 1.11.10
PhantomJS 2.1.1
Google Chrome 53.0.2785.143 (64-bit)
Linux 3.16.0-4-amd64 #1 SMP Debian

Capybara doesn't close browser when Net::ReadTimeout error happens

I am running tests for a Rails app with Capybara, Cucumber and Selenium Webdriver (Ruby). I have a question: why Capybara doesn't close browser when Net::ReadTimeout happens even I had a hook which asked browser to quit after each test scenario? How can I force it to close the browser when Net::ReadTimeout occurs?
This is my hooks.rb
after do |scenario|
if scenario.failed?
page.driver.browser.save_screenshot("#{scenario.__id__}.png")
end
Capybara.current_session.driver.browser.manage.delete_all_cookies
Capybara.current_session.driver.quit
end
I have another solution that works for me.
add gem capybara-screenshot
configure your spec_helper.rb in such way:
Capybara::Screenshot.autosave_on_failure = true
Capybara::Screenshot.prune_strategy = :keep_last_run
Capybara.default_wait_time = 60

Feature Testing with Filepicker.io and Capybara

I am currently working on feature testing a Filepicker.io upload form and cannot get a the file upload to work. I am using the Poltergeist driver for Capybara and from the debugging I have been able to do, the Filepicker iframe is never loading. I have confirmed this by using the remote debugging of Poltergeist.
Here is a sample of the test code:
within_fieldset 'Photos' do
click_button 'Find Photo'
end
within_frame 'filepicker_dialog' do
attach_file '#fileUploadInput', Rails.root.join('spec', 'files', 'photo.jpg')
end
And the error being produced:
Failure/Error: within_frame '#filepicker_dialog' do
Capybara::Poltergeist::TimeoutError:
Timed out waiting for response to {"name":"push_frame","args":["#filepicker_dialog"]}. It's possible that this happened because something took a very long time (for example a page load was slow). If so, setting the Poltergeist :timeout option to a higher value will help (see the docs for details). If increasing the timeout does not help, this is probably a bug in Poltergeist - please report it to the issue tracker.
Attempting to manually trigger Filepicker through the javascript console also yields no results.
have you tried to increase the timeout ?
Capybara.javascript_driver = :poltergeist
Capybara.register_driver :poltergeist do |app|
Capybara::Poltergeist::Driver.new(app, {:timeout => 50})
end
as the default timeout is 30
The Capybara API for within_frame is a bit weird. It expects a frame name, not a CSS selector for the frame. So Poltergeist is looking for a frame named "#filepicker_dialog" - I suspect this is your problem.

Resources