'Cypress Custom Command - Break from a .each() loop and return a value to be used in further steps

I am new to Cypress [3 days :)]. I am creating a custom command which is trying to find the column index of column in a table. I want to return the column index and store it in a variable and use it in future steps.

Here is what I have tried:

    Cypress.Commands.add('get_table_column_index', (columnName) => {

  cy.getIframeBody().find('table').within(() => {
    cy.get('tr th[scope=col]').each((element, index) => {
      let colName = element.text();
      cy.log(index, colName);
      
      if(colName == columnName)
      {
        cy.wrap(index).as('index');
        return false;
      }
    });
  });
});

let columnIndex = cy.get_table_column_index('ColName').get('@index');
cy.log('index' + columnIndex);

index is [object Object]

Can someone please guide me in resolving this issue? What am I doing wrong?

I can see that wrap is returning the correct index value but I am not sure how to extract and use it.

======= Update =========

I tried this and looks like it was able to log the correct value:

let columnIndex = 
cy.get_table_column_index(column_name).get('@index');
columnIndex.then(index => cy.log(index));

Now, I am trying to expand it to use the index value in the next step like this:

Cypress.Commands.add('get_text', (row_num, column_name) => {
    
    let txt;
    cy.test_index(column_name).get('@index').then(index => {
        let element = cy.get('main > table').within(() => {
            cy.log('${index');
                        cy.get('tr:nth-child(${row_num}) td:nth-child(${index})');
        //txt = element.text();
        cy.log(txt);
        });
    });
    return txt;
  })

I am not able to figure out how to use the value of index and row_num in cy.get('tr:nth-child(${row_num}) td:nth-child(${index})'; expression.

Error: Syntax error, unrecognized expression: :nth-child


Solution 1:[1]

All you need to do is change the way that you are using variable.

 cy.log(this.index + columnIndex);

Solution 2:[2]

I was able to get this working like this:

.get('@index').then(....

was used to extract the value of the index which is returned by my method get_table_column_index.

Then used cy.wrap again to return the cell value.

Cypress.Commands.add('get_text', (row_num, column_name) => {

cy.get_table_column_index(column_name).get('@index').then(index => {
    cy.get('main > table').within(() => {
     cy.get(`tr:nth-child(${row_num}) td:nth-child(${index})`)
        .invoke('text')
        .then((text) => {
            cy.log("Text = " + text);
            return cy.wrap(text).as('cell_value');
        })
    });
});

})

Then finally in my method call:

let cell_text = cy.get_text(2, 'Licensing').get('@cell_value');
cell_text.then(cell_value => {
    cy.log(cell_value);
    expect(cell_value).to.include('QTP');
})

The only thing I am not able to do is to store the value in a variable and use it without chaining any command like then to extract its value.

It would be great if someone can provide more information on that.

Thanks.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 ItsNotAndy
Solution 2