How does Cypress.io read the Windows environment variables?

Viewed 5439

I have set my environment variables in 'Cypress.env.json' file, while running the cypress test, it read the Cypress.env variables successfully. But to be more on the security aspect, rather than 'hard-cording' the values, my team asked me to keep this variable as separate 'parameters' which read from Windows 10 Environment variables. How do I achieve this ? It would be really helpful if someone could advise on this.

{
"QA_Server": "https://sometestingsite.com",
"username": "testQA",
"password": "Password1234!"
}
2 Answers

From cypress documentation here:

Any environment variable on your machine that starts with either CYPRESS_ or cypress_ will automatically be added and made available to you.

Conflicting values will override values from cypress.json and cypress.env.json files.

Cypress will strip off the CYPRESS_ when adding your environment variables.

Exporting cypress env variables from the command line:

export CYPRESS_HOST=laura.dev.local

export cypress_api_server=http://localhost:8888/api/v1/

If you're using Windows you can set env variables using set or setx commands.

And in your test files you can call this:

Cypress.env()             // {HOST: "laura.dev.local", api_server: "http://localhost:8888/api/v1"}
Cypress.env("HOST")       // "laura.dev.local"
Cypress.env("api_server") // "http://localhost:8888/api/v1/"

you can read it from windows env variables directly. to do so use cy.exec with echo. if you run in CMD 'echo %appdata%' it will print the path. i put wrapper around cy.exec as

cy.runExec = (js) => {
  cy.log(`--- runnnig node ${js}`);
  cy.exec(js, { failOnNonZeroExit: false }).then((z) => {
    if (z.stderr != undefined) {
      cy.log(`--- stderr`);
      let lines = z.stderr.split("\n");
      for (let n in lines) cy.log(`--- ${n}: ${lines[n]}`);
    }
    if (z.stdout != undefined) {
      cy.log(`--- stdout`);
      let lines = z.stdout.split("\n");
      for (let n in lines) cy.log(`--- ${n}: ${lines[n]}`);
    }      
  });
};

and if you call it as cy.runExec('echo %appdata%'), it will print same path in cypress output, you can modify this method to get only stdout. you can also save that value using cy.wrap(...).as(...) and get it later.

here is the direct call:

cy.getWinEnv = (s) => {
  cy.exec(`echo %${s}%`, { failOnNonZeroExit: false }).then((z) => {
    let out = z.stdout != undefined ? z.stdout : "undefined";
    cy.wrap(out).as(s);
    //do not: return out;
  });
};

usage:

//read %appdata%
cy.getWinEnv("appdata");

//log %appdata% in cypress
cy.get("@appdata").then((x) => cy.log(`--- ${x}`));

yet another update - if you add 'cypress-promise' package, then it is possible to call directly with async/await...

cy.getWinEnvEx = async (s) => {
  var out = "undefined yet";
  await cy.exec(`echo %${s}%`, { failOnNonZeroExit: false }).then((z) => {
    if (z == null) {
      cy.log("--- output is null");
    } else {      
      out = z.stdout != undefined ? z.stdout : "undefined";
      //cy.log(`--- z.stdout ${out}`);
    }
  });
  return out;
};

...

it("list windows variables", async () => {
  let z = await cy.getWinEnvEx("USERPROFILE");
  cy.log(`--- USERPROFILE ${z}`);
});
Related