How to get information about JS errors in rspec? - ruby-on-rails

A specific test in my Rails app is failing on CircleCI.
This test expects an input to exist. The input/ form is rendered by React.
Screenshots from the failing test look like the React component is simply not rendering, perhaps a JS error. But I'm having difficulty identifying the cause.
In my local dev environment the form renders correctly.
In my local test environment the test passes.
If I make a remote browser connection to the CI build, the form renders correctly.
I've tried to inspect the CI headless chrome browser console logs, but recent Chrome updates seem to cause this error:
page.driver.browser.manage.logs.get(:browser)
Selenium::WebDriver::Error::WebDriverError:
unexpected response, code=404, content-type="text/plain"
unknown command: session/1595d6324fa6ae6bdc1ed885ba8c9ebf/se/log
Does anyone have a good idea how I can investigate this issue further? Is there an easier way to get hold of the browser console logs from this specific test?

Try something like this
config.after(:each, type: :system, js: true) do
errors = page.driver.browser.manage.logs.get(:browser)
if errors.present?
aggregate_failures 'javascript errrors' do
errors.each do |error|
expect(error.level).not_to eq('SEVERE'), error.message
next unless error.level == 'WARNING'
STDERR.puts 'WARN: javascript warning'
STDERR.puts error.message
end
end
end
end

This issue caused me many headaches for a long time. Turns out to be an easy fix, and a big part of the problem was that I'd made assumptions I should have checked.
Local I was running the latest versions of Chrome and ChromeDriver.
I thought I was running the same on my CI builds. Turns out the docker image I am using did not use the latest version of Chrome as I expected, even when manually configured to download ChromeDriver.
I updated the image to a more recent ruby version, and the problem went away.

Related

UI test automation using Webdriver & Ruby; was not able to initialise the chrome browser session

