cypress - read excel file: xlsxlsx.read is not a function

330 Views Asked by At

I am getting this Excel file read error:

CypressError
cy.task('readXlsx') failed with the following error:
xlsx.read is not a function

I use cypress 12.7 with typescript

I wrote in the cypress.config.ts:

on("task", {
    readXlsx({filePath, sheetname}) {
      const buf = fs.readFileSync(filePath);
      const workbook = xlsx.read(buf, { type: 'buffer' });
      const rows = xlsx.utils.sheet_to_json(workbook.Sheets[sheetname]);
      return rows
    },
  });

and in cy-commands.ts I defined the command:

Cypress.Commands.add('readXlsx', (InputFile, string) => cy.task(
  'readXlsx',
  { filePath: InputFile, sheetName: string },
));

Furthermore to use the command in index.d.ts:

readXlsx(filePath: InputFile, sheetName: string): Chainable<CyQElem>;

The function/task readXlsx I call like this:

cy.get<string>('@LASTDOWNLOADEDFILE').then((templateFile) => {
   // create the upload file name.
   cy.log(`TEMPLATE FILE NAME: ${templateFile}`); // Correct
   cy.readXlsx(`${templateFile}`, 'SheetName1').then((rows) => {
   // first row = header row: now we need the cells...
   cy.log(`ROW: ${rdw}`);
   expect(rows[0].data[1]).to.contain(data);
   cy.log(`ROW DATA: ${rows[0].data[1]}`);
});

But what ever I do it always fails with:

enter image description here

And below is the following exception, which does not give any additional information:

From Node.js Internals:
  TypeError: xlsx.read is not a function
      at readXlsx (/local0/xxxxxxx/cypress.config.ts:113:33)
      at invoke (/local0/jonas_home/.cache/Cypress/12.7.0/Cypress/resources/app/node_modules/@packages/server/lib/plugins/child/run_plugins.js:235:16)
      at <unknown> (/local0/jonas_home/.cache/Cypress/12.7.0/Cypress/resources/app/node_modules/@packages/server/lib/plugins/util.js:59:14)
      at tryCatcher (/local0/jonas_home/.cache/Cypress/12.7.0/Cypress/resources/app/node_modules/bluebird/js/release/util.js:16:23)
      at Function.Promise.attempt.Promise.try (/local0/jonas_home/.cache/Cypress/12.7.0/Cypress/resources/app/node_modules/bluebird/js/release/method.js:39:29)
      at Object.wrapChildPromise (/local0/jonas_home/.cache/Cypress/12.7.0/Cypress/resources/app/node_modules/@packages/server/lib/plugins/util.js:58:23)
      at RunPlugins.taskExecute (/local0/jonas_home/.cache/Cypress/12.7.0/Cypress/resources/app/node_modules/@packages/server/lib/plugins/child/run_plugins.js:241:10)
      at RunPlugins.execute (/local0/jonas_home/.cache/Cypress/12.7.0/Cypress/resources/app/node_modules/@packages/server/lib/plugins/child/run_plugins.js:161:21)
      at EventEmitter.<anonymous> (/local0/jonas_home/.cache/Cypress/12.7.0/Cypress/resources/app/node_modules/@packages/server/lib/plugins/child/run_plugins.js:258:12)
      at EventEmitter.emit (node:events:527:28)
      at EventEmitter.emit (node:domain:475:12)
      at process.<anonymous> (/local0/jonas_home/.cache/Cypress/12.7.0/Cypress/resources/app/node_modules/@packages/server/lib/plugins/util.js:33:22)
      at process.emit (node:events:527:28)
      at process.emit (node:domain:475:12)
      at process.emit.sharedData.processEmitHook.installedValue [as emit] (/local0/jonas_home/.cache/Cypress/12.7.0/Cypress/resources/app/node_modules/@cspotcode/source-map-support/source-map-support.js:745:40)
      at emit (node:internal/child_process:938:14)
      at processTicksAndRejections (node:internal/process/task_queues:84:21)
1

There are 1 best solutions below

1
On

This isn't the cause of the error, but it answers one of your problems:

There would seem to be a mixup between the custom command and the type definition for it.

Cypress.Commands.add('readXlsx', (InputFile, string) => cy.task(
  'readXlsx',
  { filePath: InputFile, sheetName: string },
))

You have copied the task parameters to the type definition, but it should be this

readXlsx(InputFile: string, string: string): Chainable<CyQElem>;

Improving the naming will help you a lot, for example call the task readXlsxTask to differentiate from the custom command name.

Plus string as a parameter name confuses with the type string, perhaps this instead:

Cypress.Commands.add('readXlsx', (filePath, sheetName) => {
  cy.task('readXlsxTask', { filePath, sheetName })
})
// index.d.ts
readXlsx(filePath: string, sheetName: string): Chainable<CyQElem>;