multiple-cucumber-html-reporter icon indicating copy to clipboard operation
multiple-cucumber-html-reporter copied to clipboard

How to show Start Time and End time for each Scenario

Open qburst-hari opened this issue 4 years ago • 6 comments

I am using webdriverIO 6 with cucumber. So currently I am able to show the overall Start time and End Time using custom Data in Overall report.

But is there any option I can show the start time and end time for each feature/scenario. Its like :

When I run 10 scenarios as a suite. In overall Page, I can show - Execution Start Time and Execution End Time.

But when we click and open each Feature Report, there I would like to show the start time and end time for each feature.

Please let me know if there is any option for that.

Environment (please complete the following information):

  • multiple-cucumber-html-reporter:1.17.0
  • Node.js version: 12.0
  • NPM version: 6.14
  • Platform name and version:Ubuntu
  • Cucucmber version: 6.0.5

qburst-hari avatar Nov 13 '20 05:11 qburst-hari

Thanks for submitting an issue, I need to look into it when I have some more time

wswebcreation avatar Nov 18 '20 12:11 wswebcreation

Thanks, as it would be a nice feature to see the Start time, end time also. Currently we are showing duaration, but if we have start time and end time, it would be easily to check server logs based on failure timing

qburst-hari avatar Nov 18 '20 12:11 qburst-hari

Hi Guys I have some question How I can to see Start time and End time in my multiple-cucumber-html-reporter, normally I'm using Cypress , for my report multiple-cucumber-html-reporter, my end time working but the end time is not, maybe you have some suggestions. Screenshot 2022-01-13 134239

Dushanbe24 avatar Jan 13 '22 12:01 Dushanbe24

const report = require("multiple-cucumber-html-reporter");
const fs = require("fs-extra");
const path = require("path");
const chalk = require("chalk");
const args = process.argv;

const cucumberJsonDir = path.resolve(process.cwd(), "cypress/cucumber-json");
const cucumberReportFileMap = {};
const cucumberReportMap = {};
const jsonIndentLevel = 2;
const htmlReportDir = path.resolve(process.cwd(), "cypress/cucumber-json");
const screenshotsDir = path.resolve(process.cwd(), "cypress/screenshots");
const reportPath = "./cypress/cucumber-html-reporter/";

getCucumberReportMaps();
addScreenshots();
generateReport();

function getCucumberReportMaps() {
  filenames = fs.readdirSync(cucumberJsonDir);
  const files = fs.readdirSync(cucumberJsonDir).filter((file) => {
    return file.indexOf(".json") > -1;
  });
  files.forEach((file) => {
    const json = JSON.parse(fs.readFileSync(path.join(cucumberJsonDir, file)));
    if (!json[0]) {
      return;
    }
    const [feature] = json[0].uri.split("/").reverse();
    cucumberReportFileMap[feature] = file;
    cucumberReportMap[feature] = json;
  });
}

