selenium rspec features not running on linux - ruby-on-rails

I'm a rails dev working on a rails 4.0.4 app. As of yesterday (possibly before, yesterday was the first I noticed it, because I usually use CI), my archlinux dev machine doesn't run rspec features marked with js: true metadata tags, it just returns passes for all of them. e.g.:
$ be rspec spec/features/activity_spec.rb
..........
Finished in 0.38366 seconds
10 examples, 0 failures
There are no such problems for any other specs so far as I can tell, just those that use selenium. It does not spawn a browser (we use firefox, though I tried chrome with chromedriver). It seems to not even call the Procs created in spec_helper, as raising an exception doesn't happen:
Capybara.server do |app, port|
raise "Hell"
require 'rack/handler/thin'
Rack::Handler::Thin.run(app, :Port => port)
end
# use BROWSER=safari,chrome,etc
browser = (ENV["BROWSER"] || "firefox").to_sym
Capybara.register_driver :selenium do |app|
raise "Hell"
Capybara::Selenium::Driver.new(app, browser: browser)
end
Updating to the most recent capybara/selenium-webdriver/rspec does not change anything, nor does checking out old tags from my repo, which used previous versions of gems/ruby.
The rest of my team (all running OSX) have no problems with the exact same branch/set of gems/ruby version (these same specs ran previously on 2.1.1 and 1.9.3 on the same machine).
All of this screams "OS specific problem" at me. Any suggestions on what to try (other than switching to OSX - have had enough of that from my colleagues) would be appreciated. Cheers.

This was due to setting RETRIES=0 when using rspec-retry. Oops.

Related

Firefox is default but still get WebDriverError: unable to connect to chromedriver 127.0.0.1:9515

I'm setting up Capybara for the first time and it seems to be calling Chrome instead of Firefox by default.
At first I was getting the webdriver error:
Selenium::WebDriver::Error::WebDriverError:
unable to connect to chromedriver 127.0.0.1:9515*
with associated stacktrace
https://pastebin.com/TW5NWJgu
I was able to clear this by adding a gem 'chromedriver-helper' and the test now opens with chromium.
I also tried adding this to both spec_helper and rails_helper:
Capybara.register_driver :selenium do |app|
Capybara::Selenium::Driver.new(app, browser: :firefox)
end
I was able to confirm that rails was able to successfully call firefox because the following command in rails_helper does successfully launch Firefox (but does not take any further action) when I start the test (as per comments, I later removed this command).
RSpec.configure do |config|
driver = Selenium::WebDriver.for :firefox
end
I'm getting the same error on a separate machine and on a different rails app (also didn't have geckodriver set-up on the first pass of Capybara)
My understanding is that Capybara should call Firefox by default. There seems to be a second configuration somewhere that I can't find. Does anyone have an idea of where I might find the line that is calling chrome?
From the log file you provided we can see that you're using Rails 5.1, RSpec 3.8 and Capybara 2.18. Since the log also includes "actionpack-5.1.6/lib/action_dispatch/system_testing/driver.rb" we can tell that you're writing system tests/specs (through rspec-rails). The driver used by system tests is controlled by the driven_by method as documented in the RSpec system spec docs and by default uses the Rails registered :selenium driver which is configured to use Chrome. As documented in the Rails System Test docs you can switch to Firefox by specifying
driven_by :selenium, using: :firefox
Additionally, Capybara 2.18 is pretty much obsolete at this point. You probably want to update to the latest version (3.6 as of now) if you plan on using the latest versions of Firefox/Chrome.

How can I run headless browser system tests in Rails 5.1?

