Enable/disable javascript using Selenium WebDriver - ruby

For some reason, I've to disable javascript for Firefox (Manually, we do by following steps mentioned http://support.mozilla.org/en-US/kb/javascript-settings-for-interactive-web-pages#w_enabling-and-disabling-javascript). How can this be achieved by Selenium WebDriver using Ruby?

Yes, It is possible. But a different way. You first need to look into the link
Selenium::WebDriver::Firefox::Profile #[]=(key, value).
JavaScript settings
Once you would visit the link,try the below code :
require 'selenium-webdriver'
profile = Selenium::WebDriver::Firefox::Profile.new
profile["javascript.enabled"] = false
driver = Selenium::WebDriver.for(:firefox, :profile => profile)
profile
# => #<Selenium::WebDriver::Firefox::Profile:0x89c7568
# #additional_prefs=
# {"javascript.enabled"=>false, "webdriver_firefox_port"=>7055},
# #extensions=
# {:webdriver=>
# #<Selenium::WebDriver::Firefox::Extension:0x89c6488 # !> previous definition of proxy= was here
# #path=
# "/home/kirti/.rvm/gems/ruby-2.0.0-p0/gems/selenium-webdriver-2.33.0/lib/selenium/webdriver/firefox/extension/webdriver.xpi",
# #should_reap_root=true>},
# #load_no_focus_lib=false,
# #model=nil,
# #native_events=false,
# #secure_ssl=false,
# #untrusted_issuer=true>
Once your browser window will be opened up through the above code,then check the Preferences from Edit->Preferences->content,then you would see that Enable JavaScript: option is unchecked.

Related

Throttle CPU in chromedriver with selenium

So I'm trying to add the CPUThrottlingRate in my selenium chromedriver setup below.
require 'webdrivers/chromedriver'
module ChromeBrowser
class << self
def headless(throttling)
#browser ||= headless_chrome_browser(throttling || 'regular')
end
private
def headless_chrome_browser(throttling)
options = Selenium::WebDriver::Chrome::Options.new
# -> https://peter.sh/experiments/chromium-command-line-switches/#profiler-timing
options.add_argument '--ignore-certificate-errors'
# options.add_argument "--user-agent=#{random_user_agent}" # set Random User Agent
options.add_argument '--allow-insecure-localhost'
options.add_argument '--window-size=1400x1400'
options.add_argument '--disable-gpu'
options.add_argument '--disable-dev-shm-usage'
options.add_argument '--noerrdialogs' # Suppresses all error dialogs when present
options.add_argument '--profiler-timing=0' # whether chrome will contain timing information
options.add_argument '--disable-infobars' # prevent infobars from appearing
options.add_argument '--headless' if Rails.env.production? # headless on chrome
# options.add_argument '--blink-settings=imagesEnabled=false' # disable images
options.add_argument '--no-referrers' # don't send HTTP-Referer headers
options.add_argument '--disable-breakpad' # disables the crash reporting
options.add_argument '--disable-demo-model' # disables the chrome OS demo
options.add_argument '--disable-translate' # disable google translate
options.add_argument '--dns-prefetch-disable' # disable DNS prefetching
options.add_argument '--no-pings' # no hyperlink auditing pings
browser = Selenium::WebDriver.for :chrome, options: options
case throttling
when 'slow'
browser.network_conditions = {
offline: false,
latency: 50,
download_throughput: 51200,
upload_throughput: 51200
}
when 'regular'
browser.network_conditions = {
offline: false,
latency: 30,
download_throughput: 51200,
upload_throughput: 512000
}
when 'fast'
browser.network_conditions = {
offline: false,
latency: 20,
download_throughput: 1024000,
upload_throughput: 1024000
}
end
return browser
end
end
end
I'm looking for this solution here but in ruby.
## rate 1 is no throttle, 2 is 2x slower, etc.
driver.execute_cdp_cmd("Emulation.setCPUThrottlingRate", {'rate': 10})
developertools is installed
running on chromedriver v92
I'm trying to throttle both network speed and CPU to simulate ~kinda~ real-life requests.
Can't seem to figure it out, what am I missing? Useful links:
https://www.selenium.dev/documentation/support_packages/chrome_devtools/
CPU throttling in chrome via python selenium
https://github.com/SeleniumHQ/selenium/wiki/Ruby-Bindings
I have tried:
...
browser = Selenium::WebDriver.for :chrome, options: options
devToolsSession = browser.devtools
devToolsSession.send_cmd('Emulation.setCPUThrottlingRate', {rate: 10})
Which produces
ArgumentError: wrong number of arguments (given 2, expected 1)
from /Users/minijohn/.asdf/installs/ruby/3.0.2/lib/ruby/gems/3.0.0/gems/selenium-webdriver-4.0.3/lib/selenium/webdriver/devtools.rb:55:in `send_cmd'
and with one param
Selenium::WebDriver::Error::WebDriverError: -32602: Invalid parameters: Failed to deserialize params.rate - BINDINGS: mandatory field missing at position 7
from /Users/minijohn/.asdf/installs/ruby/3.0.2/lib/ruby/gems/3.0.0/gems/selenium-webdriver-4.0.3/lib/selenium/webdriver/devtools.rb:69:in `send_cmd'
Also tried this
browser = Selenium::WebDriver.for :chrome, options: options
browser.send_cmd('Emulation.setCPUThrottlingRate', {rate: 10})
which produces
NoMethodError: undefined method `send_cmd' for #<Selenium::WebDriver::Chrome::Driver:0x2738339e1fe77884 browser=:chrome>
from (pry):14:in `headless_chrome_browser'
The goal for Selenium is to define the common commands that the browser vendors will support in the WebDriver BiDi specification, and support them via a straightforward API, which will be accessible via Driver#devtools method.
In the meantime, any Chrome DevTools command can be executed via Driver#execute_cdp.
In this case it will look like:
SL-1495:code titusfortner$ irb
irb(main):001:0> require 'selenium-webdriver'
=> true
irb(main):002:0> driver = Selenium::WebDriver.for :chrome
=> #<Selenium::WebDriver::Chrome::Driver:0x..fc42365c4d30079b0 browser=:chrome>
irb(main):003:0> driver.execute_cdp('Emulation.setCPUThrottlingRate', rate: 10)
=> {}
irb(main):004:0>
The key here is that in Ruby we're using keywords for this instead of a Hash, and in Ruby 3, those are now handled differently.

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)

