3

在 cucumber/Watir-webdriver/page-object 环境中,我需要验证常见页眉和页脚链接的存在和功能。虽然这些都应该是相同的,并且有效,但我想将它们包含在所有相关页面上。

我正在尝试跟上 DRY 编码,并希望最大限度地减少识别 Web 应用程序上共享的页眉/页脚元素所需的次数。

我想我可以通过在 support/ 文件夹中包含一些“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

2 回答 2

5

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

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

测试功能

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 作为一个模块包含在 PageA 中时,类似的工作。

可能的问题

异常与我的预期不符,但可能是由于以下行:

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

据我所知并尝试过,这是行不通的。nav将是未定义的。我认为您想要这样做(请注意,我认为您还想要一个正则表达式而不是字符串):

link(:nav_activities){ search.link(:href => /activities/) }
于 2013-03-25T21:49:19.210 回答
1

这是Test-Factory gem的标准功能。它是为使用 Watir-webdriver 支持页面对象和数据对象而设计的。由于不支持 selenium,因此它更加精简。我将它与我为climate.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 'agent' 类用户可访问的页面

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一个可供“种植者”类用户访问的页面(不同的导航)

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  
于 2013-03-26T22:27:10.250 回答