how to download file to a specific location on .click of watir? - ruby

when I click on a link of a web page in chrome web browser with ruby watir
ie.input(:id, "c_ImageButton_Text").click
.text file start downloading. I want to download it to a specific location.I tried this code,but still getting.text file in default download location.How can I download .text file to specific location?
download_directory = "#{Dir.pwd}/downloads"
download_directory.gsub!("/", "\\") if Selenium::WebDriver::Platform.windows?
profile = Selenium::WebDriver::Chrome::Profile.new
profile['download.prompt_for_download'] = false
profile['download.default_directory'] = download_directory
b = Watir::Browser.new :chrome, :profile => profile
click here for this code

For latest watir version 6.6.1
prefs = {
prompt_for_download: false,
default_directory: Rails.root.join('tmp').to_s
}
options = Selenium::WebDriver::Chrome::Options.new
options.add_preference(:download, prefs)
browser = Watir::Browser.new :chrome, options: options

As the old saying goes, "There is more than one way to skin a cat":
You can certainly try to skin it the way you are attempting to do in your example code. However, there are a number of issues with this course of action. Namely, it is browser specific.
I really like how Elemental Selenium suggests achieving valid tests and assertions on downloading files by using the rest-client gem to curl the file's URI and assert the expectations of the file from from there: http://elemental-selenium.com/tips/8-download-a-file-revisited

Related

How to install firefox add-on using Capybara & Selenium?

