Defining a global variable in Cypress that can be used in all test files without creating a new one everytime

329 views Asked by At

I am very desperately looking for a solution to define a global variable and access it everything in all my test files. This is my commands.js. Here i am generating a random mobile number using faker.js. I am doing APIs automated testing but the APIs are executed in a sequence which means there should be one mobile number and one user ID that should be used throughout the test execution.

import { faker } from '@faker-js/faker';
Cypress.Commands.add('generateAndSetMobileNumber', () => {
  // Check if the mobile number is already set in the Cypress environment
  if (!Cypress.env('mobileNumber')) {
    const mobileNumber = faker.datatype.number({ min: 5700000000, max: 5899999999 });
    Cypress.env('mobileNumber', mobileNumber.toString());
  }
});

Cypress.Commands.add('createUser', () => {
  cy.generateRandomMobileNumber().then((mobileNumber) => {

    return cy.api({
      failOnStatusCode: false,
      method: 'POST',
      url: '/products/users/',
      body: {
        "countryCode": "971",
        "mobileNo": mobileNumber,
        "viewId": "createView",
        "agentCode": "",
        "language": "EN",
      }
    }).then((response) => {
      expect(response.status).to.eq(201);
      Cypress.env('prospectId', response.body.userId);
    });
  });
});

Now these commands are defined here and are working perfectly fine but when I use it in my test classes everything generates a new mobile number and new userID whereas I want one UserID and mobileNumber that can be used throughout the execution.

This is my test file

describe("Generating OTP", () => {
before(() => {
 cy.createUser() => {
     
    });
  it("Verify user is able to generate OTP by entering their mobile number", () => {
               UserId = Cypress.env('UserId');
               mobileNumber = Cypress.env('mobileNumber');


    cy.api({
      failOnStatusCode: false,
      method: 'POST',
      url: 'products/otp',
      body: {
        "action": "generate",
        "prospectId": prospectId,
        "countryCode": "971",
        "mobileNo": mobileNumber,
      }
    }).then((response) => {
      // Assert that the OTP was generated successfully
      expect(response.status).to.eq(200);
      expect(prospectId).to.have.length(5);
      // Assert that the OTP is valid
      expect(response.body.verified).to.eq(true);
    });
  });
});

I have tried multiple options as follow, but nothing seems to be working for me:

cypress-localstorage-commands plugin setLocalStorage getAllSessionStorage I look forward to prompt support

1

There are 1 answers

2
Aladin Spaz On BEST ANSWER

Your code already has checks to see if the mobile exists - if (!Cypress.env('mobileNumber')), which means this env var is cleared at certain points.

Certainly, it is cleared between specs: see Cypress.env

Scope
Environment variables set using Cypress.env are only in scope for the current spec file.

I guess safest approach is to save to a fixture file, using same check logic.

Cypress.Commands.add('generateAndSetMobileNumber', () => {
  cy.fixture('mobile.json').then(data => {
    if (!data.mobileNumber') {
      const mobileNumber = ...generate
      cy.writeFile('/cypress/fixtures/mobile.json', { mobileNumber })
    }
  })
})

But if you take the idea to the logical conclusion, why have code to generate the number? Why not just a fixed number in a permanent fixture file?


Note you can call cy.fixture() multiple times without the cost of reading each time, because the command is caching the first read.

You have to keep that in mind if trying to force a re-write, using cy.readFile() instead of cy.fixture().