Debug in headless Chrome

After switching from capybara_webkit to headless_chrome, I'm trying to find a way to replicate
Capybara::Webkit.configure do |config|
config.debug = true
end
or
Capybara.javascript_driver = :webkit_debug
with the new driver.
The goal is to be able to see the log of everything happening when running rspec my_spec.rb: for example, all GET requests.
Is there a way to achieve that?
There is no option when using Selenium like the capybara_webkit debug option that outputs the debug info in realtime, however you can get access to the Chrome logs and output those at the end of each test (or you could write a helper to output them whenever you call it of course).
First you'd need to configure your selenium driver for logging
Capybara.register_driver :logging_chrome do |app|
caps = Selenium::WebDriver::Remote::Capabilities.chrome(
# customize this based on which and what level logs your prefer
loggingPrefs: {
browser: 'ALL',
driver: 'ALL',
performance: 'ALL'
}
)
browser_options = ::Selenium::WebDriver::Chrome::Options.new()
browser_options.headless!
Capybara::Selenium::Driver.new(
app,
browser: :chrome,
desired_capabilities: caps,
options: browser_options
)
end
Then you'd set up to use that driver
Capybara.javascript_driver = :logging_chrome # possibly default_driver = depending on your config
and then add an after block that gets the logs and displays them
after(:each) do
# customize based on which type of logs you want displayed
log_types = page.driver.browser.manage.logs.available_types
log_types.each do |t|
puts t.to_s + ": " + page.driver.browser.manage.logs.get(t).join("\n")
end
end

Watir-Webdriver does not show dialogs in Firefox when finished testing

