Skip to content

Commit 6b9a854

Browse files
authored
feat: list relevant audits on category failure (#56)
1 parent 176049b commit 6b9a854

File tree

1 file changed

+78
-34
lines changed

1 file changed

+78
-34
lines changed

src/index.js

Lines changed: 78 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -47,32 +47,47 @@ const belowThreshold = (id, expected, categories) => {
4747
return actual < expected;
4848
};
4949

50-
const getError = (id, expected, results) => {
51-
const category = results.find((c) => c.id === id);
52-
return `Expected category ${chalk.magenta(
50+
const getError = (id, expected, categories, audits) => {
51+
const category = categories.find((c) => c.id === id);
52+
53+
const categoryError = `Expected category ${chalk.cyan(
5354
category.title,
5455
)} to be greater or equal to ${chalk.green(expected)} but got ${chalk.red(
5556
category.score !== null ? category.score : 'unknown',
5657
)}`;
58+
59+
const categoryAudits = category.auditRefs
60+
.filter(({ weight, id }) => weight > 0 && audits[id].score < 1)
61+
.map((ref) => {
62+
const audit = audits[ref.id];
63+
return ` '${chalk.cyan(
64+
audit.title,
65+
)}' received a score of ${chalk.yellow(audit.score)}`;
66+
})
67+
.join('\n');
68+
69+
return { message: categoryError, details: categoryAudits };
5770
};
5871

5972
const formatResults = ({ results, thresholds }) => {
6073
const categories = Object.values(
6174
results.lhr.categories,
62-
).map(({ title, score, id }) => ({ title, score, id }));
75+
).map(({ title, score, id, auditRefs }) => ({ title, score, id, auditRefs }));
6376

6477
const categoriesBelowThreshold = Object.entries(
6578
thresholds,
6679
).filter(([id, expected]) => belowThreshold(id, expected, categories));
6780

6881
const errors = categoriesBelowThreshold.map(([id, expected]) =>
69-
getError(id, expected, categories),
82+
getError(id, expected, categories, results.lhr.audits),
7083
);
7184

7285
const summary = {
73-
results: categories.map((cat) => ({
74-
...cat,
75-
...(thresholds[cat.id] ? { threshold: thresholds[cat.id] } : {}),
86+
results: categories.map(({ title, score, id }) => ({
87+
title,
88+
score,
89+
id,
90+
...(thresholds[id] ? { threshold: thresholds[id] } : {}),
7691
})),
7792
};
7893

@@ -86,8 +101,8 @@ const formatResults = ({ results, thresholds }) => {
86101
const getUtils = ({ utils }) => {
87102
const failBuild =
88103
(utils && utils.build && utils.build.failBuild) ||
89-
((message, { error }) => {
90-
console.error(message, error.message);
104+
((message, { error } = {}) => {
105+
console.error(message, error && error.message);
91106
process.exitCode = 1;
92107
});
93108

@@ -126,34 +141,53 @@ const runAudit = async ({ path, url, thresholds }) => {
126141
return {
127142
summary,
128143
shortSummary,
129-
error: errors.length > 0 ? new Error(`\n${errors.join('\n')}`) : false,
144+
errors,
130145
};
131146
}
132147
} catch (error) {
133148
return { error };
134149
}
135150
};
136151

152+
const prefixString = ({ path, url, str }) => {
153+
if (path) {
154+
return `\n${chalk.red('Error')} for directory '${chalk.cyan(
155+
path,
156+
)}':\n${str}`;
157+
} else if (url) {
158+
return `\n${chalk.red('Error')} for url '${chalk.cyan(url)}':\n${str}`;
159+
} else {
160+
return `\n${str}`;
161+
}
162+
};
163+
137164
const processResults = ({ summaries, errors }) => {
138165
if (errors.length > 0) {
166+
const error = errors.reduce(
167+
(acc, { path, url, errors }) => {
168+
const message = prefixString({
169+
path,
170+
url,
171+
str: errors.map((e) => e.message).join('\n'),
172+
});
173+
const details = prefixString({
174+
path,
175+
url,
176+
str: errors.map((e) => `${e.message}\n${e.details}`).join('\n'),
177+
});
178+
179+
return {
180+
message: `${acc.message}\n${message}`,
181+
details: `${acc.details}\n${details}`,
182+
};
183+
},
184+
{
185+
message: '',
186+
details: '',
187+
},
188+
);
139189
return {
140-
error: new Error(
141-
errors
142-
.map(({ path, url, error }) => {
143-
if (path) {
144-
return `\n${chalk.red('Error')} for directory '${chalk.magenta(
145-
path,
146-
)}': ${error.message}`;
147-
}
148-
if (url) {
149-
return `\n${chalk.red('Error')} for url '${chalk.magenta(
150-
url,
151-
)}': ${error.message}`;
152-
}
153-
return `\n${error.message}`;
154-
})
155-
.join('\n'),
156-
),
190+
error,
157191
};
158192
} else {
159193
return {
@@ -182,31 +216,41 @@ module.exports = {
182216
inputs,
183217
});
184218

185-
const errors = [];
219+
const allErrors = [];
186220
const summaries = [];
187221
for (const { path, url, thresholds } of audits) {
188-
const { error, summary, shortSummary } = await runAudit({
222+
const { errors, summary, shortSummary } = await runAudit({
189223
path,
190224
url,
191225
thresholds,
192226
});
193227
if (summary) {
194228
console.log(summary);
195229
}
196-
if (error) {
197-
errors.push({ path, url, error });
230+
if (Array.isArray(errors) && errors.length > 0) {
231+
allErrors.push({ path, url, errors });
198232
} else {
199233
summaries.push({ path, url, summary: shortSummary });
200234
}
201235
}
202236

203-
const { error, summary } = processResults({ summaries, errors, show });
237+
const { error, summary } = processResults({
238+
summaries,
239+
errors: allErrors,
240+
show,
241+
});
242+
204243
if (error) {
205244
throw error;
206245
}
207246
show({ summary });
208247
} catch (error) {
209-
failBuild(chalk.red('Failed with error:\n'), { error });
248+
if (error.details) {
249+
console.error(error.details);
250+
failBuild(`${chalk.red('Failed with error:\n')}${error.message}`);
251+
} else {
252+
failBuild(`${chalk.red('Failed with error:\n')}`, { error });
253+
}
210254
}
211255
},
212256
};

0 commit comments

Comments
 (0)