I have a data driven cypress code like below.
I’m trying to generate tests dynamically based on the values of "data" variable.
let data:QuestionData[];
describe("Add data to admin", ()=>{
before(async ()=>{
data = await promisify(cy.task("readCSV",csvFile));
});
data.forEach((val,index)=>{
it(`Should add val ${val}`, ()=>{
console.log(index);
})
})
});
my "readCSV" method just reads a csv and resolve data.
when I run above code I’m getting this error -> Cannot read properties of undefined (reading ‘forEach’).
The reason is "data.forEach" runs before the variable gets initialized.
if I write a "console.log" inside the "before" hook I can see data is available.
But why data variable NOT getting available outside the BEFORE HOOK ?
My code works if I access "data" variable inside "it" block and use for lood.
but I want tests to be generated dynamically.
How can I fix this in cypress.io ?
2
Answers
Try changing the arrow functions to normal ones, it can mess with the context: https://mochajs.org/#arrow-functions
And doesn’t cy.task() return a Promise? Calling promisify() on a Promise should throw an error. And even then, promisify() doesn’t return a Promise, it returns a function that returns a Promise.
The problem is Cypress is attempting to use the
data
before any commands have run (includingcy.task()
in thebefore()
block). Cypress builds the test queue by running the javascript of the test file, then it runs the test queue.Cypress has the Before Run API to get around this.
(Note set
experimentalInteractiveRunEvents:true
option in `cypress.config.js’ to use this feature).You can switch from this
to this
The first problem is how to pass the
csvFile
parameter. If you are setting it by enviroment variable, you can read it fromconfig.env
or hard-code if always the same file name.The second problem is how to send the data to the test. The easiest would be to put it in another environment var.
Then the test reads it synchronously at the top of the test.
Cypress.env()
will run outside theit()
orbefore()
blocks.Using require
Another approach to
require
orimport
the CSV as a string and parse it using plain javascript.Assuming lines of comma-separated values, somthing like