-
Notifications
You must be signed in to change notification settings - Fork 1
/
Puppeteer.js
81 lines (70 loc) · 2.5 KB
/
Puppeteer.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
const _ = require('lodash');
const path = require('path');
module.exports.Puppeteer = {
category: 'I/O',
description: `Runs a Puppeteer script and takes a screenshot of the result.`,
in: {
args: {
description: `Arguments passed to the Puppeteer script.`,
},
context: {
description: `Context variables for the Puppeteer session.`,
},
path: {
description: `Path to the Puppeteer script.`,
required: true,
},
},
out: {
context: {
description: `Context variables for the Puppeteer session.`,
},
src: {
description: `Screenshot image source.`,
},
},
async *process(context) {
const {
args,
context: maybePuppeteerContext,
path: scriptPath,
} = context.ports.read();
// Search Puppeteer scripts in the `puppeteer` directory
const resolvedPath = path.resolve(__dirname, '../puppeteer', scriptPath);
// Delete the Node.js require cache, which causes the script be be imported
// every time the now is run. This allows us to adjust the scripts on the go
// without re-running the entire test.
delete require.cache[resolvedPath];
const puppeteerScript = require(resolvedPath);
// Inject the node debugging function into the Puppeteer context, so we can
// print to the console within the scripts
const puppeteerContext = maybePuppeteerContext || {};
puppeteerContext.debug = context.debug;
// Our Puppeteer scripts are generators, so we can easily print intermittent
// status messages. We're using a context object (similar to contexts in
// Cocoon) as a way to pass on a state from node to node. Be aware that this
// state is not serialisable and gets modified by downstream nodes, so we
// intentionally break some of the isomorphic properties that we usually
// have. This has some consequences:
// - Re-running nodes may produce different results (or break)
// - Inspecting ports will not work (since we can't serialise the context)
// - Persisting a node will not work for the same reason
for await (const progress of puppeteerScript(puppeteerContext, args)) {
yield progress;
}
// Take a screenshot
const src = path.resolve(__dirname, '../puppeteer-screenshot.png');
try {
await puppeteerContext.page.screenshot({
path: src,
});
} catch {
// Ignore silently
}
// Output the context and screenshot path.
context.ports.write({
context: puppeteerContext,
src,
});
},
};