Skip to content

Commit e01f906

Browse files
committed
feat: allow passing extra headers to Lighthouse
1 parent da409e0 commit e01f906

File tree

8 files changed

+94
-22
lines changed

8 files changed

+94
-22
lines changed

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ Then add the plugin to your `netlify.toml` configuration file:
3131
# optional, deploy the lighthouse report to a path under your site
3232
[plugins.inputs]
3333
output_path = "reports/lighthouse.html"
34+
35+
# optional, extra headers to pass to Lighthouse. Useful for auditing pages that require authentication
36+
[plugins.inputs.extra_headers]
37+
# IMPORTANT - Don't put secrets in your git committed `netlify.toml` file
38+
# See here https://docs.netlify.com/configure-builds/file-based-configuration/#inject-environment-variable-values on injecting env variables
39+
Authorization = "token"
3440
```
3541

3642
By default, the plugin will serve and audit the build directory of the site.
@@ -58,6 +64,10 @@ You can customize the behavior via the `audits` input:
5864
# you can specify thresholds per audit
5965
[plugins.inputs.audits.thresholds]
6066
performance = 0.8
67+
68+
# you can specify extra_headers per audit
69+
[plugins.inputs.audits.extra_headers]
70+
CUSTOM_HEADER = "custom value"
6171
```
6272

6373
## Running Locally

functions/echo.js

Whitespace-only changes.

manifest.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ inputs:
1313
required: false
1414
description: Path to save the generated HTML Lighthouse report
1515

16+
- name: extra_headers
17+
required: false
18+
description: Extra headers to pass to Lighthouse. Useful for auditing pages that require authentication
19+
1620
- name: audits
1721
required: false
1822
description: A list of audits to perform. Each list item is an object with either a url/path to scan and an optional thresholds mapping.

netlify.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ package = "./src/index.js"
1111
[plugins.inputs]
1212
output_path = "reports/lighthouse.html"
1313

14+
[plugins.inputs.extra_headers]
15+
Authorization = "token"
16+
1417
[plugins.inputs.thresholds]
1518
performance = 0.9
1619

src/config.js

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,18 @@ const getServePath = (dir, path) => {
2020
return { path: resolvedPath };
2121
};
2222

23+
const maybeParseJSON = ({ value, name }) => {
24+
if (typeof value !== 'string') {
25+
return value;
26+
}
27+
28+
try {
29+
return JSON.parse(value);
30+
} catch (e) {
31+
throw new Error(`Invalid JSON for '${name}' input: ${e.message}`);
32+
}
33+
};
34+
2335
const getConfiguration = ({ constants, inputs } = {}) => {
2436
const serveDir =
2537
(constants && constants.PUBLISH_DIR) || process.env.PUBLISH_DIR;
@@ -36,34 +48,32 @@ const getConfiguration = ({ constants, inputs } = {}) => {
3648
);
3749
}
3850

39-
let thresholds =
40-
(inputs && inputs.thresholds) || process.env.THRESHOLDS || {};
51+
const thresholds = maybeParseJSON({
52+
value: (inputs && inputs.thresholds) || process.env.THRESHOLDS || {},
53+
name: 'thresholds',
54+
});
4155

42-
if (typeof thresholds === 'string') {
43-
try {
44-
thresholds = JSON.parse(thresholds);
45-
} catch (e) {
46-
throw new Error(`Invalid JSON for 'thresholds' input: ${e.message}`);
47-
}
48-
}
56+
const extra_headers = maybeParseJSON({
57+
value: (inputs && inputs.extra_headers) || process.env.EXTRA_HEADERS,
58+
name: 'extra_headers',
59+
});
4960

50-
let audits = (inputs && inputs.audits) || process.env.AUDITS;
51-
if (typeof audits === 'string') {
52-
try {
53-
audits = JSON.parse(audits);
54-
} catch (e) {
55-
throw new Error(`Invalid JSON for 'audits' input: ${e.message}`);
56-
}
57-
}
61+
let audits = maybeParseJSON({
62+
value: (inputs && inputs.audits) || process.env.AUDITS,
63+
name: 'audits',
64+
});
5865

