Search code examples
javascriptcypress

confused with cy.log in cypress


This is my code to print totals - length of elements product:

cy.fixture('searchProducts').then(function (arr) {
        let arrProducts = [];
        let totals ;
        let totalGetJson;
       
        arr.forEach(($product) => {
            if ($product.nameProduct == "dress") {
                arrProducts = $product;
                totalGetJson= $product.total
                productsPage.getProductList.as('listProduct')
            }
        });

        totals = cy.get('@listProduct').then(($elements) => {
            expect(totalGetJson).to.eq($elements.length)
            return $elements.length  
        })
        //print [object Object]aaaaaaaaaaaaaaa
        cy.log(totals +"aaaaaaaaaaaaaaa")
        return totals
    })
    .then((totals) => {
        // print null
        cy.log(totals) 
        
    });

when I put cy.log(totals +"aaaaaaaaaaaaaaa") before return totals then cy.log(totals) in block then() is null

If I remove line cy.log(totals +"aaaaaaaaaaaaaaa") then cy.log(totals) in block then() is $elements.length is 9

I don't understand the way work for Javascript in Cypress in situation


Solution

  • The content of your callback have some asynchronous commands inside, so you need to treat the return value asynchronously as well.

    Here's three versions of similar code using Cypress example.json and public site example.com.

    Synchronous then() callback

    cy.visit('http://example.com');
    cy.fixture('example')
      .then(exampleData => {
        const name = exampleData.name  
        return name
      })
      .then(name => {
        expect(name).to.eq('Using fixtures to represent data')    // passes
      })
    

    Asynchronous then() callback

    cy.visit('http://example.com');
    cy.fixture('example')
      .then(exampleData => {
    
        let name
    
        // Dummy async call where result is set internally
        cy.get('h1').then(() => {
          name = exampleData.name  
        })
        
        return name     // returns too soon!!
      })
      .then(name => {
        expect(name).to.eq('Using fixtures to represent data')   // fails
      })
    

    Asynchronous then() callback with async result handling

    cy.visit('http://example.com');
    cy.fixture('example')
      .then(exampleData => {
        let name
    
        return cy.get('h1').then(() => {     // return this line so that test waits 
          return name = exampleData.name     // return internal data result
        })
    
      })
      .then(name => {
        expect(name).to.eq('Using fixtures to represent data')   // passes
      })