I am using webdriver with FF38, but leaving the browser open window after my script is done. I find that dialogs no longer open in that window, if I continue after the testing.
The script is meant to automate forms input rather than doing it by hand, but the website does use dialog boxes to express choices -- (for example, deleting data that the script has just entered, so that I can rerun the script without overwriting information)
Is there a way to disconnect the webdriver dialog handling after I'm done?
I'm feeling a little foolish, but my searches haven't born fruit, so I may be using the wrong words in my search, given my newness to ruby and webdriver.
Example would be this:
require "watir-webdriver"
l_Browser = Watir::Browser.new :firefox
l_Browser.goto "http://www.w3schools.com/js/tryit.asp?filename=tryjs_alert"
# Click the button that opens the dialog
l_Browser.div(:class => "container").div(:class => "iframecontainer"). \
div(:class => "iframewrapper").iframe(:id => "iframeResult"). \
button(:onclick => "myFunction()").click
The result is that a popup will appear, but no popups will appear further attempts to click on the button once the script is done.
This includes even if no popup is triggered during the script (ie:, last line commented out)... Once the script is finished running, no popups appear in a watir webdriver opened window. (They will open if I click on the button while the script is running, but not after)
Based on the answer below, I am using:
begin
b = Watir::Browser.new :firefox
File.open('d:\\MARK.TXT', 'w') {|f| f.write(YAML.dump(b)) }
# Load MessageBox and wait here
b = YAML.load(File.read('d:\\MARK.TXT'))
ensure
if !b.nil?
b.close()
end
end
... but it currently allows for errors that can be ignored... I just don't know how wise it is to ignore them in the long run:
D:/Ruby193/lib/ruby/gems/1.9.1/gems/childprocess-0.5.6/lib/childprocess/windows/handle.rb:50:in `exit_code': The handle is invalid. (6) (ChildProcess::Error)
from D:/Ruby193/lib/ruby/gems/1.9.1/gems/childprocess-0.5.6/lib/childprocess/windows/process.rb:41:in `exited?'
from D:/Ruby193/lib/ruby/gems/1.9.1/gems/childprocess-0.5.6/lib/childprocess/abstract_process.rb:147:in `poll_for_exit'
from D:/Ruby193/lib/ruby/gems/1.9.1/gems/selenium-webdriver-2.46.2/lib/selenium/webdriver/firefox/binary.rb:59:in `quit'
from D:/Ruby193/lib/ruby/gems/1.9.1/gems/selenium-webdriver-2.46.2/lib/selenium/webdriver/firefox/launcher.rb:62:in `quit'
from D:/Ruby193/lib/ruby/gems/1.9.1/gems/selenium-webdriver-2.46.2/lib/selenium/webdriver/firefox/bridge.rb:75:in `quit'
from D:/Ruby193/lib/ruby/gems/1.9.1/gems/selenium-webdriver-2.46.2/lib/selenium/webdriver/common/driver.rb:165:in `quit'
from D:/Ruby193/lib/ruby/gems/1.9.1/gems/watir-webdriver-0.7.0/lib/watir-webdriver/browser.rb:136:in `close'
from D:/Users/risendevil/Documents/Aptana Studio 3 Workspace/Ruby Test/Default.rb:19:in `<main>'
Versions:
Firefox 38.0.5
selenium (0.2.11)
selenium-webdriver (2.46.2, 2.45.0)
watir-webdriver (0.7.0)
I learned something new answering your question: Turning an object into text is called serialization. Turning text into an object is called deserialization.
And here's a gist of you want to do, specifically.
The important part is
my_object = SomeObject.new
my_object.some_method # => returns your expected result
File.open('path/to/some.file', 'w') {|f| f.write(YAML.dump(my_object)) }
# Do whatever you want
my_object_reloaded = YAML.load(File.read('path/to/some.file'))
my_object_reloaded.some_method # => returns your expected result
You could even do this directly to your browser:
b = Watir::Browser.new
b.goto 'http://google.com' # => goes to Google
File.open('path/to/some.file', 'w') {|f| f.write(YAML.dump(b)) }
b = nil
# Do whatever you want, wait as long as you want.
# (Disclaimer: There are probably major limitations to 'as long as you want'.)
b = YAML.load(File.read('path/to/some.file'))
b.goto 'http://yahoo.com' # => goes to Yahoo
require "watir-webdriver"
l_Browser = Watir::Browser.new :firefox
l_Browser.goto "http://www.w3schools.com/js/tryit.asp?filename=tryjs_alert"
l_Browser.iframe(:id => 'iframeResult').button(:xpath => "//button[text()='Try it']").when_present.click # click on "Try it" button
l_Browser.alert.close # closing popup

Firefox 4 with watir webdriver: Need help using helperApps.neverAsk to save CSV without prompting

I learned how to use Firefox 4 with watir and webdriver (on Win7 x64), setting profile items. Example:
profile = Selenium::WebDriver::Firefox::Profile.new
profile["browser.download.useDownloadDir"] = true
profile["browser.download.dir"] = 'D:\\FirefoxDownloads'
profile["browser.helperApps.neverAsk.saveToDisk"] = "application/csv"
driver = Selenium::WebDriver.for :firefox, :profile => profile
browser = Watir::Browser.new(driver)
What I try to do with the example below, is setting CSV files to be always downloaded to a specific directory, never opened.
The code above succeeds in setting all the files automatically downloaded to the specified directory, but setting browser.helperApps.neverAsk.saveToDisk has no effect: I still get the open/save question.
After the script runs, the Firefox window is still open, and I enter the URL about:config.
I can see that browser.helperApps.neverAsk.saveToDisk was correctly set to application.csv , but in firefox/options/options/applications I don't see the entry for CSV files.
It seems that the menu setting, that is really effective, is not really bound with the about:config setting.
What am I doing wrong?
I've done some testing of this for you, unfortunately there doesn't seem to be a standard content-type for CSV files. You can try passing a comma separated list of content-types, hopefully one of those work for you. For me it was application/octet-stream that did the trick...
require 'watir-webdriver'
require 'selenium-webdriver'
profile = Selenium::WebDriver::Firefox::Profile.new
profile["browser.download.useDownloadDir"] = true
profile["browser.download.dir"] = '/tmp'
profile["browser.helperApps.neverAsk.saveToDisk"] = "text/plain, application/vnd.ms-excel, text/csv, text/comma-separated-values, application/octet-stream"
driver = Selenium::WebDriver.for :firefox, :profile => profile
browser = Watir::Browser.new(driver)
browser.goto "http://altentee.com/test/test.csv"
In Firefox 6+, I couldn't get this to work without specifically setting the 'browser.download.folderList' value:
profile = Selenium::WebDriver::Firefox::Profile.new
profile['browser.download.folderList'] = 2 #custom location
profile['browser.download.dir'] = download_directory
profile['browser.helperApps.neverAsk.saveToDisk'] = "text/csv, application/csv"
b = Watir::Browser.new :firefox, :profile => profile
See: http://watirwebdriver.com/browser-downloads/

Resources