I'm using cheezy page-object
gem and cucumber.
I have page objects for an angular website and many pages contain angular ng-select
element which is a dropdown. All of the ng-select
elements are the same format for each page. The only thing that changes is the data and the id of the ng-select
. I'd like to build some re-usable ng-select
component that I can put in my page-objects as I have quite a few methods I use on the element.
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
As you can see the wrapper method is the ng-select
element and it takes an id for the locator hash. This is as far as I got. I saw something like this but it looks like it only works for HTML elements.
How can I turn this into a re-usable component using page-object gem? As a sidenote I call my page objects using the on()
method in my step definitions. So for example on(SomePage)
. I felt like that matters for however the solution turns out.
Widgets and page sections are the 2 options for re-usable components. As you will likely want to setup getters/setters for the field, widgets are the better choice.
The widget could be defined like:
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
Page objects would define the ng-select elements like any other accessor:
class TestPage
include PageObject
ng_select(:name, id: 'name')
end
Giving the page a getter/setter for the field - eg:
page = TestPage.new(browser)
page.populate_page_with(name: 'My Name')
p page.name
#=> "My Name"