如何在 Cypress 中实现获取 table 单元格的命令?

How to implement a command to get a table cell in Cypress?

我想用这个界面创建一个命令:

cy.getTableCell({ column: 'Name', row: 42 }).contains('Douglas Adams')

其中 getTableCell 将 return table 单元格 (td) 对应于列 table 的第 42 行 'Name'。我想出了这个实现:

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);
          });
      });
  }
);

它确实找到了正确的 table 单元格。但是,由于它是在回调中执行的,因此我无法对其执行任何操作 - 我希望能够调用可链接的方法,例如 containsclick 等。我该如何重构它所以调用者可以访问这个元素,能够调用 containsclick 和其他可链接的方法?

我还可以在函数可读性方面使用一些帮助。看起来一团糟——我想问题出在嵌套的回调上……

  1. 您的命令几乎可以正常工作——主要问题是 .within() yields the same element it was given. Instead, we should use .find().

  2. 您需要生成 整个 赛普拉斯链,以便您可以根据需要链接命令。在这种情况下,在将 .within() 替换为 .find() 之后,这意味着只需在初始 cy.contains()

    之前添加一个 return
Cypress.Commands.add(
  'getTableCell',
  ({ columnName, rowIndex }: GetTableCellParams) => {
    return cy.contains('th', columnName)
      .invoke('index')
      .then((index) => {
        return cy.get('tr')
          .eq(rowIndex)
          .find('td')
          .eq(index);
      });
  }
);

它在没有 returns 的情况下工作。

Cypress 使用命令堆栈,堆栈中的最后一个主题是返回值。

.within() 的问题在于它 在完成后还原 主题。

Cypress.Commands.add('getTableCell', ({ columnName, rowIndex }: GetTableCellParams) => {

  cy.contains('th', columnName).invoke('index')
    .then(colIndex => {
      cy.get('tr').eq(rowIndex)
        .find('td').eq(colIndex)
    });
  }
)

为了说明,请尝试为 <td> 添加别名,然后通过获取别名值

跟随 .within()
Cypress.Commands.add('getTableCell', ({ columnName, rowIndex }) => {
  cy.contains('th', columnName)
    .invoke('index')
    .then(colIndex => {
      cy.get('tr')
        .eq(rowIndex)
        .within((row) => {
          cy.get('td').eq(colIndex).as('cell')
        })
        cy.get('@cell')   // last command, it's result will be returned
    });
  }
)