Capture the response from watir-webdriver - ruby

Is there a way to capture the entire response from a query submitted via a watir-webdriver object/request. For example if I took the sample code below, is there an element that will capture the entire page from the form submission so that I may parse it for errors?
#!/usr/bin/ruby
require 'watir-webdriver'
b = Watir::Browser.new
b.goto 'bit.ly/watir-webdriver-demo'
b.text_field(:id => 'entry_0').set 'your name'
b.select_list(:id => 'entry_1').select 'Ruby'
b.select_list(:id => 'entry_1').selected? 'Ruby'
b.button(:name => 'submit').click
b.text.include? 'Thank you'

The .html element will return the page's source.
puts b.html will return the source of the current page.

Related

How to open one browser in automation using ruby

I just want to know how to open one browser when i am going to test a loop. or how to clear the last inputted values in the login page to change it in the new values.
Assuming you're using watir-webdriver, you can instantiate a browser like this:
require 'watir-webdriver'
b = Watir::Browser.new
b.goto 'bit.ly/watir-webdriver-demo'
If you want to clear text entry fields, you can use the clear method:
require 'watir-webdriver'
b = Watir::Browser.new
b.goto 'bit.ly/watir-webdriver-demo'
b.text_field(:id => 'entry_1000000').set 'your name'
b.text_field(:id => 'entry_1000000').clear
I pulled this info from http://watirwebdriver.com/, so you may want to check that out.

How to create a Watir report in a .txt file?

I have a little test script to run in Watir that searches "books" on google images and then takes a screenshot of the result.
require "watir-webdriver"
browser = Watir::Browser.new :ie
browser.goto "http://www.google.com/"
puts browser.url
browser.a(:text => "Images").click
puts browser.title
browser.text_field(:name => "q").set "book"
browser.button(:value => "Search by image").click
browser.screenshot.save 'screenshots\search-results.png'
browser.close
However I would also like to include a log in a .txt file of the information I am "putting" into the console.
How would I go about doing this?
To do this I used:
require "watir-webdriver"
require 'logger'
$log = Logger.new('logs\search-books.log')
$log.info("** TEST 1 - Search books on google images and screenshot results **")
browser = Watir::Browser.new :chrome
browser.goto "http://www.google.com/"
$log.info("** PAGE URL **")
$log.info browser.url
browser.a(:text => "Images").click
$log.info("** PAGE TITLE **")
$log.info browser.title
browser.text_field(:name => "q").set "book"
browser.button(:value => "Search by image").click
browser.screenshot.save 'screenshots\search-results.png'
browser.close
By using Logger it allows you to create a log file (.log) and insert into it as you go along the script.

Nokogiri is not loading "browser" from Watir

I have this so far:
require 'watir-webdriver'
require 'date'
require 'nokogiri'
browser = Watir::Browser.start 'https://example/ViewReport.aspx'
browser.link(:text, 'Combined Employee Performance Report').click
today = Date.today
yesterday = today.prev_day.strftime('%m' '%d' '%Y')
t = browser.text_field :id => 'UC255_txtStart'
t.set yesterday
t = browser.text_field :id => 'UC255_txtEnd'
t.set yesterday
btn = browser.button :value, 'Run Report'
btn.exists?
btn.click
page = Nokogiri::HTML.parse('browser')
links = page.css("a")
puts links.length
When I try to parse browser, the variable that Watir is using for the site URI, it gives me a blank HTML page.
Problem
When you do
page = Nokogiri::HTML.parse('browser')
You are asking Nokogiri to parse the string 'browser'.
Solution
What you actually want to parse is the html in the browser.
To get the browser's html, you do:
browser.html
So to parse it, you would do:
page = Nokogiri::HTML.parse(browser.html)

post form parameters difference between Firefox and Ruby Mechanize

