-2

I have a task like this in cypress.config.js

async function setupNodeEvents(on, config) {
  allureWriter(on, config);
  await preprocessor.addCucumberPreprocessorPlugin(on, config);
  on('task', { downloadFile });
  on(
      "file:preprocessor",
      createBundler({
          plugins: [createEsbuildPlugin.default(config)],
      })
  );
  on("file:preprocessor", browserify.default(config));

  on('task', {
      log(message) {
          console.log(message)
          return null
      }
  });
  on('task', {
    createExcelFile(filePath, headers, data) {
      const workbook = new ExcelJS.Workbook();
      const worksheet = workbook.addWorksheet('Sheet 1');

      if (headers && Array.isArray(headers)) {
            worksheet.addRow(headers);
            console.log('Header Row:', headers);
        }

        // Add data rows if data is provided
          if (data && Array.isArray(data)) {
                data.forEach(row => {
                worksheet.addRow(row);
                console.log('Data Row:', row);
            });
          }


      // Save the workbook to the specified file path
      return workbook.xlsx.writeFile(filePath)
        .then(() => {
            return null; // Indicate that the task was handled
        })
        .catch(error => {
            throw error; // Propagate the error if encountered
        });
      }
  });

  return config;
}

module.exports = defineConfig({
  reporterOptions: {
      charts: true,
      reportPageTitle: "custom-title",
      embeddedScreenshots: true,
      inlineAssets: true,
      saveAllAttempts: false,
  },
  e2e: {
      setupNodeEvents,
 ----
 }

    }
  }
});

And I am calling this createExcelFile like this

Cypress.Commands.add('createImportDemoExcel', () => {
  cy.fixture('testData/api/demo-api').then(call => {
    cy.request('GET', callPath
    ).then(function (res) {
      const apiResponse = res.body.data;
      const extractedData = [];

      apiResponse.forEach(item => {
        const age = item.id;
        const name = item.name;
        const zip = item.yearLevelId;
        extractedData.push([name, age, zip]);
      });

      const excelFilePath = "cypress/fixtures/testData/ImportData.xlsx";
      let headers = ['Age', 'Name', 'Zip'];
      cy.task('createExcelFile', excelFilePath, headers, extractedData);

      localStorage.setItem('token', res.body.token);
      localStorage.setItem('refreshToken', res.body.refreshToken);
    });
  });
});

But it is giving error as Header Row: undefined and Cannot read properties of undefined (reading 'forEach'). However the extractedData.push([name, age, zip]); is generated fine.

Also if I cy.request from config file within createExcelFile then there is no error but if I call it from commands.js then it gives undefined error for extractedData and headers

What wrong am I doing?

Gregoire Ducharme
  • 1,095
  • 12
  • 24
paul
  • 4,333
  • 16
  • 71
  • 144
  • Which foreach is causing the error? – A.Pearsson Aug 16 '23 at 09:36
  • The one that adds the rows to the data, this one `data.forEach(row => { ` – paul Aug 16 '23 at 09:46
  • 3
    Thing is, you have `if (data && Array.isArray(data))` so `data` cannot be undefined. – A.Pearsson Aug 16 '23 at 09:55
  • `extractedData` is passed to it when I call it via `command.js`. So to confirm that `extractedData` is not blank/undefined I tried to print it in console and it printed the right data. Does `undefine` mean, it is not defined and I need to initialize it in `task` block itself? – paul Aug 16 '23 at 10:39
  • Even if I remove `if` block, then also it gives the error that data.forEach can not be executed on undefined. BTW, are you able to reproduce it? – paul Aug 16 '23 at 10:47
  • 1
    That is a very confused question. – Muffy Cound Aug 16 '23 at 10:58
  • Why would you remove the if block? – Muffy Cound Aug 16 '23 at 10:58
  • @MuffyCound if I don't want to check the condition `if (data && Array.isArray(data)) {` I will remove it. – paul Aug 16 '23 at 11:13
  • @MuffyCound question is if `headers` and `extractedData` are not empty, properly defined then why they never reach inside `if` block? If I prepare the data (headers, extractedData) for if blocks within the `createExcelFile` task block then it passes. Were you able to reproduce it? Is it working for you, from `command.js`? – paul Aug 16 '23 at 11:16

1 Answers1

4

As already mentioned, the code in the task can't be causing the error

if (data && Array.isArray(data)) {
  data.forEach(row => {                    <--------- data cannot be undefined

so it must be this code

apiResponse.forEach(item => {

which means you are not extracting the response correctly.

Try parsing

cy.request('GET', callPath)
  .then(res => {
    const apiResponse = JSON.parse(res.body.data)

or else examine what the response is and adjust accordingly.

There isn't enough information to say exactly, because you jumped to the wrong conclusion. In fact, the error has nothing to do with the task!