Rahul
Rahul

Reputation: 321

How to iterate over a page-object table

What's the cleanest way to check that each row in the table has an edit link?

example code:

class AccountPage
  include PageObject
  table(:cards, id: 'cards')
  link(:edit, href: /edit/)
end

I want to be able to do something like this:

page.cards_element.each do |card|
  card.edit? should == true
end

This wont work as the each block will return a PageObject table row and the only option is to iterate again to get cells and then only cell text can be achieved I suppose.

Upvotes: 2

Views: 1311

Answers (1)

Justin Ko
Justin Ko

Reputation: 46846

Solution 1 - Nested Locator

The quickest solution would be use the nested element methods while iterating through the table rows.

class AccountPage
  include PageObject
  table(:cards, id: 'cards')
end

page = AccountPage.new(browser)
page.cards_element.each do |card|
  card.link_element(href: /edit/).visible?.should == true
end

The card.link_element(href: /edit/).visible? line is saying that for each card (ie table row), check that there is visible link element.

Solution 2 - Widget

The disadvantage of using the nested locator approach is that details of the page are now in the test code rather than the page object. This can be solved by using a custom widget.

You will need to define a widget that represents a table row:

class Card < PageObject::Elements::TableRow
  def edit_element
    link_element(href: /edit/)
  end
end
PageObject.register_widget :card, Card, :tr

The page object would then be defined to include the widget:

class AccountPage
  include PageObject
  cards(:card, :css => 'table#cards tr')
end

This then allows you to write the test as:

page = AccountPage.new(browser)
page.card_elements.each do |card|
  card.edit_element.visible?.should == true
end

Note that this will fail on the first row without an edit link. To improve readability and ensure all the rows are tested, I would suggest going to the expect syntax that includes an all method:

page = AccountPage.new(browser)
expect(page.card_elements.map(&:edit_element)).to all be_visible

Upvotes: 3

Related Questions