Ruby & Selenium - how to pass arguments to browser? - ruby

My search has only turned up answers for Java - this and this
The selenium gem doesn't include addCommandLineOptions as far as I can tell, but it does have WebDriver::Remote::Capabilities.
How do I use it to add arguments? I know you pass it as desired_capabilities: to the driver constructor, but in what format?
Unfortunately the documentation has been especially useless

You can set --start-maximizedby following for Chrome. See this post for more details.
Capybara.register_driver :chrome_maximize do |app|
caps = Selenium::WebDriver::Remote::Capabilities.chrome(
'chromeOptions' => {
"args" => [ "--start-maximized", "--otherthings" ]
}
)
$driver = Capybara::Selenium::Driver.new(app, {:browser => :chrome, :desired_capabilities => caps})
end

I finally figured out!!! Here is a working example for gem "selenium-webdriver". Should work too for Capybara as well.
First line is if you want to run a custom binary. In case of --headless command line argument, support starts from firefox version 55. Don't forget to make firefox-nightly available to $PATH Env Var.
Selenium::WebDriver::Firefox.path = "/home/user/bin/firefox-nightly"
caps = Selenium::WebDriver::Remote::Capabilities.firefox(
"moz:firefoxOptions" => {
args: ["--headless"] # and other arguments...
}
)
driver = Selenium::WebDriver.for :firefox, desired_capabilities: caps
# do stuff here ....
driver.quit

Related

Issues updating desired_capabilities: Selenium WebDriver - Ruby

Super beginner here. Trying to update this test with Selenium WebDriver using Ruby the course I was going through uses the below which is deprecated.
driver = Selenium::WebDriver.for :remote, desired_capabilities: :firefox
The error I'm getting in cmd when I try to run the tests is
"WARN Selenium [DEPRECATION] [:desired_capabilities] :desired_capabilities as a parameter for driver initialization is deprecated. Use :capabilities with an Array value of capabilities/options if necessary instead."
So I've tried to find examples of how to suppress the error mentioned in This Link, but I'm having trouble finding examples of how to implement that.
I've also tried to look up several ways to just use capabilities: as suggested, but I'm having trouble finding resources for that also, so I've just messed around and tried different combinations to no avail.
Curious if anyone knows of anything that would help me find the answer for this?
Also looked at these sources
https://developer.mozilla.org/en-US/docs/Web/WebDriver/Capabilities
https://www.lambdatest.com/blog/desired-capabilities-in-selenium-testing/
Selenium include firefox profile into DesiredCapabilities for Remote Driver
https://www.selenium.dev/documentation/webdriver/remote_webdriver/
Based off the last link, I believe the below should work? But I'm sure I'm just missing something with syntax.
driver = Selenium::WebDriver.for :Remote::Capabilities.firefox
Selenium capabilities are not where they should be in Ruby. You want to avoid using Capabilities entirely now.
Here's an example in the Selenium documentation with a before/after for how to use Options properly: https://www.selenium.dev/documentation/webdriver/getting_started/upgrade_to_selenium_4/#before
It does not match how the other Selenium languages do things, so I'm planning to change the deprecations in Selenium 4.3 to get them to match.
# spec/rails_helper.rb
Capybara.server = :puma, { Silent: true }
Capybara.server_port = 9887
Capybara.register_driver :headless_chrome do |app|
options = ::Selenium::WebDriver::Chrome::Options.new.tap do |opts|
opts.args << '--headless'
opts.args << '--disable-site-isolation-trials'
opts.args << '--no-sandbox'
end
options.add_preference(:download, prompt_for_download: false, default_directory: Rails.root.join('tmp/capybara/downloads'))
options.add_preference(:browser, set_download_behavior: { behavior: 'allow' })
service_options = ::Selenium::WebDriver::Service.chrome(
args: {
port: 9515,
read_timeout: 120
}
)
remote_caps = Selenium::WebDriver::Remote::Capabilities.chrome(
'goog:loggingPrefs': {
browser: ENV['JS_LOG'].to_s == 'true' ? 'ALL' : nil
}.compact
)
Capybara::Selenium::Driver.new(
app,
browser: :chrome,
capabilities: [remote_caps, options],
service: service_options,
timeout: 120
)
end
Capybara::Screenshot.register_driver(:headless_chrome) do |driver, path|
driver.browser.save_screenshot(path)
end
Capybara.javascript_driver = :headless_chrome
I'd hope this be helpfull for you.

