lighthouse-reporting 1.6.1 → 1.6.3
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.
- package/README.md +31 -10
- package/dist/lighthouse-reporting.umd.cjs +16 -10
- package/dist/lighthouseReports.cjs +16 -10
- package/dist/lighthouseReports.d.ts +1 -1
- package/dist/lighthouseReports.js +16 -10
- package/package.json +14 -13
package/README.md
CHANGED
|
@@ -14,6 +14,8 @@ The reports include trend history support, allowing you to track performance imp
|
|
|
14
14
|
|
|
15
15
|
Examples of usage with Playwright + Lighthouse (and Storybook).
|
|
16
16
|
|
|
17
|
+
`npm i -D lighthouse playwright-lighthouse lighthouse-reporting`
|
|
18
|
+
|
|
17
19
|
### In your frontend or testing framework
|
|
18
20
|
The example of usage [playwright](https://github.com/microsoft/playwright) and [playwright-lighthouse](https://github.com/abhinaba-ghosh/playwright-lighthouse) together.
|
|
19
21
|
|
|
@@ -38,9 +40,13 @@ const lighthousePages = [
|
|
|
38
40
|
]
|
|
39
41
|
|
|
40
42
|
lighthousePages.forEach(({ name, po, thresholds, swimlanes }) => {
|
|
41
|
-
playwrightLighthouseTest(name, async ({ port, baseURL }) => {
|
|
43
|
+
playwrightLighthouseTest(name, async ({ context, port, baseURL }) => {
|
|
42
44
|
const onlyCategories = ['accessibility', 'seo', 'performance']
|
|
43
45
|
|
|
46
|
+
// make sure to acess context or page at least once
|
|
47
|
+
// to let playwright initialize context!
|
|
48
|
+
context // this is enough to make the test work
|
|
49
|
+
|
|
44
50
|
const result: LighthouseResult = await playAudit({
|
|
45
51
|
url: baseURL + po.getPath('123'),
|
|
46
52
|
port,
|
|
@@ -97,8 +103,9 @@ import {
|
|
|
97
103
|
|
|
98
104
|
playwrightLighthouseTest.setTimeout(60000)
|
|
99
105
|
const lhScoresDir = path.join(process.cwd(), process.env.LH_SCORES_DIR || 'lh-scores')
|
|
100
|
-
const
|
|
101
|
-
const
|
|
106
|
+
const csvReportDir = path.join(process.cwd(), process.env.LH_CSV_REPORT_DIR || 'lighthouse')
|
|
107
|
+
const htmlReportDir = path.join(process.cwd(), process.env.LH_REPORT_DIR || 'lighthouse')
|
|
108
|
+
const htmlFilePath = path.join(htmlReportDir, 'index.html')
|
|
102
109
|
|
|
103
110
|
// use stories.json instead of index.json for storybook v6
|
|
104
111
|
// make sure to set buildStoriesJson to true in storybook main.js feature section
|
|
@@ -126,11 +133,16 @@ const runLighthouse = async (story: StorybookIndexStory, context: BrowserContext
|
|
|
126
133
|
const thresholds = { accessibility: 100 }
|
|
127
134
|
const name = story.id
|
|
128
135
|
|
|
129
|
-
|
|
130
|
-
|
|
136
|
+
// make sure to acess context or page at least once
|
|
137
|
+
// to let playwright initialize context!
|
|
138
|
+
context // this is enough to make the test work
|
|
139
|
+
// or manually open the page
|
|
140
|
+
// const page = context.pages()[0]
|
|
141
|
+
// await page.goto(`/iframe.html?id=${story.id}`)
|
|
131
142
|
|
|
132
143
|
const result: LighthouseResult = await playAudit({
|
|
133
144
|
url: baseURL + `/iframe.html?id=${story.id}`,
|
|
145
|
+
// page, // alternatevely, path the page instead of the `url`
|
|
134
146
|
port,
|
|
135
147
|
thresholds,
|
|
136
148
|
reports: {
|
|
@@ -138,7 +150,7 @@ const runLighthouse = async (story: StorybookIndexStory, context: BrowserContext
|
|
|
138
150
|
html: true,
|
|
139
151
|
},
|
|
140
152
|
name,
|
|
141
|
-
directory:
|
|
153
|
+
directory: htmlReportDir,
|
|
142
154
|
},
|
|
143
155
|
opts: {
|
|
144
156
|
onlyCategories,
|
|
@@ -149,7 +161,7 @@ const runLighthouse = async (story: StorybookIndexStory, context: BrowserContext
|
|
|
149
161
|
})
|
|
150
162
|
|
|
151
163
|
const scores = getScores(result)
|
|
152
|
-
await writeCsvResult(
|
|
164
|
+
await writeCsvResult(csvReportDir, name, scores, thresholds)
|
|
153
165
|
await writeHtmlListEntryWithRetry(htmlFilePath, name, scores, thresholds, result.comparisonError)
|
|
154
166
|
// write score results in JSON, allows generating the Average csv report
|
|
155
167
|
await writeScoresToJson(lhScoresDir, name, scores, result)
|
|
@@ -167,7 +179,8 @@ const runLighthouse = async (story: StorybookIndexStory, context: BrowserContext
|
|
|
167
179
|
import { PlaywrightTestConfig } from '@playwright/test'
|
|
168
180
|
|
|
169
181
|
const baseURL = 'http://127.0.0.1:6009'
|
|
170
|
-
// process.env.LH_REPORT_DIR = 'lighthouse-
|
|
182
|
+
// process.env.LH_REPORT_DIR = 'lighthouse-html' // adjust lighthouse output folder if required
|
|
183
|
+
// process.env.LH_CSV_REPORT_DIR = 'lighthouse-csv' // adjust lighthouse csv report folder if required
|
|
171
184
|
// process.env.LH_SCORES_DIR = 'lh-scores' // to write and store scores in json format or write average report
|
|
172
185
|
|
|
173
186
|
|
|
@@ -217,9 +230,16 @@ export default config
|
|
|
217
230
|
<summary>global-setup.ts</summary>
|
|
218
231
|
|
|
219
232
|
```ts
|
|
233
|
+
import path from 'path'
|
|
234
|
+
import fs from 'fs/promises'
|
|
220
235
|
import { lighthouseSetup } from 'lighthouse-reporting'
|
|
221
236
|
|
|
237
|
+
const lhScoresDir = path.join(process.cwd(), process.env.LH_SCORES_DIR || 'lh-scores')
|
|
238
|
+
const csvReportDir = path.join(process.cwd(), process.env.LH_CSV_REPORT_DIR || 'lighthouse')
|
|
239
|
+
|
|
222
240
|
async function globalSetup() {
|
|
241
|
+
await fs.mkdir(lhScoresDir, { recursive: true })
|
|
242
|
+
await fs.mkdir(csvReportDir, { recursive: true })
|
|
223
243
|
await lighthouseSetup()
|
|
224
244
|
}
|
|
225
245
|
|
|
@@ -232,14 +252,15 @@ export default globalSetup
|
|
|
232
252
|
<summary>global-teardown.ts</summary>
|
|
233
253
|
|
|
234
254
|
```ts
|
|
255
|
+
import path from 'path'
|
|
235
256
|
import { lighthousePlaywrightTeardown, buildAverageCsv } from 'lighthouse-reporting'
|
|
236
257
|
|
|
237
258
|
const lhScoresDir = path.join(process.cwd(), process.env.LH_SCORES_DIR || 'lh-scores')
|
|
238
|
-
const
|
|
259
|
+
const csvReportDir = path.join(process.cwd(), process.env.LH_CSV_REPORT_DIR || 'lighthouse')
|
|
239
260
|
|
|
240
261
|
async function globalTeardown() {
|
|
241
262
|
await lighthousePlaywrightTeardown()
|
|
242
|
-
await buildAverageCsv(lhScoresDir,
|
|
263
|
+
await buildAverageCsv(lhScoresDir, csvReportDir)
|
|
243
264
|
}
|
|
244
265
|
|
|
245
266
|
export default globalTeardown
|
|
@@ -57,21 +57,27 @@
|
|
|
57
57
|
}
|
|
58
58
|
throw error;
|
|
59
59
|
};
|
|
60
|
-
const getScores = (result) => Object.entries(result.lhr.categories).reduce(
|
|
61
|
-
prev[key
|
|
62
|
-
|
|
63
|
-
}, {});
|
|
64
|
-
const writeScoresToJson = async (lhScoresDir, name, scores, result) => {
|
|
65
|
-
const json = Object.entries(scores).reduce((prev, [k, score]) => {
|
|
66
|
-
prev[k] = { score };
|
|
60
|
+
const getScores = (result) => Object.entries(result.lhr.categories).reduce(
|
|
61
|
+
(prev, [key, c]) => {
|
|
62
|
+
prev[key] = Math.floor(c.score * 100);
|
|
67
63
|
return prev;
|
|
68
|
-
},
|
|
69
|
-
|
|
64
|
+
},
|
|
65
|
+
{}
|
|
66
|
+
);
|
|
67
|
+
const writeScoresToJson = async (lhScoresDir, name, scores, result) => {
|
|
68
|
+
const json = Object.entries(scores).reduce(
|
|
69
|
+
(prev, [k, score]) => {
|
|
70
|
+
prev[k] = { score };
|
|
71
|
+
return prev;
|
|
72
|
+
},
|
|
73
|
+
{}
|
|
74
|
+
);
|
|
75
|
+
const accessibilityViolations = result.artifacts.Accessibility ? result.artifacts.Accessibility.violations.map((v) => {
|
|
70
76
|
return {
|
|
71
77
|
title: result.lhr.audits[v.id].title,
|
|
72
78
|
nodes: v.nodes.length
|
|
73
79
|
};
|
|
74
|
-
});
|
|
80
|
+
}) : [];
|
|
75
81
|
if (accessibilityViolations.length > 0) {
|
|
76
82
|
json.accessibility.issues = accessibilityViolations;
|
|
77
83
|
}
|
|
@@ -38,21 +38,27 @@ const writeHtmlListEntryWithRetry = async (htmlFilePath, name, scores, threshold
|
|
|
38
38
|
}
|
|
39
39
|
throw error;
|
|
40
40
|
};
|
|
41
|
-
const getScores = (result) => Object.entries(result.lhr.categories).reduce(
|
|
42
|
-
prev[key
|
|
43
|
-
|
|
44
|
-
}, {});
|
|
45
|
-
const writeScoresToJson = async (lhScoresDir, name, scores, result) => {
|
|
46
|
-
const json = Object.entries(scores).reduce((prev, [k, score]) => {
|
|
47
|
-
prev[k] = { score };
|
|
41
|
+
const getScores = (result) => Object.entries(result.lhr.categories).reduce(
|
|
42
|
+
(prev, [key, c]) => {
|
|
43
|
+
prev[key] = Math.floor(c.score * 100);
|
|
48
44
|
return prev;
|
|
49
|
-
},
|
|
50
|
-
|
|
45
|
+
},
|
|
46
|
+
{}
|
|
47
|
+
);
|
|
48
|
+
const writeScoresToJson = async (lhScoresDir, name, scores, result) => {
|
|
49
|
+
const json = Object.entries(scores).reduce(
|
|
50
|
+
(prev, [k, score]) => {
|
|
51
|
+
prev[k] = { score };
|
|
52
|
+
return prev;
|
|
53
|
+
},
|
|
54
|
+
{}
|
|
55
|
+
);
|
|
56
|
+
const accessibilityViolations = result.artifacts.Accessibility ? result.artifacts.Accessibility.violations.map((v) => {
|
|
51
57
|
return {
|
|
52
58
|
title: result.lhr.audits[v.id].title,
|
|
53
59
|
nodes: v.nodes.length
|
|
54
60
|
};
|
|
55
|
-
});
|
|
61
|
+
}) : [];
|
|
56
62
|
if (accessibilityViolations.length > 0) {
|
|
57
63
|
json.accessibility.issues = accessibilityViolations;
|
|
58
64
|
}
|
|
@@ -36,21 +36,27 @@ const writeHtmlListEntryWithRetry = async (htmlFilePath, name, scores, threshold
|
|
|
36
36
|
}
|
|
37
37
|
throw error;
|
|
38
38
|
};
|
|
39
|
-
const getScores = (result) => Object.entries(result.lhr.categories).reduce(
|
|
40
|
-
prev[key
|
|
41
|
-
|
|
42
|
-
}, {});
|
|
43
|
-
const writeScoresToJson = async (lhScoresDir, name, scores, result) => {
|
|
44
|
-
const json = Object.entries(scores).reduce((prev, [k, score]) => {
|
|
45
|
-
prev[k] = { score };
|
|
39
|
+
const getScores = (result) => Object.entries(result.lhr.categories).reduce(
|
|
40
|
+
(prev, [key, c]) => {
|
|
41
|
+
prev[key] = Math.floor(c.score * 100);
|
|
46
42
|
return prev;
|
|
47
|
-
},
|
|
48
|
-
|
|
43
|
+
},
|
|
44
|
+
{}
|
|
45
|
+
);
|
|
46
|
+
const writeScoresToJson = async (lhScoresDir, name, scores, result) => {
|
|
47
|
+
const json = Object.entries(scores).reduce(
|
|
48
|
+
(prev, [k, score]) => {
|
|
49
|
+
prev[k] = { score };
|
|
50
|
+
return prev;
|
|
51
|
+
},
|
|
52
|
+
{}
|
|
53
|
+
);
|
|
54
|
+
const accessibilityViolations = result.artifacts.Accessibility ? result.artifacts.Accessibility.violations.map((v) => {
|
|
49
55
|
return {
|
|
50
56
|
title: result.lhr.audits[v.id].title,
|
|
51
57
|
nodes: v.nodes.length
|
|
52
58
|
};
|
|
53
|
-
});
|
|
59
|
+
}) : [];
|
|
54
60
|
if (accessibilityViolations.length > 0) {
|
|
55
61
|
json.accessibility.issues = accessibilityViolations;
|
|
56
62
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lighthouse-reporting",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build": "vite build && vite build -c vite.umd.config.ts && tsc -p ./tsconfig.build.json",
|
|
@@ -19,7 +19,8 @@
|
|
|
19
19
|
".": {
|
|
20
20
|
"import": "./dist/index.js",
|
|
21
21
|
"require": "./dist/lighthouse-reporting.umd.cjs",
|
|
22
|
-
"default": "./dist/index.cjs"
|
|
22
|
+
"default": "./dist/index.cjs",
|
|
23
|
+
"types": "./dist/index.d.ts"
|
|
23
24
|
}
|
|
24
25
|
},
|
|
25
26
|
"optionalDependencies": {
|
|
@@ -29,20 +30,20 @@
|
|
|
29
30
|
"devDependencies": {
|
|
30
31
|
"@playwright/test": "^1.34.3",
|
|
31
32
|
"@types/fs-extra": "^11.0.1",
|
|
32
|
-
"@types/node": "^20.
|
|
33
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
|
34
|
-
"@typescript-eslint/parser": "^5.
|
|
35
|
-
"eslint": "^8.
|
|
36
|
-
"eslint-config-prettier": "^
|
|
37
|
-
"eslint-plugin-prettier": "^
|
|
33
|
+
"@types/node": "^20.5.7",
|
|
34
|
+
"@typescript-eslint/eslint-plugin": "^6.5.0",
|
|
35
|
+
"@typescript-eslint/parser": "^6.5.0",
|
|
36
|
+
"eslint": "^8.48.0",
|
|
37
|
+
"eslint-config-prettier": "^9.0.0",
|
|
38
|
+
"eslint-plugin-prettier": "^5.0.0",
|
|
38
39
|
"get-port": "^7.0.0",
|
|
39
40
|
"husky": "^8.0.3",
|
|
40
41
|
"npm-run-all": "^4.1.5",
|
|
41
|
-
"prettier": "^
|
|
42
|
-
"semantic-release": "^21.
|
|
43
|
-
"typescript": "^5.
|
|
44
|
-
"vite": "^4.
|
|
45
|
-
"vite-plugin-static-copy": "^0.
|
|
42
|
+
"prettier": "^3.0.3",
|
|
43
|
+
"semantic-release": "^21.1.1",
|
|
44
|
+
"typescript": "^5.2.2",
|
|
45
|
+
"vite": "^4.4.9",
|
|
46
|
+
"vite-plugin-static-copy": "^0.17.0"
|
|
46
47
|
},
|
|
47
48
|
"dependencies": {
|
|
48
49
|
"fs-extra": "^11.1.1"
|