Watir won't download PDF, only opens in viewer - ruby

I was trying to test with Selenium, but can not download a pdf, pdfs keep opening.
See my other post: RUBY: Selenium webdriver, setup to download pdf files instead of opening them
It was advised to try Watir, so I did, and I get the same result. Here is my Watir setup. Please advise on how to fix this issue.
require 'watir'
require 'pry'
prefs = {
download: {
prompt_for_download: false,
default_directory: '/Users/ar/pdf_downloads'
}
}
browser = Watir::Browser.new :chrome, options: {prefs: prefs}
# Goto Login Page (file)
url="file:///Users/ar/info.html"
browser.goto url
browser.button(id: 'formsubmit').click
sleep 5
# Goto info
info_url = 'https://webapp.domain.com/info'
browser.goto info_url
sleep 5
elements = browser.elements(css: "#ar-pdfreport a")
link = elements.first.attribute("href")
browser.goto link

There is a bug in Selenium-WebDriver v3.142.7 where using symbols for the prefs generates the wrong result - eg does not set the download directory. See https://github.com/SeleniumHQ/selenium/issues/7917 for more details.
Switch the symbols to Strings:
prefs = {
download: {
'prompt_for_download' => false,
'default_directory' => '/Users/ar/pdf_downloads'
},
plugins: {
'always_open_pdf_externally' => true
}
}

Related

Problems initialising browser with options using Ruby, Watir, Chrome

I have a few web-scraping scripts that I've been using for a while now that have been working without issue. However because of an update of something somewhere (I think chrome+chromedriver), the the browsers are not loading with the preferences/options I specify.
Current code:
preferences = {
:download => {
:prompt_for_download => false,
:directory_upgrade => true,
:default_directory => 'C:/DownloadFolder/',
}
}
args = ['--disable-infobars']
browser = Watir::Browser.new :chrome, :chrome_options => {:detach => true, :prefs => preferences, :args => args}
The problems I'm noticing are that the '--disable-infobars' and download folder location are not being applied.
ruby version: 2.3.3p222
watir version: 6.16.5
selenium webdriver version: 3.142.3
chrome version: 75.0.3770.100
chromedriver version : 75.0.3770.90
Taken from help I got elsewhere:
options = Selenium::WebDriver::Chrome::Options.new.tap do |o|
o.add_argument('--disable-infobars')
o.add_preference(:download, directory_upgrade: true,
prompt_for_download: false,
default_directory: 'C:\\DownloadFolder\\')
o.add_option(:detach, true)
end
browser = Watir::Browser.new :chrome, options: options
Two things solved the problem. 1 is specifying the options through selenium rather that Watir. The other is no longer being able to use single forward slashes in folder paths.

Is there a way to download files using headless chromedriver in Centos using Ruby?

I try to download a file using headless chrome and the file doesn't seems to be getting downloaded anywhere. I could see that it's actually a security feature to restrict file download in headless but, is there a workaround for the same in Ruby? Tried the below code but no luck.
download_path = "#{Pathname.pwd}/test-data/downloaded"
options = Selenium::WebDriver::Chrome::Options.new
options.add_argument("--disable-dev-shm-usage");
options.add_argument('--headless') #Declaring the browser to run in headless mode
options.add_preference(
:download, directory_upgrade: true,
prompt_for_download: false,
default_directory: download_path
)
options.add_preference(:browser, set_download_behavior: { behavior: 'allow' })
#driver = Selenium::WebDriver.for :chrome, options: options #Browser object initialization
set_screen_resolution(1400, 900)
$driver = #driver
bridge = #driver.send(:bridge)
path = '/session/:session_id/chromium/send_command'
path[':session_id'] = bridge.session_id
bridge.http.call(:post, path, cmd: 'Page.setDownloadBehavior',
params: {
behavior: 'allow',
downloadPath: download_path
})
I expect the file to be downloaded using headless chrome but it's not happening.
When you click on a download link and if it opens in a separate tab before the file starts downloading, then you need to apply your above mentioned script to the newly opened tab too, because you've set the session id only for the current tab and not for the newly opened tab. So, try apply this script to that newly opened tab before trying to download a file. I'm sure it'll work.
def download_file(label, download_path)
ele = Locator.new(:xpath, "//ul[#class='cnt']//div[text()='#{label}']/..//a")
download_url = get_attribute(ele.get_how, ele.get_what, "href")
#driver.execute_script("window.open()")
#driver.switch_to.window(#driver.window_handles.last)
bridge = #driver.send(:bridge)
path = '/session/:session_id/chromium/send_command'
path[':session_id'] = bridge.session_id
bridge.http.call(:post, path, {
"cmd" => 'Page.setDownloadBehavior',
"params" => {
"behavior" => 'allow',
"downloadPath" => download_path
}
})
#driver.get(download_url)
#driver.close
#driver.switch_to.window(#driver.window_handles.last)
end

