Общие элементы страницы — могут ли они быть унаследованы?

В среде огурца/Watir-webdriver/page-object мне нужно проверить наличие и функциональность общих ссылок верхнего и нижнего колонтитула. Хотя все они должны быть одинаковыми и работать, я хотел бы включить их на все соответствующие страницы.

Я пытаюсь не отставать от СУХОГО кодирования и хочу свести к минимуму количество раз, которое мне нужно для идентификации элементов верхнего и нижнего колонтитула, которые совместно используются в веб-приложении.

Я подумал, что смогу сделать это, включив что-то 'common_links.rb' в папку support/:

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

Попытка использовать любой из этих подходов не привела к успеху.

Удалось ли кому-нибудь объявить общие ссылки (например, верхний/нижний колонтитул) в одном файле/модуле/классе, а затем использовать их из другого класса?

Любое направление будет оценено.


person Sonja Leaf    schedule 25.03.2013    source источник


Ответы (2)


Можно наследовать от родительского класса или включить модуль.

Например, я провел следующий тест, в котором объект страницы унаследован от родительского класса. Он работал, как и ожидалось.

тест.функция

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

шаги\шаги.рб

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/) }
person Justin Ko    schedule 25.03.2013
comment
Джастин - спасибо за понимание. У меня это заработало, и частично это было связано с объявлением nav, которое я использовал. Я пытался получить вложенные элементы, но мне пришлось выполнить руководство, представленное на github. com/cheezy/page-object/wiki/Nested-Elements — спасибо за помощь здесь и в предыдущих сообщениях, на которые вы ответили! - person Sonja Leaf; 26.03.2013

Это стандартная функция гема Test-Factory. Он предназначен для поддержки объектов страницы и объектов данных с помощью Watir-webdriver. Это немного более оптимизировано, так как нет поддержки селена. Я использую его с тестами на огурцы, которые создаю для 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 страница, доступная для пользователей класса «агент»

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  
person Chuck van der Linden    schedule 26.03.2013
comment
Спасибо за примеры с гемом Test-Factory. Я это тоже расследую. Мне нравится структура, которую вы изложили здесь. Спасибо! - person Sonja Leaf; 02.04.2013