Webdriver in Ruby, how to make coke reusable by making classes - ruby

I have a simple webdriver test in ruby below:
require 'rubygems'
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :firefox
# example application under test
driver.get "https://dev08-olb.nz.thenational.com/ib4b/app/login"
element = driver.find_element :id => "accessId"
element.send_keys "123456"
element = driver.find_element :id => "userId"
element.send_keys "user1"
element = driver.find_element :id => "password"
element.send_keys "password1"
element.submit
if
"Hello".eql? driver.title
puts "Page title is #{driver.title}"
else
puts "damn it, it must be Monday"
end
driver.quit
In the future there will be lots of other cases require log in so we want to repeat as less as possible so we create the following two ruby scripts.
LogIn.rb
require 'rubygems'
require 'selenium-webdriver'
class LogIn
def initialize(accessID, user, pass)
#accessID = accessID
#user = user
#pass = pass
driver = Selenium::WebDriver.for :firefox
driver.get "https://dev08-olb.nz.thenational.com/ib4b/app/login"
element = driver.find_element :id => "accessId"
element.send_keys #accessID
element = driver.find_element :id => "userId"
element.send_keys #user
element = driver.find_element :id => "password"
element.send_keys #pass
element.submit
end
end
HelloWorld.rb
require 'rubygems'
require 'selenium-webdriver'
require './LogIn'
LogIn.new("123456","user1","password1")
driver = Selenium::WebDriver.for :firefox
if
"Hello".eql? driver.title
puts "Page title is #{driver.title}"
else
puts "damn it, it must be Monday"
end
driver.quit
However in HelloWorld.rb driver gets instantiated twice so two instance of the browser gets open at test execution, which is not desired. But if I don't instantiate driver in HelloWorld.rb, I can't access its property later.
What's your way of managing these kind of situation?
Your help is appreciated.
Thanks in advance.

This is more about how to program tests in Ruby, rather than Selenium specific. There are many ways of doing it.
Here is one, try initialize driver HelloWorld.rb, then pass it into Login.rb
HelloWorld.rb
require 'rubygems'
require 'selenium-webdriver'
require './LogIn'
driver = Selenium::WebDriver.for :firefox
LogIn.new(driver, "123456","user1","password1")
if
"Hello".eql? driver.title
puts "Page title is #{driver.title}"
else
puts "damn it, it must be Monday"
end
driver.quit
Login.rb
require 'rubygems'
require 'selenium-webdriver'
class LogIn
def initialize(driver, accessID, user, pass)
#driver = driver
#accessID = accessID
#user = user
#pass = pass
driver.get "https://dev08-olb.nz.thenational.com/ib4b/app/login"
element = driver.find_element :id => "accessId"
element.send_keys #accessID
element = driver.find_element :id => "userId"
element.send_keys #user
element = driver.find_element :id => "password"
element.send_keys #pass
element.submit
end
end

Related

How do I reference the Capybara driver for creating my pageobjects/specs.