Our team create functional tests using Rspec and UI tests using Selenium Webdriver with Ruby.
UI tests get executed as Rake tasks. While running one of the test, browser session was not opening, throwing "Error 500" with message as:
"Selenium::WebDriver::Error::SessionNotCreatedError (session not created: This version of ChromeDriver only supports Chrome version 79):"
I already updated both chrome and chrome driver version; still I was encountering the same error.
By going back and forth, I came across the solutions to similar issue but with different techstack and infra, which were not applicable to the issue I came up with.
So finally I found that there was a gem called "chromedriver-helper", which ([link] https://rubygems.org/gems/chromedriver-helper/versions/1.0.0) got deprecated and it was advised to get rid of this gem, while using another one called "webdrivers".
[link] https://everydayrails.com/2019/04/09/chromedriver-helper-webdrivers.html
[link] https://github.com/flavorjones/chromedriver-helper
So I removed the deprecated gem while added the new one which was suggested and removed following the folder under home directory:
$HOME/.chromedriver-helper. After these two changes, my team is now able to run the UI tests smoothly

Net::ReadTimeout issues when opening pdf after moving from capybara-webkit to selenium-chromedriver

I updated my test environment from Capybara-webkit to Selenium and with Chrome to test against a more modern browser. But now I have this issue with a test that opens a pdf in a new tab. I'm not sure what causes this problem.
click_on 'Print'
within_window windows.last do
io = StringIO.new(page.body)
strings = PDF::Reader.new(io).pages.map(&:text).join(' ').split('
')
# Do some testing here.
end
When Print is clicked a pdf file is generated in a new tab.
I like to read the files content using the pdf-reader gem.
When I run this test I get a Net::ReadTimeout.
In my console I see some warnings for loading the .css and .js files:
Warning: Failed to load http:localhost:3000/assets/application-92d08a385444e234a36aeb5970e4fbbaf5a5c0130ccfcc429905fa333a588b32.css
This test worked just fine with capybara-webkit.
Any ideas how to resolve this issue?
Found it!
For those running into the same problem. ActionDispatch.SystemTesting.Server is registering a Puma server with 0:1 threads. For working with pdf's you need more then 1 thread.

Rspec with elasticsearch (searchkick) fails on CI server (Codeship)

I'm having problems getting my specs to run cleanly on our CI server (Codeship).
The specs run fine locally but it seems that on the CI server elasticsearch is having issues keeping in sync.
I've researched this issue and have found potential solutions, but none of them work.
First solution I had, was creating a helper method for the test suite for whenever I needed to reindex.
def refresh_elasticsearch(model)
model.reindex
model.searchkick_index.refresh
end
Without this I was having local specs fail because documents were not being found. Once I started calling the helper method, everything started working.
I have 2 controllers that have elasticsearch functionality, and only one of them runs OK on Codeship, which is strange. These controllers are very similar to one another so I'm really confused why one controller spec passes ALL the time and the other one doesn't.
No exceptions are thrown, just some basic expectations that fail because I'm expecting a document and it finds none.
I've tried all these solutions as well:
https://github.com/ankane/searchkick/pull/95
All these solutions work locally BTW. But they all fail for the same reason on the CI server.
I'm running out of things to try at this point. Any ideas??
Any help is appreciated. Thanks!!

How can 'parse' be undefined for Time class in test environment, but not development or production?

I'm encountering a strange issue while running a test (Steak + Capybara) that requests a certain page where I get the error:
undefined method parse for Time:Class
The method call occurs in a Sunspot file called type.rb:
def value_to_utc_time(value)
if value.respond_to?(:utc)
value.utc
elsif value.respond_to?(:new_offset)
value.new_offset
else
begin
Time.parse(value.to_s).utc
rescue ArgumentError
DateTime.parse(value.to_s).new_offset
end
end
end
When I run my server in RAILS_ENV=test, I get the same error. When I run the server in development, everything is fine and dandy. This would seem to indicate that it's not just my test framework, but the whole test environment that's promoting this error.
The only info I could find online so far about Time.parse being undefined has been quite unhelpful, with most people saying that adding require 'time' will solve the problem.
My problems with this are twofold:
It's hacky
I've tried it in various places (in config/environments/test.rb, in the test file itself, etc.), and it just doesn't work.
If anyone has any ideas what is going on, I welcome them!
I figured it out! Someone had created another file called time.rb in the Rails app's test directory, so method calls on the Time class in the test environment were invoking that file rather than the actual Time class. I got the inspiration to check for this possibility from this Github issue thread

How can I see what capybara found in a failing cucumber step?

I started migrating from cucumber + webrat to cucumber + capybara. Now the behavior of "I should see " seems to be somewhat different. Most of these fail now, although I didn't change anything on the page. I replaced the snippet that should be found with some stuff that is on every page and for some text it works and for other text it doesn't. I can't find any pattern in what is found in the page's content and what is not.
Webrat used to print what the page content is that it found, in case it did not contain the required phrase. Is there anyway to have capybara show what text it got from the page in which it tried to find the text?
Then show me the page calls webrat/capybara's underlying save_and_open_page method. Found that useful when working with steak.
Try adding this step:
Then show me the page
If you want to have the browser open the page when the page fails you use the 'launchy' gem.
Add it to your gem file, and then in /features/support create a file called debugging.rb with contents:
After do |scenario|
save_and_open_page if scenario.failed?
end
If you're using Javascript or Ajax in your pages and want to see what's going on, I've found that the Poltergeist driver is very good at letting you get into the DOM and find out what's going wrong.
If you setup your Capybara driver with the remote debugging option:
Capybara.register_driver :poltergeist do |app|
Capybara::Poltergeist::Driver.new(app, inspector: true)
end
You can then put the following line in your steps:
page.driver.debug
Which fires up a new Chromium browser with the current DOM state set, letting you get at the console. (On my version of Linux, I had to symlink chromium to chromium-browser but it otherwise worked fine).
Source Info: http://jonathanleighton.com/articles/2012/poltergeist-0-6-0/
Then show me the response didn't work for me with cucumber 1.1. I found useful to write a step using capybara's command:
print page.html
This outputs the current state of the DOM
You could also use "Then show me the response" which outputs the HTML to the console if you don't want to use a browser.
You could always have it take a screen shot when something failed. I debug a LOT of failing features that way.

Resources