2013-03-25 57 views
2

在黄瓜/ Watir-webdriver /页面对象环境中,我需要验证常见页眉和页脚链接的存在和功能。虽然这些都应该是相同的,并且工作,但我想将它们包括在所有相关页面中。常见页面元素 - 它们可以被继承吗?

我试图跟上DRY编码,并且希望最小化我需要确定在Web应用程序上共享的页眉/页脚元素的次数。

我以为我可以通过在支持/文件夹出头“common_links.rb”做到这一点:

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 

我想包括在support/pages/activities_page.rb以上。当我试图加载黄瓜功能调用此,我得到以下错误:

/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>' 

我还试图建立一个“CommonPage”级,并从继承,但我发现了一个未初始化常数错误。 CommonPage类与模块相同。

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 

试图使用这两种方法都没有成功。

有没有人成功地在一个文件/模块/类中声明通用链接(如页眉/页脚),然后从另一个类中使用它们?

任何方向将不胜感激。

回答

4

可以从父类继承或包含模块。

例如,我做了以下测试,其中页面对象从父类继承。它按预期运行。

test.feature

Feature: Search 

    Scenario: Set google search field 
    When google search field set 

支持\ pages.rb

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

class CommonPage 
    include PageObject 

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

class PageA < CommonPage 

end 

步骤\ 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 

类似,包括CommonPage在网页A模块时工作。

可能出现的问题

例外的不匹配是我所期望的,但有可能是由于线路:

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

据我所知,并尝试,这不管用。 nav将是未定义的。我想你想要做的(请注意,我想你也希望有一个正则表达式,而不是一个字符串):

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

贾斯汀 - 感谢洞察力。我得到了这个工作,其中一部分是由于我使用的'nav'声明。我试图抓住嵌套的元素,但必须实现在https://github.com/cheezy/page-object/wiki/Nested-Elements提供的指导 - 在这里感谢您的帮助和以前的职位,你回答! – 2013-03-25 22:57:07

1

这是Test-Factory gem的标准功能。它旨在用Watir-webdriver支持页面对象和数据对象。由于没有硒的支持,因此它更简化了一些。我正在使用我为气候创造的黄瓜测试。COM

下面是一个例子从我的代码(具有权限共享)

base_page.rb

class BasePage < PageFactory 

    class << self 

    def header_elements 
     element(:logo) { |b| b.link(:id => "logo") } 
     element(:session_links) { |b| b.ul(:id => "session-links")} 
     element(:logout_link) { |p| p.session_links.link(:text => "Log Out") } 
     element(:login_link) { |p| p.session_links.link(:text => "Login") } 
     value(:current_user) { |p| p.session_links.li.text } 

     action(:login) { |p| p.login_link.click } 
     action(:logout) { |p| p.logout_link.click } 
    end 

    def footer_elements 
     #todo add all the footer elements once we have tests that need them 
     #climate_dot_com_link 
     #about_twi_link 
     #about_tcc_link 
     #legal_tou_link 
    end 

    def grower_nav 
     element (:grower_appnav) {|b|b.div(:class => "appnav-container")} 

     element (:dashboard_link) { |p|p.grower_appnav.link(:text => /Dashboard/)} 
     action (:dashboard) { |p|p.dashboard_link.click} 
     element (:field_weather_link) { |p|p.grower_appnav.link(:text => /Field Weather/)} 
     action (:field_weather) { |p|p.field_weather_link.click} 
     element (:forecast_link) { |p|p.grower_appnav.link(:text => /Forecast/)} 
     action (:forecast) { |p|p.forecast_link.click} 
     element (:toolbox_link) { |p|p.grower_appnav.link(:text => /Toolbox/)} 
     action (:toolbox) { |p|p.toolbox_link.click} 
     element (:crop_impact_link) { |p|p.grower_appnav.link(:text => /Crop Impact/)} 
     action (:crop_impact) { |p|p.crop_impact_link.click} 
     element (:policies_link) { |p|p.grower_appnav.link(:text => /Policies/)} 
     action (:policies) { |p|p.policies_link.click} 
     element (:settings_link) { |p|p.grower_appnav.link(:text => /Settings/)} 
     action (:settings) { |p|p.settings_link.click} 
     element (:help_link) { |p|p.grower_appnav.link(:text => /Help/)} 
     action (:help) { |p|p.help_link.click} 

    end 

    def agent_nav 
     element (:tcc_appnav) { |b| b.div(:id => "tcc_appnav")} 

     element (:home_link) { |p|p.tcc_appnav.link(:text => /Home/)} 
     action (:home) { |p|p.home_link.click} 
     element (:clients_link) { |p| p.tcc_appnav.link(:text => /Clients/)} 
     action (:clients) { |p| p.clients_link.click} 
     element (:policies_link) { |p|p.tcc_appnav.link(:text => /Policies/)} 
     action (:policies) { |p|p.policies_link.click} 
     element (:quotes_link) { |p|p.tcc_appnav.link(:text => /Quotes/)} 
     action (:quotes) { |p|p.quotes_link.click} 
     element (:sales_tools_link) { |p|p.tcc_appnav.link(:text => /Sales Tools/)} 
     action (:sales_tools) { |p|p.sales_link.click} 
     element (:marketing_hub_link) { |p|p.tcc_appnav.link(:text => /Marketing Hub/)} 
     action (:marketing_hub) { |p|p.marketing_hub.click} 
     element (:agents_link) { |p|p.tcc_appnav.link(:text => /Agents/)} 
     action (:agents) { |p|p.agents_link.click} 
     element (:policy_docs_link) { |p|p.tcc_appnav.link(:text => /Policy Docs/)} 
     action (:policy_docs) { |p|p.policy_docs.click} 
     element (:users_link) { |p|p.tcc_appnav.link(:text => /Users/)} 
     action (:users) { |p|p.users_link.click} 
     element (:licenses_link) { |p|p.tcc_appnav.link(:text => /Licenses/)} 
     action (:licenses) { |p|p.licenses_link.click} 

    end 

    def notifications 
     element (:agent_notification_bar) { |b|b.div(:class => "agent-notification-bar")} 
     value (:agent_notification_header) { |p|p.agent_notification_bar.h4.text} 
     value (:agent_notification_message) { |p|p.agent_notification_bar.text} 
     action (:return_to_client_details) { |p|p.agent_notification_bar.link(:text => "Return to Client Details").click} 

     element (:modal_dialog) { |b|b.div(:class => "modal-inner-wrapper")} 
     value (:modal_header) { |p|p.modal_dialog.div(:class => "modal-header").text} 
     value (:modal_body) { |p|p.modal_dialog.div(:class => "modal-body").text} 
    end 
    end 