5966
if (!Array.isArray(audits)) {
60-
audits = [{ path: serveDir, url: auditUrl, thresholds, output_path }];
67+
audits = [
68+
{ path: serveDir, url: auditUrl, thresholds, output_path, extra_headers },
69+
];
6170
} else {
6271
audits = audits.map((a) => {
6372
return {
6473
...a,
6574
thresholds: a.thresholds || thresholds,
6675
output_path: a.output_path || output_path,
76+
extra_headers: a.extra_headers || extra_headers,
6777
...getServePath(serveDir, a.path),
6878
};
6979
});

src/config.test.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ describe('config', () => {
8181
audit_url: 'url',
8282
thresholds: { seo: 1 },
8383
output_path: 'reports/lighthouse.html',
84+
extra_headers: { Authorization: 'test' },
8485
};
8586
const config = getConfiguration({ constants, inputs });
8687

@@ -91,6 +92,7 @@ describe('config', () => {
9192
url: 'url',
9293
thresholds: { seo: 1 },
9394
output_path: 'reports/lighthouse.html',
95+
extra_headers: { Authorization: 'test' },
9496
},
9597
],
9698
});
@@ -203,4 +205,31 @@ describe('config', () => {
203205
],
204206
});
205207
});
208+
209+
it('should use specific audit extra_headers when configured', () => {
210+
const constants = { PUBLISH_DIR: 'PUBLISH_DIR' };
211+
const inputs = {
212+
extra_headers: { Authorization: 'authorization' },
213+
audits: [
214+
{ path: 'route1' },
215+
{ path: 'route2', extra_headers: { Other: 'other' } },
216+
],
217+
};
218+
const config = getConfiguration({ constants, inputs });
219+
220+
expect(config).toEqual({
221+
audits: [
222+
{
223+
path: 'PUBLISH_DIR/route1',
224+
extra_headers: { Authorization: 'authorization' },
225+
thresholds: {},
226+
},
227+
{
228+
path: 'PUBLISH_DIR/route2',
229+
extra_headers: { Other: 'other' },
230+
thresholds: {},
231+
},
232+
],
233+
});
234+
});
206235
});

src/index.js

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,14 +120,22 @@ const getUtils = ({ utils }) => {
120120
return { failBuild, show };
121121
};
122122

123-
const runAudit = async ({ path, url, thresholds, output_path }) => {
123+
const runAudit = async ({
124+
path,
125+
url,
126+
thresholds,
127+
output_path,
128+
extra_headers,
129+
}) => {
124130
try {
125131
const { server } = getServer({ serveDir: path, auditUrl: url });
126132
const browserPath = await getBrowserPath();
127133
const { error, results } = await new Promise((resolve) => {
128134
server.listen(async () => {
129135
try {
130-
const results = await runLighthouse(browserPath, server.url);
136+
const results = await runLighthouse(browserPath, server.url, {
137+
extraHeaders: extra_headers,
138+
});
131139
resolve({ error: false, results });
132140
} catch (error) {
133141
resolve({ error });
@@ -229,12 +237,19 @@ module.exports = {
229237

230238
const allErrors = [];
231239
const summaries = [];
232-
for (const { path, url, thresholds, output_path } of audits) {
240+
for (const {
241+
path,
242+
url,
243+
thresholds,
244+
output_path,
245+
extra_headers,
246+
} of audits) {
233247
const { errors, summary, shortSummary } = await runAudit({
234248
path,
235249
url,
236250
thresholds,
237251
output_path,
252+
extra_headers,
238253
});
239254
if (summary) {
240255
console.log(summary);

src/lighthouse.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ const getBrowserPath = async () => {
3030
return info.executablePath;
3131
};
3232

33-
const runLighthouse = async (browserPath, url) => {
33+
const runLighthouse = async (browserPath, url, options) => {
3434
let chrome;
3535
try {
3636
const logLevel = 'info';
@@ -49,6 +49,7 @@ const runLighthouse = async (browserPath, url) => {
4949
port: chrome.port,
5050
output: 'html',
5151
logLevel,
52+
...options,
5253
});
5354
if (results.lhr.runtimeError) {
5455
throw new Error(results.lhr.runtimeError.message);

0 commit comments

Comments
 (0)