I am attempting to use pageobjects along with with my Capybara specs but can't seem to properly reference the driver. Basically I want to be able to use the PageObjects to define the fields on the page (this is login_page.rb), but when I try to create the object in the spec, it is throwing errors with saying that the object is nil.
spec_helper.rb:
# frozen-string-literal: true
require 'rspec'
require 'capybara/rspec'
require 'capybara/dsl'
require 'selenium-webdriver'
require 'page-object'
# loading page object files
page_paths = File.join(Dir.pwd, 'spec', 'pages', '**', '*.rb')
puts 'foo'
Dir.glob(page_paths).each { |file| puts file}
Dir.glob(page_paths).each { |file| require file }
Capybara.register_driver :firefox do |app|
Capybara::Selenium::Driver.new(app, browser: :firefox)
end
Capybara.default_driver = :firefox
Capybara.app_host = *********** #redacted
Capybara.default_max_wait_time = 5
RSpec.configure do |config|
config.before(:all) do
#browser = Capybara::Selenium::Driver
end
config.before(:each) do
config.include Capybara::DSL
end
end
login_page.rb
class LoginPage
include Capybara::DSL
include PageObject
text_field(:username, id: 'username')
text_field(:password, id: 'password')
button(:login, id: 'loginButton')
def initialize(driver)
#driver = driver
end
end
login_spec.rb
require 'spec_helper'
describe 'On Login page' do
context 'using proper password' do
before(:each) do
visit('/')
end
it 'logs in as foo' do
login_page = LoginPage.new(#browser)
login_page.username = 'foo'
login_page.password = 'bar'
login_page.login
end
end
end
Assuming you're talking about the page-object gem - https://github.com/cheezy/page-object - it doesn't support Capybara, it supports watir-webdriver/watir and selenium-webdriver. Additionally Capybara::Selenium::Driver is a class not an object instance. As shown in the page-object readme you need to pass an object instance into your page objects constructor
#browser = Selenium::WebDriver.for :firefox
If you want a page object framework that supports Capybara you may want to look at something like site-prism instead.

How can I select multiple options from a select list in ruby using selenium webdriver

I want to select multiple options.
Then I want to verify it whether it is selected or not?
Here is my code:
require 'selenium-webdriver'
class Ques7
def test_multiple_select
driver = Selenium::WebDriver.for :firefox
driver.get(url)
driver.find_element(:xpath, './/*[#id="select_1"]').click
puts driver.find_element(:xpath, './/*[#id="select_1"]').selected?
driver.find_element(:xpath, './/*[#id="select_2"]').click
driver.find_element(:xpath, './/*[#id="select_4"]').click
puts driver.find_element(:xpath =>'.//*[#id="select_1"]',
:xpath => './/*[#id="select_2"]',:xpath => './/*[#id="select_4"]').selected?
end
end
obj = Ques7.new
obj.test_multiple_select

Fail to use statement IF in Selenium

Currently I'm trying use a statement IF (If a button appears in the page, then run the IF), see the method Login in the system:
If the button doesn't appear in the page, I would like to run the next method Remove and add new expense
require "selenium-webdriver"
require "rspec"
require "rspec/expectations"
describe "#Add simple expense and after add a receipt", :suitee => true do
before(:all) do
#driver = Selenium::WebDriver.for :chrome
#base_url = "http://sitetest.com"
#driver.manage.window.maximize
end
it "Login in the system" do
#driver.get(#base_url)
#driver.find_element(:id, "user_email").send_keys "rafael#gmail.com"
#driver.find_element(:id, "user_password").send_keys "123456"
#driver.find_element(:name, "commit").click
if(#driver.find_element(:css, ".btn.btn-lg.btn-success.btn-block").displayed?)
#driver.find_element(:css, ".btn.btn-lg.btn-success.btn-block").click
#driver.find_element(:css, ".introjs-button.introjs-skipbutton").click
#driver.find_element(:css, ".i.i-pencil").click
end
end
it "Remove and add new expense" do
begin
while(#driver.find_element(:css, ".i.i-pencil.icon").displayed?)
button = #driver.find_element(:id, "expense-bulk-select")
#driver.action.click(button).perform
delete = #driver.find_element(:id, "delete-multi-btn")
#driver.action.click(delete).perform
waitDisplayModal = Selenium::WebDriver::Wait.new(:timeout => 10)
waitDisplayModal.until {#driver.find_element(:class => "bootstrap-dialog-footer-buttons")}
#driver.find_element(:xpath, "//div[3]/div/div/button[2]").click
sleep 3
end
rescue Selenium::WebDriver::Error::NoSuchElementError
#driver.find_element(:id, "current_expense_merchant").send_keys "Taxi to work"
#driver.find_element(:id, "current_expense_amount").send_keys "50"
#driver.find_element(:id, "button-add-expense").click
waitDisplayIconTrash = Selenium::WebDriver::Wait.new(:timeout => 20)
waitDisplayIconTrash.until {#driver.find_element(:css => ".i.i-pencil.icon")}
end
end
after(:all) do
#driver.quit
end
end
My problem: When I run this script, appears this in my console:
Failure/Error: if(#driver.find_element(:css, ".btn.btn-lg.btn-success.btn-block").displayed?)
Selenium::WebDriver::Error::NoSuchElementError:
no such element
(Session info: chrome=42.0.2311.135)
(Driver info: chromedriver=2.9.248304,platform=Linux 3.13.0-24-generic x86_64)
That is, the IF is not working as I would like. How can I fix it?
CHeers
https://code.google.com/p/selenium/wiki/RubyBindings
Use the Wait class to explicitly wait for some condition:
wait = Selenium::WebDriver::Wait.new(:timeout => 3)
wait.until { driver.find_element(:css, ".btn.btn-lg.btn-success.btn-block").displayed? }
....

Ruby Page object Gem - Unable to pick a platform for the provided browser (RuntimeError)

I get this error on running my feature file.
Unable to pick a platform for the provided browser (RuntimeError)
Help required, please.
Here is the code;
class GooglePage
include PageObject
def self.visitor
visit("http://www.google.com")
end
end
env.rb
require 'selenium-webdriver'
require 'page-object'
require 'rubygems'
require 'page-object/page_factory'
World (PageObject::PageFactory)
#browser = Selenium::WebDriver.for :firefox
Step-Definitions
require_relative 'GooglePage'
Given(/^I am on the Google home page$/) do
visit(GooglePage)
# visit('http://www.google.com')
on(GooglePage).visitor
end
This won't work:
visit(GooglePage)
because you haven't called page_url in GooglePage (ln 4 below)
class GooglePage
include PageObject
page_url "http://www.google.com"
def self.visitor
visit("http://www.google.com")
end
end
Move the line #browser = Selenium::WebDriver.for :firefox to the Before method in hooks.rb
Before do
#browser = Selenium::WebDriver.for :firefox
end
After do
#browser.close
end
what if you make your rake file pass on tags and BROWSER and URL,e.g.
rake my_task BROWSER=chrome URL=http://google.com.au
and hooks will check if the BROWSER is chrome, then will use the specific Webdriver for chrome. But how to pass the URL in the PageObject?
Currently from hooks I have the ff:
when "chrome" then
caps = Selenium::WebDriver::Remote::Capabilities.chrome
caps.version = "40.0.2214.115 m"
caps.native_events = false
caps.javascript_enabled= true
# This is for increasing the default timeout to 180
client = Selenium::WebDriver::Remote::Http::Default.new
client.timeout = 180
browser = Selenium::WebDriver.for :chrome
browser.manage.window.maximize
end
Before do
browser.cookies.clear
#browser = browser
end
After do
unless ENV["BROWSER"].eql? "ie"
browser.close
sleep 2
end
end
Then on my HomePage pageobject I have the ff:
class HomePage
include PageObject
page_url("#{ENV['URL']}")
#opens the url defined in ENV['URL']
def goto_homepage
visit(HomePage)
end
end
Using Watir, the URL got opened, so trying this out in Selenium and it won't work.

Watir open multiple browser's or tab's

How can I open more than one browser using my code-watir, for example via a while loop from 0 to 10?
Here is my code:
require 'watir-webdriver'
require 'headless'
class Page
#headless = Headless.new
#headless.start
#browser = Watir::Browser.start 'bit.ly/***'
def self.get_connection
puts "Browser started"
puts #browser.title
#browser.driver.manage.timeouts.implicit_wait = 3 #3 seconds
#browser.select_list(:name => 'ctl00$tresc$111').select_value('6')
puts "Selected country"
#browser.select_list(:name => 'ctl00$tresc$222').wait_until_present
#browser.select_list(:name => 'ctl00$tresc$333').select_value('95')
puts "Selected city"
end
def self.close_connection
#browser.close
#headless.destroy
end
end
Page.get_connection
Page.close_connection
But how to do something like this?
while i < 10
Page.get_connection
end
This should open ten browsers:
10.times {Watir::Browser.new}
If you want to use the browsers later, you can put them in a hash:
browsers = {}
(0..9).each {|i| browsers[i] = Watir::Browser.new}
browsers[0].goto "google.com"
browsers[1].goto "yahoo.com"

Resources