afterbefore 0.1.5 → 0.1.6
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 +47 -16
- package/dist/cli.js.map +1 -1
- package/dist/index.js +46 -15
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4,6 +4,7 @@ import { unlinkSync } from "fs";
|
|
|
4
4
|
import { exec } from "child_process";
|
|
5
5
|
|
|
6
6
|
// src/logger.ts
|
|
7
|
+
import { writeFileSync } from "fs";
|
|
7
8
|
import chalk from "chalk";
|
|
8
9
|
import ora from "ora";
|
|
9
10
|
var BAR_WIDTH = 20;
|
|
@@ -14,7 +15,13 @@ var Logger = class {
|
|
|
14
15
|
lastStep = 0;
|
|
15
16
|
lastLabel = "";
|
|
16
17
|
pipelineActive = false;
|
|
18
|
+
logBuffer = [];
|
|
19
|
+
log(level, message) {
|
|
20
|
+
const ts = (/* @__PURE__ */ new Date()).toISOString();
|
|
21
|
+
this.logBuffer.push(`${ts} [${level}] ${message}`);
|
|
22
|
+
}
|
|
17
23
|
info(message) {
|
|
24
|
+
this.log("info", message);
|
|
18
25
|
if (this.pipelineActive) return;
|
|
19
26
|
if (this.spinner) {
|
|
20
27
|
this.spinner.clear();
|
|
@@ -25,6 +32,7 @@ var Logger = class {
|
|
|
25
32
|
}
|
|
26
33
|
}
|
|
27
34
|
success(message) {
|
|
35
|
+
this.log("ok", message);
|
|
28
36
|
if (this.pipelineActive) return;
|
|
29
37
|
if (this.spinner) {
|
|
30
38
|
this.spinner.clear();
|
|
@@ -35,6 +43,7 @@ var Logger = class {
|
|
|
35
43
|
}
|
|
36
44
|
}
|
|
37
45
|
warn(message) {
|
|
46
|
+
this.log("warn", message);
|
|
38
47
|
if (this.spinner) {
|
|
39
48
|
this.spinner.clear();
|
|
40
49
|
console.log(chalk.yellow("\u26A0"), message);
|
|
@@ -44,6 +53,7 @@ var Logger = class {
|
|
|
44
53
|
}
|
|
45
54
|
}
|
|
46
55
|
error(message) {
|
|
56
|
+
this.log("error", message);
|
|
47
57
|
if (this.spinner) {
|
|
48
58
|
this.spinner.clear();
|
|
49
59
|
console.error(chalk.red("\u2716"), message);
|
|
@@ -53,6 +63,7 @@ var Logger = class {
|
|
|
53
63
|
}
|
|
54
64
|
}
|
|
55
65
|
dim(message) {
|
|
66
|
+
this.log("debug", message);
|
|
56
67
|
if (this.pipelineActive) return;
|
|
57
68
|
if (this.spinner) {
|
|
58
69
|
this.spinner.clear();
|
|
@@ -63,6 +74,7 @@ var Logger = class {
|
|
|
63
74
|
}
|
|
64
75
|
}
|
|
65
76
|
spin(message) {
|
|
77
|
+
this.log("info", message);
|
|
66
78
|
this.clearSpinner();
|
|
67
79
|
this.spinner = ora(message).start();
|
|
68
80
|
return this.spinner;
|
|
@@ -76,6 +88,7 @@ var Logger = class {
|
|
|
76
88
|
this.lastLabel = "";
|
|
77
89
|
this.pipelineActive = true;
|
|
78
90
|
this.clearSpinner();
|
|
91
|
+
this.log("info", `Pipeline started (${total} steps)`);
|
|
79
92
|
const text = this.renderPipeline(0, "Starting...");
|
|
80
93
|
this.spinner = ora({
|
|
81
94
|
text: chalk.dim(text),
|
|
@@ -86,6 +99,7 @@ var Logger = class {
|
|
|
86
99
|
if (step === this.lastStep && label === this.lastLabel) return;
|
|
87
100
|
this.lastStep = step;
|
|
88
101
|
this.lastLabel = label;
|
|
102
|
+
this.log("step", `${step}/${this.pipelineTotal} ${label}`);
|
|
89
103
|
const text = chalk.dim(this.renderPipeline(step, label));
|
|
90
104
|
if (!this.spinner) {
|
|
91
105
|
this.spinner = ora({
|
|
@@ -98,28 +112,33 @@ var Logger = class {
|
|
|
98
112
|
}
|
|
99
113
|
completePipeline(finished = false) {
|
|
100
114
|
this.pipelineActive = false;
|
|
115
|
+
this.log("info", `Pipeline ${finished ? "completed" : "stopped"}`);
|
|
101
116
|
if (this.spinner) {
|
|
102
117
|
if (finished) {
|
|
103
118
|
this.spinner.stop();
|
|
104
|
-
const bar = "
|
|
119
|
+
const bar = "#".repeat(BAR_WIDTH);
|
|
105
120
|
console.log(`${chalk.green("\u2714")} ${bar}`);
|
|
106
121
|
} else {
|
|
107
122
|
this.spinner.stop();
|
|
108
123
|
}
|
|
109
124
|
this.spinner = null;
|
|
110
125
|
} else if (finished) {
|
|
111
|
-
const bar = "
|
|
126
|
+
const bar = "#".repeat(BAR_WIDTH);
|
|
112
127
|
console.log(`${chalk.green("\u2714")} ${bar}`);
|
|
113
128
|
}
|
|
114
129
|
this.pipelineTotal = 0;
|
|
115
130
|
this.lastStep = 0;
|
|
116
131
|
this.lastLabel = "";
|
|
117
132
|
}
|
|
133
|
+
writeLogFile(filePath) {
|
|
134
|
+
if (this.logBuffer.length === 0) return;
|
|
135
|
+
writeFileSync(filePath, this.logBuffer.join("\n") + "\n", "utf-8");
|
|
136
|
+
}
|
|
118
137
|
renderPipeline(step, label) {
|
|
119
138
|
const total = this.pipelineTotal || 1;
|
|
120
139
|
const clampedStep = Math.max(0, Math.min(step, total));
|
|
121
140
|
const filled = Math.round(clampedStep / total * BAR_WIDTH);
|
|
122
|
-
const bar = "
|
|
141
|
+
const bar = "#".repeat(filled) + "-".repeat(BAR_WIDTH - filled);
|
|
123
142
|
return ` ${bar} ${clampedStep}/${total} ${label}`;
|
|
124
143
|
}
|
|
125
144
|
clearSpinner() {
|
|
@@ -1298,13 +1317,19 @@ async function captureRoutes(tasks, beforeUrl, afterUrl, outputDir, options) {
|
|
|
1298
1317
|
tagChangedComponentInstances(afterPage, changedComponents),
|
|
1299
1318
|
tagChangedComponentInstances(beforePage, changedComponents)
|
|
1300
1319
|
]);
|
|
1320
|
+
logger.dim(` Component detection on ${task.route}: ${changedComponents.length} source(s), ${afterInstances.length} after / ${beforeInstances.length} before instance(s)`);
|
|
1301
1321
|
const afterBySource = groupBySource(afterInstances);
|
|
1302
1322
|
const beforeBySource = groupBySource(beforeInstances);
|
|
1303
1323
|
for (const source of changedComponents) {
|
|
1304
1324
|
const afterList = afterBySource.get(source) ?? [];
|
|
1305
1325
|
const beforeList = beforeBySource.get(source) ?? [];
|
|
1306
1326
|
const pairCount = Math.min(afterList.length, beforeList.length);
|
|
1307
|
-
if (pairCount === 0)
|
|
1327
|
+
if (pairCount === 0) {
|
|
1328
|
+
if (afterList.length > 0 || beforeList.length > 0) {
|
|
1329
|
+
logger.dim(` ${source}: ${afterList.length} after / ${beforeList.length} before (skipping unpaired)`);
|
|
1330
|
+
}
|
|
1331
|
+
continue;
|
|
1332
|
+
}
|
|
1308
1333
|
for (let pairIndex = 0; pairIndex < pairCount; pairIndex++) {
|
|
1309
1334
|
const afterInstance = afterList[pairIndex];
|
|
1310
1335
|
const beforeInstance = beforeList[pairIndex];
|
|
@@ -1312,13 +1337,6 @@ async function captureRoutes(tasks, beforeUrl, afterUrl, outputDir, options) {
|
|
|
1312
1337
|
const itemSlug = `${sourceSlug}-${pairIndex + 1}`;
|
|
1313
1338
|
const componentName = afterInstance.name || beforeInstance.name || source.split("/").pop() || source;
|
|
1314
1339
|
const baseLabel = `${task.label} [${componentName} #${pairIndex + 1}]`;
|
|
1315
|
-
const contextPrefix = `${task.prefix}~cmp.${itemSlug}~context`;
|
|
1316
|
-
results.push({
|
|
1317
|
-
route: `${baseLabel} [context]`,
|
|
1318
|
-
prefix: contextPrefix,
|
|
1319
|
-
beforePath,
|
|
1320
|
-
afterPath
|
|
1321
|
-
});
|
|
1322
1340
|
const parentPrefix = `${task.prefix}~cmp.${itemSlug}~parent`;
|
|
1323
1341
|
const parentBeforePath = join6(outputDir, `${parentPrefix}-before.png`);
|
|
1324
1342
|
const parentAfterPath = join6(outputDir, `${parentPrefix}-after.png`);
|
|
@@ -1369,6 +1387,15 @@ async function captureRoutes(tasks, beforeUrl, afterUrl, outputDir, options) {
|
|
|
1369
1387
|
afterPath: componentAfterPath
|
|
1370
1388
|
});
|
|
1371
1389
|
}
|
|
1390
|
+
if (parentBeforeOk && parentAfterOk || componentBeforeOk && componentAfterOk) {
|
|
1391
|
+
const contextPrefix = `${task.prefix}~cmp.${itemSlug}~context`;
|
|
1392
|
+
results.push({
|
|
1393
|
+
route: `${baseLabel} [context]`,
|
|
1394
|
+
prefix: contextPrefix,
|
|
1395
|
+
beforePath,
|
|
1396
|
+
afterPath
|
|
1397
|
+
});
|
|
1398
|
+
}
|
|
1372
1399
|
}
|
|
1373
1400
|
}
|
|
1374
1401
|
}
|
|
@@ -1558,7 +1585,7 @@ async function compareScreenshots(captures, outputDir, threshold = 0.1, options)
|
|
|
1558
1585
|
}
|
|
1559
1586
|
|
|
1560
1587
|
// src/stages/report.ts
|
|
1561
|
-
import { writeFileSync } from "fs";
|
|
1588
|
+
import { writeFileSync as writeFileSync2 } from "fs";
|
|
1562
1589
|
import { join as join8 } from "path";
|
|
1563
1590
|
import { execSync as execSync4 } from "child_process";
|
|
1564
1591
|
|
|
@@ -1731,11 +1758,11 @@ async function generateReport(results, outputDir, options) {
|
|
|
1731
1758
|
await ensureDir(outputDir);
|
|
1732
1759
|
const summaryMd = generateSummaryMd(results);
|
|
1733
1760
|
const summaryPath = join8(outputDir, "summary.md");
|
|
1734
|
-
|
|
1761
|
+
writeFileSync2(summaryPath, summaryMd, "utf-8");
|
|
1735
1762
|
logger.success(`Written summary to ${summaryPath}`);
|
|
1736
1763
|
const reportHtml = generateReportHtml(results, outputDir);
|
|
1737
1764
|
const indexPath = join8(outputDir, "index.html");
|
|
1738
|
-
|
|
1765
|
+
writeFileSync2(indexPath, reportHtml, "utf-8");
|
|
1739
1766
|
logger.success(`Written report to ${indexPath}`);
|
|
1740
1767
|
if (options.post) {
|
|
1741
1768
|
const prNumber = findPrNumber();
|
|
@@ -1838,7 +1865,7 @@ async function runPipeline(options) {
|
|
|
1838
1865
|
const outputDir = resolve4(cwd, output, sessionName);
|
|
1839
1866
|
const startTime = Date.now();
|
|
1840
1867
|
try {
|
|
1841
|
-
const version = true ? "0.1.
|
|
1868
|
+
const version = true ? "0.1.6" : "dev";
|
|
1842
1869
|
console.log(`
|
|
1843
1870
|
afterbefore v${version} \xB7 Comparing against ${base}
|
|
1844
1871
|
`);
|
|
@@ -1976,6 +2003,10 @@ afterbefore v${version} \xB7 Comparing against ${base}
|
|
|
1976
2003
|
openInBrowser(resolve4(outputDir, "index.html"));
|
|
1977
2004
|
}
|
|
1978
2005
|
} finally {
|
|
2006
|
+
try {
|
|
2007
|
+
logger.writeLogFile(resolve4(outputDir, "debug.log"));
|
|
2008
|
+
} catch {
|
|
2009
|
+
}
|
|
1979
2010
|
await cleanupRegistry.runAll();
|
|
1980
2011
|
}
|
|
1981
2012
|
}
|