Changing default drivers using Capybara per scenario - ruby

I have written a small block that will launch Google Chrome when I set a tag #chrome above a scenario within a feature file.
Before ('#chrome') do
Capybara.default_driver = :selenium
Capybara.register_driver :selenium do |app|
Capybara::Selenium::Driver.new(app,
:browser => :chrome,
desired_capabilities: {
'chromeOptions' => {
'args' => %w{ window-size=1920,1080 }
}
}
)
end
end
The problem I have is that all subsequent scenarios within the feature file will also run in Chrome, even when the tag isn't set for them.
Is there a way to add to it to say revert back to Poltergeist once I'm done. I've tried the following but it didn't work:
After do |scenario|
if #chrome == true
Capybara.register_driver = :poltergeist
Capybara::Poltergeist::Driver.new(
app,
phantomjs_options: ['--ignore-ssl-errors=yes', '--ssl-protocol=TLSv1'],
window_size: [1280, 1024],
js_errors: false,
debug: false
)
end
end
Thanks in advance for any help you might have

Capybara already provides this behavior here . To use it you just need to require it and register a driver with the tag name you want to use. This would usually be in your env.rb/custom_env.rb
require 'capybara/cucumber'
Capybara.register_driver :chrome do |app|
Capybara::Selenium::Driver.new(app,
browser: :chrome,
...
)
end
The important thing is the name you use to register the driver has to match the tag used (in this case #chrome). It also shows you shouldn't be changing Capybara.default_driver on a test by test basis, that's what Capybara.current_driver is for. You also shouldn't be registering a new driver every scenario, register_driver is meant to be called once for each driver configuration you will need and then referenced by name later.

Related

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

Browser is launching for headless chrome capybara with Selenium webdriver

I'm trying to launch chrome in headless but the browser keeps on launching. Tried several different ways
used chrome options and added arguments
used chrome capabilities as well
My chrome version: 86
OS - ubuntu
capybara - 3.32.2
First Helper file:
spec_helper.rb
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.default_driver = :headless_chrome
Capybara.javascript_driver = :headless_chrome
Second try of Helper file:
Capybara.register_driver :headless_chrome do |app|
Capybara::Selenium::Driver.new(
app,
browser: :chrome,
desired_capabilities:Selenium::WebDriver::Remote::Capabilities.chrome(
chromeOptions: {
args: %w[headless disable-gpu disable-popup-blocking no-sandbox]
}
)
)
end
Capybara.default_driver = :headless_chrome
Capybara.javascript_driver = :headless_chrome
Thanks in advance
Simplest way is to not register your own driver and just use the one provided by Capybara
Capybara.default_driver = :selenium_chrome_headless
Capybara.javascript_driver = :selenium_chrome_headless
Note - this will only work if you're not using rails system tests (no indication in your question that you're using rails though) since they override these settings - see the rails/rspec system test docs (driven_by) for that.
Resolved this by adding chromeOptions separately and had to remove -- from all arguments
Apparently, for Selenium >= 3.8, you have to specify goog:chromeOptions instead of chromeOptions.
So in your example:
...
Selenium::WebDriver::Remote::Capabilities.chrome(
"goog:chromeOptions": {
args: %w[headless disable-gpu disable-popup-blocking no-sandbox]
}
)
)
I was experiencing the same issue and this solved it for me.

How to create chrome profile via Ruby Selenium Binding(or WATIR)