The documentation for Rails 5.1 system tests is a bit sparse. I'm unable to get headless tests that execute javascript running. I think one approach entails installing and running xvf. But this is more manual setup than I'm used to when running capybara in other versions of rails.
What's the most straightforward way to achieve this?
In Rails 5.1 system tests the driver used is set by the driven_by call in ApplicationSystemTestCase (test/application_system_test_case.rb). Assuming you have registered your capybara-webkit driver as 'webkit' you should be able to do
driven_by :webkit
Another potential option if you use Chrome 59+ on linux/mac is to use headless chrome
Capybara.register_driver :headless_chrome do |app|
Capybara::Selenium::Driver.new(app, :browser => :chrome, :args => ['headless'])
end
and then in your test case class
driven_by :headless_chrome
That gives you a headless version of chrome so none of the issues of capybara-webkit/poltergeist not supporting current web standards. Unfortunately currently chromedriver has issues with JS system modals (alert, confirm, prompt - workaround in capybara master branch) and hangs if you attempt to close windows during your tests. Hopefully those 2 issues will be fixed soon.
Also note that rails 5.1 should have removed the need for database_cleaner for most peoples testing since it already handles sharing of a single database connection between multiple threads in test mode.

Capybara specs failing on different servers

I've recently moved mi CI server (Teamcity) to another powerful machine with same configuration and pretty similar OS.
Since then some of my integration specs have started to fail. My setup is pretty standard, Rails 3 + capybara + poltergeist + phantomjs.
Failures are deterministic, they always happen and they are always related to some missing nodes in the DOM. Also, failures happens across different projects with similar setup so it's not something related to project configuration. This is happening with both capybara 1.x and capybara 2.
This is the simplest failing spec. Note that this spec runs with no need of javascript, so the issue is also present in rack only specs.
scenario 'require an unsubscription' do
visit unsubscribe_index_path
within main_content do
choose list.description
fill_in 'Email', :with => subscriber.email
click_button 'Unsubscribe'
end
save_page # <--- Added to debug output
# !!! HERE is the first failing assertion
page.should have_content('You should have received a confirmation message')
# Analytics event recorded
# !!! this also is failing
page.should have_event('Unsubscription', 'Sent', list_name)
# If I comment previous two lines the spec passes on CI machine
# this means that the form is submitted with success since email is triggered
# from controller code
last_email_sent.should have_subject 'Unsubscribe request received'
last_email_sent.should deliver_to subscriber.email
end
What I've tried:
run the specs on different machines, they works on every dev machine and also in a staging server. I can only reproduce the failure on the CI machine even outside of CI environment (i.e. by running the specs via command line)
Increased Capybara.default_wait_time to a ridiculous 20
Tried with a brutal sleep before the page.should have_content line
upgrade RVM, ruby, capybara, poltergeist on their latest versions on the CI machine.
upgrade teamcity to its latest version
The strangest thing I found is when I've added a save_page call just before the failing line. If i run the spec on my machine and then on the CI where the server is failing and comparing those two files the result is this:
$ diff capybara-201309071*.html
26a27,29
> <script type='text/javascript'>
> _gaq.push(["_trackEvent","Unsubscription","Sent","listname"]);
> </script>
90a94,96
> <div class="alert-message message notice">
> <p>You should have received a confirmation message</p>
> </div>
Which are the two missing pieces which make the spec failing, so the form is submitted, controller action is run successfully but there are two missing pieces of dom. How that is possible? And why this is happening only on one machine?
For the records, those two pieces of DOM are added with standard rails tools one with
redirect_to unsubscribe_index_path, notice: ...
and the other with the analytical gem
I've found the issue, the two failing projects I'm using dalli_store as session store and I've put the config.cache_store = :dalli_store line in config/application.rb instead of config/environments/production.rb.
On the old CI server there was a memcached daemon running hence all specs was running fine.
In the new server since it's just a CI server and it doesn't run any production or staging code memcached is not present thus any session write (such as flash messages) was silently discarded and this is the reason why all that kind of specs was failing.
I solved by putting the config.cache line in the appropriate environment file, but I'm still wondering why dalli gem doesn't raise any warning when no memcached is available. While the choice of not failing on missing cache daemon is reasonable since the application should work with no cached data, it could be a performance killer in production code and it might go unnoticed if no warning is given.

how can I run tests using different capybara drivers on different platforms in rails?