How to download a file using Watir 6.0

I'm trying to download a CSV file with the new Watir 6.0. I found the profile settings for Firefox:
profile = Selenium::WebDriver::Firefox::Profile.new
profile['browser.download.folderList'] = 2
profile['browser.download.dir'] = path_to_download
profile['browser.helperApps.neverAsk.saveToDisk'] = "text/csv"
browser = Watir::Browser.new :firefox, :profile => profile
But Firefox 50.0 doesn't support loading profile settings. I get this error message:
/var/lib/gems/2.3.0/gems/selenium-webdriver-3.0.0/lib/selenium/webdriver/remote/w3c_bridge.rb:80:in `initialize': unknown option: {:profile=>#<Selenium::WebDriver::Firefox::Profile
I tried also the profile settings for Chrome:
profile = Selenium::WebDriver::Chrome::Profile.new
profile['download.prompt_for_download'] = false
profile['download.default_directory'] = path_to_download
browser = Watir::Browser.new :chrome, :profile => Profile
but the file will not be saved and the file-save dialog will be not closed.
So both don't work with the new Watir. Does anyone know a way to download a file with Watir?
For Firefox, we'll have that supported in the next release of Selenium.
For Chrome you need to follow the code in the documentation:
prefs = {
download: {
prompt_for_download: false,
default_directory: "/path/to/dir"
}
}
browser = Watir::Browser.new :chrome, prefs: prefs

Block images with chromium watir-webdriver

I'm trying crawl along some pages with watir-webdriver and chromium. I haven't got any success by googling arround so here is my question:
I don't need any images so, to speed up things, I try to disable image loading.
Using firefox as my browser is relatively straigtforward
profile = Selenium::WebDriver::Firefox::Profile.new
profile['network.image.imageBehavior'] = 2
browser = Watir::Browser.new :firefox, :profile => profile
But I haven't had any success with chromium. As far as I've learned, you can set preferences and pass commandline options this way (an example):
prefs = {
:download => {
:prompt_for_download => false,
:default_directory => '/tmp'
},
}
args = ['--start-maximized', '--incognito']
browser = Watir::Browser.new :chrome, :prefs => prefs, :args => args,
That works ok. The problem is that, AFAIK, there are no commandline options nor preferences to block images in chromium.
Any idea?
My setup:
LinuxMint 16 (32.0.1700.107-0ubuntu0.13.10.1~20140204.972.1)
ruby 2.0.0p353 (2013-11-22 revision 43784) [x86_64-linux]
watir-webdriver v0.6.8
chromedriver v2.9.248304
chromium-browser 32.0.1700.107 Built on Ubuntu 13.10
I've managed to disable image loading and many more things through a proxy, being any the choosen browser driver.
I used a local proxy called privoxy in my case.
prefs = {
:profile => {
:managed_default_content_settings => {
:images => 2
}
}
}
b = Watir::Browser.new :chrome, :prefs => prefs

Custom profile for Chrome

Environment: Mac OS X 10.8.3, Ruby 2.0.0p0, selenium-webdriver 2.32.1, ChromeDriver 26.0.1383.0.
I want to change default browser language. I am testing if the site detects the browser language correctly and displays the pages in the language.
I was able to set Firefox language to German:
require "selenium-webdriver"
profile = Selenium::WebDriver::Firefox::Profile.new
profile["intl.accept_languages"] = "de"
caps = Selenium::WebDriver::Remote::Capabilities.firefox(firefox_profile: profile)
caps.platform = "Linux"
caps.version = 20
driver = Selenium::WebDriver.for(
:remote,
url: "http://USERNAME:ACCESS-KEY#ondemand.saucelabs.com:80/wd/hub",
desired_capabilities: caps)
driver.navigate.to "http://sandbox.translatewiki.net/"
I want to do the same using Chrome (and other browsers, if possible).
I have tried several things trying to open the page in German in Chrome, but every time the page is displayed in English, instead of in German.
require "selenium-webdriver"
profile = Selenium::WebDriver::Chrome::Profile.new
profile["intl.accept_languages"] = "de"
caps = Selenium::WebDriver::Remote::Capabilities.chrome(firefox_profile: profile)
caps.platform = "Linux"
caps.version = ""
driver = Selenium::WebDriver.for(
:remote,
url: "http://USERNAME:ACCESS-KEY#ondemand.saucelabs.com:80/wd/hub",
desired_capabilities: caps)
driver.navigate.to "http://sandbox.translatewiki.net/"
If I change firefox_profile: profile to profile: profile or chrome_profile: profile, the page opens in English (instead of in German) every time.
As far as I can see in the API docs, only :firefox_profile is supported.
I was able to do it on a local machine, but not when using Sauce Labs.
This should work:
require "selenium-webdriver"
profile = Selenium::WebDriver::Chrome::Profile.new
profile["intl.accept_languages"] = "de"
caps = Selenium::WebDriver::Remote::Capabilities.chrome(
platform: "Linux",
version: "",
'chrome.profile' => profile.as_json['zip']
)
Selenium::WebDriver.for(:remote,
url: "http://...#ondemand.saucelabs.com:80/wd/hub",
desired_capabilities: caps
)
Wow, the documentation for SauceLabs + Chrome + Selenium + Ruby is very inconsistent and sometimes contradictory. Unfortunately I do not have a SauceLabs account to test so all I can do is give you suggestions.
This documentation says it is a known issue that ChromeDriver does not support a custom profile. This post shows how to set a custom profile for Chrome. Go figure.
Setting a profile or a default language for that matter is NOT part of the standard WebDriver wire protocol so you may be out of luck.
One workaround would be to set your browser to use a proxy and in the proxy add/replace the Accept-Language header in the proxy.
Still, looking through the Selenium Ruby code, it looks like that post might be on to something, so give this a try:
profile = Selenium::WebDriver::Chrome::Profile.new
profile["intl.accept_languages"] = "de"
caps = Selenium::WebDriver::Remote::Capabilities.chrome
caps['chromeOptions'] = { 'profile' => profile.as_json['zip'] }
driver = Selenium::WebDriver.for(
:remote,
url: "http://USERNAME:ACCESS-KEY#ondemand.saucelabs.com:80/wd/hub",
desired_capabilities: caps)
driver.navigate.to "http://sandbox.translatewiki.net/"
EDIT: It seems like the --lang- switch does not do what you want, so ignore the following. I'm leaving it here for posterity.
This might work (forget about the profile, use command line switches):
caps = Selenium::WebDriver::Remote::Capabilities.chrome
caps['chrome.switches'] = ['--lang-de']
I am seeing the German Translation on my local machine using:
profile = Selenium::WebDriver::Chrome::Profile.new
profile["intl.accept_languages"] = "de"
#driver = Selenium::WebDriver.for :chrome, :profile => profile
#target = 'http://sandbox.translatewiki.net/'
osx: 10.7.5
ruby 1.9.3p0 (2011-10-30 revision 33570) [x86_64-darwin11.4.2]
For now you can just use this method
def launch_browser options={}
language = options.fetch(:language, "en_US")
url = options.fetch(:url, "www.google.com")
prefs = {
:intl => {
:accept_languages => language
}
}
browser = Watir::Browser.new :chrome, :prefs => prefs
browser.goto url
end
and then you just have to call
launch_browser :language => "de"

Resources