├── README ├── Rakefile ├── cucumber.yml └── features ├── Rakefile ├── checkout.feature ├── cucumber.yml ├── pages ├── catalog_page.rb ├── checkout_page.rb └── shopping_cart_page.rb ├── purchase_books.feature ├── step_definitions ├── checkout_steps.rb └── purchase_books_steps.rb └── support ├── browser.rb ├── env.rb ├── hooks.rb ├── screenshot.rb └── watir_helper.rb /README: -------------------------------------------------------------------------------- 1 | This is the code from my UI Testing series on my blog. 2 | 3 | http://www.cheezyworld.com 4 | 5 | 6 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | $:.unshift(File.dirname(__FILE__) + '/../../lib') 2 | require 'cucumber/rake/task' 3 | 4 | Cucumber::Rake::Task.new do |t| 5 | t.cucumber_opts = %w{--format pretty} 6 | end 7 | 8 | Cucumber::Rake::Task.new(:cucumber_screenshot) do |t| 9 | t.cucumber_opts = %w{--format html --out report.html} 10 | end 11 | 12 | task :default => :cucumber -------------------------------------------------------------------------------- /cucumber.yml: -------------------------------------------------------------------------------- 1 | default: --format html --out report.html --format pretty --no-source 2 | focus: --format html --out report.html --format pretty --no-source --tag @FOCUS 3 | -------------------------------------------------------------------------------- /features/Rakefile: -------------------------------------------------------------------------------- 1 | $:.unshift(File.dirname(__FILE__) + '/../../lib') 2 | require 'cucumber/rake/task' 3 | 4 | Cucumber::Rake::Task.new do |t| 5 | t.cucumber_opts = %w{--format pretty} 6 | end 7 | 8 | Cucumber::Rake::Task.new(:cucumber_screenshot) do |t| 9 | t.cucumber_opts = %w{--format html --out report.html} 10 | end 11 | 12 | task :default => :cucumber -------------------------------------------------------------------------------- /features/checkout.feature: -------------------------------------------------------------------------------- 1 | Feature: Checking out after you complete your order 2 | As an online book buyer 3 | I need to provide my personal information 4 | so that the website can process my order 5 | 6 | Background: 7 | Given I am on the depot site 8 | 9 | Scenario: Filling in all fields 10 | When I purchase a book 11 | And I complete the order with: 12 | | name | address | email | pay_type | 13 | | Sam Smith | 1213 Main Street | sam@example.com | Credit card | 14 | Then I should see "Thank you for your order" 15 | 16 | Scenario: Name is required 17 | When I purchase a book 18 | And I complete the order leaving the "Name" field blank 19 | Then I should see an error message with "Name can't be blank" 20 | 21 | Scenario: Address is required 22 | When I purchase a book 23 | And I complete the order leaving the "Address" field blank 24 | Then I should see an error message with "Address can't be blank" 25 | 26 | Scenario: Email is required 27 | When I purchase a book 28 | And I complete the order leaving the "Email" field blank 29 | Then I should see an error message with "Email can't be blank" 30 | 31 | Scenario: Options for Pay with 32 | When I purchase a book 33 | And go to the checkout page 34 | Then the Pay with dropdown should contain "Check" 35 | And the Pay with dropdown should contain "Credit card" 36 | And the Pay with dropdown should contain "Purchase order" 37 | -------------------------------------------------------------------------------- /features/cucumber.yml: -------------------------------------------------------------------------------- 1 | default: --format html --out report.html --format pretty --no-source 2 | focus: --format html --out report.html --format pretty --no-source --tag @FOCUS 3 | -------------------------------------------------------------------------------- /features/pages/catalog_page.rb: -------------------------------------------------------------------------------- 1 | class CatalogPage 2 | include WatirHelper 3 | 4 | BOOK_MAPPING = { 5 | "Pragmatic Project Automation" => 1, 6 | "Pragmatic Unit Testing (C#)" => 2, 7 | "Pragmatic Version Control" => 3 8 | } 9 | 10 | def initialize(browser) 11 | @browser = browser 12 | end 13 | 14 | def visit 15 | visit_page 'http://localhost:3000/store' 16 | end 17 | 18 | def add_book_to_shopping_cart(name="Pragmatic Project Automation") 19 | @browser.button(:value => 'Add to Cart', :index => BOOK_MAPPING[name]).click 20 | ShoppingCartPage.new(@browser) 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /features/pages/checkout_page.rb: -------------------------------------------------------------------------------- 1 | 2 | class CheckoutPage 3 | include WatirHelper 4 | 5 | DEFAULT_DATA = { 6 | 'name' => 'Cheezy', 7 | 'address' => '123 Main Street', 8 | 'email' => 'cheezy@example.com', 9 | 'pay_type' => 'Check' 10 | } 11 | 12 | text_field(:name, :id => 'order_name') 13 | text_field(:address, :id => 'order_address') 14 | text_field(:email, :id => 'order_email') 15 | select_list(:pay_type, :id => 'order_pay_type') 16 | button(:place_order, :value => 'Place Order') 17 | 18 | def initialize(browser) 19 | @browser = browser 20 | end 21 | 22 | def complete_order(data={}) 23 | data = DEFAULT_DATA.merge(data) 24 | self.name = data['name'] 25 | self.address = data['address'] 26 | self.email = data['email'] 27 | self.pay_type = data['pay_type'] 28 | place_order 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /features/pages/shopping_cart_page.rb: -------------------------------------------------------------------------------- 1 | class ShoppingCartPage 2 | include WatirHelper 3 | 4 | QUANTITY_COLUMN = 1 5 | DESCRIPTION_COLUMN = 2 6 | EACH_COLUMN = 3 7 | TOTAL_COLUMN = 4 8 | HEADER_OFFSET = 2 9 | 10 | link(:checkout, :text => 'Checkout') 11 | link(:continue_shopping, :text => 'Continue shopping') 12 | cell(:cart_total, :class => 'total-cell') 13 | table(:shopping_cart, :index => 1) 14 | 15 | def initialize(browser) 16 | @browser = browser 17 | end 18 | 19 | def goto_checkout_page 20 | checkout 21 | CheckoutPage.new(@browser) 22 | end 23 | 24 | def quantity_for_line(line_number) 25 | cart_data_for_line(line_number)[QUANTITY_COLUMN].text 26 | end 27 | 28 | def description_for_line(line_number) 29 | cart_data_for_line(line_number)[DESCRIPTION_COLUMN].text 30 | end 31 | 32 | def each_for_line(line_number) 33 | cart_data_for_line(line_number)[EACH_COLUMN].text 34 | end 35 | 36 | def total_for_line(line_number) 37 | cart_data_for_line(line_number)[TOTAL_COLUMN].text 38 | end 39 | 40 | private 41 | 42 | def cart_data_for_line(line) 43 | shopping_cart[HEADER_OFFSET+line] 44 | end 45 | 46 | end 47 | -------------------------------------------------------------------------------- /features/purchase_books.feature: -------------------------------------------------------------------------------- 1 | Feature: Purchase Books 2 | In order to read 3 | An online shopper will need to purchase books 4 | 5 | Background: 6 | Given I am on the shopping page 7 | 8 | @focus 9 | Scenario: Verify cart with one book 10 | When I purchase "Pragmatic Project Automation" 11 | Then I should see "1" in the quantity for line 1 12 | And I should see "Pragmatic Project Automation" in the description for line 1 13 | And I should see "29.95" in the each for line 1 14 | And I should see "29.95" in the total for line 1 15 | And I should see "29.95" in the cart total 16 | 17 | 18 | Scenario: verify cart with two books 19 | When I purchase "Pragmatic Project Automation" 20 | And I continue shopping 21 | And I purchase "Pragmatic Project Automation" 22 | Then I should see "2" in the quantity for line 1 23 | And I should see "Pragmatic Project Automation" in the description for line 1 24 | And I should see "29.95" in the each for line 1 25 | And I should see "59.90" in the total for line 1 26 | And I should see "59.90" in the cart total 27 | 28 | Scenario: verify cart with two different books 29 | When I purchase "Pragmatic Project Automation" 30 | And I continue shopping 31 | And I purchase "Pragmatic Version Control" 32 | Then I should see "1" in the quantity for line 1 33 | And I should see "Pragmatic Project Automation" in the description for line 1 34 | And I should see "29.95" in the each for line 1 35 | And I should see "29.95" in the total for line 1 36 | And I should see "1" in the quantity for line 2 37 | And I should see "Pragmatic Version Control" in the description for line 2 38 | And I should see "28.50" in the each for line 2 39 | And I should see "28.50" in the total for line 2 40 | And I should see "58.45" in the cart total 41 | 42 | Scenario: Purchase two books 43 | When I purchase "Pragmatic Unit Testing (C#)" 44 | And I continue shopping 45 | And I purchase "Pragmatic Version Control" 46 | And I checkout 47 | And I enter "Cheezy" in the name field 48 | And I enter "123 Main Street" in the address field 49 | And I enter "cheezy@example.com" in the email field 50 | And I select "Credit card" from the pay type dropdown 51 | And I place my order 52 | Then I should see "Thank you for your order" 53 | 54 | Scenario: Our first high level scenario 55 | When I purchase "Pragmatic Unit Testing (C#)" 56 | And I checkout with 57 | | name | address | email | pay_type | 58 | | Cheezy | 123 Main Street | cheezy@example.com | Credit card | 59 | Then I should see "Thank you for your order" 60 | 61 | Scenario: Using some default data 62 | When I purchase a book 63 | And I checkout with 64 | | pay_type | 65 | | Credit card | 66 | Then I should see "Thank you for your order" 67 | 68 | Scenario: Using all default data 69 | When I purchase a book 70 | And I complete the order 71 | Then I should see "Thank you for your order" 72 | 73 | -------------------------------------------------------------------------------- /features/step_definitions/checkout_steps.rb: -------------------------------------------------------------------------------- 1 | 2 | Given /^I am on the depot site$/ do 3 | @catalog = CatalogPage.new(@browser) 4 | @catalog.visit 5 | end 6 | 7 | When /^I complete the order with:$/ do |table| 8 | @checkout_page = @shopping_cart.goto_checkout_page 9 | @checkout_page.complete_order(table.hashes.first) 10 | end 11 | 12 | When /^I complete the order leaving the "([^\"]*)" field blank$/ do |field| 13 | @checkout_page = @shopping_cart.goto_checkout_page 14 | @checkout_page.complete_order(field.downcase => "") 15 | end 16 | 17 | Then /^I should see an error message with "([^\"]*)"$/ do |message| 18 | @checkout_page.content.should include message 19 | end 20 | 21 | When /^go to the checkout page$/ do 22 | @checkout_page = @shopping_cart.goto_checkout_page 23 | end 24 | 25 | Then /^the Pay with dropdown should contain "([^\"]*)"$/ do |value| 26 | @checkout_page.pay_type_select_list.options.should include value 27 | end 28 | -------------------------------------------------------------------------------- /features/step_definitions/purchase_books_steps.rb: -------------------------------------------------------------------------------- 1 | 2 | Transform /^line (\d+)$/ do |line_string| 3 | line_string.to_i 4 | end 5 | 6 | Transform /^(\d+\.\d{2})$/ do |dollar_amount| 7 | "$#{dollar_amount}" 8 | end 9 | 10 | Given /^I am on the shopping page$/ do 11 | @catalog = CatalogPage.new(@browser) 12 | @catalog.visit 13 | end 14 | 15 | When /^I purchase "([^\"]*)"$/ do |book| 16 | @shopping_cart = @catalog.add_book_to_shopping_cart(book) 17 | end 18 | 19 | When /^I continue shopping$/ do 20 | @shopping_cart.continue_shopping 21 | end 22 | 23 | Then /^I should see "([^\"]*)" in the quantity for (line \d+)$/ do |quantity, line| 24 | @shopping_cart.quantity_for_line(line).should include quantity 25 | end 26 | 27 | Then /^I should see "([^\"]*)" in the description for (line \d+)$/ do |desc, line| 28 | @shopping_cart.description_for_line(line).should == desc 29 | end 30 | 31 | Then /^I should see "([^\"]*)" in the each for (line \d+)$/ do |each, line| 32 | @shopping_cart.each_for_line(line).should == each 33 | end 34 | 35 | Then /^I should see "([^\"]*)" in the total for (line \d+)$/ do |total, line| 36 | @shopping_cart.total_for_line(line).should == total 37 | end 38 | 39 | Then /^I should see "([^\"]*)" in the cart total$/ do |total| 40 | @shopping_cart.cart_total.should == total 41 | end 42 | 43 | 44 | When /^I checkout$/ do 45 | @checkout = @shopping_cart.goto_checkout_page 46 | end 47 | 48 | When /^I enter "([^\"]*)" in the name field$/ do |name| 49 | @checkout.name = name 50 | end 51 | 52 | When /^I enter "([^\"]*)" in the address field$/ do |address| 53 | @checkout.address = address 54 | end 55 | 56 | When /^I enter "([^\"]*)" in the email field$/ do |email| 57 | @checkout.email = email 58 | end 59 | 60 | When /^I select "([^\"]*)" from the pay type dropdown$/ do |pay_type| 61 | @checkout.pay_type = pay_type 62 | end 63 | 64 | When /^I place my order$/ do 65 | @checkout.place_order 66 | end 67 | 68 | Then /^I should see "([^\"]*)"$/ do |expected_text| 69 | @catalog.content.should include expected_text 70 | end 71 | 72 | And /^I checkout with$/ do |table| 73 | @checkout_page = @shopping_cart.goto_checkout_page 74 | @checkout_page.complete_order(table.hashes.first) 75 | end 76 | 77 | When /^I purchase a book$/ do 78 | @shopping_cart = @catalog.add_book_to_shopping_cart('Pragmatic Version Control') 79 | end 80 | 81 | And /^I complete the order$/ do 82 | @checkout_page = @shopping_cart.goto_checkout_page 83 | @checkout_page.complete_order 84 | end 85 | -------------------------------------------------------------------------------- /features/support/browser.rb: -------------------------------------------------------------------------------- 1 | if ENV['FIREWATIR'] 2 | require 'firewatir' 3 | Browser = FireWatir::Firefox 4 | else 5 | case RUBY_PLATFORM 6 | when /darwin/ 7 | require 'safariwatir' 8 | Browser = Watir::Safari 9 | when /win32|mingw/ 10 | require 'watir' 11 | Browser = Watir::IE 12 | when /java/ 13 | require 'celerity' 14 | Browser = Celerity::Browser 15 | else 16 | raise "This platform is not supported (#{PLATFORM})" 17 | end 18 | end 19 | 20 | 21 | -------------------------------------------------------------------------------- /features/support/env.rb: -------------------------------------------------------------------------------- 1 | require 'spec/expectations' 2 | 3 | -------------------------------------------------------------------------------- /features/support/hooks.rb: -------------------------------------------------------------------------------- 1 | 2 | Before do 3 | @browser = Browser.new 4 | end 5 | 6 | After do 7 | @browser.close 8 | end 9 | 10 | 11 | After do | scenario| 12 | embed_screenshot("screehshot=#{Time.new.to_i}") if scenario.failed? 13 | end 14 | -------------------------------------------------------------------------------- /features/support/screenshot.rb: -------------------------------------------------------------------------------- 1 | 2 | module Screenshots 3 | 4 | if Cucumber::OS_X 5 | def embed_screenshot(id) 6 | `screencapture -t png #{id}.png` 7 | embed("#{id}.png", "image/png") 8 | end 9 | elsif Cucumber::WINDOWS 10 | require 'watir/screen_capture' 11 | require 'win32/clipboard' 12 | 13 | include Watir::ScreenCapture 14 | include Win32 15 | 16 | def embed_screenshot(id) 17 | keybd_event = API.new("keybd_event", 'IILL', 'V', 'user32') 18 | keybd_event.call(VK_SNAPSHOT,0,0,0) 19 | File.open("#{id}.bmp", 'wb'){ |fh| 20 | fh.write Win32::Clipboard.data(Clipboard::DIB) 21 | } 22 | end 23 | else 24 | # Other platforms... 25 | def embed_screenshot(id) 26 | STDERR.puts "Sorry - no screenshots on your platform yet." 27 | end 28 | end 29 | end 30 | World(Screenshots) 31 | 32 | 33 | -------------------------------------------------------------------------------- /features/support/watir_helper.rb: -------------------------------------------------------------------------------- 1 | module WatirHelper 2 | # A helper class to make accessing web elements via Watir easier. 3 | # All methods take an identifier parameter. This parameter is 4 | # an array of hashes that are used to identify an element on the 5 | # page. On elements that support multiple attributes you can 6 | # provide multiple identifiers. 7 | # 8 | # This module assumes there is a @browser variable available. 9 | 10 | def self.included(cls) 11 | cls.extend ClassMethods 12 | end 13 | 14 | module ClassMethods 15 | # adds three methods - one to put data in a text field, another 16 | # to fetch that data, and another to return the actual text_field. 17 | # 18 | # Example: text_field(:first_name, {:id => "first_name}) 19 | # will generate the 'first_name', 'first_name=', and 20 | # 'first_text_field' methods 21 | def text_field(name, identifier) 22 | define_method(name) do 23 | @browser.text_field(identifier).value 24 | end 25 | define_method("#{name}=") do |value| 26 | @browser.text_field(identifier).set(value) 27 | end 28 | define_method("#{name}_text_field") do 29 | @browser.text_field(identifier) 30 | end 31 | end 32 | 33 | # adds three methods - one to put data in a hidden field, another 34 | # to fetch that data, and a third to return the hidden field. 35 | # 36 | # Example: hidden(:first_name, {:id => "first_name}) 37 | # will generate the 'first_name', 'first_name=' and 38 | # 'first_hidden' methods 39 | def hidden(name, identifier) 40 | define_method(name) do 41 | @browser.hidden(identifier).value 42 | end 43 | define_method("#{name}=") do |value| 44 | @browser.hidden(identifier).set(value) 45 | end 46 | define_method("#{name}_hidden") do 47 | @browser.hidden(identifier) 48 | end 49 | end 50 | 51 | # adds four methods - one to select an item in a drop-down, 52 | # another to fetch the currently selected item, 53 | # another to see if a particular value is selected 54 | # and another to return the select_list. 55 | # 56 | # Example: select_list(:state, {:id => "state"}) 57 | # will generate the 'state', 'state=', 'state_selected?' 58 | # and 'state_select_list' methods 59 | def select_list(name, identifier) 60 | define_method(name) do 61 | @browser.select_list(identifier).value 62 | end 63 | define_method("#{name}=") do |value| 64 | @browser.select_list(identifier).select(value) 65 | end 66 | define_method("#{name}_selected?") do |value| 67 | @browser.select_list(identifier).selected?(value) 68 | end 69 | define_method("#{name}_select_list") do 70 | @browser.select_list(identifier) 71 | end 72 | end 73 | 74 | # adds three methods - one to check, one to uncheck and 75 | # a third to return a checkbox 76 | # 77 | # Example: checkbox(:active, {:name => "is_active"}) 78 | # will generate the 'check_active', 'uncheck_active', and 79 | # 'active_checkbox' methods 80 | def checkbox(name, identifier) 81 | define_method("check_#{name}") do 82 | @browser.checkbox(identifier).set 83 | end 84 | define_method("uncheck_#{name}") do 85 | @browser.checkbox(identifier).clear 86 | end 87 | define_method("#{name}_checkbox") do 88 | @browser.checkbox(identifier) 89 | end 90 | end 91 | 92 | # adds four methods - one to select, another to clear, 93 | # another to determine if the button is set 94 | # and another to return a radio button 95 | # 96 | # Example: radio_button(:north, {:id => "north"}) 97 | # will generate 'select_north', 'clear_north', 98 | # 'select_set?' and'north_radio_button' methods 99 | def radio_button(name, identifier) 100 | define_method("select_#{name}") do 101 | @browser.radio(identifier).set 102 | end 103 | define_method("#{name}_set?") do 104 | @browser.radio(identifier).set? 105 | end 106 | define_method("clear_#{name}") do 107 | @browser.radio(identifier).clear 108 | end 109 | define_method("#{name}_radio_button") do 110 | @browser.radio(identifier) 111 | end 112 | end 113 | 114 | # adds three methods - one click a button, another 115 | # to click a button without waiting for the action to 116 | # complete, and a third to return the button. 117 | # 118 | # Example: button(:save, {:value => "save"}) 119 | # will generate the 'save', 'save_no_wait', and 120 | # 'save_button' methods 121 | def button(name, identifier) 122 | define_method(name) do 123 | @browser.button(identifier).click 124 | end 125 | define_method("#{name}_no_wait") do 126 | @browser.button(identifier).click_no_wait 127 | end 128 | define_method("#{name}_button") do 129 | @browser.button(identifier) 130 | end 131 | end 132 | 133 | # adds three methods - one to select a link, another 134 | # to select a link and not wait for the corresponding 135 | # action to complete, and a third to return the link. 136 | # 137 | # Example: link(:add_to_cart, {:text => "Add to Cart"}) 138 | # will generate the 'add_to_cart', 'add_to_cart_no_wait', 139 | # and 'add_to_cart_link' methods 140 | def link(name, identifier) 141 | define_method(name) do 142 | @browser.link(identifier).click 143 | end 144 | define_method("#{name}_no_wait") do 145 | @browser.link(identifier).click_no_wait 146 | end 147 | define_method("#{name}_link") do 148 | @browser.link(identifier) 149 | end 150 | end 151 | 152 | # adds a method that returns a table element 153 | # 154 | # Example: table(:shopping_cart, {:index => 1}) 155 | # will generate a 'shopping_cart' method 156 | def table(name, identifier) 157 | define_method(name) do 158 | @browser.table(identifier) 159 | end 160 | end 161 | 162 | # adds two methods - one to return the text within 163 | # a row and one to return a table row element 164 | # 165 | # Example: row(:header, {:id => :header}) will 166 | # generate a 'header' and 'header_row' method 167 | def row(name, identifier) 168 | define_method(name) do 169 | @browser.row(identifier).text 170 | end 171 | define_method("#{name}_row") do 172 | @browser.row(identifier) 173 | end 174 | end 175 | 176 | # adds a method to return the text of a table data element 177 | # and another one to return the cell object 178 | # 179 | # Example: cell(:total, {:id => "total"}) 180 | # will generate a 'total' method and a 'total_cell' 181 | # method 182 | def cell(name, identifier) 183 | define_method(name) do 184 | @browser.cell(identifier).text 185 | end 186 | define_method("#{name}_cell") do 187 | @browser.cell(identifier) 188 | end 189 | end 190 | 191 | # adds a method that returns the content of a
192 | # and another method that returns the div element 193 | # 194 | # Example: div(:header, {:id => "banner"}) 195 | # will generate a 'header' and 'header_div' methods 196 | def div(name, identifier) 197 | define_method(name) do 198 | @browser.div(identifier).text 199 | end 200 | define_method("#{name}_div") do 201 | @browser.div(identifier) 202 | end 203 | end 204 | 205 | # adds a method that returns the content of a