How do I register IEDriver and Edge Driver with Capybara while using the Webdrivers gem?

The ruby webdrivers gem allows automatic downloads of drivers without me having to do it manually when my browser is updated.
And I know that latest Capybara supports drivers out of the box like :selenium, :selenium_chrome, :selenium_chrome_headless just to name a few. This makes it easy in that I don't have to register any drivers beforehand.
Are there similar keywords I can use for IEDriver and Edge Driver? The Webdrivers gem supports these but I am not sure how to get it working with Capybara so that the drivers are automatically downloaded and then run. If there are no keywords/default driver names I can use, how do I register these?
No, there are no preregistered drivers for IE or Edge. To add them you need to use register_driver - https://www.rubydoc.info/github/jnicklas/capybara/Capybara.register_driver - and inside the block pass the options to configure selenium to use the browser you want. You can see how Capybara registers the provided drivers by looking in https://github.com/teamcapybara/capybara/blob/master/lib/capybara/registrations/drivers.rb
Capybara.register_driver :internetExplorer do |app|
# p Capybara::Selenium::Driver::InternetExplorerDriver.options
Capybara::Selenium::Driver.new(
app,
:browser => :internet_explorer,
:options => Selenium::WebDriver::IE::Options.new({
:ignore_zoom_levels => true,
:ignore_zoom_setting => true,
# :browser_attach_timeout => 1,
:javascript_enabled => true,
:persistent_hover => true,
# :require_window_focus => true,
:ignore_protected_mode_settings =>true,
})
)
end
Capybara.register_driver :edgeBrowser do |app|
# p Capybara::Selenium::Driver::InternetExplorerDriver.options
Capybara::Selenium::Driver.new(
app,
:browser => :edge,
:desired_capabilities =>Selenium::WebDriver::Remote::Capabilities::edge({
:javascript_enabled => true,
:css_selectors_enabled => true,
}),
)
end

Selenium Webdriver - set preferred browser language DE

I have a problem setting the preferred (accepted language) within headless Chrome using Selenium Webdriver and Ruby. I use the following WebDriver settings:
Selenium::WebDriver::Chrome.driver_path = #config[<path to the Chrome Driver>]
options = Selenium::WebDriver::Chrome::Options.new
options.add_argument('--headless')
options.add_argument('--disable-translate')
options.add_argument("--lang=de")
The driver is then initialized with:
#selenium_driver = Selenium::WebDriver.for :chrome, options: options
Everything works fine but at some pages Chrome returns English content even when I navigate to the German page URL (e.g. page.de). In these cases the Chrome driver returns the English content due to an internal forwarding to page.de/en. I do not specify the en path in my queried URL.
I have tried to set the language using the Webdriver preference:
options.add_preference('accept_languages', 'de')
instead of the add_argument but it doesn't change anything of the behavior.
Does anyone have an idea how to force a headless Chrome controlled by Selenium Webdriver within Ruby to request page content in a defined language or - not optimal but it might help as a workaround - to stop the forwarding?
Any help greatly appreciated
Best
Krid
I found a solution that works for me. As in many cases the problem was sitting in front of the screen and simply doesn't work precisely enough ;-)
Instead of using
options.add_argument("--lang=de")
you have to use
options.add_argument("--lang=de-DE")
When I use an IETF language tag the code I initially posted works as expected.
I'am using this in my test_helper.rb Works fine for me.
Capybara.register_driver :selenium do |app|
Chromedriver.set_version "2.36"
desired_capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
'chromeOptions' => {
'prefs' => {
'intl.accept_languages' => 'en-US'
},
args: ['disable-gpu', 'headless']
}
)
Capybara::Selenium::Driver.new(app, { browser: :chrome, desired_capabilities: desired_capabilities })
end
Capybara.javascript_driver = :chrome
Capybara.default_driver = :selenium
This prefs hash inside an options hash did the trick for me. It's at the end of the driven_by :selenium line.
(Inside test/application_syste_test_case.rb)
# frozen_string_literal: true
require 'test_helper'
require 'capybara/rails'
class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
driven_by :selenium, using: :chrome, screen_size: [1400, 1400], options: { prefs: { 'intl.accept_languages' => 'de,de-DE;q=0.9,en;q=0.1' } }
# ...
2021-06-14 UPDATE:
The previous example produces this deprecation warning:
WARN Selenium [DEPRECATION] :prefs is deprecated. Use Selenium::WebDriver::Chrome::Options#add_preference instead.
IMO, the solution below is uglier, but I'm posting it for when it's fully deprecated and the original stops working.
class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
driven_by(:selenium,
using: :chrome,
screen_size: [1400, 1400],
options: {
options: Selenium::WebDriver::Chrome::Options.new(
prefs: { 'intl.accept_languages' => 'de,de-DE;q=0.9,en;q=0.1' }
)
},
)
You should be able to solve your problem by adding an experimental option:
options.add_option('prefs', {'intl.accept_languages': 'en,en_US'})
I'm sure it works with Python, but I've not tried with Ruby: this approach is the correct one, not sure about the implementation.
You can find in this repository the code which handles your problem in Python code, and in this Q&A how to implement experimental_options in Ruby
For me works:
options = Selenium::WebDriver::Firefox::Options.new
options.add_preference("intl.accept_languages", 'de-DE')
Capybara::Selenium::Driver.new(app, browser: :firefox, options: options)

