How to enter password in a popup using watir? - ruby

I'm writing some watir test cases:
browser.goto "http://egauge2592.egaug.es/"
browser.link(:href,"/settings.html").click
browser.text_field(:index,4).set("some text")
browser.button(:id,"save_button").click
then a 'Authentication Required' dialogue opens, asking for username and password .
No matter how I tried, I couldn't access the text fields.
I tried send_keys and JavaScript.
I also tried Watir.autoit but it says undefined method.
I'm using watir on a Ubuntu machine with the FireFox browser.
How to fill in username and password fields of that dialogue box?
I was able to enter username with browser.alert.set but could only set username couldn't access password field.

I wrote a firefox plugin to deal with this problem recently. I haven't tried it with headless Firefox, but it might work... worth a try. See the following for details:
http://www.natontesting.com/2012/10/06/firefox-plugin-test-automation-password-manager/
To get it working with watir, try the following:
browser = Watir::Browser.new
#go to a page that won't bring up the authentication dialog...
browser.goto 'http://www.google.co.uk'
#prepare the script...
pass_man_update_script = <<-SCRIPT
var addCredentialsEvent = new CustomEvent("add_credentials_to_passman", {
detail: {
host: 'http://secure.example.com',
username: 'bob',
password: 'P45sword'
}
});
window.dispatchEvent(addCredentialsEvent);
SCRIPT
#inject the script into the browser:
browser.execute_script pass_man_update_script
#go to the page that prompts the dialog box...
browser.goto "http://secure.example.com"
#you should now be past the dialog box!

