Site Prism, Capybara: Selector with variable

4.2k views Asked by At

I'm mucking around with the site_prism to implement a Page Object Model in capybara. It looks very interesting.

How would I specify a selector such as "[data-id='x']" where x is an integer? Something like this:

class Home < SitePrism::Page
  set_url "http://www.example.com"
  element :row, "[data-id='@id']"
end

And then in my tests:

Then /^the home page should contain a row$/ do
  @home.should have_row 1234
end
3

There are 3 answers

1
Nat Ritmeyer On BEST ANSWER

Because SitePrism sets the element locator when the element is defined, what you've suggested doesn't work. To achieve what you've asked for, take a look at the following:

class Home < SitePrism::Page
  elements :rows, "tr[data-id]"

  def row_ids
    rows.map {|row| row['data-id']}
  end
end

Instead of mapping a single row, they're all mapped (using elements instead of element). A separate method called row_ids collects all of the rows that have 'data-id' value, maps all those values into a new array, and returns that new array.

The tests would then contain something like:

Then /^the home page should contain a row$/ do
  @home.row_ids.should include @id
end

...which will check that there is a row with an ID that matches @id.

Not as pretty, but it should work.

0
Hamza Izmail On

I solved it by doing the following - its a hack and by no means following page object pattern. But i couldn't work out the answers from above.

My feature:

 Then I click on book 3 from the list

....

My step looks something like this:

 Then /^I click on book (.*) from the list$/ do |index|
   page.method_find(index)
 end

In my page object class:

  def method_find(index)
    find(div > div > span.nth-child({index})).click
  end
0
alex.ikhelis On

Or, if you prefer this way, you can go 1 step further to what Nat suggested and define a row element as a simple method, which then can take id as an argument:

class Home < SitePrism::Page
    elements :rows, "tr[data-id]"

    def row_with_id(id)
         rows.find {|row| row['data-id'] == id.to_s}
    end
end

and then in your step definition

Then /^the home page should contain a row$/ do
    @home.row_with_id(1234).should_not be_nil
end