I have a project that we've been developing thus far entirely on PCs and then deploying on linux. We've developed our tests using capybara and capybara-webkit for javascript.
Turns out, as we try to run things on the mac with mountain lion, that capybara-webkit is broken (I get all kinds of pipe errors, 246 failures out of 1606 tests, 46 when switching to webkit_debug). Judging from their web page and the number of times that error is reported, these kinds of failures just happen. So, I'd like to run our rails tests on windows via capybara and capybara-webkit, but use something like selenium or some other comparable test driver (ie, so that the spec files and locations don't have to change). How can I do this? I'm familiar with C defines, would something like that in the gem files and spec_helper.rb files be sufficient?
Couldn't you do something along the lines of
if RUBY_PLATFORM =~ /mac/
Capybara.javascript_driver = :firefox
else
Capybara.javascript_driver = :webkit
end
in spec/support/env.rb?
I don't have a mac, so I'm not sure what the value of RUBY_PLATFORM should be, but by running puts RUBY_PLATFORM in irb, I'm sure you can figure out an appropriate value.

Is it possible to run capybara-webkit (i.e. forked webkit_server) on Heroku Cedar?

I need to run capybara-webkit inside a Rails application to enable headless web browsing with JavaScript support (i.e. not for testing/CI purposes, and webrat or other acceptance testing drivers/frameworks will not work). I'm wondering if this is possible on a Heroku deployment, specifically because it requires QtWebKit and the ability to fork the webkit_server process with socket communication. I'm open to creative ideas on how to make this work on Heroku (e.g. a pool of worker dynos). I'm hoping someone has a better handle on what constraints exist in the Heroku environment, or can categorically rule out the possibility so I can move on to AWS EC2 if necessary.
Searching for this tends to turn up a lot about capybara testing and add-ons for CI servers, neither of which are relevant for my use case. I'm not testing anything (at least not in the traditional cucumber/rspec/etc sense) - I'm using Capybara's integration with the webkit driver, finders and node/element model to navigate a website that requires a significant amount of client-side JS in order to work.
I'm also open to other (native Ruby) solutions for programmatically interacting with web sites using JavaScript-enabled DOM.
I spoke to Heroku support about this and their answer was that this is basically a) unsupported; b) very difficult, including (among other things) a statically built version of QtWebKit.
My own investigation into this on Amazon EC2 also made me realize that QtWebKit requires a running instance of Xvfb. I highly doubt this would be available on Heroku, and I suspect it would be extremely difficult to make it work.
My own approach has been to put this functionality on an EC2 instance. After making some attempts with Amazon's standard AMIs (their build and RHEL), I found that the packages available through Ubuntu's package management systems made it MUCH easier to get up an running.
Long story short: Heroku is a non-starter, Amazon EC2 with Ubuntu is the best way to go.
I was able to successfully run Capybara + Poltergeist + PhantomJS on Heroku
I've placed compiled phantomjs binaries for OSX (for my development machine) and linux-64 (for Heroku) in bin/ folder of my Rails application.
initializers/capybara.rb
require 'capybara/poltergeist'
Capybara.register_driver :poltergeist do |app|
phantomjs_path = if RUBY_PLATFORM['x86_64-darwin']
Rails.root.join('bin', 'phantomjs-osx').to_s
elsif RUBY_PLATFORM['x86_64-linux']
Rails.root.join('bin', 'phantomjs-linux-64').to_s
else
raise "Can't load PhantomJS for OS: #{RUBY_PLATFORM}"
end
options = {
phantomjs: phantomjs_path,
phantomjs_logger: Logger.new('/dev/null'),
phantomjs_options: %w[--load-images=no --ignore-ssl-errors=yes],
js_errors: false,
timeout: 90
}
Capybara::Poltergeist::Driver.new(app, options)
end
Capybara.default_driver = :poltergeist
Capybara.javascript_driver = :poltergeist
Capybara.default_wait_time = 1
Example code:
session ||= Capybara::Session.new(:poltergeist)
session.visit('http://google.com')
Good luck!
You may be able to accomplish what you want using PhantomJS.
This project has a JavaScript, rather than Ruby API, although the browser instance can expose a web-server, allowing you to communicate with it from Ruby over HTTP.
http://code.google.com/p/phantomjs/wiki/Interface

Resources