I use watir-webdriver instead and this (http://watirwebdriver.com/basic-browser-authentication/) works for me.

Just put your basic auth credentials in the url:
browser.goto "http://user:pass#egauge2592.egaug.es/"

Related

Selenium w/ Firefox not accepting HTTP Proxy IP with user authentication

I'm looking to use Selenium with a username/password authenticated proxy in Ruby. I realize that most people use ProxyChain when doing this in Chrome, but I'd like to use a solution without any additional gems since it doesn't play well on Heroku, plus I'm using Firefox so there seems to be a possible other option judging by THIS question though it's written in Python.
I used the selenium docs to translate that code to Ruby, but Selenium is still not using my proxy when navigating to a webpage. Oddly enough when I refresh the page manually it prompts me for the username/password but it doesn't do that on the initial page load.
profile = Selenium::WebDriver::Firefox::Profile.new
profile["network.proxy.type"] = 1
# proxy ip and port are fake for this example
profile["network.proxy.http"] = "182.192.157.60"
profile["network.proxy.http_port"] = 12345
# set the username and password
profile["network.proxy.socks_username"] = "my_username"
profile["network.proxy.socks_password"] = "my_password"
options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
driver = Selenium::WebDriver.for :firefox, options: options
If anyone has any ideas I would certainly appreciate the help. Thank you.

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"

Watir - Cannot get through basic authentication on IE8

I'm having trouble getting through basic authentication on one of our websites on IE8 using Watir.
When I navigate(goto) the url, the basic authentication dialog is displayed showing 'Connect to ' as the title, with user name, password edit fields and OK, Cancel buttons (the usual!).
In Watir, after passing the following code:
b = Watir::Browser.new
b.goto '<our url>'
the dialog is displayed but the goto statement never completes. If I cancel or login manually, then the goto statement returns a number (this is in IRB by the way).
I've done lots of investigation and tried out all sorts of ideas but now seem to be stumped!
When we login to the site manually, we have to pass our credentials like below:
User Name: <domain>\<username>
Password: <password>
I've tried this in the url string i.e.
http://<domain>\<username>:<password>#<url>:<port>
http://lnd\mbartram:mypassword#xxx.xx.xx.xx:xxxx
but this doesn't work in code or if I enter it manually in the address bar.
Perhaps I need to escape the \ part to get this to work but how?
Any help is greatly appreciated.
M.
Ok, using a bit of a hack but it works consistently for me. I'm using a simple Wscript.Shell SendKeys method. See below:
`start #{theURL]`
loginDialog = WIN32OLE.new('Wscript.Shell')
loginDialog.AppActivate('Connect to #{ip}')
sendKeys = "#{userName}{TAB}"
loginDialog.SendKeys(sendKeys)
sleep(1)
sendKeys = "#{password}{TAB}{ENTER}"
loginDialog.SendKeys(sendKeys)

Suppress auto-closing window in Watir

I am using Watir with Chromedriver to automate form submission on some website. I have to login and submit multiple forms. The problem is, when I click the submit button the page the page automatically closes, so when I goto('next_url') I get this error:
/Users/jackz/.rvm/gems/ruby-1.9.3-p327/gems/selenium-webdriver-2.27.2/lib/selenium/webdriver/remote/response.rb:52:in `assert_ok': 'auto_id' does not refer to an open tab (Selenium::WebDriver::Error::UnknownError)
The Watir instance is still there, but the window is closed. I could create a new instance every time, but then I would have to login again every time and this would take longer.
So how can I either:
Open a new window in the same Watir instance
or
Suppress the window from closing after I submit
require 'watir-webdriver'
#b = Watir::Browser.new :chrome
#b.goto(URL)
#b.buttons.first.click
#this is when the window closes
#b.goto(NEW_URL)
#then I get an error
Thanks
I figured out an answer to my own question. I can open a new window in Watir using javascript:
b = Watir::Browser.new
b.execute_script("window.open()")
b.windows.last.use
This opens a window where I can fill out the form, then when the window automatically closes I still have the original window to work with. Probably not the best solution, but it works for now.
Add this to your existing code if your using chrome. else, modify accordingly as per your browser.
This will keep the window open, and the current watir session active.
caps = Selenium::WebDriver::Remote::Capabilities.chrome("chromeOptions" => {'detach' => false})
browser = Watir::Browser.new :chrome
What Mrityunjeyan suggested above was in a right direction, but you need to change a few things to make it work.
caps = Selenium::WebDriver::Remote::Capabilities.chrome("chromeOptions" => {'detach' => true })
b = Watir::Browser.new('chrome', desired_capabilities: caps)
Check the documentation here.
https://sites.google.com/a/chromium.org/chromedriver/capabilities

Watir-webdriver: Script working on Firefox but failing on Chrome or Opera. why?

I'm testing this on ark.com..
the following code works perfectly for firefox with watir-webdriver but gives me an error for google chrome and opera browsers respectively.
heres the code:
require "rubygems"
require "watir-webdriver"
b = Watir::Browser.new :ff
b.goto "http://www.ark.com"
# Signing in
7.times{b.link(:text, "Sign in").flash}
sleep 3
b.link(:text, "Sign in").click
sleep 3
# Popup
b.text_field(:name, "login_email").set "email#gmail.com"
b.send_keys :tab
b.text_field(:name, "login_password").set "password"
b.button(:value, "Sign in").click
puts b.title
changing the code as follows gives me errors:
b = Watir::Browser.new :chrome
or
b = Watir::Browser.new :opera
I get the following error message:
You may only interact with visible elements (Selenium::WebDriver::Error::ElementNotVisibleError)
I've tried the following stack overflow suggestion to no avail How do I use Watir::Waiter::wait_until to force Chrome to wait?
Also, my code works perfectly in firefox but not in other browsers, why might this be the case?
Any help would be appreciated. Thanks.
As mentioned in some other posts, you can full screen the browser with the following:
screen_width = b.execute_script("return screen.width;")
screen_height = b.execute_script("return screen.height;")
b.driver.manage.window.resize_to(screen_width,screen_height)
b.driver.manage.window.move_to(0,0)
Then like anonygoose said, the sign in link should be there (assuming your screen isn't too small).
Looking at the website in both Chrome and Firefox I'd say there's some sort of bug or unwanted feature going on with it.
If the web browser you're using is too narrow in width the sign-up button disappears completely.
I'd say that's why you're getting strange errors.
Test this by maximizing the Chrome browser as soon as it launches. From my testing this allows the signup button to be found.
I am not sure of a way to maximize either browser by default, but perhaps someone else on here will know or be able to suggest a way to go about it.

Resources