Search code examples
rubywatir-webdriver

Access two tables inside tr tag of an outer table, which in turn contains tables and other elements like select list, text area


My need is to identify the table and check the values of each select list for particular Problem name and their corresponding notes values.

Here I found that the question itself got split into two tables and I'm facing difficulty in accessing them.

My HTML structure looks like the below.

    <table class="dataentry">
<tbody>
    <tr>
        <td width="50%">
            <table class="genetichxtable entirewidth">
                <tbody>
                    <tr>
                        <th></th>
                        <th>Y/N</th>
                        <th>Notes</th>
                    </tr>
                    <tr>
                        <td>Huntington's Chorea</td>
                        <td class="nowrap">
                            <select name="GSANS{1}{ANSWERYN}" questionid="1" section="GENETICHX" type="SELECT">
                                <option value=""></option>
                                <option value="Y">Yes</option>
                                <option value="N">No</option>
                            </select>
                        </td>
                        <td class="nowrap">
                            <textarea  name="GSANS{1}{ANSWERNOTES}"  type="TEXTAREA">
                            </textarea>
                        </td>
                    </tr>
                    <tr>
                        <td>History of Hepatitis</td>
                        <td class="nowrap">
                            <select name="GSANS{2}{ANSWERYN}" questionid="2" section="GENETICHX" type="SELECT">
                                <option value=""></option>
                                <option value="Y">Yes</option>
                                <option value="N">No</option>
                            </select>
                        </td>
                        <td class="nowrap"><textarea  name="GSANS{2}{ANSWERNOTES}"  type="TEXTAREA"></textarea>
                        </td>
                    </tr>
                    <tr>
                        <td>Intellectual Disability/Autism</td>
                        <td class="nowrap">
                            <select name="GSANS{5}{ANSWERYN}" questionid="5" section="GENETICHX" type="SELECT">
                                <option value=""></option>
                                <option value="Y">Yes</option>
                                <option value="N">No</option>
                            </select>
                        </td>
                        <td class="nowrap"><textarea  name="GSANS{5}{ANSWERNOTES}"  type="TEXTAREA"></textarea>
                        </td>
                    </tr>
                </tbody>
            </table>
        </td>
        <td width="50%">
            <table class="genetichxtable entirewidth">
                <tbody>
                    <tr>
                        <th></th>
                        <th>Y/N</th>
                        <th>Notes</th>
                    </tr>
                    <tr>
                        <td>Thalassemia (Italian, Greek, Mediterranean, Or Asian Background): MCV &lt; 80</td>
                        <td class="nowrap">
                            <select name="GSANS{4}{ANSWERYN}" questionid="4" section="GENETICHX" type="SELECT">
                                <option value=""></option>
                                <option value="Y">Yes</option>
                                <option value="N">No</option>
                            </select>
                        </td>
                        <td class="nowrap"><textarea  name="GSANS{4}{ANSWERNOTES}"  type="TEXTAREA"></textarea>
                        </td>
                    </tr>
                    <tr>
                        <td>Congenital Heart Defect</td>
                        <td class="nowrap">
                            <select name="GSANS{3}{ANSWERYN}" questionid="3" section="GENETICHX" type="SELECT">
                                <option value=""></option>
                                <option value="Y">Yes</option>
                                <option value="N">No</option>
                            </select>
                        </td>
                        <td class="nowrap"><textarea  name="GSANS{3}{ANSWERNOTES}"  type="TEXTAREA"></textarea>
                        </td>
                    </tr>
                </tbody>
            </table>
        </td>
    </tr>
</tbody>

I want to iterate over the table to select values for select_list from dropdown and enter notes.Is there any way to automate this using WATIR?


Solution

  • Each question is encapsulated in a row - tr element. However, some of the rows are not rows - ex the tr containing the 2 child tables and the tr containing column headers. What differentiates the question rows is that contain a select list (ie a question).

    You can find the question rows by finding the inner rows with select lists:

    outer_tr = browser.table(class: 'dataentry').tr
    questions = outer_tr.trs.select { |tr| tr.select.exists? }
    

    While less Watir-like, this can be more succinctly written using XPath:

    questions = browser.trs(xpath: '//table[@class="dataentry"]//tr[./td/select]')
    

    Regardless of which of the above approaches you use, you now have each question row in a collection. This allows you to iterate over each row and find the title, select list and notes field that are for the same question. The following iterates over each question:

    questions.each do |tr|
      # The data/fields of interest for the row
      title = tr.td.text
      select = tr.select
      notes = tr.textarea
    
      # Do stuff with the fields
      p title
      select.select('Yes')
      notes.set('some note')
    end
    

    If you are looking to set a specific question, I assume by the title, you can iterate over the questions using the find method. This will return the specific row related to question. For example, the following finds the question related to "History of Hepatitis". You can see the select/textarea for the question are the correct related fields (ie question 2).

    question = questions.find { |q| q.td.text == 'History of Hepatitis' }
    p question.td.text
    #=> "History of Hepatitis"
    p question.select.name
    #=> "GSANS{2}{ANSWERYN}"
    p question.textarea.name
    #=> "GSANS{2}{ANSWERNOTES}"
    

    Note that if you are using the page-object gem, the nested element method names are different. The following shows iterating through each question in the page-object syntax:

    outer_tr = table_element(class: 'dataentry').row_element
    questions = outer_tr.row_elements.select { |tr| tr.select_list_element.exists? }
    
    questions.each do |question|
      # The data/fields of interest for the row
      title = question.cell_element.text
      select = question.select_list_element
      notes = question.text_area_element
    
      # Do stuff with the fields
      p title
      select.select('Yes')
      notes.value = 'some note'
    end