I am trying to install an add-on on Firefox, however, I couldn't achieve it with whatever I've tried.
require 'capybara'
require 'selenium-webdriver'
Capybara.register_driver :selenium_proxy do |app|
desired_caps = Selenium::WebDriver::Remote::Capabilities.firefox
options = Selenium::WebDriver::Firefox::Options.new
profile = Selenium::WebDriver::Firefox::Profile.new
# Here is the add-on I am trying to install.
profile.add_extension('/home/user/Downloads/try_xpath-1.3.5-fx.xpi')
options.profile = profile
Capybara::Selenium::Driver.new(app, {
browser: :firefox,
desired_capabilities: desired_caps,
options: options
})
end
browser = Capybara::Session.new(:selenium_proxy)
browser.visit 'https://google.com'
What am I doing wrong here? The browser visits the URL without installing any add-on. I am able to install an add-on manually from the file.
Moreover, when I want to add a profile I get the error below:
Errno::ENOENT: No such file or directory # rb_file_s_stat - /tmp/webdriver-rb-profilecopy20200815-25523-ie6apk/lock
from /home/burak/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/rubyzip-2.2.0/lib/zip/entry.rb:405:in `stat'
Well, since noone has answered yet I will share how I've overcome this problem in case you want to install extensions.
If anyone else has a better answer then I can accept their answer, so please answer if you have a better solution.
1st Method
I was just messing around with the Firefox profile folders and I figured that I could use an already existing profile folder with only the extensions folder in it. So I've deleted all the other files/folders in the profile folder that I wanted to use.
So basically the steps are:
Create a Firefox profile or use an existing one.
Install your desired add-on using the browser with the same profile.
Close the browser.
Navigate to the same Firefox profile folder and delete all the other files/folders in the profile folder.
Then use the path to that Firefox profile folder when you are instantiating a Selenium::WebDriver::Firefox::Profile like so:
Capybara.register_driver :selenium_proxy do |app|
desired_caps = Selenium::WebDriver::Remote::Capabilities.firefox
options = Selenium::WebDriver::Firefox::Options.new
profile = Selenium::WebDriver::Firefox::Profile.new '/path/to/firefox/profile/folder/'
options.profile = profile
Capybara::Selenium::Driver.new(app, {
browser: :firefox,
desired_capabilities: desired_caps,
options: options
})
end
browser = Capybara::Session.new(:selenium_proxy)
browser.visit 'https://google.com'
I've tried to create a folder named profile and inside that folder I've created another folder named extensions the same way Firefox does and moved all the add-ons I wanted to upload into that extensions folder but that didn't work.
I guess Firefox changes the add-on file when installing the add-on so downloading an add-on from their website and trying to use it in the profile folder doesn't work. This is my guess of course.
2nd Method
You could alternatively use:
browser = Capybara::Session.new(:selenium_proxy)
browser.driver.browser.install_addon '/path/to/addon.xpi'
I know this looks messy so you could just stop using Capybara and use selenium directly but Capybara has some cool methods as well.

How to specify the location of the chromedriver binary

Earlier I had put the Chrome binary, "chromedriver.exe", in the "C:/Windows" directory and Watir was picking it from there. Now I have to move my project to another machine so I can't hardcode the executable path. I also want the binary to be kept with our code on Git rather than making each test engineer manually update the binary as newer versions are released.
Now I have placed Chrome binary at a absolute path, but it is not being found. Here is what I tried (hooks.rb):
Before do
puts "inside hooks in before"
profile = Selenium::WebDriver::Chrome::Profile.new
profile['download.prompt_for_download'] = false
profile['download.default_directory'] = File.join(File.absolute_path('../..', File.dirname(__FILE__)),"browsers/chromedriver.exe")
#browser = Watir::Browser.new :chrome, :profile => profile
end
The output is:
inside hooks in before
Selenium::WebDriver::Error::WebDriverError: Unable to find the chromedriver executable. Please download the server from http://chromedriver.storage.googleapis.com/index.html and place it somewhere on your PATH. More info at http://code.google.com/p/selenium/wiki/ChromeDriver.
C:/Ruby193/lib/ruby/gems/1.9.1/gems/selenium-webdriver-2.44.0/lib/selenium/webdriver/chrome/service.rb:21:in `executable_path'
C:/Ruby193/lib/ruby/gems/1.9.1/gems/selenium-webdriver-2.44.0/lib/selenium/webdriver/chrome/service.rb:34:in `default_service'
C:/Ruby193/lib/ruby/gems/1.9.1/gems/selenium-webdriver-2.44.0/lib/selenium/webdriver/chrome/bridge.rb:14:in `initialize'
C:/Ruby193/lib/ruby/gems/1.9.1/gems/selenium-webdriver-2.44.0/lib/selenium/webdriver/common/driver.rb:37:in `new'
C:/Ruby193/lib/ruby/gems/1.9.1/gems/selenium-webdriver-2.44.0/lib/selenium/webdriver/common/driver.rb:37:in `for'
C:/Ruby193/lib/ruby/gems/1.9.1/gems/selenium-webdriver-2.44.0/lib/selenium/webdriver.rb:67:in `for'
C:/Ruby193/lib/ruby/gems/1.9.1/gems/watir-webdriver-0.6.11/lib/watir-webdriver/browser.rb:46:in `initialize'
C:/Users/Admin/watircukepractice/test_puppies/features/support/hooks.rb:11:in `new'
C:/Users/Admin/watircukepractice/test_puppies/features/support/hooks.rb:11:in `Before'
I am on Windows 7, Using Ruby version 1.9.3p551 and I am referring to tutorial http://watirwebdriver.com/chrome/.
How do I tell Watir (and Selenium-WebDriver) the location of the chromedriver.exe?
Solution 1 - Selenium::WebDriver::Chrome.driver_path=
There is a Selenium::WebDriver::Chrome.driver_path= method that allows specifying of the chromedriver binary:
require 'watir'
# Specify the driver path
chromedriver_path = File.join(File.absolute_path('../..', File.dirname(__FILE__)),"browsers","chromedriver.exe")
Selenium::WebDriver::Chrome.driver_path = chromedriver_path
# Start the browser as normal
b = Watir::Browser.new :chrome
b.goto 'www.google.com'
b.close
Solution 2 - Specify :driver_path during browser initialization
As an alternative, you can also specify the driver path when initializing the browser. This is a bit nicer in that you do not need to have Selenium code, but would be repetitive if you initialize the browser in different places.
# Determine the driver path
chromedriver_path = File.join(File.absolute_path('../..', File.dirname(__FILE__)),"browsers","chromedriver.exe")
# Initialize the browser with the driver path
browser = Watir::Browser.new :chrome, driver_path: chromedriver_path
Solution 3 - Update ENV['PATH']
When I had originally answered this question, for whatever reason, I had not been able to get the above solution to work. Setting the value did not appear to be used when Selenium-WebDriver started the driver in. While the first solution is the recommended approach, this is an alternative.
Another option is to programmatically add the desired directory to the path, which is stored in the ENV['PATH']. You can see in the Selenium::WebDriver::Platform that the binary is located by checking if the executable exists in any of the folders in the path (from version 2.44.0):
def find_binary(*binary_names)
paths = ENV['PATH'].split(File::PATH_SEPARATOR)
binary_names.map! { |n| "#{n}.exe" } if windows?
binary_names.each do |binary_name|
paths.each do |path|
exe = File.join(path, binary_name)
return exe if File.executable?(exe)
end
end
nil
end
To specify the folder that includes the binary, you simply need to change the ENV['PATH'] (to append the directory):
require 'watir'
# Determine the directory containing chromedriver.exe
chromedriver_directory = File.join(File.absolute_path('../..', File.dirname(__FILE__)),"browsers")
# Add that directory to the path
ENV['PATH'] = "#{ENV['PATH']}#{File::PATH_SEPARATOR}#{chromedriver_directory}"
# Start the browser as normal
b = Watir::Browser.new :chrome
b.goto 'www.google.com'
b.close
In Selenium webdriver 3.x configs, change:
caps = Selenium::WebDriver::Remote::Capabilities.chrome("chromeOptions" => {"binary" => <path to chrome (example: chrome portable)>})
Capybara::Selenium::Driver.new(app, :browser => :chrome, :driver_path => <path to chrome driver>, :desired_capabilities => caps)
driver_path: Define path to chromedriver chromedriver page
binary: Define path to binary chrome app chromepage. You can use a chrome portable to use differents versions of chrome.
Update your Selenium driver_path directly.
Just call this before launching your new Chrome browser window:
Selenium::WebDriver::Chrome::Service.driver_path = Rails.root.join( "lib", "chromedriver" ).to_s
Of course, change the path to where your chromedriver is.
NOTE: driver_path needs to be a String, so don't pass in a File or Path object.
This works for me:
options = Selenium::WebDriver::Chrome::Options.new
Selenium::WebDriver::Chrome::Service.driver_path = '/app/.chromedriver/bin/chromedriver'
chrome_bin_path = ENV.fetch('GOOGLE_CHROME_SHIM', nil)
if chrome_bin_path
options.binary = chrome_bin_path if chrome_bin_path
options.add_argument '--no-sandbox'
options.add_argument '--window-size=1200x600'
options.add_argument '--headless'
options.add_argument '--disable-gpu'
end
browser = Watir::Browser.new(:chrome, options:)

