WasiqB / multiple-cucumber-html-reporter

Generate beautiful Cucumber HTML reports
https://github.com/WasiqB/multiple-cucumber-html-reporter/blob/main/README.md
MIT License
250 stars 120 forks source link

How to show Start Time and End time for each Scenario #136

Open qburst-hari opened 3 years ago

qburst-hari commented 3 years ago

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):

wswebcreation commented 3 years ago

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

qburst-hari commented 3 years ago

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

Dushanbe24 commented 2 years ago

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 commented 2 years ago
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

jaxfellow commented 1 year ago

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()}
            ]
        }
    });
});
thierryiseli commented 1 year ago

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