Cheezy 页面对象中的可重用组件

Re-Usable Components in Cheezy Page Object

我正在使用芝士 page-object gem 和黄瓜。

我有一个 angular 网站的页面对象,许多页面包含 angular ng-select 元素,这是一个下拉列表。每个页面的所有 ng-select 元素都是相同的格式。唯一改变的是 ng-select 的数据和 ID。我想构建一些可重复使用的 ng-select 组件,我可以将其放入我的页面对象中,因为我在元素上使用了很多方法。

class NGSelectComponent
  include PageObject

  def wrapper(id)
    element(:element, tag_name: 'ng-select', id: id)
  end

  def wrapper_text_field
    wrapper.text_field_element
  end

  def wrapper_span
    wrapper.span_element(class: ['ng-value-label','ng-star-inserted'])
  end

  def wrapper_value
    wrapper_span.text
  end

  def wrapper_values
    wrapper.div_elements
  end
end

如您所见,包装器方法是 ng-select 元素,它采用定位器哈希的 id。据我所知。我看到了类似 this 的东西,但它看起来只适用于 HTML 元素。

如何使用页面对象 gem 将它变成可重用的组件?作为旁注,我在我的步骤定义中使用 on() 方法调用我的页面对象。例如 on(SomePage)。无论结果如何,我都觉得这很重要。

小部件和页面部分是可重用组件的两个选项。由于您可能希望为该字段设置 getters/setters,因此小部件是更好的选择。

小部件可以这样定义:

class NGSelectComponent < PageObject::Elements::Element
  def self.accessor_methods(accessor, name)   
    #
    # Define a getter
    #
    accessor.send(:define_method, "#{name}") do
      self.send("#{name}_element").value
    end

    #
    # Define a setter. Use "#{name}=" so that the widget can be used
    # in #populate_page_with
    # 
    #
    accessor.send(:define_method, "#{name}=") do |value|
      self.send("#{name}_element").set(value)
    end
  end

  def set(value)
    text_field_element.set(value)
  end

  def value
    text_field_element.value
  end

  def wrapper_text_field
    text_field_element
  end

  def wrapper_span
    span_element(class: ['ng-value-label','ng-star-inserted'])
  end

  def wrapper_value
    wrapper_span.text
  end

  def wrapper_values
    div_elements
  end

  PageObject.register_widget :ng_select, self, :element
end

页面对象将像任何其他访问器一样定义 ng-select 元素:

class TestPage
  include PageObject

  ng_select(:name, id: 'name')
end

为该字段指定页面 getter/setter - 例如:

page = TestPage.new(browser)
page.populate_page_with(name: 'My Name')
p page.name
#=> "My Name"