end 

register.rb自注册页面撕开,具有页脚元素,但不标头或导航

class Register < BasePage 

    page_url "#{$test_site}/preso/register.html" 

    footer_elements 

    element(:first_name) { |b|b.text_field(:id => "first_name")} 
    element(:last_name) { |b|b.text_field(:id => "last_name")} 
    element(:email) { |b|b.text_field(:id => "email")} 
    element(:phone) { |b|b.text_field(:id => "phone")} 
    element(:zip_code) { |b|b.text_field(:id => "zip_code")} 
    element(:password) { |b|b.text_field(:id => "self_reg_password")} 
    element(:confirm_password) { |b|b.text_field(:id => "self_reg_confirm_password")} 
    element(:has_agent) { |b|b.select(:id => "has_agent")} 
    element(:agents_name) { |b|b.text_field(:id => "source")} 
    element(:contact_me) { |b|b.checkbox(:id => "contact_me")} 
    element(:agree_to_terms) { |b|b.checkbox(:id => "terms")} 
    button ("Create Account") 
    element(:spinner) { |b|b.div(:class => "spinner")} 
    action(:wait_on_spinner) { |p|p.spinner.wait_while_present} 

    element(:agree_to_terms_required_message) {|b|b.div(:class => "terms-error")} 

end 

agent_ clients.rb一页accessable到 '代理人' 类别的用户

class AgentClients < BasePage 

    page_url "#{$test_site}/apps/admin/named_insureds?q[enabled_eq]=true" 

    header_elements 
    footer_elements 
    agent_nav 

    expected_element :session_links 

    element (:client_list_table) { |b|b.table(:id => "named_insureds")} 

end 

dashboard.rb一页accessable为 '种植者' 类用户(不同NAV)

class Dashboard < BasePage 

    page_url "#{$test_site}/apps/preso/growerapps/dashboard.html" 

    header_elements 
    footer_elements 
    grower_nav 
    notifications 

    expected_element :session_links 

    element(:sort_by_precip) { |b| b.button(:text => "Precip 7d") } 
    element(:sort_by_soil_moiosture) { |b| b.button(:text => "Soil Moisture") } 
    element(:sort_by_growth_stage) { |b| b.button(:text => "Growth Stage") } 

    element(:fields_list) { |b|b.divs(:class => "field-group-card")} 


end 
+0

感谢您使用Test-Factory gem的例子。我也会调查一下。我喜欢你在这里摆放的结构。谢谢! – 2013-04-02 18:02:26