Fishingrod
Fishingrod

Reputation: 13

Cypress. Saving text element to use for assertion

Im having issues with saving an element as text, to use later for an assertion.

cy.getR6('contact-lastName').clear().type('TestarNameChange').then((nameCheck) => {

  cy.getR6('contact-lastName').invoke('text').as('nameCheck');

  cy.get('.r6modal-buttons-right > .r6btn').click();

  cy.get('.r6loader').should('not.be.visible');

  cy.get('[r6-personal-details=""] > :nth-child(1) > .r6widget > .r6widget-content').contains(this.nameCheck);
})

The response i get from Cypress is: "cy.contains() can only accept a string, number or regular expression."

I have also tried the $div way:

cy.getR6('contact-lastName').then(($div) => {
    var nameCheck = $div.text()

    cy.get('.r6modal-buttons-right > .r6btn').click();
    
    cy.get('[r6-personal-details=""] > :nth-child(1) > .r6widget > .r6widget- content').contains(this.nameCheck);

Also tried to wrap it, with similar success. })

Upvotes: 1

Views: 590

Answers (2)

Sanja Paskova
Sanja Paskova

Reputation: 1110

If you want to validate if some element contains text, use this:

cy.get('[r6-personal-details=""] > :nth-child(1) > .r6widget > .r6widget- content').should('contain', this.nameCheck);

Upvotes: 2

Muditha Perera
Muditha Perera

Reputation: 1252

There are few mistakes that you have done in both of your trials. To explain it I'll break your code into 4 parts ( block 1 )

//Step 1
cy.getR6('contact-lastName').clear().type('TestarNameChange').then((nameCheck) => {

//Step 2
  cy.getR6('contact-lastName').invoke('text').as('nameCheck');

//Step 3
  cy.get('.r6modal-buttons-right > .r6btn').click();
  cy.get('.r6loader').should('not.be.visible');

//Step 4
  cy.get('[r6-personal-details=""] > :nth-child(1) > .r6widget > .r6widget-content').contains(this.nameCheck);
})

Step 1 - You try to type the values in the nameCheck input box and you refer the input box element with nameCheck inside .then ( There is no error in this step )

Step 2 - You try to get the typed last name value and assign it to Alias.

Mistakes

  • You can get the text values of an element using invoke('text') if the value you want is a button name, paragraph text, etc. Ex: (<button>Name</button> will return "Name" with invoke('text')) But here I believe you need the value of the input box. In that case, you need to use invoke('attr','value'). (Here you don't even have to do it, will add the improved code bellow)

Step 3 - You click a button and wait till the loader is not displayed. This step also have no errors.

Step 4 - You are trying to validate the existence of the value using the previously created alias

Mistake

  • This is one of the common mistakes that cypress developers do. You need to understand the asynchronous nature of cypress. In your code, in execution from step 2 to step 4, all will be executed asynchronously. Which means when you use this.nameCheck, nameCheck is not defined. So you need to wait until aliases are created before using them (you can use .then to achieve it)

I'm adding the fixed code below. I have done a few modifications too.

    //type the last name and refer the lastname object with the name "lastName"
    cy.getR6('contact-lastName').clear().type('TestarNameChange').then((lastName) => {

        //extract the value of lastname object with .val() and wrap it with cy.wrap
        // assign the wrapped value to aliase named "nameCheck"
        //You can use  cy.getR6('contact-lastName').invoke('attr','value').as('nameCheck');insted of the below code too
        cy.wrap(lastName.val()).as('nameCheck').then(() =>{

        //As you can see, since we used .then, the next steps will be executed after the aliase is created
        cy.get('.r6modal-buttons-right > .r6btn').click();
        cy.get('.r6loader').should('not.be.visible');
        cy.get('[r6-personal-details=""] > :nth-child(1) > .r6widget > .r6widget-content').contains(this.nameCheck);
        })
      })

In your second code, one of the mistakes that you have done is using this. to refer the defined variable.

And the other mistake is using .text() to extract the value of input field (var nameCheck = $div.text()). You should use .val()

So if we do the same steps of block 1, according to your second try, it will look like.

        cy.getR6('contact-lastName').clear().type('TestarNameChange').then(($div) => {
            var nameCheck = $div.val()
            cy.get('.r6modal-buttons-right > .r6btn').click();
            cy.get('.r6loader').should('not.be.visible');
            cy.get('[r6-personal-details=""] > :nth-child(1) > .r6widget > .r6widget-content').contains(nameCheck);
        })

By any chance, if you want to use cy.getR6('contact-lastName').invoke('attr','value').as('nameCheck'), you can change my first samle like this,

    //Type text
    cy.getR6('contact-lastName').clear().type('TestarNameChange');
    //create alias and continue
    cy.getR6('contact-lastName').invoke('attr','value').as('nameCheck').then(() =>{
    cy.get('.r6modal-buttons-right > .r6btn').click();
    cy.get('.r6loader').should('not.be.visible');
    cy.get('[r6-personal-details=""] > :nth-child(1) > .r6widget > .r6widget-content').contains(this.nameCheck);
    })

Upvotes: 2

Related Questions