Skip to content

Custom page object elements by using widgets.

Ivo Dimitrov edited this page Apr 12, 2020 · 3 revisions

Problem:

Often we need to interact with elements that are abstracted by so other element and selenium/watir will not let you directly perform actions on that element. As example I will use radio button that have a label element abstracting it to give nice styled looks to it.

Example HTML code:

<div class="flat-radio grid-col-6">
  <input type="radio" id="forwarding" name="forward-type" value="forwarding" aria-hidden="true">
  <label for="forwarding" class="forwarding no-cap">label text</label>
</div>

Now I'm only interested in radio_button element, however since element is not visible I cannot click on it or use page populator with it.

###Solution:

Instead of redefining methods on the page, in order to interact with abstracted elements that are not visible. Let's create new widget to handle new element pair, in particular radio_button have related label element that is defined using attribute for=#radio_button_id_attribute. Using the relations between radio_button and the label following widget was generated:

***Credit should go to @jkotests

class HiddenRadioButton < PageObject::Elements::RadioButton
  def self.accessor_methods(accessor, name)
    accessor.send(:define_method, "#{name}_selected?") do
      self.send("#{name}_element").selected?
    end

    accessor.send(:define_method, "select_#{name}") do
      self.send("#{name}_element").select
    end
  end

  def select
    label_element.click unless selected?
  end

  def visible?
    label_element.visible?
  end

  def label_element
    element.browser.label(for: element.id)
  end
end
PageObject.register_widget :hidden_radio_button, HiddenRadioButton, :radio

Now if you have styled radio_button all you need to change on your page class is change accessor.

module Pages
  class MyNewPage
    hidden_radio_button(:forward, label: 'forwarding')
  end
end   

This will let you interact with abstracted ratio_button just like it's regular simple radio button.