I want to create a command with this interface:
cy.getTableCell({ column: 'Name', row: 42 }).contains('Douglas Adams')
Where getTableCell would return the table cell (td) corresponding to the 42-th row of the table on the column 'Name'. I came up with this implementation:
type GetTableCellParams = {
  columnName: string;
  rowIndex: number;
};
Cypress.Commands.add(
  'getTableCell',
  ({ columnName, rowIndex }: GetTableCellParams) => {
    cy.contains('th', columnName)
      .invoke('index')
      .then((index) => {
        cy.get('tr')
          .eq(rowIndex)
          .within((row) => {
            return cy.get('td').eq(index);
          });
      });
  }
);
It does find the right table cell. However, since it does so inside a callback, I can't do anything with it - I would like to be able to call chainable methods such as contains, click, etc. How can I refactor this so the caller has access to this element, being able to call contains, click and other chainable methods?
I could also use some help on the function readability. It looks like a mess - I guess the problem lies with the nested callbacks...
                        
It works with no returns at all.
Cypress uses a command stack, and the last subject on the stack is the value returned.
The problem with
.within()is it reverts the subject after it finishes.To illustrate, try aliasing the
<td>and follow the.within()by getting the alias value