5

I want to get a text from a div with a class name of .inventory_item_name. The HTML looks like this:

<div class="inventory_item_name">Backpack</div>

And my JS code is as follow:

const article = cy.get('.inventory_item_price').then((theElement) => {
  theElement.text();
});

The problem: When I do cy.log(article) I get Object{5}

Joshua
  • 3,055
  • 3
  • 22
  • 37
  • 4
    you cannot assign or work with the return values of any cypress command. Commands are enqueued and run asynchronously. The first hint will be `cy.get('div').should('have.text', 'Backpack')` in case you try to assert on element’s text content – Alex Izbas Jul 16 '20 at 11:01

4 Answers4

8

Just like Alex mentioned in the comment, you cannot return a value from cy commands. But you can do so in the .then block just like:

it("should have text of 'Backpack'", () => {
  // I have changed the selector since the class name in your HTML is ".inventory_item_name" not ".inventory_item_price"
  cy.get('.inventory_item_name').then(($el) => {
    const text = $el.text(); // Now you have the text "Backpack"

    // Do the assertion here
    expect(text).to.eq('Backpack');
  });
});

You can learn more about why Cypress doesn't return value in this documentation

Joshua
  • 3,055
  • 3
  • 22
  • 37
1

You can't assign text values like this.

const article = cy.get('.inventory_item_price').then((theElement) => {
      theElement.text();
   });

The reason is the bellow code does not return a text element.

cy.get('.inventory_item_price').then((theElement) => {
          theElement.text();
       });

So you need to change it like this.

cy.get('.inventory_item_price').then((theElement) => {
         const article = theElement.text();
         //not you can use article
       });
0

As cypress documentation says

You cannot assign or work with the return values of any Cypress command. Commands are enqueued and run asynchronously.

// this won't work the way you think it does
const button = cy.get('button')
const form = cy.get('form')
button.click()

For more information refer : variables-and-aliases

You have a few options. But you need to keep in mind the asynchronous nature of cypress

  • Use alias (if you want to share the article variable in other tests ) so the code will look like this,

Example:

it("Test 1", () => {
cy.get('.inventory_item_price').invoke('text').as('article')
})

//Now you can use this.article in all the other test cases
//If you are using aliases remember Not to use arrow functions on hooks

it("Test 2", function(){
//this will log Backpack
cy.log(this.article)
})
  
  • Use .then, As mentioned by @konekoya in the answer, Since cypress is asynchronous you need to use .then to execute a task after a previous task is completed.

Example:

cy.get('.inventory_item_price').invoke('text').then(article=> {
//you can use articale variable as much as you want inside .then 
//you can't use it outside

const value = articale ;
cy.log(article)
cy.log(value )
})

Note: to get inner Text you there are several methods. You can do the same thing using,

cy.get('.inventory_item_price').then(article => {
const value = articale.text() ;
cy.log(article.text())
cy.log(value)
})
Muditha Perera
  • 1,216
  • 8
  • 24
-1

You can return the article text with below code. Please also look at the link where I have shared the answer for more details.

Storing an element's text in Cypress outside of a chainer method

return cy.get('.inventory_item_price').then((theElement) => {
      return theElement.text();
    }).then(article => {
      cy.log(`article is ${article}`);
    })
Srinu Kodi
  • 486
  • 4
  • 8
  • I want to store the price in an variable called price and then I want to make a test with this variable. I tried to overwrite your code but this doesn't help. Maybe you can show me how to do. –  Jul 16 '20 at 13:57