skip to Main Content

I have a problem in a cypress the test run basing on JavaScript.

If I run the following test probably the arrays and / or global variable / array do not work.

In the browser test step log it says "wrap null". So I assume the values and arrays are empty. Is that so?

// Global variable for later use
let globalValues;

describe('Test a specific page', () => {
    it('Check a specific table', () => {

        let valuesArray = [];

    // Run through the table row and save values in an array

        cy.get('.table1 > tbody > tr.table_class3 > td:nth-child(1)').each(($e1, index, $list) => {
            var titletext = $e1.text()
            if (titletext.includes('Amount Summery')) {
                let values = [];
                // Run through the columns 2 to 15
                for (let i = 2; i <= 15; i++) {
                    cy.get(`.table1 > tbody > tr.table_class3 > td:nth-child(${i})`).eq(index).then(function (amount) {
                        values.push(amount.text().trim());
                    });
                }

                valuesArray.push(values);
            }
        });

    // Wait until all values are read and save them into the global variable

        cy.wrap(null).should(() => {
            globalValues = valuesArray;
        });

    // The global variable is ready to use for other tasks in the test

    })
})

Maybe this part is synchron?

cy.wrap(null).should(() => {
        globalValues = valuesArray;
    });

If I do something like this for asynchronous reasons:

cy.get('#anHTMLelement').then(function(wrapfunction){
    cy.wrap(null).should(() => {
            globalValues = valuesArray;
        });
})

This does not work neither.

I do not find the error. Any idea?

2

Answers


  1. Change wrap() to then(), but you may have to use the value inside the then() depending on what your "other tasks" are.

    // Run through the table row and save values in an array
    cy.get(...)
      .each(...)
      .then(() => {
        globalValues = valuesArray;
    
        // can use result here (obvious)
      });
    
    // can only use globalValues at this point inside other .then() or .should()
    // for example 
    cy.get('some-selector').invoke('text').should('eq', globalValues[0][2])
    

    Other option to avoid putting all other tasks in .then(), gather the data in before() or beforeEach().

    let globalValues 
    
    before(() => {
      // Run through the table row and save values in an array
      ...
    
      cy.then(() => globalValues = valuesArray)
    })
    
    it('uses globalValues in the test', () => {
      // globalValues is set properly
    })
    

    This works because Mocha before() and it() blocks complete all commands before running the next block.

    You can find out general concepts about global values from this page Variables and Aliases

    Login or Signup to reply.
  2. You can change your cy.wrap().should() line to assert the data is present

    cy.wrap(globalValues).should('have.length.gt', 0)    // retries until true
    

    but as @rubio says that only ensures the data is present inside command callbacks, not at the test context level, for example

    HTML Table

    <table>
      <tbody>
        <tr>
          <td>Cell 1</td>
          <td>Cell 2</td>
        </tr>
        <tr>
          <td>Cell 3</td>
          <td>Cell 4</td>
        </tr>
      </tbody>
    </table>
    

    Test failing at test context usage of globalValues

    let globalValues = [];
    
    it('getting table data with Cypress commands', () => {
      
      cy.get('table tbody tr td')
        .each(td => {
          globalValues.push(td.text())
        })
    
      cy.wrap(globalValues).should('have.length.gt', 0)
    
      // passes
      cy.wrap(globalValues).should('deep.eq', ['Cell 1', 'Cell 2', 'Cell 3', 'Cell 4'])
    
      // fails 
      const thirdCell = globalValues[2]  
      cy.wrap(thirdCell).should('eq', 'Cell 3')
    })
    

    enter image description here


    Using jQuery to extract data in the test context

    If the page is fully loaded, you can use jQuery equivalent to Cypress commands:

    it('getting table data with jQuery commands', () => {
      
      Cypress.$('table tbody tr td')
        .each((index, td) => {
          globalValues.push(td.innerText)
        })
    
      cy.wrap(globalValues).should('have.length.gt', 0)
    
      // passes
      cy.wrap(globalValues).should('deep.eq', ['Cell 1', 'Cell 2', 'Cell 3', 'Cell 4'])
    
      // passes 
      const thirdCell = globalValues[2]  
      cy.wrap(thirdCell).should('eq', 'Cell 3')
    })
    

    enter image description here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search