instantiating a page object in Ruby with Selenium and Cucumber - ruby

I'm trying to automatize a browser to navigate a website and click on different pages. To do this I have two classes AllPages and SearchPage which inherits from AllPages.
The first thing I do is instantiate AllPages, go to the website and click a link which leads me to a Searchpage, at which point I try to instantiate SearchPage using these lines of code
AllPages:
def return_search_page browser
#browser = browser
end
Steps:
#newpage = AllPages.new #browser
#searchpage = #newpage.return_search_page #newpage
#searchpage.find_searchbox
the error i get trying to run this is:
"undefined method `find_searchbox' for #< AllPages:0x00000002632cf0> (NoMethodError)"
My method find_searchbox which is located in SearchPage is this
def find_searchbox
#browser.find_element(:class, "searchbox")
end
I'm guessing i'm freaking up the instantiation of the object #searchpage, since that's in a scenario that comes after opening the browser and navigating to the website.
Any help will be appreciated

def return_search_page browser
SearchPage.new browser
end
#newpage = AllPages.new #browser
#searchpage = #newpage.return_search_page #browser
#searchpage.find_searchbox
And if you are setting #browser in your initialize, you wouldn't need to pass it in as a parameter to #return_seearch_page

Related

Ruby Watir -- Trying to loop through links in cnn.com and click each one of them

