Question

Using page-object and watir-webdriver how can I click a link in a table, based on the row text as below:

The table contains 3 rows which have names in the first column, and a corresponding Details link in columns to the right:

DASHBOARD .... Details

EXAMPLE .... Details

and so on.

<div class="basicGridHeader">
    <table class="basicGridTable">ALL THE DETAILS: 
    ....soon
    </table>

</div>

<div class="basicGridWrapper">
    <table class="basicGridTable">
        <tbody id="bicFac9" class="ide043">
            <tr id="id056">
                <td class="bicRowFac10">
                    <span>
                        <label class="bicDeco5">
                            <b>DASHBOARD:</b> ---> Based on this text
                        </label>
                    </span>
                </td>

                <td class="bicRowFac11">
                    ....some element
                </td>

                <td class="bicRowFac12">
                    <span>
                        <a class="bicFacDet5">Details</a> ---> I should able click this link
                    </span>
                </td>
            </tr>
        </tbody>
    </table>
</div>
Was it helpful?

Solution

You could locate a cell that contains the specified text, go to the parent row and then find the details link in that row.

Assuming that there might be other detail links you would want to click, I would define a view_details method that accepts the text of the row you want to locate:

class MyPage
  include PageObject

  table(:grid){ div_element(:class => 'basicGridWrapper')
    .table_element(:class => 'basicGridTable') }

  def view_details(label)
    grid_element.cell_element(:text => /#{label}/)
      .parent
      .link_element(:text => 'Details')
      .click
  end

end

You can then click the link with:

page.view_details('DASHBOARD')

OTHER TIPS

Table elements include the Enumerable module, and I find it very useful in cases like these. http://ruby-doc.org/core-2.0.0/Enumerable.html. You could use the find method to locate and return the row that matches the criteria you are looking for. For example:

class MyPage
  include PageObject

  table(:grid_table, :class => 'basicGridTable')

  def click_link_by_row_text(text_value)
    matched_row = locate_row_by_text(text_value)
    matched_row.link_element.click
    #if you want to make sure you click on the link under the 3rd column you can also do this...
    #matched_row[2].link_element.click
  end

  def locate_row_by_text(text_value)
    #find the row that matches the text you are looking for
    matched_row = grid_table_element.find { |row| row.text.include? text_value }
    fail "Could not locate the row with value #{text_value}" if matched_row.nil?
    matched_row
  end
end

Here, locate_row_by_text will look for the row that includes the text you are looking for, and will throw an exception if it doesnt find it. Then, once you find the row, you can drill down to the link, and click on it as shown in the click_link_by_row_text method.

Just for posterity, I would like to give an updated answer. It is now possible to traverse through a table using table_element[row_index][column_index]. A little bit more verbose:

  1. row_index could also be the text in a row to be matched - in your case - table_element['DASHBOARD']

  2. Then find the corresponding cell/td element using either the index(zero based) or the header of that column

table_element['DASHBOARD'][2] - Selecting the third element in the selected row.

Since you do not have a header row (<th> element) you can filter the cell element using the link's class attribute. Something like this

table_element['DASHBOARD'].link_element(:class => 'bicRowFac10').click

So the code would look something like this:

class MyPage
  include PageObject

  def click_link_by_row_text(text_value)
    table_element[text_value].link_element(:class => 'bicRowFac10').click      
  end
end

Let me know if you need more explanation. Happy to help :)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top