Serhii Kaihorodov
Serhii Kaihorodov

Reputation: 91

Capybara + Rspec: How to set up multi browser TC running?

I am trying to set up environment to run my TC in different browsers. But currently TC are run normally just in Chrome browser, Firefox browser is opened but nothing happens (test scenarios are not run) when I am trying to run TC in FF, Opera, Safari browsers. How to adjust my settings to be able to run TC successfully in all browsers? Also is there a way to run TC in parallel? Here is my rails_helper.rb file:

require 'test/unit'
require 'selenium-webdriver'
require 'capybara'
require 'rspec'
require "rails/all"
require 'capybara/rspec'
require "page-object"
require 'rspec/expectations'
require 'securerandom'
require '../Test_helpers/login_helper'
require 'capybara-screenshot/rspec'
require 'launchy'

RSpec.configure do |config|

  config.include LoginHelper
  config.include RSpec::Matchers
  config.include Capybara::DSL

  environment = 'firefox'

  if environment =='chrome'
    Selenium::WebDriver::Chrome.driver_path = '../Resources/chromedriver.exe'
    Capybara.default_driver = :chrome
    Capybara.register_driver :selenium do |app|
      options = {
          :js_errors => false,
          :timeout => 360,
          :debug => false,
          :inspector => false,
      }
      Capybara::Selenium::Driver.new(app, :browser => :chrome)
    end
  elsif environment =='firefox'
    Capybara.default_driver = :firefox
    Capybara.register_driver :selenium do |app|
      options = {
          :js_errors => true,
          :timeout => 360,
          :debug => false,
          :inspector => false,
      }
      Capybara::Selenium::Driver.new(app, :browser => :firefox)
    end
  elsif environment == 'safari'
    Capybara.default_driver = :safari
    Capybara.register_driver :safari do |app|
      options = {
          :js_errors => false,
          :timeout => 360,
          :debug => false,
          :inspector => false,
      }
      Capybara::Selenium::Driver.new(app, :browser => :safari)
    end
  elsif environment == 'opera'
    Capybara.default_driver = :opera
    Capybara.register_driver :opera do |app|
      options = {
          :js_errors => false,
          :timeout => 360,
          :debug => false,
          :inspector => false,
      }
      Capybara::Selenium::Driver.new(app, :browser => :opera)
    end
  elsif
  Capybara.default_driver = :poltergeist
    Capybara.register_driver :poltergeist do |app|
      options = {
          :js_errors => false,
          :timeout => 360,
          :debug => false,
          :phantomjs_options => ['--load-images=no', '--disk-cache=false'],
          :inspector => false,
      }
      Capybara::Poltergeist::Driver.new(app, options)
    end
  end

  Capybara.save_path = "../Reports" # path where screenshots are saved

  config.after { |example_group| CapybaraScreenshot.save_and_open_page_path if example_group.exception }

  Capybara::Screenshot.register_filename_prefix_formatter(:rspec) do |example|
    "screenshot_#{example.description.gsub(' ', '-').gsub(/^.*\/spec\//, '')}"
  end

end

Capybara.default_max_wait_time = 15

Upvotes: 2

Views: 2740

Answers (2)

igorsantos07
igorsantos07

Reputation: 4686

If you happen to pass here looking for a way to run every test through many browsers, I wrote this (working!) (overly talkative) snippet based on Thomas Walpole's accepted answer:

Rspec.configure do |conf|

  Capybara.register_driver :chrome do |mode|
      Capybara::Selenium::Driver.new mode, :browser => :remote, :desired_capabilities => :chrome
    end

    Capybara.register_driver :firefox do |mode|
      Capybara::Selenium::Driver.new mode, :browser => :remote, :desired_capabilities => :firefox
  end

  ## Here we politely ask every example to run twice, for each browser we want
  conf.around do |example|
    puts '~> ' + example.metadata[:example_group][:full_description]
    # avoid looping over Capybara.drivers as it will also contain "selenium" generic driver and "rack_test" basic (js-less) browser
    [:chrome, :firefox].each do |browser|
      Capybara.current_driver = browser
      puts "~~> #{example.description} @ #{browser}"
      example.run
    end
  end

  Capybara.default_driver = :chrome
end

The output ends being something like:

~> The contact page
~~> loads @ chrome
~~> loads @ firefox
.

Finished in 20.9 seconds (files took 2.69 seconds to load)
1 example, 0 failures

Obviously all puts lines can be removed / commented out, they're there just for sample purposes :)

After each ~~> line the said browser opens and runs the example.
Care must be taken, however, to remove :js => true from your examples, or else Capybara will force-run them against the default javascript_driver instead.

Upvotes: 1

Thomas Walpole
Thomas Walpole

Reputation: 49880

The options you're passing to the drivers you're registering are only valid for poltergeist. Rather than the big if/else you can just register all the drivers and then use the one you need.

RSpec.configure do |config|

  config.include LoginHelper # You probably want to only include this for feature tests
  config.include RSpec::Matchers # not needed if you use the standard capybara rspec setup by including capybara/rspec
  config.include Capybara::DSL # not needed if you use the standard capybara rspec setup by including capybara/rspec

  end

  Capybara.save_path = "../Reports" # path where screenshots are saved

  config.after { |example_group| CapybaraScreenshot.save_and_open_page_path if example_group.exception }

  Capybara::Screenshot.register_filename_prefix_formatter(:rspec) do |example|
    "screenshot_#{example.description.gsub(' ', '-').gsub(/^.*\/spec\//, '')}"
  end

end

    Selenium::WebDriver::Chrome.driver_path = '../Resources/chromedriver.exe'
    Capybara.register_driver :selenium_chrome do |app|
      Capybara::Selenium::Driver.new(app, :browser => :chrome)
    end

    Capybara.register_driver :selenium_firefox do |app|
      Capybara::Selenium::Driver.new(app, :browser => :firefox)
    end

    Capybara.register_driver :selenium_safari do |app|
      Capybara::Selenium::Driver.new(app, :browser => :safari)
    end

    Capybara.register_driver :selenium_opera do |app|
      Capybara::Selenium::Driver.new(app, :browser => :opera)
    end

    Capybara.register_driver :poltergeist do |app|
      options = {
          :js_errors => false,
          :timeout => 360,
          :debug => false,
          :phantomjs_options => ['--load-images=no', '--disk-cache=false'],
          :inspector => false,
      }
      Capybara::Poltergeist::Driver.new(app, options)
    end

Then set either Capybara.default_driver and/or Capybara.javascript_driver (depending on whether or not you run some tests with rack_test and tag tests that need JS) to the driver you want to use to run your tests.

Capybara.default_driver = :selenium_chrome

To run all your tests against multiple browsers it's normal to configure your CI system to run multiple times and just set a different driver (based on an environment variable for instance) for each run. If you need to run them all in one run you could make your RSpec tests all shared examples and then configure test blocks that include the shared examples but each set a different driver in a before block.

For parallel testing you can look at the parallel_tests gems - https://github.com/grosser/parallel_tests

Upvotes: 0

Related Questions