I am trying to figure out if mechanize sends correct post query.
I want to log in to a forum (please see html source, mechanize log in my other question) but I get only the login page again. When looking into it I can see that firefox sends out post with parameters like
auth_username=myusername&auth_password=mypassword&auth_login=Login but my script sends
auth_username=radek&auth_password=mypassword is that ok or the &auth_login=Login part must be present?
When I tried to add it using login_form['auth_login'] = 'Login' I got an error gems/mechanize-0.9.3/lib/www/mechanize/page.rb:13 inmeta': undefined method search' for nil:NilClass (NoMethodError)
It seems to me that auth_login is a form button not a field (I don't know if it matters)
[#<WWW::Mechanize::Form
{name nil}
{method "POST"}
{action
"http://www.somedomain.com/login?auth_successurl=http://www.somedomain.com/forum/yota?baz_r=1"}
{fields
#<WWW::Mechanize::Form::Field:0x36946c0 #name="auth_username", #value="">
#<WWW::Mechanize::Form::Field:0x369451c #name="auth_password", #value="">}
{radiobuttons}
{checkboxes}
{file_uploads}
{buttons
#<WWW::Mechanize::Form::Button:0x36943b4
#name="auth_login",
#value="Login">}>
]
My script is as follow
require 'rubygems'
require 'mechanize'
require 'logger'
agent = WWW::Mechanize.new {|a| a.log = Logger.new("loginYOTA.log") }
agent.follow_meta_refresh = true #Mechanize does not follow meta refreshes by default, we need to set that option.
page = agent.get("http://www.somedomain.com/login?auth_successurl=http://www.somedomain.com/forum/yota?baz_r=1")
login_form = page.form_with(:method => 'POST') #works
puts login_form.buttons.inspect
puts page.forms.inspect
STDIN.gets
login_form.fields.each { |f| puts "#{f.name} : #{f.value}" }
#STDIN.gets
login_form['auth_username'] = 'myusername'
login_form['auth_password'] = 'mypassword'
login_form['auth_login'] = 'Login'
STDIN.gets
page = agent.submit login_form
#Display message if logged in
puts page.parser.xpath("/html/body/div/div/div/table/tr/td[2]/div/strong").xpath('text()').to_s.strip
puts
puts page.parser.xpath("/html/body/div/div/div/table/tr/td[2]/div").xpath('text()').to_s.strip
output = File.open("login.html", "w") {|f| f.write(page.parser.to_html) }
You can find more code, html, log in my other related question log in with browser and then ruby/mechanize takes it over?
the absence of one parameter compare to firefox in POST caused mechanize not to log in. Adding new parameter solved this problem. So it seems to me that the web server requires &auth_login=Login parameter to be in POST.
You can read how to add new field to mechanize form in another question.

How to get redirect log in Mechanize?

In ruby, if you use mechanize following 301/302 redirects like this
require 'mechanize'
m = WWW::Mechanize.new
m.get('http://google.com')
how to get the list of the pages mechanize was redirected through? (Like http://google.com => http://www.google.com => http://google.com.ua)
OK, here is the code in mechanize responsible for redirection
elsif res_klass <= Net::HTTPRedirection
return page unless follow_redirect?
log.info("follow redirect to: #{ response['Location'] }") if log
from_uri = page.uri
raise RedirectLimitReachedError.new(page, redirects) if redirects + 1 > redirection_limit
redirect_verb = options[:verb] == :head ? :head : :get
page = fetch_page( :uri => response['Location'].to_s,
:referer => page,
:params => [],
:verb => redirect_verb,
:redirects => redirects + 1
)
#history.push(page, from_uri)
return page
but trying to m.history.map {|p| puts p.uri} shows 3 times the uri of last page..
The key here is to take advantage of the built in logging in Mechanize. Here's a full code sample using the built in Rails logging facilities.
require 'mechanize'
require 'logger'
mechanize_logger = Logger.new('log/mechanize.log')
mechanize_logger.level = Logger::INFO
url = 'http://google.com'
agent = Mechanize.new
agent.log = mechanize_logger
agent.get(url)
And then check the output of log/mechanize.log in your log directory and you'll see the whole mechanize process including the intermediate urls.
I'm not certain, but here are a couple of things to try:
see what's in m.history[i].uri after the get()
You might need something like:
for m.redirection_limit in 0..99
begin
m.get(url)
break
rescue WWW::Mechanize::RedirectLimitReachedError
# code here could get control at
# intermediate redirection levels
end
end

Resources