-
Notifications
You must be signed in to change notification settings - Fork 1
/
run-chrome.mjs
executable file
·138 lines (114 loc) · 3.44 KB
/
run-chrome.mjs
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#!/usr/bin/env node
import puppeteer from "puppeteer";
import express from "express";
import cors from "cors";
import { argosScreenshot } from "@argos-ci/puppeteer";
/**
* Get the port number from the URL.
*/
function getPort(url) {
const INITIAL_PORT = 4320;
const urlObj = new URL(url);
const browserId = urlObj.searchParams.get("browser");
if (browserId) {
return INITIAL_PORT + parseInt(browserId, 10);
}
return INITIAL_PORT;
}
(async () => {
const argv = Array.from(process.argv);
const url = argv.pop();
const execIndex = argv.findIndex(
(value) =>
value.endsWith("argos-chrome") || value.endsWith("run-chrome.mjs"),
);
const args = argv.slice(execIndex + 1);
const headless = args.includes("--headless");
const port = getPort(url);
const viewport = (() => {
const windowSizeArg = args.find((arg) => arg.startsWith("--window-size="));
if (!windowSizeArg) {
return null;
}
// Example --window-size=1440,900
// Parse the size from the argument
const match = windowSizeArg.match(/=(\d+),(\d+)/);
if (!match) {
return null;
}
const [, width, height] = match;
return { width: parseInt(width, 10), height: parseInt(height, 10) };
})();
const app = express();
app.use(cors());
app.use((req, res, next) => {
next();
});
app.post("/screenshot", express.json(), async (req, res) => {
try {
// Take a screenshot of the page
const emberTesting = await page.$("#ember-testing");
if (!emberTesting) {
throw new Error("No #ember-testing element found");
}
const emberTestingContainer = await page.$("#ember-testing-container");
if (!emberTesting) {
throw new Error("No #ember-testing-container element found");
}
const { name, ...options } = req.body;
// Emulate prefers-reduced-motion: reduce
await page.emulateMediaFeatures([
{ name: "prefers-reduced-motion", value: "reduce" },
]);
// Resize ember-testing to the viewport
await emberTesting.evaluate((element) => {
element.style.width = "auto";
element.style.height = "auto";
element.style.transform = "none";
});
await emberTestingContainer.evaluate((element) => {
element.style.width = "100vw";
element.style.height = "fit-content";
element.style.left = "0";
element.style.top = "0";
});
await argosScreenshot(page, name, {
element: emberTesting,
...options,
});
// Reset the styles
await emberTesting.evaluate((element) => {
element.style.width = "";
element.style.height = "";
element.style.transform = "";
});
await emberTestingContainer.evaluate((element) => {
element.style.width = "";
element.style.height = "";
element.style.left = "";
element.style.top = "";
});
res.sendStatus(200);
} catch (error) {
res.send(error.stack);
console.error(error);
res.sendStatus(500);
}
});
const server = app.listen(port, () => {
console.log(`Listening on 127.0.0.1:${port}`);
});
process.on("SIGTERM", () => {
server.close();
});
const browser = await puppeteer.launch({ headless, args });
process.on("SIGTERM", () => {
browser.close();
});
const pages = await browser.pages();
const [page] = pages;
if (viewport) {
await page.setViewport(viewport);
}
await page.goto(url);
})();