I’ve been playing around with React lately.
I built a Rails API backed app as a learning exercise, the app is a Todo List, but not the usual TodoMVC. Think multiple users with multiple lists of items. I felt that would be enough exposure into the React way of doing things.
Well, actually since I like to torture myself when learning new things, I started out doing this in Relay, including building the GraphQL server using graphql-ruby.
Next stop was doing it in Vanilla React, which felt horribly painful after all the magick that Relay brings to the table.
After that came doing it again with Redux, I figured it made sense to expose myself to more than one way of doing things in React.
Once I got it all running halfway decently I wanted to try and get RSpec integration tests up and running. After much searching and finding random tidbits that worked here and there, once I got a working setup I figured I’d document it. This setup will save a screenshot on failure and open it in the appropriate app (I’ve only tested this bit on macOS).
You will need to install chromedriver, you can get it here or install it via homebrew.
Here are the relevant files for a working (as of 2018-02-26) RSpec/React integration test setup.
Gemfile
...
group :test do
gem 'capybara', '~> 2.4.4'
gem 'capybara-screenshot', '~> 1.0.11'
gem 'database_cleaner'
gem 'rspec-rails'
gem 'selenium-webdriver'
end
Procfile-react-test
web: cd clients/react && yarn start
api: RAILS_ENV=test bundle exec rails s -p 3001
spec/rails_helper.rb (add this bit after require 'rspec/rails'
)
Dir['spec/support/**/*.rb'].each do |file|
require Rails.root.join(file).to_s
end
spec/support/capybara.rb
require 'capybara/rspec'
require 'capybara/rails'
require 'capybara-screenshot/rspec'
Capybara.app_host = "http://localhost:3000"
Capybara.default_wait_time = 5
Capybara::Screenshot.webkit_options = {
width: 1024,
height: 768
}
Capybara::Screenshot.autosave_on_failure = false
Capybara::Screenshot.prune_strategy = :keep_last_run
RSpec.configure do |config|
config.after do |example|
if example.metadata[:type] == :feature and example.metadata[:js] and example.exception.present?
Capybara::Screenshot.screenshot_and_open_image
end
end
end
spec/support/capybara_drivers/selenium.rb (I have multiple files as I was testing different drivers, that’s also the reason for catching LoadError)
begin
require 'selenium/webdriver'
require 'capybara/rspec'
Capybara.register_driver :selenium do |app|
options = Selenium::WebDriver::Chrome::Options.new(
args: %w[headless disable-gpu no-sandbox]
)
Capybara::Selenium::Driver.new(app, browser: :chrome, options: options)
end
Capybara.javascript_driver = :selenium
rescue LoadError
end
spec/features/signups_spec.rb
require 'rails_helper'
RSpec.feature "Signups", type: :feature, js: true do
scenario "Visitor signs up for a new account" do
visit("/signup")
fill_in "name", with: "Bob"
fill_in "email", with: "bob@example.com"
fill_in "password", with: "password"
click_button "Create Account"
expect(page).to have_text("Logout Bob")
end
end
To run the tests you need to start the server and client.
foreman start -p 3000 -f Procfile-react-test
And run your feature specs
% bundle exec rspec spec/features
.
Finished in 4.98 seconds (files took 9.46 seconds to load)
1 example, 0 failures
And there you have it, those are the changes you need to get this working.