GlyphGryph GlyphGryph - 6 months ago 30
Ruby Question

Finding if a content exists in a given column in a table, with Capybara or Xpath?

Problem:
Given a table, a specific piece of content should appear in the same column as a specific header.

Clarification:
I can not test the column position numerically, or at least I can't hardcode it that way, since the number of columns can change based on various other conditions and I don't want to make my test that fragile.

Example:

Name || Phone Number || Address
==============================================================
... || ... || ...
Joe || 555-787-7878 || 42 Nowhere Lane, Mulberry, California
... || ... ||


With the code looking like so:

<table>
<tr>
<th>Name</th>
<th>Phone Number</th>
<th>Registered</th>
<th>Address</th>
</tr>
<tr>
...
</tr>

<tr>
<td>Joe</td>
<td>555-377-7347</td>
<td>Yes</td>
<td>42 Nowhere Lane1, Mulberry1, California</td>
</tr>
<tr>
<td>Jerry</td>
<td>555-787-7878</td>
<td>Yes</td>
<td>50 Nowhere Lane, Mulberry, California</td>
</tr>

<tr>
<td>Tom</td>
<td>555-678-0987</td>
<td>No</td>
<td>43 Nowhere Lane2, Mulberry2, California</td>
</tr>
<tr>
...
</tr>
</table>


Scenario:
I want to insure the correct address (42 Nowhere...) appears in the column with the header "Address".

How can I do this?

The solution might be as simple as a decent xpath query, to be honest, perhaps I don't even need anything particularly "Capybara" related!

I came across similar one, but here I need to check whether 'Jerry' registered or not. Please help me how can i automate using ruby/capybara

Thanks in Advance

Answer

I think @Snekse is very close. Here are some expressions that have been tested. The following returns the table cell corresponding to the th whose value is Address:

/table/tr/td[(count(../../tr/th[.='Address']/preceding-sibling::*)+1)]

This can be used to get the value of the cell:

42 Nowhere Lane, Mulberry, California

...which you could then use to perform the final test:

/table/tr/td[(count(../../tr/th[.='Address']/preceding-sibling::*)+1)]
                               [.='42 Nowhere Lane, Mulberry, California']

This will return the cell itself, if the addresses match. It will return an empty node-set, which will evaluate to false in a boolean context, if no such node exists.

You probably also need to specify the row you're testing, which can be done with a slight modification to the start of the expression:

/table/tr[$n]/<rest_of_expression>

...where $n is the index of the row to select.