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

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

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.

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

Related

Headless recording black screen

I am trying to record my tests which I would like to debug as we are running them on a server hosted on aws. I am using headless as there is no display connected.
When I run the test it only records a black screen.
Ubuntu - 22.04
require 'rspec'
require 'selenium-webdriver'
describe 'Home' do
before :all do
system('seed')
#headless = Headless.new(:video => { :frame_rate => 12, :codec => 'libx264', :provider => 'libav', :display => 99})
# #headless = Headless.new
#headless.start
#headless.video.start_capture
options = Selenium::WebDriver::Chrome::Options.new
options.add_argument('--headless')
options.add_argument('--disable-gpu')
options.add_argument('--no-sandbox')
#driver = HomeHelper.new Selenium::WebDriver.for :chrome, options:options
end
after :all do
#driver.quit
#headless.video.stop_and_save("test1.mov")
#headless.destroy
end

Headless mode in cucumber capybara ruby automation

I have seeing a lot of similar question, but non of them have help me to understand.
how to run my .feature file in headless mode using chromedrive, selenium, capybara, ruby and cucumber.
this is my env.rb:
require_relative 'helper.rb'
BROWSER = ENV['BROWSER']
World(Helper)
Capybara.register_driver :selenium do |app|
if BROWSER.eql?('chrome_headless')
Capybara::Selenium::Driver.new(app,
:browser => :chrome,
:desired_capabilities => Selenium::WebDriver::Remote::Capabilities.chrome(
'chromeOptions' => {
'args' => [ "headless", "window-size=1440x768", "disable-gpu"]
}
)
)
elsif BROWSER.eql?('chrome')
Capybara::Selenium::Driver.new(app,browser: :chrome)
end
end
Capybara.configure do |config|
config.default_driver =:selenium
Capybara.page.driver.browser.manage.window.resize_to(1440,768)
end
Capybara.default_max_wait_time = 60
this is my helper.rb:
module Helper
def take picture(file_name, res)
file_path = "reports/screenshot/"
dateTime = DateTime.now.to_s
dateTime.split(':')
date = dataHora[0..12].to_s+dataHora[14..15].to_s+dataHora[17..21].to_s
picture = "#{file_path}#{date}#{nome_arquivo}-#{res}.png"
temp_shot = page.save_screenshot(picture)
shot = Base64.encode64(File.open(temp_shot, "rb").read)
attach(shot, 'image/png')
end
end
this is my step_definition file .rb
just a normal rb file containing capybara elements
adm = LoginAdmin.new
admInic = TelaInicialAdmin.new
varGlobal = YAML.load(File.read('./configuracoesGlobaisTeste.yaml'))
#nomeOferta = varGlobal["nomeOferta"]
#nomeProduto = varGlobal["nomeProduto"]
Dado('que acessei a página da Vivo') do
acesso.load
end
Quando('clicar em Entrar posso digitar minhas credenciais ') do
page.driver.browser.navigate.refresh
sleep 3
inicio.btnEntrar.click
inicio.usuario.set #usuario
inicio.senha.set #senha
inicio.btnAcessarConta.click
end
is there missing something?
this is how i run the automation on terminal using the tag in my feature file:
cucumber -t#criarClienteCompraLojaClone
this command opens a browser using a GUI. i wish not open GUI. I wish to perform a headless test.
i have just try every tutorial in stackoverflow and google.
Please any suggestion will help!
My headless works updating the env.rb file for this:
require_relative 'helper.rb'
BROWSER = ENV['BROWSER']
#HEADLESS
World(Helper)
Capybara.register_driver :headless_chrome do |app|
Capybara::Selenium::Driver.new(app, browser: :chrome,
options: Selenium::WebDriver::Chrome::Options.new(args: %w[headless no-sandbox disable-gpu]))
end
Capybara.configure do |config|
config.default_driver =:headless_chrome
#Capybara.page.driver.browser.manage.window.resize_to(1440,768)
end
Capybara.default_max_wait_time = 60

Need sample code to load extension on Chrome browser after launching it through selenium

