lighthouse-reporting 1.6.7 → 1.6.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,281 +1,281 @@
1
1
  (function(global, factory) {
2
- typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("os"), require("path"), require("fs-extra"), require("url"), require("net"), require("@playwright/test")) : typeof define === "function" && define.amd ? define(["exports", "os", "path", "fs-extra", "url", "net", "@playwright/test"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.lh_rep = {}, global.os, global.path, global.fse, global.url, global.net, global.test));
3
- })(this, function(exports2, os, path, fse, url, net, test) {
4
- "use strict";
5
- var _documentCurrentScript = typeof document !== "undefined" ? document.currentScript : null;
6
- const INDEX_HTML = "index.html";
7
- const LH_OUT_DIR = "lighthouse";
8
- const PW_TMP_DIR = "pwlh";
9
- let dirname;
10
- if (typeof __dirname !== "string") {
11
- const filename = url.fileURLToPath(typeof document === "undefined" && typeof location === "undefined" ? require("url").pathToFileURL(__filename).href : typeof document === "undefined" ? location.href : _documentCurrentScript && _documentCurrentScript.src || new URL("lighthouse-reporting.umd.cjs", document.baseURI).href);
12
- dirname = path.dirname(filename);
13
- } else {
14
- dirname = __dirname;
15
- }
16
- const reportDir = path.join(process.cwd(), process.env.LH_REPORT_DIR || LH_OUT_DIR);
17
- const htmlTemplatePath = path.join(dirname, "lighthouse.html");
18
- async function lighthouseSetup() {
19
- await fse.ensureDir(reportDir);
20
- await fse.copyFile(htmlTemplatePath, path.join(reportDir, INDEX_HTML));
21
- }
22
- async function lighthousePlaywrightTeardown() {
23
- await fse.remove(path.join(os.tmpdir(), PW_TMP_DIR));
24
- }
25
- const writeCsvResult = async (reportDir2, name, scores, thresholds = {}, swimlanes = []) => {
26
- let csvData = Object.keys(scores).join(",");
27
- if (swimlanes.length > 0) {
28
- csvData += "," + swimlanes.map((swimlane) => `${swimlane}_threshold`);
29
- }
30
- csvData += "\n";
31
- csvData += Object.values(scores).join(",");
32
- if (swimlanes.length > 0 && Object.keys(thresholds).length > 0) {
33
- csvData += "," + swimlanes.map((swimlane) => thresholds[swimlane]);
34
- }
35
- await fse.writeFile(path.join(reportDir2, `${name}.csv`), csvData);
36
- };
37
- const writeHtmlListEntry = async (htmlFilePath, name, scores, thresholds, error, addReportLink) => {
38
- const htmlFileData = (await fse.readFile(htmlFilePath)).toString("utf-8").split("\n");
39
- const insertIdx = htmlFileData.findIndex((v) => v.includes("// lighthouse-page-results"));
40
- if (insertIdx < 0) {
41
- throw new Error("Failed to write results to index.html");
42
- }
43
- htmlFileData.splice(insertIdx + 1, 0, JSON.stringify({ href: `${name}.html`, name, scores, thresholds, error, addReportLink }) + ",");
44
- await fse.writeFile(htmlFilePath, htmlFileData.join("\n"));
45
- };
46
- const writeHtmlListEntryWithRetry = async (htmlFilePath, name, scores, thresholds, comparisonError, addReportLink = true) => {
47
- let attempts = 10;
48
- let error;
49
- while (attempts > 0) {
50
- attempts--;
51
- try {
52
- await writeHtmlListEntry(htmlFilePath, name, scores, thresholds, comparisonError, addReportLink);
53
- return;
54
- } catch (e) {
55
- error = e;
56
- }
57
- await new Promise((resolve) => setTimeout(resolve, 10));
58
- }
59
- throw error;
60
- };
61
- const getScores = (result) => Object.entries(result.lhr.categories).reduce(
62
- (prev, [key, c]) => {
63
- const score = typeof c.score === "number" ? c.score : 0;
64
- prev[key] = Math.floor(score * 100);
65
- return prev;
66
- },
67
- {}
68
- );
69
- const writeScoresToJson = async (lhScoresDir, name, scores, result) => {
70
- const json = Object.entries(scores).reduce(
71
- (prev, [k, score]) => {
72
- prev[k] = { score };
73
- return prev;
74
- },
75
- {}
76
- );
77
- const accessibilityViolations = result.artifacts.Accessibility ? result.artifacts.Accessibility.violations.map((v) => {
78
- return {
79
- title: result.lhr.audits[v.id].title,
80
- nodes: v.nodes.length
81
- };
82
- }) : [];
83
- if (accessibilityViolations.length > 0) {
84
- json.accessibility.issues = accessibilityViolations;
85
- }
86
- await fse.writeFile(path.join(lhScoresDir, `${name}.json`), JSON.stringify(json, null, 2));
87
- };
88
- const buildAverageCsv = async (lhScoresDir, reportDir2) => {
89
- const files = await fse.readdir(lhScoresDir);
90
- const jsonFiles = files.filter((f) => f.endsWith(".json"));
91
- if (jsonFiles.length === 0) {
92
- return;
93
- }
94
- const scores = {};
95
- for (const fileName of jsonFiles) {
96
- const score = await fse.readJson(
97
- path.join(lhScoresDir, fileName)
98
- );
99
- Object.entries(score).forEach(([k, v]) => {
100
- if (!scores[k]) {
101
- scores[k] = 0;
102
- }
103
- scores[k] += v.score;
104
- });
105
- }
106
- Object.entries(scores).forEach(([k, v]) => {
107
- scores[k] = v / jsonFiles.length;
108
- });
109
- await writeCsvResult(reportDir2, "_AVERAGE_", scores);
110
- };
111
- class Locked extends Error {
112
- constructor(port) {
113
- super(`${port} is locked`);
114
- }
115
- }
116
- const lockedPorts = {
117
- old: /* @__PURE__ */ new Set(),
118
- young: /* @__PURE__ */ new Set()
119
- };
120
- const releaseOldLockedPortsIntervalMs = 1e3 * 15;
121
- let timeout;
122
- const getLocalHosts = () => {
123
- const interfaces = os.networkInterfaces();
124
- const results = /* @__PURE__ */ new Set([void 0, "0.0.0.0"]);
125
- for (const _interface of Object.values(interfaces)) {
126
- for (const config of _interface) {
127
- results.add(config.address);
128
- }
129
- }
130
- return results;
131
- };
132
- const checkAvailablePort = (options) => new Promise((resolve, reject) => {
133
- const server = net.createServer();
134
- server.unref();
135
- server.on("error", reject);
136
- server.listen(options, () => {
137
- const { port } = server.address();
138
- server.close(() => {
139
- resolve(port);
140
- });
141
- });
142
- });
143
- const getAvailablePort = async (options, hosts) => {
144
- if (options.host || options.port === 0) {
145
- return checkAvailablePort(options);
146
- }
147
- for (const host of hosts) {
148
- try {
149
- await checkAvailablePort({ port: options.port, host });
150
- } catch (error) {
151
- if (!["EADDRNOTAVAIL", "EINVAL"].includes(error.code)) {
152
- throw error;
153
- }
154
- }
155
- }
156
- return options.port;
157
- };
158
- const portCheckSequence = function* (ports) {
159
- if (ports) {
160
- yield* ports;
161
- }
162
- yield 0;
163
- };
164
- async function getPorts(options) {
165
- let ports;
166
- let exclude = /* @__PURE__ */ new Set();
167
- if (options) {
168
- if (options.port) {
169
- ports = typeof options.port === "number" ? [options.port] : options.port;
170
- }
171
- if (options.exclude) {
172
- const excludeIterable = options.exclude;
173
- if (typeof excludeIterable[Symbol.iterator] !== "function") {
174
- throw new TypeError("The `exclude` option must be an iterable.");
175
- }
176
- for (const element of excludeIterable) {
177
- if (typeof element !== "number") {
178
- throw new TypeError("Each item in the `exclude` option must be a number corresponding to the port you want excluded.");
179
- }
180
- if (!Number.isSafeInteger(element)) {
181
- throw new TypeError(`Number ${element} in the exclude option is not a safe integer and can't be used`);
182
- }
183
- }
184
- exclude = new Set(excludeIterable);
185
- }
186
- }
187
- if (timeout === void 0) {
188
- timeout = setTimeout(() => {
189
- timeout = void 0;
190
- lockedPorts.old = lockedPorts.young;
191
- lockedPorts.young = /* @__PURE__ */ new Set();
192
- }, releaseOldLockedPortsIntervalMs);
193
- if (timeout.unref) {
194
- timeout.unref();
195
- }
196
- }
197
- const hosts = getLocalHosts();
198
- for (const port of portCheckSequence(ports)) {
199
- try {
200
- if (exclude.has(port)) {
201
- continue;
202
- }
203
- let availablePort = await getAvailablePort({ ...options, port }, hosts);
204
- while (lockedPorts.old.has(availablePort) || lockedPorts.young.has(availablePort)) {
205
- if (port !== 0) {
206
- throw new Locked(port);
207
- }
208
- availablePort = await getAvailablePort({ ...options, port }, hosts);
209
- }
210
- lockedPorts.young.add(availablePort);
211
- return availablePort;
212
- } catch (error) {
213
- if (!["EADDRINUSE", "EACCES"].includes(error.code) && !(error instanceof Locked)) {
214
- throw error;
215
- }
216
- }
217
- }
218
- throw new Error("No available ports found");
219
- }
220
- const playwrightLighthouseTest = test.test.extend({
221
- port: [
222
- // eslint-disable-next-line no-empty-pattern
223
- async ({}, use) => {
224
- const port = await getPorts();
225
- await use(port);
226
- },
227
- { scope: "worker" }
228
- ],
229
- context: [
230
- async ({ port, launchOptions }, use) => {
231
- const context = await test.chromium.launchPersistentContext(
232
- path.join(os.tmpdir(), PW_TMP_DIR, `${Math.random()}`.replace(".", "")),
233
- {
234
- args: [...launchOptions.args || [], `--remote-debugging-port=${port}`]
235
- }
236
- );
237
- await use(context);
238
- await context.close();
239
- },
240
- { scope: "test" }
241
- ]
242
- });
243
- const storybookPlaywright = {
244
- getStories: (pathToStorybookIndexJson, storyFilterFn) => {
245
- if (!fse.existsSync(pathToStorybookIndexJson)) {
246
- console.log(pathToStorybookIndexJson, "doesn't exist.");
247
- throw new Error("Please build storybook before running tests!");
248
- }
249
- const storybookIndexJson = fse.readJsonSync(pathToStorybookIndexJson);
250
- const storyObject = storybookIndexJson.entries || storybookIndexJson.stories;
251
- const stories = Object.values(storyObject).filter(storyFilterFn);
252
- return stories;
253
- },
254
- captureScreenshot: async (story, context, screenshotOptions, options = {
255
- waitForLoadStateTimeout: 2e3
256
- }, actionBeforeScreenshot) => {
257
- const page = context.pages()[0];
258
- await page.goto(`/iframe.html?id=${story.id}`);
259
- await test.expect(page.locator(".sb-show-main")).toBeVisible();
260
- await test.expect(page.locator(".sb-show-errordisplay")).not.toBeVisible();
261
- try {
262
- await page.waitForLoadState("networkidle", { timeout: options.waitForLoadStateTimeout });
263
- } catch {
264
- }
265
- if (actionBeforeScreenshot) {
266
- await actionBeforeScreenshot(page);
267
- }
268
- await test.expect(page).toHaveScreenshot(`${story.id}.png`, screenshotOptions);
269
- }
270
- };
271
- exports2.buildAverageCsv = buildAverageCsv;
272
- exports2.getScores = getScores;
273
- exports2.lighthousePlaywrightTeardown = lighthousePlaywrightTeardown;
274
- exports2.lighthouseSetup = lighthouseSetup;
275
- exports2.playwrightLighthouseTest = playwrightLighthouseTest;
276
- exports2.storybookPlaywright = storybookPlaywright;
277
- exports2.writeCsvResult = writeCsvResult;
278
- exports2.writeHtmlListEntryWithRetry = writeHtmlListEntryWithRetry;
279
- exports2.writeScoresToJson = writeScoresToJson;
280
- Object.defineProperty(exports2, Symbol.toStringTag, { value: "Module" });
2
+ typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("os"), require("path"), require("fs-extra"), require("url"), require("net"), require("@playwright/test")) : typeof define === "function" && define.amd ? define([
3
+ "exports",
4
+ "os",
5
+ "path",
6
+ "fs-extra",
7
+ "url",
8
+ "net",
9
+ "@playwright/test"
10
+ ], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.lh_rep = {}, global.os, global.path, global.fse, global.url, global.net, global["@playwright/test"]));
11
+ })(this, function(exports, os, path, fs_extra, url, net, _playwright_test) {
12
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
13
+ //#region \0rolldown/runtime.js
14
+ var __create = Object.create;
15
+ var __defProp = Object.defineProperty;
16
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
17
+ var __getOwnPropNames = Object.getOwnPropertyNames;
18
+ var __getProtoOf = Object.getPrototypeOf;
19
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
20
+ var __copyProps = (to, from, except, desc) => {
21
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
22
+ key = keys[i];
23
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
24
+ get: ((k) => from[k]).bind(null, key),
25
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
26
+ });
27
+ }
28
+ return to;
29
+ };
30
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
31
+ value: mod,
32
+ enumerable: true
33
+ }) : target, mod));
34
+ //#endregion
35
+ os = __toESM(os, 1);
36
+ path = __toESM(path, 1);
37
+ fs_extra = __toESM(fs_extra, 1);
38
+ url = __toESM(url, 1);
39
+ net = __toESM(net, 1);
40
+ //#region src/constants.ts
41
+ var INDEX_HTML = "index.html";
42
+ var PW_TMP_DIR = "pwlh";
43
+ //#endregion
44
+ //#region src/hooks.ts
45
+ var dirname;
46
+ if (typeof __dirname !== "string") {
47
+ const filename = url.default.fileURLToPath({}.url);
48
+ dirname = path.default.dirname(filename);
49
+ } else dirname = __dirname;
50
+ var reportDir = path.default.join(process.cwd(), process.env.LH_REPORT_DIR || "lighthouse");
51
+ var htmlTemplatePath = path.default.join(dirname, "lighthouse.html");
52
+ async function lighthouseSetup() {
53
+ await fs_extra.default.ensureDir(reportDir);
54
+ await fs_extra.default.copyFile(htmlTemplatePath, path.default.join(reportDir, INDEX_HTML));
55
+ }
56
+ async function lighthousePlaywrightTeardown() {
57
+ await fs_extra.default.remove(path.default.join(os.default.tmpdir(), PW_TMP_DIR));
58
+ }
59
+ //#endregion
60
+ //#region src/lighthouseReports.ts
61
+ var writeCsvResult = async (reportDir, name, scores, thresholds = {}, swimlanes = []) => {
62
+ let csvData = Object.keys(scores).join(",");
63
+ if (swimlanes.length > 0) csvData += "," + swimlanes.map((swimlane) => `${swimlane}_threshold`);
64
+ csvData += "\n";
65
+ csvData += Object.values(scores).join(",");
66
+ if (swimlanes.length > 0 && Object.keys(thresholds).length > 0) csvData += "," + swimlanes.map((swimlane) => thresholds[swimlane]);
67
+ await fs_extra.default.writeFile(path.default.join(reportDir, `${name}.csv`), csvData);
68
+ };
69
+ var writeHtmlListEntry = async (htmlFilePath, name, scores, thresholds, error, addReportLink) => {
70
+ const htmlFileData = (await fs_extra.default.readFile(htmlFilePath)).toString("utf-8").split("\n");
71
+ const insertIdx = htmlFileData.findIndex((v) => v.includes("// lighthouse-page-results"));
72
+ if (insertIdx < 0) throw new Error("Failed to write results to index.html");
73
+ htmlFileData.splice(insertIdx + 1, 0, JSON.stringify({
74
+ href: `${name}.html`,
75
+ name,
76
+ scores,
77
+ thresholds,
78
+ error,
79
+ addReportLink
80
+ }) + ",");
81
+ await fs_extra.default.writeFile(htmlFilePath, htmlFileData.join("\n"));
82
+ };
83
+ /**
84
+ * workaround conflicts when multiple threads write the same file
85
+ */
86
+ var writeHtmlListEntryWithRetry = async (htmlFilePath, name, scores, thresholds, comparisonError, addReportLink = true) => {
87
+ let attempts = 10;
88
+ let error;
89
+ while (attempts > 0) {
90
+ attempts--;
91
+ try {
92
+ await writeHtmlListEntry(htmlFilePath, name, scores, thresholds, comparisonError, addReportLink);
93
+ return;
94
+ } catch (e) {
95
+ error = e;
96
+ }
97
+ await new Promise((resolve) => setTimeout(resolve, 10));
98
+ }
99
+ throw error;
100
+ };
101
+ var getScores = (result) => Object.entries(result.lhr.categories).reduce((prev, [key, c]) => {
102
+ const score = typeof c.score === "number" ? c.score : 0;
103
+ prev[key] = Math.floor(score * 100);
104
+ return prev;
105
+ }, {});
106
+ var writeScoresToJson = async (lhScoresDir, name, scores, result) => {
107
+ const json = Object.entries(scores).reduce((prev, [k, score]) => {
108
+ prev[k] = { score };
109
+ return prev;
110
+ }, {});
111
+ const accessibilityViolations = result.artifacts.Accessibility ? result.artifacts.Accessibility.violations.map((v) => {
112
+ return {
113
+ title: result.lhr.audits[v.id].title,
114
+ nodes: v.nodes.length
115
+ };
116
+ }) : [];
117
+ if (accessibilityViolations.length > 0) json.accessibility.issues = accessibilityViolations;
118
+ await fs_extra.default.writeFile(path.default.join(lhScoresDir, `${name}.json`), JSON.stringify(json, null, 2));
119
+ };
120
+ /**
121
+ * Generate average csv file. Make sure to use `writeScoresToJson` in your test!
122
+ * @param lhScoresDir path to folder with lighthouse json files. See `writeScoresToJson`.
123
+ * @param reportDir folder where `_AVERAGE_.json` will be generated
124
+ */
125
+ var buildAverageCsv = async (lhScoresDir, reportDir) => {
126
+ const jsonFiles = (await fs_extra.default.readdir(lhScoresDir)).filter((f) => f.endsWith(".json"));
127
+ if (jsonFiles.length === 0) return;
128
+ const scores = {};
129
+ for (const fileName of jsonFiles) {
130
+ const score = await fs_extra.default.readJson(path.default.join(lhScoresDir, fileName));
131
+ Object.entries(score).forEach(([k, v]) => {
132
+ if (!scores[k]) scores[k] = 0;
133
+ scores[k] += v.score;
134
+ });
135
+ }
136
+ Object.entries(scores).forEach(([k, v]) => {
137
+ scores[k] = v / jsonFiles.length;
138
+ });
139
+ await writeCsvResult(reportDir, "_AVERAGE_", scores);
140
+ };
141
+ //#endregion
142
+ //#region node_modules/get-port/index.js
143
+ var Locked = class extends Error {
144
+ constructor(port) {
145
+ super(`${port} is locked`);
146
+ }
147
+ };
148
+ var lockedPorts = {
149
+ old: /* @__PURE__ */ new Set(),
150
+ young: /* @__PURE__ */ new Set()
151
+ };
152
+ var releaseOldLockedPortsIntervalMs = 1e3 * 15;
153
+ var reservedPorts = /* @__PURE__ */ new Set();
154
+ var timeout;
155
+ var getLocalHosts = () => {
156
+ const interfaces = os.default.networkInterfaces();
157
+ const results = /* @__PURE__ */ new Set([void 0, "0.0.0.0"]);
158
+ for (const _interface of Object.values(interfaces)) for (const config of _interface) results.add(config.address);
159
+ return results;
160
+ };
161
+ var checkAvailablePort = (options) => new Promise((resolve, reject) => {
162
+ const server = net.default.createServer();
163
+ server.unref();
164
+ server.on("error", reject);
165
+ server.listen(options, () => {
166
+ const { port } = server.address();
167
+ server.close(() => {
168
+ resolve(port);
169
+ });
170
+ });
171
+ });
172
+ var getAvailablePort = async (options, hosts) => {
173
+ if (options.host || options.port === 0) return checkAvailablePort(options);
174
+ for (const host of hosts) try {
175
+ await checkAvailablePort({
176
+ port: options.port,
177
+ host
178
+ });
179
+ } catch (error) {
180
+ if (!["EADDRNOTAVAIL", "EINVAL"].includes(error.code)) throw error;
181
+ }
182
+ return options.port;
183
+ };
184
+ var isLockedPort = (port) => lockedPorts.old.has(port) || lockedPorts.young.has(port) || reservedPorts.has(port);
185
+ var portCheckSequence = function* (ports) {
186
+ if (ports) yield* ports;
187
+ yield 0;
188
+ };
189
+ async function getPorts(options) {
190
+ let ports;
191
+ let exclude = /* @__PURE__ */ new Set();
192
+ if (options) {
193
+ if (options.port) ports = typeof options.port === "number" ? [options.port] : options.port;
194
+ if (options.exclude) {
195
+ const excludeIterable = options.exclude;
196
+ if (typeof excludeIterable[Symbol.iterator] !== "function") throw new TypeError("The `exclude` option must be an iterable.");
197
+ for (const element of excludeIterable) {
198
+ if (typeof element !== "number") throw new TypeError("Each item in the `exclude` option must be a number corresponding to the port you want excluded.");
199
+ if (!Number.isSafeInteger(element)) throw new TypeError(`Number ${element} in the exclude option is not a safe integer and can't be used`);
200
+ }
201
+ exclude = new Set(excludeIterable);
202
+ }
203
+ }
204
+ const { reserve, ...netOptions } = options ?? {};
205
+ if (timeout === void 0) {
206
+ timeout = setTimeout(() => {
207
+ timeout = void 0;
208
+ lockedPorts.old = lockedPorts.young;
209
+ lockedPorts.young = /* @__PURE__ */ new Set();
210
+ }, releaseOldLockedPortsIntervalMs);
211
+ if (timeout.unref) timeout.unref();
212
+ }
213
+ const hosts = getLocalHosts();
214
+ for (const port of portCheckSequence(ports)) try {
215
+ if (exclude.has(port)) continue;
216
+ let availablePort = await getAvailablePort({
217
+ ...netOptions,
218
+ port
219
+ }, hosts);
220
+ while (isLockedPort(availablePort)) {
221
+ if (port !== 0) throw new Locked(port);
222
+ availablePort = await getAvailablePort({
223
+ ...netOptions,
224
+ port
225
+ }, hosts);
226
+ }
227
+ if (reserve) reservedPorts.add(availablePort);
228
+ else lockedPorts.young.add(availablePort);
229
+ return availablePort;
230
+ } catch (error) {
231
+ if (!["EADDRINUSE", "EACCES"].includes(error.code) && !(error instanceof Locked)) throw error;
232
+ }
233
+ throw new Error("No available ports found");
234
+ }
235
+ //#endregion
236
+ //#region src/playwrightLighthouseTest.ts
237
+ var playwrightLighthouseTest = _playwright_test.test.extend({
238
+ port: [async ({}, use) => {
239
+ await use(await getPorts());
240
+ }, { scope: "worker" }],
241
+ context: [async ({ port, launchOptions }, use) => {
242
+ const context = await _playwright_test.chromium.launchPersistentContext(path.default.join(os.default.tmpdir(), PW_TMP_DIR, `${Math.random()}`.replace(".", "")), { args: [...launchOptions.args || [], `--remote-debugging-port=${port}`] });
243
+ await use(context);
244
+ await context.close();
245
+ }, { scope: "test" }]
246
+ });
247
+ //#endregion
248
+ //#region src/storybookPlaywright.ts
249
+ var storybookPlaywright = {
250
+ getStories: (pathToStorybookIndexJson, storyFilterFn) => {
251
+ if (!fs_extra.default.existsSync(pathToStorybookIndexJson)) {
252
+ console.log(pathToStorybookIndexJson, "doesn't exist.");
253
+ throw new Error("Please build storybook before running tests!");
254
+ }
255
+ const storybookIndexJson = fs_extra.default.readJsonSync(pathToStorybookIndexJson);
256
+ const storyObject = storybookIndexJson.entries || storybookIndexJson.stories;
257
+ return Object.values(storyObject).filter(storyFilterFn);
258
+ },
259
+ captureScreenshot: async (story, context, screenshotOptions, options = { waitForLoadStateTimeout: 2e3 }, actionBeforeScreenshot) => {
260
+ const page = context.pages()[0];
261
+ await page.goto(`/iframe.html?id=${story.id}`);
262
+ await (0, _playwright_test.expect)(page.locator(".sb-show-main")).toBeVisible();
263
+ await (0, _playwright_test.expect)(page.locator(".sb-show-errordisplay")).not.toBeVisible();
264
+ try {
265
+ await page.waitForLoadState("networkidle", { timeout: options.waitForLoadStateTimeout });
266
+ } catch {}
267
+ if (actionBeforeScreenshot) await actionBeforeScreenshot(page);
268
+ await (0, _playwright_test.expect)(page).toHaveScreenshot(`${story.id}.png`, screenshotOptions);
269
+ }
270
+ };
271
+ //#endregion
272
+ exports.buildAverageCsv = buildAverageCsv;
273
+ exports.getScores = getScores;
274
+ exports.lighthousePlaywrightTeardown = lighthousePlaywrightTeardown;
275
+ exports.lighthouseSetup = lighthouseSetup;
276
+ exports.playwrightLighthouseTest = playwrightLighthouseTest;
277
+ exports.storybookPlaywright = storybookPlaywright;
278
+ exports.writeCsvResult = writeCsvResult;
279
+ exports.writeHtmlListEntryWithRetry = writeHtmlListEntryWithRetry;
280
+ exports.writeScoresToJson = writeScoresToJson;
281
281
  });