apex-auditor 0.2.2 → 0.2.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/dist/cli.js +85 -18
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -6,6 +6,16 @@ const ANSI_RESET = "\u001B[0m";
|
|
|
6
6
|
const ANSI_RED = "\u001B[31m";
|
|
7
7
|
const ANSI_YELLOW = "\u001B[33m";
|
|
8
8
|
const ANSI_GREEN = "\u001B[32m";
|
|
9
|
+
const ANSI_CYAN = "\u001B[36m";
|
|
10
|
+
const ANSI_BLUE = "\u001B[34m";
|
|
11
|
+
const LCP_GOOD_MS = 2500;
|
|
12
|
+
const LCP_WARN_MS = 4000;
|
|
13
|
+
const FCP_GOOD_MS = 1800;
|
|
14
|
+
const FCP_WARN_MS = 3000;
|
|
15
|
+
const TBT_GOOD_MS = 200;
|
|
16
|
+
const TBT_WARN_MS = 600;
|
|
17
|
+
const CLS_GOOD = 0.1;
|
|
18
|
+
const CLS_WARN = 0.25;
|
|
9
19
|
function parseArgs(argv) {
|
|
10
20
|
let configPath;
|
|
11
21
|
let ci = false;
|
|
@@ -70,11 +80,12 @@ export async function runAuditCli(argv) {
|
|
|
70
80
|
printLowestPerformancePages(summary.results, useColor);
|
|
71
81
|
const elapsedMs = Date.now() - startTimeMs;
|
|
72
82
|
const elapsedText = formatElapsedTime(elapsedMs);
|
|
83
|
+
const elapsedDisplay = useColor ? `${ANSI_CYAN}${elapsedText}${ANSI_RESET}` : elapsedText;
|
|
73
84
|
const runsPerTarget = effectiveConfig.runs ?? 1;
|
|
74
85
|
const comboCount = summary.results.length;
|
|
75
86
|
const totalRuns = comboCount * runsPerTarget;
|
|
76
87
|
// eslint-disable-next-line no-console
|
|
77
|
-
console.log(`\nCompleted in ${
|
|
88
|
+
console.log(`\nCompleted in ${elapsedDisplay} (${comboCount} page/device combinations x ${runsPerTarget} runs = ${totalRuns} Lighthouse runs).`);
|
|
78
89
|
}
|
|
79
90
|
function buildMarkdown(results) {
|
|
80
91
|
const header = [
|
|
@@ -104,32 +115,37 @@ function buildRow(result) {
|
|
|
104
115
|
return `| ${result.label} | ${result.path} | ${result.device} | ${scores.performance ?? "-"} | ${scores.accessibility ?? "-"} | ${scores.bestPractices ?? "-"} | ${scores.seo ?? "-"} | ${lcpSeconds} | ${fcpSeconds} | ${tbtMs} | ${cls} | ${error} | ${issues} |`;
|
|
105
116
|
}
|
|
106
117
|
function buildConsoleRow(result, useColor) {
|
|
107
|
-
const
|
|
108
|
-
const
|
|
109
|
-
const
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
|
|
118
|
+
const scoreLine = buildConsoleScoreLine(result, useColor);
|
|
119
|
+
const metricsLine = buildConsoleMetricsLine(result, useColor);
|
|
120
|
+
const errorLine = buildConsoleErrorLine(result, useColor);
|
|
121
|
+
const issuesLine = buildConsoleIssuesLine(result);
|
|
122
|
+
const lines = [scoreLine, metricsLine];
|
|
123
|
+
if (errorLine.length > 0) {
|
|
124
|
+
lines.push(errorLine);
|
|
113
125
|
}
|
|
114
|
-
if (
|
|
115
|
-
lines.push(
|
|
126
|
+
if (issuesLine.length > 0) {
|
|
127
|
+
lines.push(issuesLine);
|
|
116
128
|
}
|
|
117
129
|
return lines.join("\n");
|
|
118
130
|
}
|
|
119
|
-
function
|
|
131
|
+
function buildConsoleScoreLine(result, useColor) {
|
|
120
132
|
const scores = result.scores;
|
|
121
|
-
const metrics = result.metrics;
|
|
122
|
-
const lcpSeconds = metrics.lcpMs !== undefined ? (metrics.lcpMs / 1000).toFixed(1) : "-";
|
|
123
|
-
const fcpSeconds = metrics.fcpMs !== undefined ? (metrics.fcpMs / 1000).toFixed(1) : "-";
|
|
124
|
-
const tbtMs = metrics.tbtMs !== undefined ? Math.round(metrics.tbtMs).toString() : "-";
|
|
125
|
-
const cls = metrics.cls !== undefined ? metrics.cls.toFixed(3) : "-";
|
|
126
133
|
const performanceText = colourScore(scores.performance, useColor);
|
|
127
134
|
const accessibilityText = colourScore(scores.accessibility, useColor);
|
|
128
135
|
const bestPracticesText = colourScore(scores.bestPractices, useColor);
|
|
129
136
|
const seoText = colourScore(scores.seo, useColor);
|
|
130
|
-
|
|
137
|
+
const deviceText = formatDeviceLabel(result.device, useColor);
|
|
138
|
+
return `| ${result.label} | ${result.path} | ${deviceText} | ${performanceText} | ${accessibilityText} | ${bestPracticesText} | ${seoText} | | | | |`;
|
|
131
139
|
}
|
|
132
|
-
function
|
|
140
|
+
function buildConsoleMetricsLine(result, useColor) {
|
|
141
|
+
const metrics = result.metrics;
|
|
142
|
+
const lcpText = formatMetricSeconds(metrics.lcpMs, LCP_GOOD_MS, LCP_WARN_MS, useColor);
|
|
143
|
+
const fcpText = formatMetricSeconds(metrics.fcpMs, FCP_GOOD_MS, FCP_WARN_MS, useColor);
|
|
144
|
+
const tbtText = formatMetricMilliseconds(metrics.tbtMs, TBT_GOOD_MS, TBT_WARN_MS, useColor);
|
|
145
|
+
const clsText = formatMetricRatio(metrics.cls, CLS_GOOD, CLS_WARN, useColor);
|
|
146
|
+
return `| | | | | | | | ${lcpText} | ${fcpText} | ${tbtText} | ${clsText} |`;
|
|
147
|
+
}
|
|
148
|
+
function buildConsoleErrorLine(result, useColor) {
|
|
133
149
|
const errorCode = result.runtimeErrorCode;
|
|
134
150
|
const errorMessage = result.runtimeErrorMessage;
|
|
135
151
|
if (!errorCode && !errorMessage) {
|
|
@@ -139,7 +155,7 @@ function buildConsoleRowLine2(result, useColor) {
|
|
|
139
155
|
const prefix = useColor ? `${ANSI_RED}↳ Error:${ANSI_RESET}` : "↳ Error:";
|
|
140
156
|
return ` ${prefix} ${errorText}`;
|
|
141
157
|
}
|
|
142
|
-
function
|
|
158
|
+
function buildConsoleIssuesLine(result) {
|
|
143
159
|
const issues = formatTopIssues(result.opportunities);
|
|
144
160
|
if (issues.length === 0) {
|
|
145
161
|
return "";
|
|
@@ -159,6 +175,57 @@ function formatTopIssues(opportunities) {
|
|
|
159
175
|
});
|
|
160
176
|
return items.join("; ");
|
|
161
177
|
}
|
|
178
|
+
function formatMetricSeconds(valueMs, goodThresholdMs, warnThresholdMs, useColor) {
|
|
179
|
+
if (valueMs === undefined) {
|
|
180
|
+
return "-";
|
|
181
|
+
}
|
|
182
|
+
const seconds = valueMs / 1000;
|
|
183
|
+
const text = `${seconds.toFixed(1)}s`;
|
|
184
|
+
if (!useColor) {
|
|
185
|
+
return text;
|
|
186
|
+
}
|
|
187
|
+
const colour = selectColourForThreshold(valueMs, goodThresholdMs, warnThresholdMs);
|
|
188
|
+
return `${colour}${text}${ANSI_RESET}`;
|
|
189
|
+
}
|
|
190
|
+
function formatMetricMilliseconds(valueMs, goodThresholdMs, warnThresholdMs, useColor) {
|
|
191
|
+
if (valueMs === undefined) {
|
|
192
|
+
return "-";
|
|
193
|
+
}
|
|
194
|
+
const rounded = Math.round(valueMs);
|
|
195
|
+
const text = `${rounded}ms`;
|
|
196
|
+
if (!useColor) {
|
|
197
|
+
return text;
|
|
198
|
+
}
|
|
199
|
+
const colour = selectColourForThreshold(valueMs, goodThresholdMs, warnThresholdMs);
|
|
200
|
+
return `${colour}${text}${ANSI_RESET}`;
|
|
201
|
+
}
|
|
202
|
+
function formatMetricRatio(value, goodThreshold, warnThreshold, useColor) {
|
|
203
|
+
if (value === undefined) {
|
|
204
|
+
return "-";
|
|
205
|
+
}
|
|
206
|
+
const text = value.toFixed(3);
|
|
207
|
+
if (!useColor) {
|
|
208
|
+
return text;
|
|
209
|
+
}
|
|
210
|
+
const colour = selectColourForThreshold(value, goodThreshold, warnThreshold);
|
|
211
|
+
return `${colour}${text}${ANSI_RESET}`;
|
|
212
|
+
}
|
|
213
|
+
function selectColourForThreshold(value, goodThreshold, warnThreshold) {
|
|
214
|
+
if (value <= goodThreshold) {
|
|
215
|
+
return ANSI_GREEN;
|
|
216
|
+
}
|
|
217
|
+
if (value <= warnThreshold) {
|
|
218
|
+
return ANSI_YELLOW;
|
|
219
|
+
}
|
|
220
|
+
return ANSI_RED;
|
|
221
|
+
}
|
|
222
|
+
function formatDeviceLabel(device, useColor) {
|
|
223
|
+
if (!useColor) {
|
|
224
|
+
return device;
|
|
225
|
+
}
|
|
226
|
+
const colour = device === "mobile" ? ANSI_CYAN : ANSI_BLUE;
|
|
227
|
+
return `${colour}${device}${ANSI_RESET}`;
|
|
228
|
+
}
|
|
162
229
|
function colourScore(score, useColor) {
|
|
163
230
|
if (score === undefined) {
|
|
164
231
|
return "-";
|