Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
WIP: Capybara Integration with Rails (AKA System Tests) #26703
Update: This PR changed a lot over the course of being open. Please refer to the documentation or code in master / 5-1-stable to use system tests
I'm really excited to open this initial PR for bringing system/acceptance test support to Rails through Capybara.
The goal of this PR is for Rails to take on all the setup that is needed in applications to allow Capybara and make system testing default in Rails applications.
The test framework has been moved it it's own gem under the Rails name and is now ActionSystemTest
How do I add System tests to my application?
Capybara's selenium driver requires some setup by the programmer, so I've added a layer between Capybara and Rails so that Rails' takes on that work called
The reason I have chosen Chrome as the default browser is because Firefox doesn't work out of the box. Selenium and the current version of Firefox don't play nicely together so I've set up the driver to default to Chrome, but it can easily be switched to using Firefox. I'd also like to provide support for Safari.
Instead of requiring the programmer to set up the port, browser, server, etc Rails handles that setup and frees up the programmer to work on writing their tests.
The Rails drivers allow the default configuration to be changed by initializing a new driver:
# config/environments/test.rb config.system_testing.driver = SystemTesting::DriverAdapters::RailsSeleniumDriver.new( browser: :firefox )
What if I don't want to use Selenium?
# config/environments/test.rb config.system_testing.driver = :poltergeist
Each of the Capybara default drivers that requires a server defaults to Puma. Any of the settings can be changed by initializing a new
# config/environments/test.rb config.system_testing.driver = SystemTesting::DriverAdapters::CapybaraDriver.new( name: :poltergeist, server: :webrick )
What if I'm making a new application and don't want system testing at all?
What if I already use Capybara and don't want to use Rails?
I want to try it out!
Cool! What's next?
Below is a list of what is done and what's left to do. Once we sort out naming and other issues I'll finish up the items below.
The selenium driver is one that Rails can take on all of the setup without any extra requirements from the programmer.
If there's a compelling reason to change the default it's as simple as swapping out the pre-set default and ensuring that Rails takes on the setup for that.
@pixeltrix Since this PR doesn't change how Capybara works, but rather provides a layer between Capybara and Rails.Currently, no, the request object isn't defined, but
Looks sweet! Especially looking forward to the
DatabaseCleaner work around
It feels to me that this should be a new gem. It have its own namespace, its own railtie it can be skipped and I don't think we should add capybara as dependency of actionpack. I'd create a new gem, inside the rails repository and add it as dependency of Rails.
This is ready for review from @dhh. I've finished all the above work: added guides, got tests in Railties passing, rebased, cleaned up some commits, and moved everything to a new gem called ActionSystemTest.
This file is where anyone writing system tests would add additional Capybara configuration if desired, and where the setup/teardown requirements live. Specifically out of the box tests handle resetting Capybara sessions, taking screenshots of failed tests, and setting the ActiveJob queue adapter to async.
One note: I did not add DatabaseCleaner type code to Active Record. After discussing this with Aaron we found that Active Record was behaving incorrectly and not closing connections after opening them.
Fixing that makes DatabaseCleaner unnecessary because then Active Record would know how to rollback. I'm still working on finishing those changes up because there are some failures in AR, but I don't consider this a blocker for merging system tests because 1) this doesn't affect models that use fixtures and 2) database cleaner still works
Pinging @twalpole, the maintainer of Capybara, for his input on this as well.
I've had a look through this PR, and I have some comments:
I think it's not optimal to add a layer around Capybara drivers like this is doing. I understand that there is some desire from Rails' perspective to take ownership of the experience here, but this has a significant downside that we should be aware of: it requires every Capybara driver to also have a Rails-Capybara driver. It also just seems plain unnecessary to me, since Capybara already has a system for registering and managing drivers. If the desire is to make this look more Rails-native then simply building a thin shim around this system would be preferable, I think.
For example, supposing that Rails wants to change some defaults for the selenium driver, then Rails could just to something like this:
Capybara.register_driver :rails_selenium do |app| Capybara::Selenium::Driver.new(app, browser: :chrome) end Capybara.default_driver = :rails_selenium
And Rails could build a shim around
module ActionSystemTest def self.current_driver Capybara.current_driver end def self.current_driver=(name) Capybara.current_driver = name end end
I think that maybe the purpose of this configuration is to be able to switch to something other than Capybara for these tests, but if that is the case, I'd like you to consider the following two issues: 1) Actually building an alternative driver would be a huge undertaking 2) This is precisely what Capybara already does and was in fact exactly what Capybara was created for, abstracting away the differences between multiple drivers transparently.
I think it'd be best to avoid adding a "Rails-dialect" of Capybara, where some methods come from Capybara, some from Rails, etc... This would make it much more difficult for users to discover where methods are coming from, and create confusion for people switching between ActionSystemTest and plain Capybara projects.
Also, since my post was a bit critical I want to say thank you to @eileencodes for pushing forward on this and doing so much work to make this happen. Making it easier and more discoverable for Rails users to use Capybara/system/integration tests is really great.
Thanks for the feedback Jonas. I appreciate hearing your input and will need to look closer to determine if I'm going to change anything. Some of your comments seem like perhaps my documentation isn't clear (for one capybara drivers need not be aware of the Rails side of things). I'm away the next two weeks and am not sure when I'll get to look closely at your comments.…
On Jan 2, 2017, at 6:31 AM, Jonas Nicklas ***@***.***> wrote: Also, since my post was a bit critical I want to say thank you to @eileencodes for pushing forward on this and doing so much work to make this happen. Making it easier and more discoverable for Rails users to use Capybara/system/integration tests is really great. — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.