how to remove the log of ie web driver? - ruby

I am using watir-webdriver + ruby + win7 to test same pages. and I would get these logs while I start the ie explorer by using watir-webdriver:
Started InternetExplorerDriver server (32-bit)
2.32.3.0
Listening on port 5555
are there any methods to remove these logs? any help would be appreciated!

IEDriver supports a --silent flag that suppresses diagnostic output when the server is started.
Unfortunately, at least to my knowledge, it is not configurable when creating a browser instance. Instead, you need to directly modify the Selenium::Webdriver::IE::Server class' server_args method. You can modify the lib\selenium\webdriver\ie\server.rb file directly, but it is probably easier to monkey patch.
To monkey patch the silent flag, add the following to your code some point after requiring watir-webdriver (ie selenium-webdriver) but before opening the browser.
class Selenium::WebDriver::IE::Server
old_server_args = instance_method(:server_args)
define_method(:server_args) do
old_server_args.bind(self).() << "--silent"
end
end
For example, the following will no longer log any messages.
require 'watir-webdriver'
class Selenium::WebDriver::IE::Server
old_server_args = instance_method(:server_args)
define_method(:server_args) do
old_server_args.bind(self).() << "--silent"
end
end
b = Watir::Browser.new :ie

Related

Using proxies with Selenium WebDriver and chrome

Im writing a selenium-webdriver script in ruby and im trying to figure out how to make the browser window that selenium opens use a proxy with user pass authentication.
i.e. (234.43.234:2345:user:pass)
so far my code is thus....
def scrape_n_vote
driver = Selenium::WebDriver.for(:chrome)
loop do
driver.get "https://poll.fm/poll_id"
driver.find_element(id: 'answer_id').click
sleep 1
driver.find_element(class: 'btn-large').click
sleep rand(1..3)
end
end
Does anyone know how to make the browser programatically accept a proxy via this ruby script for chrome to make the connection with?

How do I use my own cookies in capybara?