I know how to create profile for Firefox
require 'watir'
options = Selenium::WebDriver::Firefox::Options.new
options.profile = "default"
#driver = Selenium::WebDriver.for :firefox, options: options
#b = Watir::Browser.new #driver
But when I do same thing for Chrome it's not creating, Infact I realized that options(please look above) object doesn't even have the method profile= so I try adding profile like as given below(I saw how people are creating in Java Selenium Binding so I have done the same but it's not working here)
options = Selenium::WebDriver::Firefox::Options.new
options.add_argument('user-data-dir=C:\Users\user_name\AppData\Local\Google\Chrome\User Data\Default')
#driver = Selenium::WebDriver.for :chrome, options: options
Can someone help me how to create Chrome Profile via Ruby Selenium binding(or WATIR)?
Using an existing or creating a new profile can be done via Chromedrivers user-data-dir argument. In Watir, you can pass the argument via the :args parameter:
browser = Watir::Browser.new :chrome,
args: ['user-data-dir=C:\Users\user_name\AppData\Local\Google\Chrome\User Data']
Note that if you trying to use the existing default profile, you do not want to include the "Default" directory in the path.
I made a function for creating new browser. You can use it.
def new_browser
if Rails.env.production?
chrome_bin = ENV.fetch('GOOGLE_CHROME_SHIM', nil)
Selenium::WebDriver::Chrome.path = "/app/.apt/usr/bin/google-chrome"
Selenium::WebDriver::Chrome.driver_path = "/app/vendor/bundle/bin/chromedriver"
end
profile = Selenium::WebDriver::Chrome::Profile.new
profile['general.useragent.override'] = 'Mozilla/5.0(iPad; U; CPU iPhone OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B314 Safari/531.21.10'
driver = Selenium::WebDriver.for :chrome, :profile => profile
pid = driver.instance_variable_get(:#service).instance_variable_get(:#process).instance_variable_get(:#pid)
begin
browser = Watir::Browser.new driver
rescue => e
system("kill -9 #{#pid}")
end
return {:browser => browser , :pid => pid}
end
Since you asked in the comments for a more detailed explanation for Capybara, I post it as an answer (although you seem to already have a working solution now - sorry for the delayed answer).
In my rails projects I usually configure the Selenium chrome driver as follows:
gem 'chromedriver-helper'
in the Gemfile (or install it locally). Then in a system-test initializer define
Capybara.register_driver :selenium_chrome_headless_no_sandbox do |app|
browser_options = ::Selenium::WebDriver::Chrome::Options.new
browser_options.args << '--headless'
browser_options.args << '--disable-gpu'
browser_options.args << '--no-sandbox'
Capybara::Selenium::Driver.new(app, browser: :chrome, options: browser_options)
end
and later (configuring RSpec) I set it as the used driver like:
RSpec.configure do |config|
config.before(:each, type: :system, js: true) do
driven_by :selenium_chrome_headless_no_sandbox
end
end
Maybe this helps someone. Cheers
edit: added chromedriver-helper

Print all logs in console when running Selenium test with Capybara

I am using Capybara with Selenium driver for my acceptance tests
Versions used:
Selenium 2.53.1
Capybara 2.7.1
cucumber 2.2.0
cucumber-core 1.3.1
According to Selenium/Logging, known log types are browser, client, driver, performance and server. I would like to log all these log types in console output in realtime.
Based on what I understood, to enable full logging I am configuring Capybara as following:
Capybara.configure do |config|
config.run_server = false
config.app_host = ENV['APP_HOST'] # APP HOST from Cucumber.yml file
config.default_driver = :selenium
config.match = :prefer_exact
config.default_max_wait_time = 10
Capybara.register_driver :selenium do |app|
Capybara::Selenium::Driver.new(
app,
:browser => ENV['BROWSER'].downcase.to_sym,
:desired_capabilities => {
:loggingPrefs => {
:browser => "ALL",
:client => "ALL",
:driver => "ALL",
:server => "ALL"
}
}
)
end
end
Where ENV['BROWSER'] is 'Chrome'.
What I am still unclear is how to print the logs to console. I am looking for a way to print the logs for all scenarios.
I tried adding following code to hooks.rb
After do |scenario|
puts #browser.driver.manage.get_log(:browser)
puts #browser.driver.manage.get_log(:client)
puts #browser.driver.manage.get_log(:server)
puts #browser.driver.manage.get_log(:driver)
end
but #browser is nil.
Also tried following in hooks.rb
After do |scenario|
puts page.driver.browser.manage.logs.get(:browser)
end
But works only for browser logs.
Question: How do I print these logs after each scenario, or even better in realtime?

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