Skip to content

Instantly share code, notes, and snippets.

@zeropaper
Last active October 29, 2019 10:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zeropaper/a0e0b84f6e8f10b716433955caceab6f to your computer and use it in GitHub Desktop.
Save zeropaper/a0e0b84f6e8f10b716433955caceab6f to your computer and use it in GitHub Desktop.
Example of Jest environment to generate documentation
// NOTE: this code is not intended to work as-is,
// it needs to be adapted to your setup/environment
const NodeEnvironment = require('jest-environment-node');
const puppeteer = require('puppeteer');
const path = require('path');
const rimraf = require('rimraf');
const mkdirp = require('mkdirp');
const httpServer = require('http-server');
// very useful tool to turn a callback function into a async function ;)
const { promisify } = require('util');
const { writeFile: fsWriteFile } = require('fs');
const documentationTemplate = require('./e2e.documentation-template');
const writeFile = promisify(fsWriteFile);
const slugify = str => str
.trim()
.toLowerCase()
.split(/[^a-z0-9]+/g)
.join('-');
const {
TEST_KEEP_BROWSER,
NODE_WATCH,
HEADLESS,
JEST_SERVE,
SLOWMO,
} = process.env;
const docsOutputDir = path.resolve(__dirname, '../test-results/docs');
const processDocsScreenshot = ({
title,
slug,
testPages,
number,
}) => async ({
pageIndex = 0,
description = '',
}) => {
const screenshotPath = path
.join(docsOutputDir, 'screenshots', `${number}-${pageIndex}-${slug}.png`);
await testPages[pageIndex].screenshot({
path: screenshotPath,
});
return {
title,
slug,
pageIndex,
screenshotPath: path.relative(docsOutputDir, screenshotPath),
description,
};
};
class PuppeteerEnvironment extends NodeEnvironment {
async setup() {
await super.setup();
this.counter = 0;
this.docsInfo = [];
rimraf.sync(docsOutputDir);
mkdirp.sync(path.join(docsOutputDir, 'screenshots'));
const browser = await puppeteer.launch({});
// The tests from which code is taken is using several browser contexts
// each of them stored in a global "testPages" array
this.global.testPages = [
await browser.newPage(),
];
const addNewPageWithNewContext = async () => {
const page = await newPageWithNewContext(browser);
this.global.testPages.push(page);
};
this.global.addNewPageWithNewContext = addNewPageWithNewContext;
await addNewPageWithNewContext();
this.global.writeDocs = async ({
info = {},
screenshots = [],
} = {}) => {
const {
title = 'Missing title',
description = '',
} = info;
const generated = {
title,
description,
screenshots: await Promise
.all(screenshots
.map(processDocsScreenshot({
title,
slug: slugify(title),
testPages: this.global.testPages,
number: this.docsInfo.length,
}))),
};
this.docsInfo.push(generated);
};
}
async teardown() {
const content = await documentationTemplate({
title: 'Documenation',
info: this.docsInfo,
});
await writeFile(path.join(docsOutputDir, 'index.html'), content, 'utf8');
await super.teardown();
}
runScript(script) {
return super.runScript(script);
}
}
module.exports = PuppeteerEnvironment;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment