Capybara / Selenium gets Net :: ReadTimeout randomly at location.reload ()

I am using Capybara, a selenium-webdriver gem and chromedriver, to run my javascript validated tests.

The problem is that about 50% of our builds fail due to an error Net::ReadTimeout

. At first it showed up as an "could not find element" error, but after I increased the Capybara max to 30 seconds, I started seeing a timeout.

I looked at the screenshots when the timeout occurs, it is stuck in the "Successfully registered" modal, which we will show briefly before using the Javascript function location.reload()

to reload the page.

I ran the test locally and sometimes reproduce it randomly as well. Sometimes it snaps onto this modal and reloads so quickly that you can barely see it, while other times it just hangs forever.

I don't like the issue of compiling assets as the site is already loaded at this point for the user to be able to access the login form.

I wonder if anyone has seen this before and knows the solution.

Specific code:

    visit login_path

    page.within '#sign-in-pane__body' do
      fill_in 'Email', with: user.email
      click_button 'Submit'
    end

    expect(page).to have_content 'Enter Password'

    page.within '#sign-in-pane__body' do
      fill_in 'Password', with: user.password
      click_button 'Submit'
    end

    expect(page).to have_text 'Home page landing text'

      

The gap happens between click_button 'Submit'

and waiting for the home page text.

The logic thread causing the timeout is a custom form, we expect the server to render a template .js.erb

that fires a JS event on successful login. When this trigger occurs, we show a modal statement that the login was successful, then execute location.reload()

.

+3


source to share


2 answers


It turned out that this is not an exception to execute location.reload()

in JS. Sometimes it's just a visit to a page.

The solution for me was to create an HTTP client for the selenium driver and define a longer timeout:



Capybara.register_driver :chrome do |app|
  client = Selenium::WebDriver::Remote::Http::Default.new
  client.read_timeout = 120

  Capybara::Selenium::Driver.new(app, {browser: :chrome, http_client: client})
end

      

+2


source


Solved a similar issue using my own version of the visit method:



 def safe_visit(url)
  max_retries = 3
  times_retried = 0
  begin
    visit url
  rescue Net::ReadTimeout => error
    if times_retried < max_retries
      times_retried += 1
      puts "Failed to visit #{current_url}, retry #{times_retried}/#{max_retries}"
      retry
    else
      puts error.message
      puts error.backtrace.inspect
      exit(1)
    end
  end
end

      

0


source







All Articles