206 | # and another method that returns the div element 207 | # 208 | # Example: p(:header, {:id => "banner"}) 209 | # will generate a 'header' and 'header_p' methods 210 | def p(name, identifier) 211 | define_method(name) do 212 | @browser.p(identifier).text 213 | end 214 | define_method("#{name}_p") do 215 | @browser.p(identifier) 216 | end 217 | end 218 | 219 | 220 | # adds a method that returns the content of a

221 | # and another method that returns the dd element 222 | def dd(name, identifier) 223 | define_method(name) do 224 | @browser.dd(identifier).text 225 | end 226 | define_method("#{name}_dd") do 227 | @browser.dd(identifier) 228 | end 229 | end 230 | 231 | # adds a method that returns the content of a
232 | # and another that returns the dl element 233 | def dl(name, identifier) 234 | define_method(name) do 235 | @browser.dl(identifier).text 236 | end 237 | define_method("#{name}_dl") do 238 | @browser.dl(identifier) 239 | end 240 | end 241 | 242 | # adds a method that returns the content of a
243 | # and another that returns the dt element 244 | def dt(name, identifier) 245 | define_method(name) do 246 | @browser.dt(identifier).text 247 | end 248 | define_method("#{name}_dt") do 249 | @browser.dt(identifier) 250 | end 251 | end 252 | 253 | # adds a method that returns the content of a 254 | #
element and another that returns the 255 | # form element 256 | def form(name, identifier) 257 | define_method(name) do 258 | @browser.form(identifier).text 259 | end 260 | define_method("#{name}_form") do 261 | @browser.form(identifier) 262 | end 263 | end 264 | 265 | # adds a method that returns a the content of a 266 | # element and another that returns the 267 | # frame element 268 | def frame(name, identifier) 269 | define_method(name) do 270 | @browser.frame(identifier).text 271 | end 272 | define_method("#{name}_frame") do 273 | @browser.frame(identifier) 274 | end 275 | end 276 | 277 | # adds a method that returns an image element 278 | def image(name, identifier) 279 | define_method(name) do 280 | @browser.image(identifier) 281 | end 282 | end 283 | 284 | # adds a method that returns the content of an h1 285 | # and another method that returns the h1 element 286 | # 287 | # Example: h1(:header, {:id => "banner"}) 288 | # will generate a 'header' and 'header_h1' methods 289 | def h1(name, identifier) 290 | define_method(name) do 291 | @browser.h1(identifier).text 292 | end 293 | define_method("#{name}_h1") do 294 | @browser.h1(identifier) 295 | end 296 | end 297 | 298 | # adds a method that returns the content of an h2 299 | # and another method that returns the h1 element 300 | # 301 | # Example: h2(:header, {:id => "banner"}) 302 | # will generate a 'header' and 'header_h2' methods 303 | def h2(name, identifier) 304 | define_method(name) do 305 | @browser.h2(identifier).text 306 | end 307 | define_method("#{name}_h2") do 308 | @browser.h2(identifier) 309 | end 310 | end 311 | 312 | # adds a method that returns the content of an h3 313 | # and another method that returns the h3 element 314 | # 315 | # Example: h3(:header, {:id => "banner"}) 316 | # will generate a 'header' and 'header_h3' methods 317 | def h3(name, identifier) 318 | define_method(name) do 319 | @browser.h3(identifier).text 320 | end 321 | define_method("#{name}_h3") do 322 | @browser.h3(identifier) 323 | end 324 | end 325 | 326 | # adds a method that returns the content of an h4 327 | # and another method that returns the h4 element 328 | # 329 | # Example: h4(:header, {:id => "banner"}) 330 | # will generate a 'header' and 'header_h4' methods 331 | 332 | def h4(name, identifier) 333 | define_method(name) do 334 | @browser.h4(identifier).text 335 | end 336 | define_method("#{name}_h4") do 337 | @browser.h4(identifier) 338 | end 339 | end 340 | 341 | # adds a method that returns the content of an h5 342 | # and another method that returns the h5 element 343 | # 344 | # Example: h5(:header, {:id => "banner"}) 345 | # will generate a 'header' and 'header_h5' methods 346 | def h5(name, identifier) 347 | define_method(name) do 348 | @browser.h5(identifier).text 349 | end 350 | define_method("#{name}_h5") do 351 | @browser.h5(identifier) 352 | end 353 | end 354 | 355 | # adds a method that returns the content of an h6 356 | # and another method that returns the h6 element 357 | # 358 | # Example: h6(:header, {:id => "banner"}) 359 | # will generate a 'header' and 'header_h6' methods 360 | def h6(name, identifier) 361 | define_method(name) do 362 | @browser.h6(identifier).text 363 | end 364 | define_method("#{name}_h6") do 365 | @browser.h6(identifier) 366 | end 367 | end 368 | 369 | 370 | end 371 | 372 | def content 373 | @browser.text 374 | end 375 | 376 | def visit_page(page_url) 377 | @browser.goto(page_url) 378 | end 379 | 380 | def page_title 381 | @browser.title 382 | end 383 | 384 | def wait_for_page 385 | @browser.wait 386 | end 387 | end 388 | --------------------------------------------------------------------------------