cypress: Add failed screenshot to test information for custom reporter

Current behavior:

When writing a custom reporter you have access to some information from the test, but no indication of the screenshot taken automatically on failure.

runner.on('test end', function(test) {
  console.log(test);
});

Desired behavior:

the test object to have the screenshot path

runner.on('test end', function(test) {
  console.log(test.screenshot);
  // or
  console.log(test.failedScreenshot);
});

Steps to reproduce: (app code and test code)

simple runner reporters/test.js

module.exports = function(runner, config) {
  runner.on('test end', function(test) {
    console.log('test done');
  });
}

use in cypress.json

{
  "reporter": "reporters/test.js"
}

Versions

Cypress 3.3.1
OS: Linux (Ubuntu) Browser: Any

Workaround

You can access the files with fs and path no problem in the end hook. This is less than ideal as you have to try and map file names to your failures

runner.on('end', function() {
  //getFilePaths is a helper to list all files in a directory
  console.log('end:', getFilePaths('cypress/screenshots'));
});

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 6
  • Comments: 16 (2 by maintainers)

Most upvoted comments

@jennifer-shehane Yeah, have added screenshots to mochawesome using mapping filename approach and it was a long road of defining how screenshot names behave with special symbols (some are supported, other deleted) and after switch from 3.2 to 3.3 it has changed >< So it would be great to have it accessible inside test object.

@irfancharania Here is the one that works even if there are failures in any of the hooks as well.

Cypress.on('test:after:run', (test, runnable ) => {
if (test.state === 'failed') {
  let item = runnable
  const nameParts = [runnable.title]
  while (item.parent) {
    nameParts.unshift(item.parent.title)
    item = item.parent
  }
  if(runnable.hookName) {
    nameParts.push(`${runnable.hookName} hook`)
    }
  const fullTestName = nameParts.filter(Boolean).join(' -- ')
  const screenshotPath = `cypress/screenshots/${Cypress.spec.name}/${fullTestName} (failed).png`.replace("  "," ")

  addContext({ test }, screenshotPath)
}
})

this is how I improved on the workaround mentioned above:

const addContext = require('mochawesome/addContext');

Cypress.Screenshot.defaults({
	onAfterScreenshot($el, props) {
		document.querySelector('html').setAttribute('screenshot-path', props.path);
	},
});

Cypress.on('test:after:run', (test) => {
	if (test.state === 'failed') {
		const screenshotPath = document
			.querySelector('html')
			.getAttribute('screenshot-path');
		const reporterDirPath = Cypress.config()['reporterOptions']['reportDir'];

		addContext({ test }, `${screenshotPath.split(`${reporterDirPath}/`)[1]}`);
	}
});