Skip to content
This repository was archived by the owner on Oct 11, 2024. It is now read-only.

Commit 31a7a29

Browse files
authored
feat: puppeteer with watch (#315)
1 parent 757da05 commit 31a7a29

9 files changed

Lines changed: 132 additions & 69 deletions

File tree

aw.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ yargs
4545
});
4646
} else {
4747
[...scopes.keys()]
48-
.filter(k => (!k.includes('example-chrome') && !k.includes('example-protractor')))
48+
.filter(k => (!k.includes('example-chrome') && !k.includes('example-protractor') && !k.includes('example-puppeteer')))
4949
.map(k => scopes.get(k))
5050
.forEach((p) => {
5151
glob = [...glob, `${p}/test/**/*.spec.{js,ts}`];

commands/node/src/index.js

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/* eslint no-console: 0, max-len: 0, global-require: 0, import/no-dynamic-require: 0, object-curly-newline: 0, class-methods-use-this: 0 */
2+
const EventEmitter = require('events');
23
const readline = require('readline');
34
const globby = require('globby');
45
const Mocha = require('mocha');
@@ -20,8 +21,9 @@ const getSourceContent = (filename) => {
2021
return fs.readFileSync(filename, 'utf8');
2122
};
2223

23-
class Runner {
24-
constructor(argv, libs) {
24+
class Runner extends EventEmitter {
25+
constructor(argv, libs = { Mocha, NYC, importCwd, chokidar }) {
26+
super();
2527
this.argv = argv;
2628
this.testFiles = [];
2729
this.onlyTestFiles = [];
@@ -200,7 +202,7 @@ class Runner {
200202
this.testFiles = globby.sync(this.argv.glob).map(f => path.resolve(f));
201203
if (!this.testFiles.length) {
202204
console.log('No files found for:', this.argv.glob);
203-
process.exit(1);
205+
this.exit(1);
204206
}
205207
return this;
206208
}
@@ -225,13 +227,12 @@ class Runner {
225227

226228
onFinished(failures) {
227229
this.isRunning = false;
230+
this.emit('onFinished', failures);
228231
process.on('exit', () => {
229-
// safeSaveCache();
230-
process.exit(failures);
232+
this.exit(failures);
231233
});
232234
if (this.argv.exit) {
233-
// safeSaveCache();
234-
process.exit();
235+
this.exit();
235236
}
236237
}
237238

@@ -267,6 +268,7 @@ class Runner {
267268
process.stdin.setEncoding('utf8');
268269
process.stdin.on('keypress', (str) => {
269270
if (str === '\u0003') {
271+
this.emit('forceExit');
270272
process.exit(0);
271273
}
272274
if (this.isRunning) {
@@ -339,7 +341,7 @@ class Runner {
339341
if (this.argv.watch) {
340342
return;
341343
}
342-
process.exit(1);
344+
this.exit(1);
343345
}
344346
}
345347

@@ -403,6 +405,10 @@ class Runner {
403405
}
404406
return this;
405407
}
408+
409+
exit(code) {
410+
process.exit(code);
411+
}
406412
}
407413

408414
const configure = (configPath) => {
@@ -445,7 +451,7 @@ const node = {
445451
if (argv.presetEnv) {
446452
require(argv.presetEnv);
447453
}
448-
const runner = new node.Runner(argv, { Mocha, NYC, importCwd, chokidar });
454+
const runner = new node.Runner(argv);
449455
runner
450456
.addToMatchSnapshot()
451457
.autoDetectDebug()

commands/puppeteer/package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@
2020
},
2121
"homepage": "https://github.com/qlik-oss/after-work.js#readme",
2222
"dependencies": {
23-
"globby": "8.0.1",
24-
"mocha": "5.2.0"
23+
"@after-work.js/node": "5.0.0-beta.2",
24+
"@after-work.js/utils": "5.0.0-beta.2",
25+
"puppeteer-core": "1.7.0",
26+
"chrome-launcher": "0.10.2"
2527
},
2628
"files": [
2729
"/src"

commands/puppeteer/src/index.js

Lines changed: 53 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,77 +1,73 @@
1-
/* eslint global-require: 0, no-console: 0, import/no-unresolved: 0, import/no-extraneous-dependencies: 0, import/no-dynamic-require: 0, max-len: 0 */
2-
const path = require('path');
3-
const fs = require('fs');
4-
const globby = require('globby');
5-
const Mocha = require('mocha');
6-
const options = require('./options');
1+
/* eslint global-require: 0, import/no-dynamic-require: 0, object-curly-newline: 0 */
2+
const chromeFinder = require('chrome-launcher/dist/chrome-finder');
3+
const { getPlatform } = require('chrome-launcher/dist/utils');
4+
const { Runner, configure } = require('@after-work.js/node/src/');
5+
const nodeOptions = require('@after-work.js/node/src/options');
6+
const utils = require('@after-work.js/utils');
7+
const puppetOptions = require('./options');
78

8-
process.on('unhandledRejection', (err) => {
9-
console.error(`Promise Rejection:${err}`);
10-
});
9+
const options = Object.assign({}, nodeOptions, puppetOptions);
1110

12-
function runTests(files, mochaOpts) {
13-
return (resolve) => {
14-
const mocha = new Mocha(mochaOpts);
15-
files.forEach(f => mocha.addFile(f));
16-
mocha.run((failures) => {
17-
resolve(failures);
18-
});
19-
};
20-
}
21-
function run(files, mochaOpts) {
22-
return new Promise(runTests(files, mochaOpts));
23-
}
11+
const getChromeExecutablePath = async () => {
12+
const installations = await chromeFinder[getPlatform()]();
13+
if (installations.length === 0) {
14+
throw new Error('Chrome not installed');
15+
}
16+
return installations[0];
17+
};
2418

2519
const puppet = {
2620
command: ['puppeteer', 'puppet'],
2721
desc: 'Run tests with puppeteer',
2822
builder(yargs) {
2923
return yargs
3024
.options(options)
31-
.config('config', (configPath) => {
32-
if (configPath === null) {
33-
return {};
34-
}
35-
if (!fs.existsSync(configPath)) {
36-
throw new Error(`Config ${configPath} not found`);
25+
.config('config', configure)
26+
.coerce('babel', utils.coerceBabel)
27+
.coerce('nyc', (opt) => {
28+
if (opt.babel) {
29+
// opt.require.push('babel-register');
30+
opt.sourceMap = false; // eslint-disable-line no-param-reassign
31+
opt.instrumenter = './lib/instrumenters/noop'; // eslint-disable-line no-param-reassign
3732
}
38-
let config = {};
39-
const foundConfig = require(configPath);
40-
if (typeof foundConfig === 'function') {
41-
config = Object.assign({}, foundConfig());
42-
} else {
43-
config = Object.assign({}, foundConfig);
44-
}
45-
return config;
33+
return opt;
4634
});
4735
},
4836
handler(argv) {
49-
let puppeteer;
50-
try {
51-
puppeteer = require('puppeteer');
52-
} catch (_) {
53-
console.log('Could not load puppeteer');
54-
const p = `${path.resolve(process.cwd())}/node_modules/puppeteer`;
55-
console.log(`Trying: ${p}`);
56-
try {
57-
puppeteer = require(p);
58-
} catch (__) {
59-
console.log('Puppeteer could not be found by after-work.js! Please verify that it has been added as a devDependencies in your package.json');
60-
process.exit(1);
61-
}
62-
}
63-
const files = globby.sync(argv.glob);
64-
if (!files.length) {
65-
console.log('No test files found for:', argv.glob);
66-
process.exit(1);
67-
}
6837
(async function launchAndRun() {
38+
const puppeteer = require('puppeteer-core');
39+
if (argv.presetEnv) {
40+
require(argv.presetEnv);
41+
}
42+
const runner = new Runner(argv);
43+
if (!argv.chrome.executablePath) {
44+
argv.chrome.executablePath = await getChromeExecutablePath(); //eslint-disable-line
45+
}
6946
const browser = await puppeteer.launch(argv.chrome);
7047
global.browser = browser;
7148
global.page = await browser.newPage();
72-
const failures = await run(files, argv.mocha);
73-
await browser.close();
74-
process.exit(failures);
49+
const closeBrowser = () => {
50+
(async function close() {
51+
await browser.close();
52+
}());
53+
};
54+
runner.on('onFinished', failures => runner.exit(failures));
55+
runner.on('forceExit', closeBrowser);
56+
runner.exit = (code) => {
57+
if (argv.watch) {
58+
return;
59+
}
60+
process.exitCode = code;
61+
closeBrowser();
62+
};
63+
runner
64+
.addToMatchSnapshot()
65+
.autoDetectDebug()
66+
.setupKeyPress()
67+
.setTestFiles()
68+
.setSrcFiles()
69+
.require()
70+
.run();
7571
}());
7672
},
7773
};

examples/puppeteer/README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# puppeteer
2+
3+
## From the project root run
4+
5+
```shell
6+
npx aw puppeteer -c examples/puppeteer/aw.config.js
7+
```

examples/puppeteer/aw.config.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module.exports = {
2+
glob: ['examples/puppeteer/test/*.spec.js'],
3+
watchGlob: ['examples/puppeteer/test/*.{js,html}']
4+
}

examples/puppeteer/package.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"name": "@after-work.js/example-puppeteer",
3+
"private": true,
4+
"version": "5.0.0-beta.2",
5+
"description": "Puppeteer example",
6+
"main": "src/index.js",
7+
"scripts": {
8+
"lint": "eslint test"
9+
},
10+
"repository": {
11+
"type": "git",
12+
"url": "git+ssh://git@github.com/qlik-oss/after-work.js.git"
13+
},
14+
"author": "QlikTech International AB",
15+
"license": "MIT",
16+
"bugs": {
17+
"url": "https://github.com/qlik-oss/after-work.js/issues"
18+
},
19+
"homepage": "https://github.com/qlik-oss/after-work.js#readme"
20+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<html lang="en">
2+
3+
<head>
4+
<title>Test</title>
5+
<meta charset="utf-8">
6+
<base href="/">
7+
<style>
8+
#container {
9+
width: 100%;
10+
height: 100%;
11+
}
12+
</style>
13+
</head>
14+
15+
<body>
16+
<div id="container">hello world</div>
17+
</body>
18+
19+
</html>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/* global page */
2+
describe('Puppeteer', () => {
3+
it('should say hello world', async () => {
4+
await page.goto(`file://${__dirname}/hello.fix.html`);
5+
const container = await page.$('#container');
6+
const txt = await (await container.getProperty('textContent')).jsonValue();
7+
expect(txt).to.equal('hello world');
8+
});
9+
});

0 commit comments

Comments
 (0)