I'm setting up my page object model and I have sections that have the same name but with an added index at the end of each. I want to be able to have a collection of sections that I can iterate through based on the index and then call an element in that specific section

sections :sizes, Sizes, 'div[data-hr-id]'
def size_with_id(id)
  sizes.find {|size| size['data-hr-id'] == 'sizeRow' + id.to_s}
end

class Sizes < SitePrism::Section
  element :sizeName, '[data-hr-id="sizeName"] > input'
  element :sizePrice, '[data-hr-id="sizePrice"]'
  element :sizeCost, '[data-hr-id="sizeCost"]'
  element :sizeDefault, 'button[data-hr-id="sizeDefault"]'
  element :locationOverride, '[data-tooltip="Location Overrides"]'
  element :sizeReference, '[data-hr-id="sizeReference"]'
  element :sizeDelete, 'button[data-hr-id="sizeDelete"]'
end

so that in my test I can call it out like

@items_page.newItem.size_with_id(0).sizePrice.set '5.99'

note: the sizes sections are within the newItem section on the items_page

Is this possible?

I get this error message

Failure/Error: sizes.detect {|size| size['data-hr-id'] == 'sizeRow' + id.to_s}

     NoMethodError:
       undefined method `[]' for #<Sizes:0x00007fc5b66a7088>
1

There are 1 best solutions below

2
Ivan Neverov On

Short answer:

Sizes is a SitePrism::Section class and an attribute is not deligated to root_element here size['data-hr-id']. You can achieve the goal by doing the following.

sizes.detect {|size| size.root_element['data-hr-id'] == 'sizeRow' + id.to_s}

Long answer:

I'd rewrite the section definition:

sections :sizes, Size, 'div[data-hr-id*="sizeRow"]'

def size_with_id(id)
  sizes.find {|size| size.root_element['data-hr-id'] == 'sizeRow' + id.to_s}
end

class Size < SitePrism::Section
  element :size_name,         '[data-hr-id="sizeName"] > input'
  element :size_price,        '[data-hr-id="sizePrice"]'
  element :size_cost,         '[data-hr-id="sizeCost"]'
  element :size_default,      'button[data-hr-id="sizeDefault"]'
  element :location_override, '[data-tooltip="Location Overrides"]'
  element :size_reference,    '[data-hr-id="sizeReference"]'
  element :size_delete,       'button[data-hr-id="sizeDelete"]'
end
  • don't use camelcase for methods in Ruby
  • name section as singular Size instead of Sizes
  • Search for more exact section locator in if you have any other div with data-hr-id on the page it will be also found as Size section