Commit 4e42696f authored by Fred Chasen's avatar Fred Chasen

Add Jest + Puppeteer test runner

parent 663d1667
......@@ -2,3 +2,4 @@
node_modules
dist
lib
__diff_output__
......@@ -60,3 +60,6 @@ Build the `dist` output
```sh
$ npm run prepare
```
## Testing
`brew install ghostscript`
module.exports = {
globalSetup: './jest/setup.js',
globalTeardown: './jest/teardown.js',
testEnvironment: './jest/puppeteer_environment.js',
}
const path = require('path');
const os = require('os');
const DIR = path.join(os.tmpdir(), 'jest_puppeteer_global_setup')
const WS_ENDPOINT_PATH = path.join(DIR, 'wsEndpoint')
const DEBUG = process.env.NODE_ENV === 'debug';
const PORT = 9999;
const ORIGIN = `http://localhost:${PORT}`;
const CI = process.env.CI === 'true';
module.exports = {
DIR,
WS_ENDPOINT_PATH,
DEBUG,
PORT,
ORIGIN,
CI
}
const chalk = require('chalk');
const NodeEnvironment = require('jest-environment-node');
const puppeteer = require('puppeteer');
const fs = require('fs');
const os = require('os');
const path = require('path');
const { WS_ENDPOINT_PATH, DIR, DEBUG, ORIGIN } = require('./constants');
class PuppeteerEnvironment extends NodeEnvironment {
constructor(config) {
super(config);
}
async setup() {
DEBUG && console.log(chalk.yellow('Setup Test Environment.'));
await super.setup()
const wsEndpoint = fs.readFileSync(WS_ENDPOINT_PATH, 'utf8');
if (!wsEndpoint) {
throw new Error('wsEndpoint not found');
}
this.global.browser = await puppeteer.connect({
browserWSEndpoint: wsEndpoint,
})
this.global.origin = ORIGIN;
this.global.DEBUG = DEBUG;
}
async teardown() {
DEBUG && console.log(chalk.yellow('Teardown Test Environment.'));
await super.teardown();
}
runScript(script) {
return super.runScript(script);
}
}
module.exports = PuppeteerEnvironment;
const chalk = require('chalk');
const puppeteer = require('puppeteer');
const fs = require('fs');
const mkdirp = require('mkdirp');
const os = require('os');
const path = require('path');
const express = require('express');
const app = express();
const { WS_ENDPOINT_PATH, DIR, DEBUG, CI, PORT } = require('./constants');
module.exports = async function() {
DEBUG && console.log(chalk.green('Starting Static Server\n'));
app.use(express.static(path.join(__dirname, '../')));
const server = app.listen(PORT);
global.server = server;
global.origin = `http://localhost:${PORT}`;
DEBUG && console.log(chalk.green('Setup Puppeteer'));
let args = CI ? ['--no-sandbox', '--disable-setuid-sandbox'] : [];
const browser = await puppeteer.launch({
headless: DEBUG ? false : true,
args: args
})
global.browser = browser;
mkdirp.sync(DIR);
fs.writeFileSync(WS_ENDPOINT_PATH, browser.wsEndpoint());
}
const chalk = require('chalk');
const puppeteer = require('puppeteer');
const rimraf = require('rimraf');
const os = require('os');
const path = require('path');
const { DIR, DEBUG, CI, PORT } = require('./constants');
module.exports = async function() {
DEBUG && console.log(chalk.green('Teardown Puppeteer'));
if (!DEBUG) {
await global.browser.close();
global.server.close();
}
rimraf.sync(DIR);
}
This diff is collapsed.
......@@ -17,6 +17,13 @@
"babel-cli": "^6.26.0",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-env": "^1.6.1",
"chalk": "^2.4.1",
"express": "^4.16.3",
"ghostscript4js": "^2.0.7",
"jest": "^22.4.3",
"jest-image-snapshot": "^2.4.1",
"puppeteer": "^1.3.0",
"rimraf": "^2.6.2",
"rollup": "^0.57.0",
"rollup-plugin-commonjs": "^9.1.0",
"rollup-plugin-json": "^2.3.0",
......@@ -28,7 +35,7 @@
"scripts": {
"build": "./node_modules/.bin/rollup -c",
"start": "./node_modules/.bin/rollup -w -c rollup.server.config.js",
"test": "node test/test.js",
"test": "jest",
"compile": "./node_modules/.bin/babel src/ -d lib/",
"pretest": "npm run build",
"prepare": "npm run build && npm run compile",
......
......@@ -8,6 +8,10 @@ export default `
--margin-left: 1in;
}
@page {
size: var(--width) var(--height);
}
.page {
box-sizing: border-box;
width: var(--width);
......
......@@ -75,7 +75,7 @@ ready.then(async function () {
let msg = "Rendering " + flow.total + " pages took " + (endTime - startTime) + " milliseconds.";
if (typeof window.onPagesRendered !== "undefined") {
window.onPagesRendered(msg, styles.width.value + styles.width.unit, styles.height.value + styles.height.unit, styles.orientation);
window.onPagesRendered(msg, styles.width && styles.width.value + styles.width.unit, styles.height && styles.height.value + styles.height.unit, styles.orientation);
}
});
<!DOCTYPE html PUBLIC>
<html lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<title>
The Project Gutenberg eBook of Auroræ: Their Characters and Spectra, by J. Rand Capron.
</title>
<link rel="coverpage" href="images/cover.jpg" />
<script src="../../../dist/paged.polyfill.js"></script>
</head>
<body>
<section id="cover">
<h1>Auroræ : their characters and spectra</h1>
</section>
</body>
</html>
const path = require('path');
const gs = require('ghostscript4js')
const fs = require('fs');
const { toMatchImageSnapshot } = require('jest-image-snapshot');
const rimraf = require('rimraf');
const timeout = 10000;
const handleError = (error) => {
console.error(error);
};
describe('break', async () => {
let page;
let rendered;
beforeAll(async () => {
expect.extend({ toMatchImageSnapshot });
page = await browser.newPage()
page.addListener('pageerror', handleError);
page.addListener('error', handleError);
let renderedResolve;
rendered = new Promise(function(resolve) {
renderedResolve = resolve;
});
await page.exposeFunction('onPagesRendered', (msg, width, height, orientation) => {
renderedResolve(msg, width, height, orientation);
});
await page.goto(global.origin+'/tests/specs/default/default.html', { waitUntil: 'networkidle2' });
return rendered;
}, timeout)
afterAll(async () => {
if (!DEBUG) {
await page.close();
}
})
it('should render text', async () => {
let text = await page.evaluate(() => document.body.textContent);
expect(text).toContain('Auroræ');
})
it('should render 1 page', async () => {
let pages = await page.$$eval(".pages", (r) => r.length);
expect(pages).toBe(1);
})
it('should create a pdf', async () => {
let outputPath = path.join(__dirname, './output.pdf');
let pdf = await page.pdf({
path: outputPath,
printBackground: true,
displayHeaderFooter: false,
margin: {
top: 0,
right: 0,
bottom: 0,
left: 0,
}
// format: 'A4'
}).catch((e) => {
console.error(e);
});
// Output an image from the pdf
let pdfImage;
try {
// create image
let imagePath = path.join(__dirname, './output.png');
let page = 1;
gs.executeSync(`-dFirstPage=${page} -dLastPage=${page} -sDEVICE=pngalpha -o ${imagePath} -sDEVICE=pngalpha -r144 ${outputPath}`)
// load image
pdfImage = fs.readFileSync(imagePath);
// remove output
if (!DEBUG) {
rimraf.sync(imagePath);
rimraf.sync(outputPath);
}
} catch (err) {
throw err
}
expect(pdfImage).toMatchImageSnapshot();
})
}
)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment