Skip to content

Commit

Permalink
feat(puppet): dump screenshots on failing test
Browse files Browse the repository at this point in the history
  • Loading branch information
Christoffer Åström authored and stoffeastrom committed Mar 18, 2020
1 parent 20170aa commit 3ca2303
Show file tree
Hide file tree
Showing 6 changed files with 221 additions and 23 deletions.
4 changes: 3 additions & 1 deletion commands/puppeteer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@
"@after-work.js/watch-plugin": "6.0.13",
"chrome-launcher": "0.13.0",
"import-cwd": "3.0.0",
"puppeteer-core": "1.20.0"
"puppeteer-core": "1.20.0",
"terminal-image": "0.2.0",
"mkdirp": "0.5.1"
},
"files": [
"/src"
Expand Down
63 changes: 61 additions & 2 deletions commands/puppeteer/src/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
/* eslint global-require: 0, import/no-dynamic-require: 0, object-curly-newline: 0, class-methods-use-this: 0, max-len: 0 */
const path = require('path');
const util = require('util');
const mkdirp = require('mkdirp');
const importCwd = require('import-cwd');
const chromeFinder = require('chrome-launcher/dist/chrome-finder');
const { getPlatform } = require('chrome-launcher/dist/utils');
const terminalImage = require('terminal-image');
const createServer = require('@after-work.js/server');
const { Runner, configure } = require('@after-work.js/node/src/');
const nodeOptions = require('@after-work.js/node/src/options');
Expand All @@ -10,10 +14,17 @@ const puppetOptions = require('./options');

const options = Object.assign({}, nodeOptions, puppetOptions);

const getSafeFileName = title => {
const fileName = title.replace(/[^a-z0-9().]/gi, '_').toLowerCase();
return util.format('%s-%s-%s.png', fileName, 'chrome', +new Date());
};

class PuppetRunner extends Runner {
constructor(puppeteer, argv, libs) {
argv.coverage = false;
super(argv, libs);
this.puppeteer = puppeteer;
this.screenshots = [];
}

static async getChromeExecutablePath(stable) {
Expand Down Expand Up @@ -57,8 +68,51 @@ class PuppetRunner extends Runner {
}
}

runTests() {
super.runTests();
this.mochaRunner.on('fail', (test, err) => {
const screenshotsPath = `${this.argv.artifactsPath}/screenshots`;
mkdirp.sync(screenshotsPath);
const filePath = path.resolve(
screenshotsPath,
getSafeFileName(test.fullTitle()),
);
const screenshot = {
title: test.fullTitle(),
buffer: page.screenshot({
path: filePath,
fullPage: true,
err,
}),
filePath,
};
this.screenshots.push(screenshot);
});
}

async handleScreenshots() {
if (this.screenshots.length) {
console.error('\u001b[31mscreenshots:\u001b[0m');
console.error('');
}
await Promise.all(
this.screenshots.map(async screenshot => {
const buffer = await screenshot.buffer;
console.error(` ${screenshot.title}`);
console.error(` \u001b[90m${path.relative(process.cwd(), screenshot.filePath)}\u001b[0m`);
console.error('');
if (this.argv.screenshotsStderr) {
console.error(await terminalImage.buffer(buffer));
console.error('');
}
}),
);
this.screenshots.length = 0;
}

closeBrowser() {
(async () => {
await this.handleScreenshots();
await this.browser.close();
})();
}
Expand Down Expand Up @@ -96,7 +150,8 @@ const puppet = {
.middleware(utils.addDefaults)
.options(options)
.config('config', configure)
.coerce('babel', utils.coerceBabel);
.coerce('babel', utils.coerceBabel)
.coerce('artifactsPath', p => path.resolve(process.cwd(), p));
},
handler(argv) {
(async function launchAndRun() {
Expand All @@ -113,6 +168,7 @@ const puppet = {
}
}
const runner = new PuppetRunner(puppeteer, argv);

if (argv.presetEnv) {
require('@after-work.js/preset-plugin')(runner);
}
Expand All @@ -122,7 +178,10 @@ const puppet = {
argv.interactive = true;
}
if (argv.interactive) {
require('@after-work.js/interactive-plugin')(runner);
const onWatchEnd = async () => {
await runner.handleScreenshots();
};
require('@after-work.js/interactive-plugin')(runner, onWatchEnd);
}
if (argv.watch) {
require('@after-work.js/watch-plugin')(runner);
Expand Down
10 changes: 10 additions & 0 deletions commands/puppeteer/src/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -226,4 +226,14 @@ module.exports = {
default: false,
type: 'boolean',
},
screenshotsStderr: {
description: 'Log screenshot of failing test in stderr',
default: false,
type: 'boolean',
},
artifactsPath: {
description: 'Base path to artifacts like screenshots',
default: 'test/__artifacts__',
type: 'string',
},
};
9 changes: 7 additions & 2 deletions examples/puppeteer/test/hello.fix.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,20 @@
<meta charset="utf-8" />
<base href="/" />
<style>
#container {
#parent {
display: flex;
width: 100%;
height: 100%;
align-items: center;
justify-content: center;
}
</style>
</head>

<body>
<div id="container" onclick="getData();">hello world</div>
<div id="parent">
<div id="container" onclick="getData();">hello world</div>
</div>
<script>
window.getData = () => {
const container = document.querySelector("#container");
Expand Down
7 changes: 5 additions & 2 deletions plugins/interactive-plugin/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,10 @@ const onInteractive = async runner => {
}
};

module.exports = function interactivePlugin(runner) {
runner.on('watchEnd', () => onInteractive(runner));
module.exports = function interactivePlugin(runner, onWatchEnd = async () => {}) {
runner.on('watchEnd', async () => {
await onWatchEnd();
onInteractive(runner);
});
runner.on('interactive', () => onInteractive(runner));
};
Loading

0 comments on commit 3ca2303

Please sign in to comment.