Cypress 自定义查找命令不可链接

Thé*_*aux 4 javascript testing jquery typescript cypress

我想创建一个find像这样的自定义 Cypress 命令来利用data-test属性。

赛普拉斯/支持/index.ts

declare global {
  namespace Cypress {
    interface Chainable {
      /**
       * Custom command to get a DOM element by data-test attribute.
       * @example cy.getByTestId('element')
       */
       getByTestId(selector: string): Chainable<JQuery<HTMLElement>>;

      /**
       * Custom command to find a DOM element by data-test attribute.
       * @example cy.findByTestId('element')
       */
      findByTestId(selector: string): Chainable<JQuery<HTMLElement>>;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

赛普拉斯/支持/commands.ts

Cypress.Commands.add('getByTestId', (selector, ...args) => {
  return cy.get(`[data-test=${selector}]`, ...args);
});

Cypress.Commands.add(
  'findByTestId',
  { prevSubject: 'element' },
  (subject, selector) => {
    return subject.find(`[data-test=${selector}]`);
  }
);
Run Code Online (Sandbox Code Playgroud)

这里subject是 typeJQuery<HTMLElement>而不是Cypress.Chainable<JQuery<HTMLElement>>,因此subject.find不能与其他方法链接。

我从 Typescript 收到以下错误。

No overload matches this call.
  Overload 1 of 4, '(name: "findByTestId", options: CommandOptions & { prevSubject: false; }, fn: CommandFn<"findByTestId">): void', gave the following error.
  Overload 2 of 4, '(name: "findByTestId", options: CommandOptions & { prevSubject: true | keyof PrevSubjectMap<unknown> | ["optional"]; }, fn: CommandFnWithSubject<"findByTestId", unknown>): void', gave the following error.
  Overload 3 of 4, '(name: "findByTestId", options: CommandOptions & { prevSubject: "element"[]; }, fn: CommandFnWithSubject<"findByTestId", JQuery<HTMLElement>>): void', gave the following error.ts(2769)
cypress.d.ts(22, 5): The expected type comes from property 'prevSubject' which is declared here on type 'CommandOptions & { prevSubject: false; }'
Run Code Online (Sandbox Code Playgroud)

所需用途

cy.getByTestId('some-element')
  .findByTestId('some-test-id')
  .should('have.text', 'Text');
Run Code Online (Sandbox Code Playgroud)

我该如何解决这个问题?

Fod*_*ody 9

我可能偏离了主题,但subject.find(...)正在使用 jQuery find。

也许您想要cy.wrap(subject).find(...)哪个应该产生 Cypress.Chainable 包装器。


jjh*_*ero 8

你的commands文件会有这样的命令。请注意,这将记录 cy.wraps,log: false如果您选择,您可能需要传递以抑制它。您还可以添加另一个参数并使用一个文本if块来使用data-testid.contains()

Cypress.Commands.add(
  'byTestId',
  { prevSubject: 'optional' },
  (subject, id) => {
    if (subject) {
      return cy.wrap(subject).find(`[data-testid="${id}"]`)
    }
    return cy.get(`[data-testid="${id}"]`)
  },
)
Run Code Online (Sandbox Code Playgroud)

这将是该命令的应用。

cy.byTestId('first-id')
  // maybe some assertions here for visibility check
  .byTestId('id-inside-first-element')
  // maybe some assertions here for visibility check
  .byTestId('id-within-this-second-element')
Run Code Online (Sandbox Code Playgroud)

  • 该命令原样很好,但只是为了兴趣 - 你可以在一行中完成它 `return cy.get(subject || 'body').find(``[data-testid="${id}" ]``)` 因为 `cy.get()` 隐式地在 `&lt;body&gt;` 中进行查找。 (2认同)