function addScreenshots() {
  if (fs.existsSync(screenshotsDir)) {
    //only if screenshots exists
    const prependPathSegment = (pathSegment) => (location) =>
      path.join(pathSegment, location);

    const readdirPreserveRelativePath = (location) =>
      fs.readdirSync(location).map(prependPathSegment(location));

    const readdirRecursive = (location) =>
      readdirPreserveRelativePath(location).reduce(
        (result, currentValue) =>
          fs.statSync(currentValue).isDirectory()
            ? result.concat(readdirRecursive(currentValue))
            : result.concat(currentValue),
        []
      );

    const screenshots = readdirRecursive(path.resolve(screenshotsDir)).filter(
      (file) => {
        return file.indexOf(".png") > -1;
      }
    );

    const featuresList = Array.from(
      new Set(screenshots.map((x) => x.match(/[\w-_.]+.feature/g)[0]))
    );

    featuresList.forEach((feature) => {
      screenshots.forEach((screenshot) => {
        const regex =
          /(?<=--\ ).+?((?=\ (example\ #\d+))|(?=\ (failed))|(?=.\w{3}))/g;
        const [scenarioName] = screenshot.match(regex);

        var filename = screenshot.replace(/^.*[\\\/]/, "");

        const featureSelected = cucumberReportMap[feature][0];

        let myScenarios = [];

        cucumberReportMap[feature][0].elements.forEach((item) => {
          let fullFileName = featureSelected.name + " -- " + item.name;
          if (filename.includes(fullFileName)) {
            myScenarios.push(item);
          }
        });

        if (!myScenarios) {
          return;
        }
        let foundFailedStep = false;
        myScenarios.forEach((myScenario) => {
          if (foundFailedStep) {
            return;
          }
          let myStep;
          if (screenshot.includes("(failed)")) {
            myStep = myScenario.steps.find(
              (step) => step.result.status === "failed"
            );
          } else {
            myStep = myScenario.steps.find(
              (step) => step.result.status === "passed"
            );
          }
          if (!myStep) {
            return;
          }
          const data = fs.readFileSync(path.resolve(screenshot));
          if (data) {
            const base64Image = Buffer.from(data, "binary").toString("base64");
            if (!myStep.embeddings) {
              myStep.embeddings = [];
              myStep.embeddings.push({
                data: base64Image,
                mime_type: "image/png",
                name: myStep.name,
              });
              foundFailedStep = true;
            }
          }
        });
        //Write JSON with screenshot back to report file.
        fs.writeFileSync(
          path.join(cucumberJsonDir, cucumberReportFileMap[feature]),
          JSON.stringify(cucumberReportMap[feature], null, jsonIndentLevel)
        );
      });
    });
  }
}

function generateReport() {
  if (!fs.existsSync(cucumberJsonDir)) {
    console.warn("REPORT CANNOT BE CREATED!");
  } else {
    //  var runInfos = JSON.parse();
    report.generate({
      jsonDir: cucumberJsonDir,
      reportPath: htmlReportDir,
      displayDuration: true,
      durationInMS: true,
      openReportInBrowser: true,
      useCDN: true,
      pageTitle: "Customer Admin",
      reportName: `System-Test Report - ${new Date().toLocaleString()}`,
      metadata: {
        app: {
          name: "Simulacion de Credito Online",
          version: "1",
        },
        browser: {
          name: "Chrome",
        },
        device: "Cypress",
        platform: {
          name: "Windows",
        },
      },
      customData: {
        title: "Run info",
        data: [
          { label: "Project", value: "Simulacion de Credito" },
          { label: "Release", value: "2" },
          {
            label: "Execution Start Time",
            // value: `${new Date().toLocaleTimeString()}`,
            value: new Date().toLocaleTimeString(),
          },
          { label: "Execution End Time", value: new Date().toLocaleString() },
        ],
      },
    });
  }
}

this method I used for cucumber -html-report.js

Dushanbe24 avatar Jan 13 '22 12:01 Dushanbe24

here is a solution from @thierryiseli mentioned here

It doesn't work for me, but maybe someone else can try it out

1- Save the run info results after the run by adding after:run to your cypress.config file

const cucumber = require('cypress-cucumber-preprocessor').default
const fs = require('fs');

module.exports = (on, config) => {
 on('file:preprocessor', cucumber()),
 on('after:run', (results) => {
   if (results) {
     fs.mkdirSync("cypress/.run", { recursive: true });
     fs.writeFile("cypress/.run/results.json", JSON.stringify(results));
   }
 })
}

2- Use this json file in the report

const report = require('multiple-cucumber-html-reporter');
const fs = require('fs');

const mapOs = (os) => {
    if(os.startsWith('win')) {
        return 'windows';
    } else if (os.startsWith('osx')) {
        return 'osx';
    } else if (os.startsWith('linux')) {
        return 'linux';
    } else if (os.startsWith('ubuntu')) {
        return 'ubuntu';
    } else if (os.startsWith('android')) {
        return 'android';
    } else if (os.startsWith('ios')) {
        return 'ios';
    }
};

fs.readFile('cypress/.run/results.json', function read(err, data) {
    if (err) {
        throw err;
    }
    var runInfos = JSON.parse(data);
    report.generate({
        jsonDir: './cypress/result/',
        reportPath: './cypress/report/',
        metadata:{
            browser: {
                name: runInfos.browserName,
                version: runInfos.browserVersion
            },
            device: 'Cypress',
            platform: {
                name: mapOs(runInfos.osName)
            }
        },
        customData: {
            title: 'Run info',
            data: [
                {label: 'Project', value: 'project'},
                {label: 'Execution Start Time', value: new Date(runInfos.startedTestsAt).toLocaleString()},
                {label: 'Execution End Time', value: new Date(runInfos.endedTestsAt).toLocaleString()}
            ]
        }
    });
});

jaxfellow avatar Feb 03 '23 13:02 jaxfellow

I found here an example how I did it: https://github.com/thierryiseli/javascript-demo-todolist-cypress/tree/legacy, but it's really outdated... I also did an example with the latest versions: https://github.com/thierryiseli/javascript-demo-todolist-cypress

thierryiseli avatar Feb 05 '23 15:02 thierryiseli