I'm trying to (ab)use the capybara web testing framework to automate some tasks on github that are not accessible via the github API and which require me to be logged in and click on buttons to send AJAX requests.
Since capybara/selenium is a testing framework it helpfully creates a temporary session which has no cookies in it. I'd like to either stop it from doing that, or else I'd like to know how to load my cookie store into the browser session that it creates.
All I'm trying to do is this:
#!/usr/bin/env ruby
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :chrome
driver.navigate.to "https://github.com"
Or this:
#!/usr/bin/env ruby
require 'capybara'
Capybara.register_driver :selenium do |app|
Capybara::Selenium::Driver.new(app, :browser => :chrome)
end
session = Capybara::Session.new(:selenium)
session.visit "https://www.github.com"
In both cases I get the github.com landing page you'd see as a logged-out user or incognito mode in the browser. I'd like to get my logged-in landing page like I just fired up a web browser myself and navigated to that URL.
Since I have 2FA setup on github that makes automating the login process from the github landing page somewhat annoying, so I'd like to avoid automating logging into github. The tasks that I want to automate do not require re-authenticating via 2FA.
ANSWER:
For MacOSX+Ruby+Selenium this works:
#!/usr/bin/env ruby
require 'selenium-webdriver'
caps = Selenium::WebDriver::Remote::Capabilities.chrome("chromeOptions" => {"debuggerAddress" => "127.0.0.1:20480"}, detach: false)
driver = Selenium::WebDriver.for :chrome, :desired_capabilities => caps
driver.navigate.to "https://github.com"
Then fire up chrome with this:
% /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --user-data-dir=/Users/lamont/Library/Application\ Support/Google/Chrome --profile-directory=Default --remote-debugging-port=20480
Obviously the paths will need to be adjusted because they're OSX-centric and have my homedir in them.
There is also a bug in the selenium-webdriver gem for ruby where it inserts a 'detach' option which gets into a fight with 'debuggerAddress':
/Users/lamont/.rvm/gems/ruby-2.2.4/gems/selenium-webdriver-2.53.0/lib/selenium/webdriver/remote/response.rb:70:in `assert_ok': unknown error: cannot parse capability: chromeOptions (Selenium::WebDriver::Error::UnknownError)
from unknown error: unrecognized chrome option: detach
The lib/selenium/webdriver/chrome/bridge.rb file can be edited to take that out as a quick hack:
chrome_options['binary'] = Chrome.path if Chrome.path
chrome_options['nativeEvents'] = true if native_events
chrome_options['verbose'] = true if verbose
#chrome_options['detach'] = detach.nil? || !!detach
chrome_options['noWebsiteTestingDefaults'] = true if no_website_testing_defaults
chrome_options['prefs'] = prefs if prefs
To implement something similar in Ruby, check out this page that goes over that. Thanks to lamont for letting me know in the comments.
You can start chrome using a specific Chrome profile. I am not sure what the ruby implementation would look like, but in python it looks something like:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options as ChromeOptions
options = ChromeOptions()
# more on this line here later.
options.add_experimental_option('debuggerAddress', '127.0.0.1:7878')
driver = webdriver.Chrome(chrome_options=otpions)
In order for this to work you need to do a few things.
manually start chrome from terminal/command prompt with these command line arguments
--user-data-dir=/path/to/any/custom/directory/home/user/Desktop/Chromedir --profile-directory="Profile 1" --remote-debugging-port=7878
make sure "Profile 1" is already existing in the same --user-data-dir (make sure user Profile 1 has necessary chrome://components/
to run any apps that require those components)
you can use any free port in place of 7878
verify that http://localhost:7878 is running and returns value.
This should manually launch chrome with the "Profile 1" profile, and so long as it has logged into the site in question, it will stay logged in like a normal user so long as you follow these instructions to run the tests.
I used this to write a quick netflix bot that clicks the "continue playing" button when it pops up, and it's the only way to get DRM content to play as far as I have found. But it retains the cookies for the login, and also launches chrome with whatever components the profile is set up to have.
I have tried launching chrome with specific profiles before using different methodologies, but this was the only way to really force it to work how I wanted it to.
Edit: There are methods for saving cookie info as well although I don't know how well they work. Check out this link for more info, as my solution is probably not the best solution even if it works.
The show_me_the_cookies gem provides cross-driver cookie manipulation and can let you add new cookies. The one thing to be aware of when using selenium is that you need to visit the domain before you can create cookie for it, so you'll need to do something like
visit "https://www.github.com"
create_cookie(...)
visit "https://www.github.com"
for it to work - first visit just puts the browser/driver in a state where you can create the cookie, second visit actually goes to the page with the cookies set.
I had to tweak the OP's answer (from within her question) to get this going with Ruby in 2022.
Prerequisites
Chromedriver installed and allowed to run even though it's not signed:
> brew install chromedriver
> xattr -d com.apple.quarantine /usr/local/bin/chromedriver
Chrome launched and accepting commands on a specific port:
> /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --user-data-dir=~/Library/Application\ Support/Google/Chrome --profile-directory=Default --remote-debugging-port=20480
This created a new profile in Chrome so I signed in to my account and got the browser set up, ready to start interacting with the (legacy EdTech) site I'm trying to automate.
Actual use
require 'selenium-webdriver'
caps = Selenium::WebDriver::Remote::Capabilities.chrome("goog:chromeOptions" => {"debuggerAddress" => "127.0.0.1:20480"})
driver = Selenium::WebDriver.for :chrome, capabilities: caps
driver.navigate.to "https://www.google.com"

Using Cucumber and Ruby to Download File

I've written some Ruby code (connected with Cucumber) that will go to a website and click a file that I'd like to download. The browser I'm using for this is Google Chrome.
Typically, when you go to download a file in Chrome, it doesn't ask for permission. However, when I run the code I made, it says:
"This type of file can harm your computer. Do you want to keep file_name.exe anyway?" It gives 2 options, "keep" or "discard". I have to click keep.
Obviously, you don't want all executables to just start downloading; however, this particular website/file should always be trustworthy.
Is there a command in Ruby or Cucumber that allows you to click the "keep" button automatically? This could just be a general "click at this pixel" or something. Or is there a way to mark a particular website in Chrome as safe. You can't inspect the element because it's not part of the website, but, instead, part of the browser. Preferably without having to download other software.
With this being said, this suggests that if it is possible, it should also be possible to automate an installation (as in clicking next -> next -> etc) for you. Hopefully this is correct?
Thanks in advance.
You can implement it in any browser. But, for Google Chrome, here is the solution -
profile = Selenium::WebDriver::Chrome::Profile.new
profile['download.prompt_for_download'] = false
profile['download.default_directory'] = "Absolute or relative path to your download directory"
browser = Selenium::WebDriver.for :chrome, :profile => profile
You haven't specified which gem you use for browser. But, even if you use watir-webdriver, you can use the same profile you created above with watir-webdriver.
browser = Watir::Browser.new :chrome, :profile => profile
I actually switched to using Sikuli, which worked pretty well. Thanks for the help, though.
Do you really need or want the browser to download the file? Are you really testing the browser's download feature, or do you want to verify that the server can serve the file and that it is what you expect?
I found the idea of setting up a default directory and having to check for the file clumsy, fragile and prone to errors, especially when setting up on a new host, especially for tests that run in multiple browsers.
My solution is to just use Ruby (or whatever language) features to download the file directly, and then validate that it is the file it's supposed to be. I'm not testing the browser, I'm testing the software. The only exception to that idea I can think of is if you use some javascript logic or something browser-dependent to redirect you to a link, but please don't ever do that.
However, you run into a problem if you have to log in to access your file; you either have to implement auth in your Ruby code, which isn't technically part of your Cucumber specification, or you need the cookies. I use this code to copy the cookies to avoid logging in again, and grab the file:
def assert_file_link(uri, filename, content_type)
f = open_uri_with_cookies uri
attachment_filename = f.meta["content-disposition"].sub("Attachment;filename=", "") # "Attachment;filename=Simple Flow - Simple Form.rtf"
content_length = Integer(f.meta["content-length"])
assert(f.status == ["200", "OK"], "Response was not 200 OK")
assert(f.content_type == content_type, "Expected content-type of '#{content_type}' but was '#{f.content_type}'")
assert(attachment_filename == filename, "Expected filename of '#{filename}' but was '#{attachment_filename}'")
assert(content_length > 0, "Expected content-length > 0 but was '#{content_length}'")
end
def open_uri_with_cookies(uri)
# hack the cookies from the existing session so we don't need to log in!
cookies = ""
#driver.manage.all_cookies.each { |cookie| cookies.concat("#{cookie[:name]}=#{cookie[:value]}; ") }
if block_given?
open(uri, "Cookie" => cookies, :proxy => nil) do |f|
yield f
end
else
open(uri, "Cookie" => cookies, :proxy => nil)
end
end
Hope this helps.

How to use same browser window for automated test using selenium-webdriver (ruby)?

I am automating test cases for a website using selenium-webdriver and cucumber in ruby. I need each feature to run in a particular order and using the same browser window. Atm each feature creates a new window to run test in. Though in some test cases this behavior is desired- in many cases it is not. From my research so far it seems there are mixed answers about whether or not it is possible to drive the same browser window with selenium throughout test cases. Most answers I have run into were for other languages and were work arounds specific to a browser (I am developing my test while testing IE but will be expected to run these test in other browsers). I am working in Ruby and from what I have read it seems as though I'd have to make a class for the page? I'm confused as to why I would have to do this or how that helps.
my env.rb file:
require 'selenium-webdriver'
require 'rubygems'
require 'nokogiri'
require 'rspec/expectations'
Before do
#driver ||= Selenium::WebDriver.for :ie
#accept_next_alert = true
#driver.manage.timeouts.implicit_wait = 30
#driver.manage.timeouts.script_timeout = 30
#verification_errors = []
end
After do
##driver.quit
##verification_errors.should == []
end
Some information I've gathered so far of people with similar problems:
https://code.google.com/p/selenium/issues/detail?id=18
Is there any way to attach an already running browser to selenium webdriver in java?
Please ask me questions if anything about my question is not clear. I have many more test to create but I do not want to move on creating test if my foundation is sloppy and missing requested capabilities. (If you notice any other issues within my code please point them out in a comment)
The Before hook is run before each scenario. This is why a new browser is opened each time.
Do the following instead (in the env.rb):
require "selenium-webdriver"
driver = Selenium::WebDriver.for :ie
accept_next_alert = true
driver.manage.timeouts.implicit_wait = 30
driver.manage.timeouts.script_timeout = 30
verification_errors = []
Before do
#driver = driver
end
at_exit do
driver.close
end
In this case, a browser will be opened at the start (before any tests). Then each test will grab that browser and continue using it.
Note: While it is usually okay to re-use the browser across tests. You should be careful about tests that need to be run in a specific order (ie become dependent). Dependent tests can be hard to debug and maintain.
I had a similar problem in creating a spec_helper file. I did the following (simplified for locally-run firefox) for my purposes and it works very, very reliably. RSpec will use the same browser window for all it blocks in your _spec.rb file.
Rspec.configure do |config|
config.before(:all) do
#driver = Selenium::WebDriver.for :firefox
end
config.after(:all) do
#driver.quit
end
end
If you switch to :each instead of :all, you can use a separate browser instance for each assertion block... again, with :each RSpec will give a new browser instance for each it. Both are useful depending on the circumstance.
As the answers solve the problem but do not answer the question "How to connect to an existing session".
I managed to do this with the following code since it is not officially supported.
# monkey-patch 2 methods
module Selenium
module WebDriver
class Driver
# Be able to set the driver
def set_bridge_to(b)
#bridge = b
end
# bridge is a private method, simply create a public version
def public_bridge
#bridge
end
end
end
end
caps = Selenium::WebDriver::Remote::Capabilities.send("chrome")
driver = Selenium::WebDriver.for(
:remote,
url: "http://chrome:4444/wd/hub",
desired_capabilities: caps
)
used_bridge = driver.bridge
driver.get('https://www.google.com')
# opens a new unused chrome window
driver2 = Selenium::WebDriver.for(
:remote,
url: "http://chrome:4444/wd/hub",
desired_capabilities: caps
)
driver2.close() # close unused chrome window
driver2.set_bridge_to(used_bridge)
driver2.title # => "Google"
Sadly this did not test work between 2 rescue jobs, will update this in the future when I made it work for my own use case.

How do I prevent Watir from auto closing firefox?

I am automating test cases using Ruby and Watir. One of my methods opens the web browser, but as soon as my script leaves the "open browser" method and goes to the next method (filling out forms within the browser), the browser auto closes. When I automate using the IE browser it will not close until it hits the IE.close statement, but with firefox it closes automatically. Is there any way to avoid this?
Code:
require 'rubygems'
require 'watir-webdriver'
require 'rexml/document'
def openbrowser
$user = "user"
$pass = "password"
ff = Watir::Browser.new :firefox
ff.goto "http://<some website>"
ff.text_field(:name, "username").set($user)
ff.text_field(:name, "password").set($pass)
ff.button(:value,"Sign In").click
ff.link(:xpath => "html/body/div[1]/div[2]/a[1]").click
ff.text_field(:name,"userID").set($ID)
ff.button(:value,"View User").click
ff.link(:xpath => "html/body/div[1]/ul[1]/li[2]/a").click
sleep 20
end
# Run Program
openbrowser
I was attempting to run this code in NetBeans, so this behavior may just be specific to that editor.
There were two causes I have found for it shutting down, first is when there is an error in the code, the browser will shut down as soon as an exception is thrown. Second, the browser shuts down at the end of the program if there is no sleep established.
I use the Test Unit class, I open the browser in the setup method and generally close it down in the teardown method, this works for me in IE & Firefox.
More information here, http://wiki.openqa.org/display/WTR/Test+Unit

Resources