Quiero crear un comando de find de Cypress personalizado para utilizar un atributo data-test .
ciprés/soporte/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>>; } } }ciprés/soporte/comandos.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}]`); } ); Aquí el subject es de tipo JQuery<HTMLElement> y no Cypress.Chainable<JQuery<HTMLElement>> , por lo que subject.find no se puede encadenar con otros métodos.
Recibo los siguientes errores de 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; }'uso deseado
cy.getByTestId('some-element') .findByTestId('some-test-id') .should('have.text', 'Text');¿Cómo podría arreglar esto?
Su archivo de commands tendría un comando como este. Tenga en cuenta que esto registrará cy.wraps y es posible que desee pasar log: false para suprimir eso si lo desea. También puede agregar otro elemento y tener un bloque if para que el texto use data-testid con .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}"]`) }, )Esta sería una aplicación del comando.
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')Puedo estar equivocado, pero subject.find(...) está usando jQuery find.
Tal vez desee cy.wrap(subject).find(...) que debería producir el envoltorio Cypress.Chainable.
Tuve que agregar un comando cy.wrap alrededor del elemento JQuery así.
Cypress.Commands.add( 'findByTestId', { prevSubject: 'element' }, (subject, selector) => { return cy.wrap(subject).find(`[data-test=${selector}]`); } )