'How can I create a custom command to fill fields in both scenarios with different structures?

So I have 2 scenarios, from different pages on the application I'm testing:

Scenario 1:

<tbody>   
     <tr>
        <td class="colLabel90 colCampo">
          <label style="font-weight: bold">* Nome:</label>
        </td>
        <td>
          <input  type="text" class="ui-inputfield ui-inputtext ui-widget ui-state-default ui-corner-all requiredColor role="textbox" aria-disabled="false" aria-readonly="false">
        </td>   
     </tr>
     <tr>
         .....   
     </tr> 
</tbody>

Scenario 2:

<tr role="row">
   <th id="dataTableFormId:DataTableId:j_idt169" class="ui-state-default ui-sortable-column ui-filter-column ui-resizable-column colFilterSize" role="columnheader" aria-label="Nome: activate to sort column ascending" scope="col" style="width:90%" aria-sort="other">
      <span class="ui-column-resizer ui-draggable ui-draggable-handle">&nbsp;</span>
      <span class="ui-column-title">Name</span>
      <span class="ui-sortable-column-icon ui-icon ui-icon-carat-2-n-s"> </span>
      <input id="dataTableFormId:DataTableId:j_idt169:filter" name="dataTableFormId:DataTableId:j_idt169:filter" class="ui-column-filter ui-inputfield ui-inputtext ui-widget ui-state-default ui-corner-all" autocomplete="off" role="textbox" aria-disabled="false" aria-readonly="false">
   </th>
   <th id="dataTableFormId:DataTableId:j_idt171" class="ui-state-default ui-sortable-column ui-filter-column ui-resizable-column colFilterSize" role="columnheader" aria-label="Fabricante: activate to sort column ascending" scope="col" style="width:90%">
      <span class="ui-column-resizer ui-draggable ui-draggable-handle" style="display: none;">&nbsp;</span>
      <span class="ui-column-title">Manufacturer</span>
      <span class="ui-sortable-column-icon ui-icon ui-icon-carat-2-n-s"></span>
      <input id="dataTableFormId:DataTableId:j_idt171:filter" name="dataTableFormId:DataTableId:j_idt171:filter" class="ui-column-filter ui-inputfield ui-inputtext ui-widget ui-state-default ui-corner-all" autocomplete="off" role="textbox" aria-disabled="false" aria-readonly="false">
   </th>
</tr>

Here is what I'm trying to do on Cypress:

Cypress.Commands.add("typeOnFields", (field, value) => {
   cy.get('#center').contains(field).parent().find('input').clear().type(value)

})
//Where field is the name of the field in <label> or <span>, in this case it's 'Name'

This is not working, find() won't find the input in any scenario.



Solution 1:[1]

Because the two scenarios have different structures and parent elements, you would need to use a variant of .parents() that keeps moving up to the first parent that contains an input

cy.contains(field)             // return the <label> or <span> with "field"
  .parents(':has(input)')      // move up until element has an <input> inside
  .eq(0)                       // take first (multiple are returned)
  .find('input')               // find the <input> element   
  .clear().type(value)

To avoid complexity, I would actually use two commands here one for the table header and one for the table body.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1