Home > Software engineering >  i have not yet fully understood the functionality of the aliases (.as)
i have not yet fully understood the functionality of the aliases (.as)

Time:10-16

i have the following code:

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

after cy.get('@firstCheckbox').should('be.checked').click() the checkbox is moved to the last index position instead of the first. According to my understanding of aliases this should not matter, because I reference it with ('@') and it doesn't matter at which position it is. Unfortunately the next cy.get('@firstCheckbox') accesses the new first element and not the one I originally referenced. I can't figure it out from the documentation either. where is the error?

https://docs.cypress.io/guides/core-concepts/variables-and-aliases

https://docs.cypress.io/api/commands/as

Update for @agoff:

it seems to work better with your code but there is a new problem I notice with the new code. if you uncheck the checkbox then the class is reloaded with js causing it to briefly disappear from the dom. After that it can't find it anymore and the test aborts. I also tried with reload but it can't find the element anymore. How to deal with this?

the checked checkbox class has the name custom-control-input ng-untouched ng-pristine ng-valid. after unchecking the class name changed to custom-control-input.ng-untouched.ng-valid.ng-dirty for a second and then the element is removed and reloaded to the DOM with with the class name custom-control-input ng-untouched ng-pristine ng-valid. the problem is here that the second cy.wrap($el) tries to find the element custom-control-input.ng-untouched.ng-valid.ng-dirty although the initial element with the class custom-control-input ng-untouched ng-pristine ng-valid was searched and found. that's something else I don't understand.

CodePudding user response:

I think you are confusing and misusing aliases. When you use the .then(), you've already yielded the found element. So, instead of using the alias, you can reference the object directly (after wrapping it). I believe that something like this should fix your problem...

cy.get('input:checkbox').then(($el) => {
  cy.wrap($el).should('be.checked').click()
              .and('not.be.checked').click()
              .and('be.checked')
})

CodePudding user response:

It happens if during the click event the app removes the input and appends a new one at the end. Then your alias is invalid, because it points to an element no longer in the DOM.

If I move the element within the click handler, your code works.

If I clone the element within the click handler, your code fails.

What to do?

Refresh your alias after the click()

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')
})
  • Related