0

I use cy.intercept() and cy.wait() to listen to the request and yield content from it.

let number;

describe("some test", () => {
  before(() => {
    cy.clearCookies();
  });
  it("some test", () => {
    cy.someCommand();
    clientPage.someMethod();
    cy.intercept("**/request").as("idNumber");
    clientPage.someMethod1();
    cy.wait("@idNumber").then((res) => {
      number = res.response.body.numbers.id
    });
    cy.get(#someELement).type(number)
 });
});

It gives me "cy.type() can only accept a string or number. You passed in: undefined" When I try to log cy.log(number) under "number = res.response.body.numbers.id" it works. When I try to pass the variable out of this code block it is undefined. How can I pass it into the further steps?

wojnarto
  • 411
  • 4
  • 9

3 Answers3

4

To make sure the value of number is passed on to the type, you have to add a then, something like:

let number

describe('some test', () => {
  before(() => {
    cy.clearCookies()
  })
  it('some test', () => {
    cy.someCommand()
    clientPage.someMethod()
    cy.intercept('**/request').as('idNumber')
    clientPage.someMethod1()
    cy.wait('@idNumber')
      .then((res) => {
        number = res.response.body.numbers.id
      })
      .then(() => {
        cy.get('#someELement').type(number)
      })
  })
})

If you want to use the variable globally throughout the project, you can use the Cypress.env() method. Cypress Docs.

describe('some test', () => {
  before(() => {
    cy.clearCookies()
  })
  it('some test', () => {
    cy.someCommand()
    clientPage.someMethod()
    cy.intercept('**/request').as('idNumber')
    clientPage.someMethod1()
    cy.wait('@idNumber').then((res) => {
      cypress.env('number', res.response.body.numbers.id) //Sets Number
    })
    cy.get('#someELement').type(Cypress.env('number')) //Gets Number and types it
  })

  it('some different test', () => {
    cy.get('#someELement').type(Cypress.env('number')) //types the number
  })
})
Alapan Das
  • 17,144
  • 3
  • 29
  • 52
  • Thank you. It works. But what if I would reuse in the next steps not necessarily in the next then() or even what if I would reuse in the different it()? – wojnarto Jul 01 '22 at 19:21
  • Thank you. Your solution seems excellent, but it looks like Cypress.env stores the "number" value from the previous test. So when I try to use this number in the current test the code is not valid. I log number from ```cy.wait('@idNumber').then((res) => { Cypress.env('number', res.response.body.numbers.id) //Sets Number``` and then I try to log the same number outside of the block, 2 lines later. The first number is correct, but the second log shows the old code (from the previous test). The question is if it's the Cypress issue or the architecture of my app. – wojnarto Jul 02 '22 at 08:39
  • E.g. ```wait @number log 407288 log 474212 ``` and next text will log: ```wait @number log 304431 log 407288 ``` – wojnarto Jul 02 '22 at 08:46
2

@alex-izbas answer is good if you need for immediate use.

In the option that you need to use it later in your test, you'll need to set it an .alias() and use it in junction with function(){} and this keyword.

describe("some test", () => {
  before(() => {
    cy.clearCookies();
  });
  // use function() {} to be able to use this keyword
  it("some test", function() {
    cy.someCommand();
    clientPage.someMethod();
    cy.intercept("**/request").as("idNumber");
    clientPage.someMethod1();

    // use .its() to get the id and store in alias
    cy.wait("@idNumber")
      .its('response.body.numbers.id')
    // add an assertion to check type with .should()
      .as('number')

    // some more actions

    // get alias using this keyword
    cy.get(#someELement).type(this.number)
 });
});
jjhelguero
  • 2,281
  • 5
  • 13
  • Thank you for your response. Unfortunately using this solution I am getting "Cannot read properties of undefined (reading 'number')" The test doesn't even start. – wojnarto Jul 02 '22 at 08:22
  • Ops I forgot to erase the `let number` section. – jjhelguero Jul 02 '22 at 18:22
1

It happens because of the asynchronous nature of cypress, and at the moment number is called, its value was not assigned yet. Any further action can be chained by wait command without polluting your scope with context variables:

 cy.wait("@idNumber").then((res) => {
    cy.get(#someELement).type(res.response.body.numbers.id)
 });

Alex Izbas
  • 595
  • 5
  • 8