I am trying to launch Chrome browser using Selenium with extension added to it. But i am getting below error.
Error - Could not load extension from ''. Manifest file is missing or unreadable.
My Code:
when "CHROME"
chrome_extensions = []
begin
File.open('/Users/chinmayajb/Downloads/MPM_testing/packages/extension_1_2_4.crx', "rb") do |file|
chrome_extensions << Base64.encode64(file.read.chomp)
puts 'Encoded....'
end
rescue Exception => e
raise "ERROR: Couldn't File.read or Base64.encode64 a Chrome extension: #{e.message}"
end
caps_opts = {'chrome.switches' => chrome_extensions}
chrome_switches = %w[--enable-logging --v=1 --disable-popup-blocking --disable-extensions-file-access-check --always-authorize-plugins --disable-improved-download-protection --allow-file-access --load-extension='caps_opts']
Capybara.register_driver :selenium_chrome do |app|
# Capybara::Selenium::Driver.new(app, :browser => :chrome, :desired_capabilities => capabilities)
Capybara::Selenium::Driver.new(app, :browser => :chrome, :switches => chrome_switches)
# Capybara::Selenium::Driver.new(app, :browser => :chrome, :switches => ["--allow-legacy-extension-manifests--load-extension=/Users/chinmayajb/Downloads/MPM_testing/packages/extension_1_2_4.crx"])
end
Capybara.default_driver = :selenium_chrome
end

How to stabilize IE windows in capybara/ruby environment

Tests that I run well in Chrome and Firefox appear flaky or blinky in IE9. I understand a java based fix for this is setting a capability
caps.setCapability("requireWindowFocus", true);
I interpreted a rough ruby attempt in the env.rb...
Capybara.default_driver = :selenium
Capybara.register_driver :selenium do |app|
case get_browser
when 'ie'
caps = Selenium::WebDriver::Remote::Capabilities.internet_explorer
caps.setCapability("requireWindowFocus", true)
Capybara::Selenium::Driver.new(app, :browser => :internet_explorer, :desired_capabilities => caps)
else
Capybara::Selenium::Driver.new(app, :browser => :chrome)
end
end
and caught the following nomethod error
NoMethodError: undefined method `setCapability' for #<Selenium::WebDriver::Remote::Capabilities:0x3e9b218>
A ruby fix for this will be greatly appreciated.
Based on the Ruby bindings page, the capabilities are set like:
caps = Selenium::WebDriver::Remote::Capabilities.internet_explorer
caps["requireWindowFocus"] = true
Capybara::Selenium::Driver.new(app, :browser => :internet_explorer, :desired_capabilities => caps)

Getting Cucumber/Capybara to close and open another browser after scenarios

Say I have 3 Scenario Outlines and I need to run scenario 1 with Firefox, close the browser, then run scenario 2 with Chrome, close the browser, then finally run scenario 3 with Firefox.
Is there any way to close/quit the browser in Cucumber/Capybara after each scenario?
So far I have registered two drivers, one for Firefox and one for Chrome:
Capybara.register_driver :selenium_firefox do |app|
Capybara::Driver::Selenium.new(app, :browser => :firefox)
end
Capybara.register_driver :selenium_chrome do |app|
Capybara::Driver::Selenium.new(app, :browser => :chrome)
end
Then in hooks.rb, I'm using a 'custom' tag "#alternate_browser"
Before('#alternate_browser') do
driver = Capybara.current_driver
if driver == :selenium_firefox
Capybara.current_driver = :selenium_chrome
else
Capybara.current_driver = :selenium_firefox
end
end
Is there a way to force the browser to close after each scenario?
EDIT: I tried:
page.evaluate_script("window.close()")
page.execute_script("window.close()")
But both statements had no effect.
This is what you should do.
Stop closing the windows.
Change to explicit browser tags (#firefox,#chrome)
I haven't tried it but this should work.
Capybara.register_driver :selenium_firefox do |app|
Capybara::Driver::Selenium.new(app, :browser => :firefox)
end
Capybara.register_driver :selenium_chrome do |app|
Capybara::Driver::Selenium.new(app, :browser => :chrome)
end
Before('#firefox') do
Capybara.current_driver = :selenium_firefox
end
Before('#chrome') do
Capybara.current_driver = :selenium_chrome
end

Resources