What is replica of this java code "setExperimentalOption" in ruby to open chrome browser with 'useAutomationExtension' as false

The below java code works fine in my machine to disable automation extension.
How I can write a replica of this code in ruby
Java
ChromeOptions options = new ChromeOptions();
options.setExperimentalOption("useAutomationExtension", false);
In Watir Ruby
this code doesn't work
Watir::Browser.new(:chrome, :switches => %w[--disable-popup-blocking --disable-extensions --disable-infobars] )
Maybe try passing it as a raw option:
b = Watir::Browser.new :chrome, options: {options: {'useAutomationExtension' => false}}
You should be able to pass them along with args: See the update of Watir 6.6: http://watir.com/watir-6-6/
In short:
Watir::Browser.new :chrome, options: {args: %w[--disable-popup-blocking --disable-extensions --disable-infobars]}
This is how I like to start the browser keeping all options variable.
browser_name = ENV['BROWSER'] || 'chrome'
settings = {}
if ENV['DEVICE'] == 'remote'
settings[:url] = 'http://selenium__standalone-chrome:4444/wd/hub/'
end
if browser_name == 'chrome'
args = ['--ignore-certificate-errors', '--disable-popup-blocking', '--disable-translate', '--use-fake-device-for-media-stream', '--use-fake-ui-for-media-stream']
settings[:options] = {args: args}
end
Watir::Browser.new browser_name.to_sym, settings
I found the root cause which is not allowing the script to run.
I navigated to below path in "regedit" and deleted the "ExtensionInstallBlacklist" folder but this is a temporary solution the registry will be auto created in some time.
Path:
“HKEY_CURRENT_USER\Software\Policies\Google\Chrome\ExtensionInstallBlacklist”

Cannot assign an inst variable in Switch "--user-data-dir" in Selenium Wedriver Chrome

I have the following code and i want to create a user Directory with the name 'mydir' where chrome should output console logs, but wat happens is it creates a directory #{dir} instead. I also tried using CONST Variables still the same result. Can some help me out?
require "selenium-webdriver"
class MyClass
dir='mydir'
#driver = Selenium::WebDriver.for :chrome, :switches => %w[--ignore-certificate-errors --user-data-dir=#{dir} --enable-logging]
end
The %w literal is similar to using single quotes for Strings. There is no interpolation. As a result, the --user-data-dir is exactly what was typed - "#{dir}". To enable interpolation, you need to use a capital W - ie %W:
You can see the difference with:
dir = 'mydir'
# Without interpolation
p %w[--user-data-dir=#{dir}]
#=> ["--user-data-dir=\#{dir}"]
# With interpolation
p %W[--user-data-dir=#{dir}]
#=> ["--user-data-dir=mydir"]
In the end, your script would become:
require "selenium-webdriver"
class MyClass
dir='mydir'
#driver = Selenium::WebDriver.for :chrome, :switches => %W[--ignore-certificate-errors --user-data-dir=#{dir} --enable-logging]

Resources