I have created this method to loop through the links in a certain div in the web site. My porpose of the method Is to collect the links insert them in an array then click each one of them.
require 'watir-webdriver'
require 'watir-webdriver/wait'
site = Watir::Browser.new :chrome
url = "http://www.cnn.com/"
site.goto url
box = Array.new
container = site.div(class: "column zn__column--idx-1")
wanted_links = container.links
box << wanted_links
wanted_links.each do |link|
link.click
site.goto url
site.div(id: "nav__plain-header").wait_until_present
end
site.close
So far it seems like I am only able to click on the first link then I get an error message stating this:
unable to locate element, using {:element=>#<Selenium::WebDriver::Element:0x634e0a5400fdfade id="0.06177683611003881-3">} (Watir::Exception::UnknownObjectException)
I am very new to ruby. I appreciate any help. Thank you.
The problem is that once you navigate to another page, all of the element references (ie those in wanted_links) become stale. Even if you return to the same page, Watir/Selenium does not know it is the same page and does not know where the stored elements are.
If you are going to navigate away, you need to collect all of the data you need first. In this case, you just need the href values.
# Collect the href of each link
wanted_links = container.links.map(&:href)
# You have each page URL, so you can navigate directly without returning to the homepage
wanted_links.each do |link|
site.goto url
end
In the event that the links do not directly navigate to a page (eg they execute JavaScript when clicked), you will need to collect enough data to re-locate the elements later. What you use as the locator will depend on what is known to be static/unique. As an example, I will assume that the link text is a good locator.
# Collect the text of each link
wanted_links = container.links.map(&:text)
# Iterate through the links
wanted_links.each do |link_text|
container = site.div(class: "column zn__column--idx-1")
container.link(text: link_text).click
site.back
end

Watir: How I can click button in IE popup windows

I have a customized popup IE window where there are buttons included into iframe. I can't click on any button in it. I know how to work with iframes, but I can't switch to this window. Window has title and URL.
I wrote this method:
def confirm_ok
self.in_iframe(:id => 'frmMain') do |frame|
self.button_element(:id => 'btnOK', :frame => frame).click
end
end
But I get this error:
Watir::Exception::UnknownFrameException: unable to locate iframe using {:id=>"frmMain", :tag_name=>"iframe"}
I use Watir, PageObject. And run scenarios under IE.
Watir's method doesn't work:
browser.window(:title => "annoying popup").use do
browser.button(:id => "close").click
end
I get error
NoMethodError: undefined method `window' for #<PA_Main:0x33f6780>
As best as I can tell you have two separate issues.
Firstly, I have no idea how you set your browser variable to a page object instance. The Page Object Module definitely sets browser as a readable attribute.
So if the code is within a class that has import PageObject, you should be able to do browser.window(...) just fine.
If you are using the code outside of such a class, you need to make sure that you are in a scope that has access to the Watir::Browser instance. If you have a page object defined, you can use it like: my_page_object.browser.window(...)
Secondly - based on what you are describing, the iframe usage has to be combined with the window usage:
browser.window(title: "annoying popup") do
browser.iframe(id: 'frmMain').button(id: "close").click
end

Strange redirecting with koala gem

I'm using ruby, sinatra, and the koala gem to create an app for facebook.
When I redirect to /auth/facebook It does what is needed, however it first redirects to a page with this rectangle, then goes to the auth dialog. I think this is very ugly for the end user. How can I remove this strange redirection?
Code:
#This function defines a get and post route with the same parameters.
def get_or_post(path, opts={}, &block)
get(path, opts, &block)
post(path, opts, &block)
end
get "/auth/facebook/?" do
redirect authenticator.url_for_oauth_code(:permissions => FACEBOOK_SCOPE)
end
get_or_post '/auth/facebook/callback/?' do
session[:access_token] = authenticator.get_access_token(params[:code])
update_user()
redirect '/'
end
I guess you are doing the redirect inside of the canvas iframe? That of course would try to display the auth dialog inside of that iframe, and the auth dialog does not want to be displayed in any kind of (i)frame.
So instead of redirecting (where you can not specify a target), use JavaScript to “redirect” – have your script put out a small HTML document, that basically just contains one line of JavaScript, that uses
top.location.href = '{auth dialog URL goes here}';
to load a new URL in the top frame of the current browser window.

How do you get window titles, ids, and names in selenium-webdriver?

Im trying to implement the following methods from selenium-webdriver (ruby)
get_all_window_ids
get_all_window_titles
get_all_window_names
I ran Selenium IDE and exported my script to Ruby Test::Unit. Saved it as .rb
Opened my script for editing using Aptana Studio 3
Initial code snippet as follows:
require "rubygems"
require "selenium-webdriver"
require "test/unit"
class SwitchToPopup3 < Test::Unit::TestCase
def setup
#driver = Selenium::WebDriver.for :firefox
#base_url = (URL of my test website)
#driver.manage.timeouts.implicit_wait = 30
#verification_errors = []
end
def teardown
#driver.quit
assert_equal [], #verification_errors
end
def test_switch_to_popup3
.
.
puts #driver.get_all_window_ids()
puts #driver.get_all_window_titles()
puts #driver.get_all_window_names()
.
.
end
The error I keep getting is
NoMethodError: undefined method `get_all_window_ids' for # <Selenium::WebDriver::Driver:0x101e4b040 browser=:chrome>
/Users/rsucgang/Documents/Aptana Studio 3 Workspace/Testing/SwitchToPopup2.rb:37:in `test_switch_to_popup3'
I've studied the documentation for the ruby bindings for selenium-webdriver
http://selenium.googlecode.com/svn/trunk/docs/api/rb/Selenium/Client/GeneratedDriver.html#get_all_window_titles-instance_method
Ultimately my goal here is to run my automation script:
Click on a link that opens a new window with target=_blank and no windowID available (does not implement JS)
Identify the names of all opened windows in the browser
switch to a new pop-up window using the switchToWindow(name) method
continue running my script on that pop-up window
I've googled and researched this on the internet and I have not gotten any much information.
Thanks and please let me know if you need more information.
OSL Mac OSX 10.7.3
Ruby: ruby 1.8.7 (2010-01-10 patchlevel 249) [universal-darwin11.0]
Browser: Firefox 9.0.1 (Mac)
Chrome: Chrome 17.0.963.79 (Mac)
Selenium-Server: Ruby gem 2.20.0
Justin, you have a good approach. But there is a gotcha in assuming that the window handles will return in the correct order. This isn't always the case across all browsers. I outline a slightly different approach in my free weekly Selenium tip newsletter (elemental-selenium.com).
It goes like this:
#driver.get 'http://the-internet.herokuapp.com/windows'
main_window = #driver.window_handle
#driver.find_element(css: '.example a').click
windows = #driver.window_handles
windows.each do |window|
if main_window != window
#new_window = window
end
end
#driver.switch_to.window(main_window)
#driver.title.should_not =~ /New Window/
#driver.switch_to.window(#new_window)
#driver.title.should =~ /New Window/
You can see the full tip here.
The problem is that the get_all_window_ids is for Selenium::Client rather than Selenium::Webdriver. I believe that Selenium::Client is the old version Selenium and the API is not the same as Selenium::Webdriver (see here). Since you are using Selenium::Webdriver, this explains why you get an 'undefined method' error.
For Selenium::Webdriver, the only way I know how to switch between windows is using:
#driver.switch_to.window("<window_handle>")
You can get all the known window_handles by:
#driver.window_handles
#=> Returns all window handles as an array of strings
If you want to switch to the popup you just opened you can do the following. Note that this assumes .window_handles are in the order that the windows were opened, which I believe is true:
#driver.switch_to.window #driver.window_handles.last
To summarize, assuming you only care about accessing the popup (and not about accessing by name) you can do:
#Click control that opens popup
#driver.find_element(:id, 'button that opens popup').click
#Switch to popup
#driver.switch_to.window #driver.window_handles.last
#Do actions in new popup
#driver.find_element(:id, 'id of element in popup').click
Note that if after working with the popup, you will want to return to the original window, then I suggest you do the following. By passing a block to the switch_to.window, the block will be executed in the popup and when the block ends #driver will automatically point back to the original window.
#Click control that opens popup
#driver.find_element(:id, 'button that opens popup').click
#Switch to popup
#driver.switch_to.window( #driver.window_handles.last ){
#Do actions in new popup
#driver.find_element(:id, 'id of element in popup').click
}
#Continue with original window
#driver.find_element(:id, 'button in original window').click

Watir can't locate frame which houses an element in Firefox but works fine in IE

I have a script:
BROWSER.frame( :name, 'FRAME_NAVIGATION' ).span(:text=>'foo').fire_event('onmouseup')
which clicks on elements of a tree view (inside a frame) which works great in IE, but when I set:
require 'watir'
Watir::Browser.default = 'firefox'
and run it I get:
Failure/Error:
BROWSER.frame( :name, 'FRAME_NAVIGATION').span(:text=>'foo').fire_event('onmouseup')
Watir::Exception::UnknownFrameException:
Unable to locate a frame using name and FRAME_NAVIGATION.
I get this with any elements inside a frame on my page. Not just the tree view. I've tried requiring firewatir as well, or just on its own with no luck.
Any insight would be greatly appreciated!
Thanks,
-M
You're not using the frame method correctly. Try this way:
BROWSER.frame(:name => 'FRAME_NAVIGATION').span(:text => 'foo').fire_event('onmouseup')
You may be able to diagnose the problem by adding a BROWSER.show_frames call. That would tell you what Firefox thinks it can see.

Resources