Watir Webdriver Load Chrome Extension

I'm trying to load a chrome extension with Watir, and I'm having issues.
I found this related question: Ability to launch chrome with extensions loaded with watir-webdriver. However, I am still having the same issue after following that.
require 'rubygems'
require 'watir-webdriver'
require 'ruby-debug'
require 'nokogiri'
browser = Watir::Browser.new :chrome, :switches => %w[--load-extension=~/.config/google-chrome/Default/Extensions/anepbdekljkmmimmhbniglnnanmmkoja/0.1.12_0]
sleep(10)
browser.close
I also tried copying the extension from /Extensions to /Desktop and loading from there to no avail.
The error I get is Could not load extension from ... Manifest File Missing or Unreadable.
The Manifest file does indeed exist and seems to be a correct file in JSON format.
Trying to load different extensions fails as well.
Download the chrome extension crx file,
Store the args or any other option need to pass in the watir_opts hash
watir_opts[:extensions] = ['path of *.crx file']
browser = Watir::Browser.new :chrome, options: watir_opts
This worked for me.
Note: I didn't encode using 'base64' gem
If you pack the extension and then base64 it, you can load it into the Chrome browser right from your ruby code.
Pack your extension into a *.crx file. You can follow this guide, or just google how to pack a chrome extension.
Base64 it then add it to your desired capabilities list. You could use some code similar to this one:
chrome_extensions = []
chrome_extension_path = '\home\user\packed_chrome_extension.crx'
begin
File.open(chrome_extension_path, "rb") do |file|
chrome_extensions << Base64.encode64(file.read.chomp)
end
rescue Exception => e
raise "ERROR: Couldn't File.read or Base64.encode64 a Chrome extension: #{e.message}"
end
# Append the extensions to your capabilities hash
my_capabilities.merge!({'chrome.extensions' => chrome_extensions})
desired_capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(my_capabilities)
browser = Watir::Browser.new(:remote, :url => 'http://localhost:4444/wd/hub' :desired_capabilities => desired_capabilities)
And don't forget to require 'base64' too.
The example is for a remote web-driver instance, but I think it should work when using web-driver locally too. Just adjust the arguments passed to Watir::Browser.new.

