paint-brush
RSpec, Capybara, CircleCI And Chrome Headless Webdriver Configurationby@knapsackpro
3,804 reads
3,804 reads

RSpec, Capybara, CircleCI And Chrome Headless Webdriver Configuration

by Knapsack ProJanuary 15th, 2021
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

RSpec, Capybara, CircleCI And Chrome Headless Webdriver Configuration. I will show you how to configure Circle CI 2.0 and your Ruby on Rails project to use capybara/selenium/chrome headless together. Run 1 hour test suite in 2 minutes with optimal parallelisation on CI server. Run tests on your development machine with RSpec.rb feature 'Homepage Features' and run Chrome headless with Selenium Webdriver. Use RSpec and RSpec to run the test suite.
featured image - RSpec, Capybara, CircleCI And Chrome Headless Webdriver Configuration
Knapsack Pro HackerNoon profile picture

I’ve been using Capybara-WebKit for a long time but while switching from CircleCI 1.0 to CircleCI 2.0 I had some problems to use it on the CI.

This triggered to try Chrome Headless with Selenium Webdriver. I will show you how to configure Circle CI 2.0 and your Ruby on Rails project to use capybara/selenium/chrome headless together.

Add capybara and selenium-webdriver

Let’s add capybara and selenium-webdriver gems to 

Gemfile
:

# Gemfile
group :development, :test do
  gem 'capybara'
  gem 'selenium-webdriver'
end

and run 

bundle install
.

If you already had the gems in your 

Gemfile
 then ensure you have latest version with 
bundle update capybara selenium-webdriver
.

If you want to make sure Capybara feature specs will work on your development machine:

$ brew install chromedriver

If your feature specs fail then upgrade the driver because you may have installed old one.

$ brew upgrade chromedriver

Configure Capybara

Add config file for Capybara:

# spec/support/config/capybara.rb
JS_DRIVER = :selenium_chrome_headless

Capybara.default_driver = :rack_test
Capybara.javascript_driver = JS_DRIVER
Capybara.default_max_wait_time = 2

RSpec.configure do |config|
  config.before(:each) do |example|
    Capybara.current_driver = JS_DRIVER if example.metadata[:js]
    Capybara.current_driver = :selenium if example.metadata[:selenium]
    Capybara.current_driver = :selenium_chrome if example.metadata[:selenium_chrome]
  end

  config.after(:each) do
    Capybara.use_default_driver
  end
end

Ensure you load config files from 

spec/support
 directory:

# spec/rails_helper.rb

# The following line is provided for convenience purposes. It has the downside
# of increasing the boot-up time by auto-requiring all files in the support
# directory. Alternatively, in the individual `*_spec.rb` files, manually
# require only the support files necessary.
Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }

Example feature spec

We can create example feature spec to test if everything works:

# spec/features/home_spec.rb
feature 'Homepage Features' do
  before { visit root_path }

  # it won't run js code but it is fast
  it do
    expect(page).to have_content 'Hello World'
  end

  # it will run js code
  it '', :js do
    expect(page).to have_content 'Hello World'
  end

  # it will open Firefox
  # remove x from xit to run the test in Firefox on your machine to preview
  xit '', :selenium do
    expect(page).to have_content 'Hello World'
  end

  # it will open Chrome
  # remove x from xit to run the test in Chrome on your machine to preview
  xit '', :selenium_chrome do
    expect(page).to have_content 'Hello World'
  end
end

And run tests on your development machine with 

bin/rspec spec/features/home_spec.rb
 or 
bundle exec rspec spec/features/home_spec.rb
.

Configure CircleCI 2.0 to run Chrome headless

Here is example 

.circleci/config.yml
:

# .circleci/config.yml
version: 2
jobs:
  build:
    parallelism: 1
    working_directory: ~/project-name
    docker:
      # this is important to use proper image with browsers support
      - image: circleci/ruby:2.4.2-node-browsers
        environment:
          PGHOST: 127.0.0.1
          PGUSER: project-name
          RAILS_ENV: test
      - image: circleci/postgres:9.4.12-alpine
        environment:
          POSTGRES_DB: project-name_test
          POSTGRES_PASSWORD: ""
          POSTGRES_USER: project-name
      - image: redis:3.2.7
    steps:
      - checkout

      # Restore bundle cache
      - type: cache-restore
        # remove space between { {
        key: project-name-{ { checksum "Gemfile.lock" }}

      # Bundle install dependencies
      - run: bundle install --path vendor/bundle

      # Store bundle cache
      - type: cache-save
        # remove space between { {
        key: project-name-{ { checksum "Gemfile.lock" }}
        paths:
          - vendor/bundle

      # Prepare .env, useful if you use dotenv gem
      - run: cp .env.example .env

      # Database setup
      - run: bundle exec rake db:create
      - run: bundle exec rake db:schema:load

      # Run rspec in parallel
      - type: shell
        command: |
          bundle exec rspec --profile 10 \
                            --format RspecJunitFormatter \
                            --out /tmp/test-results/rspec.xml \
                            --format progress

      # Save artifacts
      - type: store_test_results
        path: /tmp/test-results

Speed up your tests with Circle CI parallelisation

If your feature specs are very long you can save some time by running multiple parallel CI nodes. For instance set it to 

6
 in
.circleci/config.yml
 and use dynamic RSpec specs allocation across CI nodes with 
knapsack_pro
 gem and Queue Mode to get optimal test suite split to save as much time as possible.

# .circleci/config.yml
jobs:
  build:
    parallelism: 6

  steps:
    # some tests that are not balanced and executed only on first CI node
    - run: case $CIRCLE_NODE_INDEX in 0) npm test ;; esac

    # auto-balancing CI build time execution to be flat and optimal (as fast as possible).
    # Queue Mode does dynamic tests allocation so the previous not balanced run command won't
    # create a bottleneck on the CI node
    - run:
      name: RSpec via knapsack_pro Queue Mode
      command: |
        # export word is important here!
        export RAILS_ENV=test
        bundle exec rake "knapsack_pro:queue:rspec[--format documentation]"

You can learn how RSpec test suite parallelisation works in 1 minute video.

Summary

Now you are good to push your code to a repository and see how your Capybara feature specs work with Chrome Headless on CircleCI 2.0.

Previously published at https://docs.knapsackpro.com/2017/circleci-2-0-capybara-feature-specs-selenium-webdriver-with-chrome-headless