Tengo el siguiente código:
cy.get('input:checkbox').first().as('firstCheckbox').then(() => { cy.get('@firstCheckbox').should('be.checked').click() cy.get('.globalMessage-display > :nth-child(1) > .alert').should('be.visible') cy.get('.globalMessage-display > :nth-child(1) > .alert').should('not.exist') cy.get('@firstCheckbox').should('not.be.checked').click() cy.get('.globalMessage-display > :nth-child(1) > .alert').should('be.visible') cy.get('.globalMessage-display > :nth-child(1) > .alert').should('not.exist') cy.get('@firstCheckbox').should('be.checked') }) después de cy.get('@firstCheckbox').should('be.checked').click() la casilla de verificación se mueve a la última posición del índice en lugar de a la primera. De acuerdo con mi comprensión de los alias, esto no debería importar, porque lo hago referencia con ('@') y no importa en qué posición se encuentre. Desafortunadamente, el siguiente cy.get('@firstCheckbox') accede al nuevo primer elemento y no al que hice referencia originalmente. Tampoco puedo descifrarlo de la documentación. donde esta el error
https://docs.cypress.io/guides/core-concepts/variables-and-aliases
https://docs.cypress.io/api/commands/as
Actualización para @agoff:
parece funcionar mejor con su código, pero noto un nuevo problema con el nuevo código. si desmarca la casilla de verificación, la clase se vuelve a cargar con js, lo que hace que desaparezca brevemente del dom. Después de eso, ya no puede encontrarlo y la prueba aborta. También probé con recargar pero ya no puede encontrar el elemento. Como lidiar con esto?
la clase de casilla de verificación marcada tiene el nombre custom-control-input ng-untouched ng-pristine ng-valid . después de desmarcar el nombre de la clase cambió a custom-control-input.ng-untouched.ng-valid.ng-dirty por un segundo y luego el elemento se elimina y vuelve a cargar en el DOM con el nombre de clase custom-control-input ng-untouched ng-pristine ng-valid . el problema aquí es que el segundo cy.wrap($el) intenta encontrar el elemento custom-control-input.ng-untouched.ng-valid.ng-dirty aunque el elemento inicial con la clase custom-control-input ng-untouched ng-pristine ng-valid Se buscó y se encontró custom-control-input ng-untouched ng-pristine ng-valid . eso es otra cosa que no entiendo.
Ocurre si durante el evento de clic, la aplicación elimina la entrada y agrega una nueva al final. Entonces su alias no es válido porque apunta a un elemento que ya no está en el DOM.
Si muevo el elemento dentro del controlador de clics, su código funciona.
Si clono el elemento dentro del controlador de clics, su código falla.
¿Qué hacer?
Actualice su alias después del clic ()
cy.get('input:checkbox').first().as('myCheckbox').then(() => { cy.get('@myCheckbox').should('be.checked').click() .then(() => cy.get('input:checkbox').last().as('myCheckbox')) // it's last now! cy.get('.globalMessage-display > :nth-child(1) > .alert').should('be.visible') cy.get('.globalMessage-display > :nth-child(1) > .alert').should('not.exist') cy.get('@myCheckbox').should('not.be.checked').click() .then(() => cy.get('input:checkbox').last().as('myCheckbox')) cy.get('.globalMessage-display > :nth-child(1) > .alert').should('be.visible') cy.get('.globalMessage-display > :nth-child(1) > .alert').should('not.exist') cy.get('@myCheckbox').should('be.checked') })El comando alias también tiene otro truco.
Si el elemento se clona y reemplaza, el elemento original se separa del DOM .
El cy.get('@alias') detecta elementos separados y reproduce el comando original para actualizar automáticamente.
No funciona con .first() porque el elemento cambia de posición.
Pero si usa un atributo data-cy en lugar de .first() , su código funcionará.
cy.get('input:checkbox[data-cy="first-checkbox"]') .as('myCheckbox').then(() => { cy.get('@myCheckbox') .should('be.checked').click() // cloned and moved to another position ... cy.get('@myCheckbox') // detached by previous click .should('not.be.checked').click() // so alias replays original get // with [data-cy="first-checkbox"] ... cy.get('@myCheckbox').should('be.checked') // as above })Aquí está el código de Cypress que lo hace
let { subject, alias, command } = aliasObj const resolveAlias = () => { if ($dom.isElement(subject)) { // if this is a DOM element const replay = () => { cy.replayCommandsFrom(command) return undefined } if ($dom.isDetached(subject)) { // is it detached? subject = subject.filter((index, el) => $dom.isAttached(el)) // all detached? if (!subject.length) { return replay() // perform the replay } }Creo que estás confundiendo y usando mal los alias. Cuando usa .then() , ya ha producido el elemento encontrado. Entonces, en lugar de usar el alias, puede hacer referencia al objeto directamente (después de envolverlo). Creo que algo como esto debería solucionar tu problema...
cy.get('input:checkbox').then(($el) => { cy.wrap($el).should('be.checked').click() .and('not.be.checked').click() .and('be.checked') })