Reputation: 321
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
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