javascriptcypresslighthousecypress-cucumber-preprocessorcypress-task

how to give a custom name for lighthouse report which is generated by cypress-audit package


I need to generate multiple lighthouse reports for multiple test scenarios. by using cypress-audit package I wrote a method for generating lighthouse report.

in below you can see that method

export function lighthouseAudit(scenarioId, baseValueData) {
    const lighthouseMetrics = {
        performance: baseValueData.performance,
        accessibility: baseValueData.accessibility,
        seo: baseValueData.seo,
        pwa: baseValueData.pwa
    };

    cy.log("lighthousemetrics", lighthouseMetrics);

    const desktopConfig = {
        formFactor: 'desktop',
        screenEmulation: { disabled: true },
    };

    cy.lighthouse(lighthouseMetrics, desktopConfig);
}

below you can see how I generated the report once after called "lighthouseAudit" method

//cypress.config.js file
    module.exports = defineConfig({
      reporter: 'mochawesome',
      defaultCommandTimeout: 6000,
      taskTimeout: 20000,
      execTimeout: 6000,
      viewportWidth: 1920,
      viewportHeight: 1080,
      e2e: {
        experimentalSessionAndOrigin:true,
        setupNodeEvents(on, config) {
          getCompareSnapshotsPlugin(on, config);
          on('file:preprocessor', cucumber())
          on("before:browser:launch", (browser = {}, launchOptions) => {
            prepareAudit(launchOptions);
          });
          on('task', {
            lighthouse: lighthouse((lighthouseReport) => {
              const folderPathForLH = "cypress/lightHouse"
              if (!fs.existsSync(folderPathForLH)) {
                fs.mkdirSync(folderPathForLH);
              }
              fs.writeFileSync(`${folderPathForLH}/lightHouseReport.html`, ReportGenerator.generateReport(lighthouseReport.lhr, 'html'));
              return lighthouseReport;
            }),
          });
        },
        specPattern: "**/*.{feature,features}"
      },
    });

enter image description here

as you can see I gave the name as "lightHouseReport.html" for the report. but the issue is it will replace when each test ran. I want to create reports for each and every test.

enter image description here

when calling "lighthouseAudit" method I am passing "scenarioId" as a parameter. I want to create the lighthouse report by that name.

example

lighthouseAudit("storydashboard",baseValues);

output should be

"storydashboard.html"

used packages

  "@cypress-audit/lighthouse": "^1.3.1",
  "cypress": "^10.9.0",
  "cypress-audit": "^1.1.0",
  "cypress-cucumber-preprocessor": "^4.3.1",

Solution

  • To me, the simplest way would be to add another task that sends the name from the test into the node process.

    cypress.config.js

    let lighthouseReportName;                          // add this to hold the name
    
    module.exports = defineConfig({
      reporter: 'mochawesome',
      defaultCommandTimeout: 6000,
      taskTimeout: 20000,
      execTimeout: 6000,
      viewportWidth: 1920,
      viewportHeight: 1080,
      e2e: {
        experimentalSessionAndOrigin:true,
        setupNodeEvents(on, config) {
          getCompareSnapshotsPlugin(on, config);
          on('file:preprocessor', cucumber())
          on("before:browser:launch", (browser = {}, launchOptions) => {
            prepareAudit(launchOptions);
          });
          on('task', {
    
            setLighthouseReportName: (name) => {             // called any time 
              lighthouseReportName = name                    // you want a new name
            }
           
            lighthouse: lighthouse((lighthouseReport) => {
              const folderPathForLH = "cypress/lightHouse"
              if (!fs.existsSync(folderPathForLH)) {
                fs.mkdirSync(folderPathForLH);
              }
    
              const filePath = `${folderPathForLH}/${lightHouseReportName}.html`
    
              fs.writeFileSync(filePath, 
                ReportGenerator.generateReport(lighthouseReport.lhr, 'html'));
              return lighthouseReport;
            }),
          });
        },
        specPattern: "**/*.{feature,features}"
      },
    });
    

    Test helper function

    export function lighthouseAudit(scenarioId, baseValueData) {
        const lighthouseMetrics = {
            performance: baseValueData.performance,
            accessibility: baseValueData.accessibility,
            seo: baseValueData.seo,
            pwa: baseValueData.pwa
        };
    
        cy.log("lighthousemetrics", lighthouseMetrics);
    
        const desktopConfig = {
            formFactor: 'desktop',
            screenEmulation: { disabled: true },
        };
    
        cy.task('setLighthouseReportName', scenarioId)   
    
        cy.lighthouse(lighthouseMetrics, desktopConfig);
    }
    

    Without looking into the code, I presume that cy.lighthouse() will internally call the task lighthouse without your intervention.

    Since there's some asynchronous actions going on, you may need to sequence the setLighthouseReportName task and the subsequent report like this

    cy.task('setLighthouseReportName', scenarioId)  
      .then(() => {
        cy.lighthouse(lighthouseMetrics, desktopConfig);
      })