Common Page elements - Can they be inherited?

cucumber, page-object-gem, ruby, watir-webdriver

Solution

It is possible to inherit from a parent class or include a module.

For example, I did the following test where the page object inherited from a parent class. It ran as expected.

test.feature

Feature: Search

    Scenario: Set google search field
    When google search field set

support\pages.rb

require 'watir-webdriver'
require 'page-object'

class CommonPage
    include PageObject

    text_field(:search, :name => 'q')
end

class PageA < CommonPage

end

steps\steps.rb

When /google search field set/ do
    b = Watir::Browser.new
    b.goto 'www.google.ca'
    page = PageA.new(b)
    page.search = 'test'    
end

Similar worked when including CommonPage as a module in PageA.

Possible Issues

The exceptions do not match what I would expect, but it is possible it is due to the line:

nav.link(:nav_activities, :href => "/activities/")

As far as I know and have tried, this will not work. `nav` will be undefined. I think you want to do (note that I think you also want a regex instead of a string):

link(:nav_activities){ search.link(:href => /activities/) }

Problem

In a cucumber/Watir-webdriver/page-object environment, I need to verify the presence and functionality of common header and footer links. While these should all be the same, and work, I'd like to include them on all of the relevant pages. I'm trying to keep up on DRY coding, and want to minimize the amount of times I need to identify Header/Footer elements that are shared on a web application. I thought I could do this by including somethings 'common_links.rb' in the support/ folder: ``` module CommonLinks include PageObject # Header links link(:log_out_header_link, :text => "Log Out") link(:logo, :id => "logo") #Logged in nav links div(:nav, :id => "globalnav_wrapper") nav.link(:nav_activities, :href => "/activities/") # Footer Links link(:contact_us_footer, :text => "CONTACT US") # Social Media Links link(:social_twitter, :id => "soc_twitter") link(:social_facebook, :id => "soc_fb") link(:social_pinterest, :id => "soc_pin") link(:social_google_plus, :id => "soc_gplus") link(:social_youtube, :id => "soc_yt") end ``` I'm trying to include the above in `support/pages/activities_page.rb`. When I attempt to load a cucumber feature that calls this, I get the following error: ``` /Users/user_name/.rvm/gems/ruby-2.0.0-p0/gems/page-object-0.8.6.1/lib/page-object/accessors.rb:1110:in `block (2 levels) in <module:Accessors>' /Users/user_name/svn/watir/cukes/client/features/support/common_links.rb:12:in `<module:CommonLinks>' /Users/user_name/svn/watir/cukes/client/features/support/common_links.rb:1:in `<top (required)>' /Users/user_name/.rvm/gems/ruby-2.0.0-p0/gems/cucumber-1.2.1/lib/cucumber/rb_support/rb_language.rb:129:in `load' /Users/user_name/.rvm/gems/ruby-2.0.0-p0/gems/cucumber-1.2.1/lib/cucumber/rb_support/rb_language.rb:129:in `load_code_file' /Users/user_name/.rvm/gems/ruby-2.0.0-p0/gems/cucumber-1.2.1/lib/cucumber/runtime/support_code.rb:171:in `load_file' /Users/user_name/.rvm/gems/ruby-2.0.0-p0/gems/cucumber-1.2.1/lib/cucumber/runtime/support_code.rb:83:in `block in load_files!' /Users/user_name/.rvm/gems/ruby-2.0.0-p0/gems/cucumber-1.2.1/lib/cucumber/runtime/support_code.rb:82:in `each' /Users/user_name/.rvm/gems/ruby-2.0.0-p0/gems/cucumber-1.2.1/lib/cucumber/runtime/support_code.rb:82:in `load_files!' /Users/user_name/.rvm/gems/ruby-2.0.0-p0/gems/cucumber-1.2.1/lib/cucumber/runtime.rb:175:in `load_step_definitions' /Users/user_name/.rvm/gems/ruby-2.0.0-p0/gems/cucumber-1.2.1/lib/cucumber/runtime.rb:40:in `run!' /Users/user_name/.rvm/gems/ruby-2.0.0-p0/gems/cucumber-1.2.1/lib/cucumber/cli/main.rb:43:in `execute!' /Users/user_name/.rvm/gems/ruby-2.0.0-p0/gems/cucumber-1.2.1/lib/cucumber/cli/main.rb:20:in `execute' /Users/user_name/.rvm/gems/ruby-2.0.0-p0/gems/cucumber-1.2.1/bin/cucumber:14:in `<top (required)>' /Users/user_name/.rvm/gems/ruby-2.0.0-p0/bin/cucumber:23:in `load' /Users/user_name/.rvm/gems/ruby-2.0.0-p0/bin/cucumber:23:in `<main>' /Users/user_name/.rvm/gems/ruby-2.0.0-p0/bin/ruby_noexec_wrapper:14:in `eval' /Users/user_name/.rvm/gems/ruby-2.0.0-p0/bin/ruby_noexec_wrapper:14:in `<main>' ``` I have also attempted to create a 'CommonPage' class, and inherit from that, but I'm getting an unitialized constant error. The CommonPage class is identical to the module. ``` class CommonPage include PageObject #Header links link(:log_out_header_link, :text => "Log Out") link(:logo, :id => "logo") #Logged in nav links div(:nav, :id => "globalnav_wrapper") nav.link(:nav_activities, :href => "/activities/") # Footer Links link(:contact_us_footer, :text => "CONTACT US") # Social Media Links link(:social_twitter, :id => "soc_twitter") link(:social_facebook, :id => "soc_fb") link(:social_pinterest, :id => "soc_pin") link(:social_google_plus, :id => "soc_gplus") link(:social_youtube, :id => "soc_yt") end ``` Attempting to use either of these approaches has not resulted in success. Has anyone had success declaring common links (like header/footer) in one file/module/class and then using them from another class? Any direction will be appreciated.

Original source