Ruby Selenium Firefox only downloading to ~/Downloads on MacOS - ruby

I am having trouble getting Selenium to download files to the specified folder on MacOS.
Running:
Ruby 3.0.1p64
Rails 6.1.3.1
selenium-webdriver 4.0.0beta3
This is my current code, which has attempts to change the directory in four places (any help much appreciated):
require 'selenium-webdriver'
require 'fileutils'
Selenium::WebDriver.logger.level = :info
#download_dir = File.join(Dir.pwd, "lib/forecastdownloads")
FileUtils.mkdir_p #download_dir # Create the folder if missing
profile = Selenium::WebDriver::Firefox::Profile.new
profile['browser.download.dir'] = #download_dir
profile['browser.download.default_directory'] = #download_dir
options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
options.add_argument('--headless')
options.add_preference('download.directory_upgrade', true)
options.add_preference('download.folderList', 2)
options.add_preference('download.prompt_for_download', false)
options.add_preference('download.dir', #download_dir)
options.add_preference('download.default_directory', #download_dir)
options.add_preference('browser.helperApps.neverAsk.saveToDisk', 'application/pdf, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel, text/csv')
driver = Selenium::WebDriver.for :firefox, capabilities: options
driver.manage.timeouts.implicit_wait = 10 # seconds
wait = Selenium::WebDriver::Wait.new(:timeout => 15)
driver.get "https://...[the webpage]"
element = wait.until { driver.find_element(:class, "buttons-excel") }
element.click
driver.quit
With the above code, files are downloading to the regular ~/Downloads folder instead of #download_dir.

The problem is the setting for download.dir.
Instead of File.join(Dir.pwd, "lib/forecastdownloads"), it should be:
profile['browser.download.dir'] = Dir.pwd + '/forecastdownloads'

Related

Error page is appeared on clicking a button in headless browser in Ruby-Selenium

I am automating process of Walmart shopping card from product selection till complete Checkout process. I am using headless chrome browser for that in Ruby Selenium. When I click on 'Checkout' button after adding product to Cart, it navigates me to 'Error page' and returns me page title, 'Walmart Omnivore' and checkout process fails however checkout flow is completed successfully when I do it by launching browser. Problem is only in the checkout in headless browser.
I am using
Ruby 2.4.3
Selenium Gem : selenium-webdriver-3.5.2
Chrome version: Version 67.0.3396.99 (Official Build) (64-bit)
Here is my code,
require 'selenium-webdriver'
class TestBrowserHeadless
chromePath = "chromedriver.exe" #Chrome browser exe file path
# Selenium::WebDriver::Chrome.driver_path = chromePath
# driver = Selenium::WebDriver.for :chrome, switches: ['--incognito']
# driver.manage.window.maximize
Selenium::WebDriver::Chrome.driver_path = chromePath
options = Selenium::WebDriver::Chrome::Options.new
options.add_argument('--headless')
driver = Selenium::WebDriver.for :chrome, options: options
driver.get "https://www.walmart.com/"
puts driver.title
driver.save_screenshot("test1.png")
sleep 5
search_field = driver.find_element(:id, 'global-search-input')
search_field.click
search_field.send_keys("623649985")
search_field.submit
sleep 5
driver.save_screenshot("test2.png")
puts driver.title
prod_name = driver.find_element(:xpath, "//img[#class='Tile-img']")
prod_name.click
sleep 5
driver.save_screenshot("test3.png")
puts driver.title
puts "Adding item to Cart"
button_addCart = driver.find_element(:xpath, "//button[text()='Add to Cart']")
button_addCart.click
sleep 3
driver.save_screenshot("test4.png")
puts driver.title
checkout_Btn = driver.find_element(:xpath, "//div[#class='Cart-PACModal-POSContainer']/descendant::button[text()='Check Out']")
checkout_Btn.click
driver.save_screenshot("test5.png")
sleep 4
driver.save_screenshot("test6.png")
puts driver.title
puts "success"
end
NOTE:: Also, I tried clicking Checkout button after login walmart user and found same result
This issue is resolved by using 'headless' gem of ruby. https://leonid.shevtsov.me/post/headless/

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”

Ruby & Selenium - how to pass arguments to browser?

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

Open a Selenium browser with my cookies

I'm trying to create an automated script that goes to a website (Yik Yak) and submits stuff. It needs to access my cookies to know that I logged in before. It requires entering a key from my phone, and I can't automate that.
require 'selenium-webdriver'
profileDir = File.absolute_path("/home/carson/.mozilla/firefox/237ie3yd.default")
profile = Selenium::WebDriver::Firefox::Profile.from_name profileDir
driver = Selenium::WebDriver.for :firefox, :profile => profile
driver.navigate.to "https://www.yikyak.com/nearby/new"
wait = Selenium::WebDriver::Wait.new(:timeout => 10)
element = driver.find_element(:class, 'form-control')
element.send_keys "Tessttt"
element.submit
It runs and opens Firefox, but it stops at the page where I have to enter the key my phone gets.
Any help?
default_profile = Selenium::WebDriver::Firefox::Profile.from_name "default"
default_profile.native_events = true
driver = Selenium::WebDriver.for(:firefox, :profile => default_profile)
Via Ruby Bindings

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