How to check the location of download folder programmatically in browsers like Safari, Firefox etc on Mac?

I am a part of Automation testing and I am downloading and installing the files programmatically with Selenium and Applescript on Mac. Is their any way to check the location of download folder on browsers programmatically?? if so pls suggest and also ways to change the location of download folder in Java or Applescript.
may be you can try like this on firefox:
profile = Selenium::WebDriver::Firefox::Profile.new
profile['browser.download.dir'] = "/tmp/webdriver-downloads"
profile['browser.download.folderList'] = 2
profile['browser.helperApps.neverAsk.saveToDisk'] = "application/pdf"
b = Watir::Browser.new :firefox, :profile => profile
Safari has a preference for it in ~/Library/Preferences/com.apple.Safari.plist:
defaults read com.apple.Safari DownloadsPath
You can also change it by modifying the property list, but the changes aren't applied until Safari is reopened.
defaults write com.apple.Safari DownloadsPath "~/Desktop"

Watir Changing Mozilla Firefox Preferences

I'm running a Ruby script using Watir to automate some things for me. I'm attempting to automatically save some files to a certain directory. So, in my Mozilla settings I set my default download directory to say the desktop and choose to automatically save files.
These changes, however, are not reflected when I begin to run my script. It seems like the preferences revert back to default. I've included the following
require "rubygems" # Optional.
require "watir-webdriver" # For web automation.
require "win32ole" # For file save dialog.
and open a new firefox instance with:
browser = Watir::Browser.new(:firefox)
Any ideas on why the preferences would be set back by this? Or any alternative ideas for what I am trying to do? (Automatically save files).
Thanks
WebDriver uses a clean profile for each browser instance, which is why the preferences appear to be "reset". You can tell it to use your default profile:
Watir::Browser.new :firefox, :profile => "default"
or tweak profile preferences programatically before launching the browser:
profile = Selenium::WebDriver::Firefox::Profile.new
profile['some.preference'] = true
profile.add_extension "/path/to/some/extension.xpi"
Watir::Browser.new :firefox, :profile => profile
For an example of configuring automatic file downloads, see this section on the Selenium wiki.
change default Watir preferences for download location
for chrome
profile = Selenium::WebDriver::Chrome::Profile.new
download_dir = File.join(Rails.root, 'lib', 'assets')
profile['download.default_directory'] = download_dir
profile[download.prompt_for_download] = false
#b = Watir::Browser.new :chrome, :profile => profile
for firefox
profile = Selenium::WebDriver::Firefox::Profile.new
download_dir = File.join(Rails.root, 'lib', 'assets')
profile['browser.download.dir'] = download_dir
profile['browser.helperApps.neverAsk.saveToDisk'] = "text/csv,application/pdf"
#b = Watir::Browser.new. :firefox, :profile => profile
note: to be be able to access the Rails.root/lib folder easily from within your rails app, you'll need to add this code or something like it to your config/application.rb file:
config.autoload_paths += Dir["#{config.root}/lib/**/"]
for more information: http://watirwebdriver.com/browser-downloads/

Resources