afterbefore 0.1.9 → 0.1.11
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 +39 -16
- package/dist/cli.js.map +1 -1
- package/dist/index.js +38 -15
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -819,7 +819,8 @@ function findRoutesForFile(file, graph) {
|
|
|
819
819
|
}
|
|
820
820
|
|
|
821
821
|
// src/stages/worktree.ts
|
|
822
|
-
import { execSync as execSync2 } from "child_process";
|
|
822
|
+
import { exec as execCb, execSync as execSync2 } from "child_process";
|
|
823
|
+
import { promisify } from "util";
|
|
823
824
|
import { rm, mkdtemp } from "fs/promises";
|
|
824
825
|
import { join as join4 } from "path";
|
|
825
826
|
import { tmpdir } from "os";
|
|
@@ -848,14 +849,12 @@ function pmExec(pm) {
|
|
|
848
849
|
}
|
|
849
850
|
|
|
850
851
|
// src/stages/worktree.ts
|
|
852
|
+
var exec = promisify(execCb);
|
|
851
853
|
async function createWorktree(base, cwd) {
|
|
852
854
|
const worktreeDir = await mkdtemp(join4(tmpdir(), "afterbefore-wt-"));
|
|
853
855
|
logger.dim(`Creating worktree for ${base} at ${worktreeDir}`);
|
|
854
856
|
try {
|
|
855
|
-
|
|
856
|
-
cwd,
|
|
857
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
858
|
-
});
|
|
857
|
+
await exec(`git worktree add "${worktreeDir}" "${base}"`, { cwd });
|
|
859
858
|
} catch (err) {
|
|
860
859
|
throw new AfterbeforeError(
|
|
861
860
|
`Failed to create worktree for ref "${base}".`,
|
|
@@ -864,10 +863,7 @@ async function createWorktree(base, cwd) {
|
|
|
864
863
|
}
|
|
865
864
|
const pm = detectPackageManager(cwd);
|
|
866
865
|
logger.dim(`Installing dependencies with ${pm}`);
|
|
867
|
-
|
|
868
|
-
cwd: worktreeDir,
|
|
869
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
870
|
-
});
|
|
866
|
+
await exec(`${pm} install`, { cwd: worktreeDir });
|
|
871
867
|
const cleanup = async () => {
|
|
872
868
|
logger.dim(`Cleaning up worktree at ${worktreeDir}`);
|
|
873
869
|
try {
|
|
@@ -912,7 +908,7 @@ function waitForServer(url, timeoutMs) {
|
|
|
912
908
|
await fetch(url);
|
|
913
909
|
resolve5();
|
|
914
910
|
} catch {
|
|
915
|
-
setTimeout(poll,
|
|
911
|
+
setTimeout(poll, 150);
|
|
916
912
|
}
|
|
917
913
|
};
|
|
918
914
|
poll();
|
|
@@ -921,8 +917,8 @@ function waitForServer(url, timeoutMs) {
|
|
|
921
917
|
async function startServer(projectDir, port) {
|
|
922
918
|
const url = `http://localhost:${port}`;
|
|
923
919
|
const pm = detectPackageManager(projectDir);
|
|
924
|
-
const
|
|
925
|
-
const [cmd, ...baseArgs] =
|
|
920
|
+
const exec2 = pmExec(pm);
|
|
921
|
+
const [cmd, ...baseArgs] = exec2.split(" ");
|
|
926
922
|
const lockFile = join5(projectDir, ".next", "dev", "lock");
|
|
927
923
|
if (existsSync5(lockFile)) {
|
|
928
924
|
throw new AfterbeforeError(
|
|
@@ -1009,6 +1005,7 @@ async function detectSections(page, maxSections) {
|
|
|
1009
1005
|
if (!container || tagged.has(container)) continue;
|
|
1010
1006
|
if (container.scrollHeight > document.documentElement.scrollHeight * 0.9) continue;
|
|
1011
1007
|
container.setAttribute("data-ab-section", String(idx));
|
|
1008
|
+
heading.setAttribute("data-ab-heading", String(idx));
|
|
1012
1009
|
tagged.add(container);
|
|
1013
1010
|
results.push({
|
|
1014
1011
|
label: (heading.textContent ?? "").trim(),
|
|
@@ -1067,6 +1064,7 @@ async function tagSectionOnPage(page, headingText, index) {
|
|
|
1067
1064
|
}
|
|
1068
1065
|
if (el) {
|
|
1069
1066
|
el.setAttribute("data-ab-section", String(idx));
|
|
1067
|
+
match.setAttribute("data-ab-heading", String(idx));
|
|
1070
1068
|
return true;
|
|
1071
1069
|
}
|
|
1072
1070
|
return false;
|
|
@@ -1074,12 +1072,33 @@ async function tagSectionOnPage(page, headingText, index) {
|
|
|
1074
1072
|
{ text: headingText, idx: index }
|
|
1075
1073
|
);
|
|
1076
1074
|
}
|
|
1075
|
+
async function hideSectionHeading(page, sectionIndex) {
|
|
1076
|
+
await page.evaluate((idx) => {
|
|
1077
|
+
const heading = document.querySelector(`[data-ab-heading="${idx}"]`);
|
|
1078
|
+
if (heading instanceof HTMLElement) {
|
|
1079
|
+
heading.style.display = "none";
|
|
1080
|
+
}
|
|
1081
|
+
}, sectionIndex);
|
|
1082
|
+
}
|
|
1083
|
+
async function showSectionHeading(page, sectionIndex) {
|
|
1084
|
+
await page.evaluate((idx) => {
|
|
1085
|
+
const heading = document.querySelector(`[data-ab-heading="${idx}"]`);
|
|
1086
|
+
if (heading instanceof HTMLElement) {
|
|
1087
|
+
heading.style.display = "";
|
|
1088
|
+
}
|
|
1089
|
+
}, sectionIndex);
|
|
1090
|
+
}
|
|
1077
1091
|
async function cleanupSectionTags(page) {
|
|
1078
1092
|
await page.evaluate(() => {
|
|
1079
|
-
const
|
|
1080
|
-
for (const el of tagged) {
|
|
1093
|
+
for (const el of document.querySelectorAll("[data-ab-section]")) {
|
|
1081
1094
|
el.removeAttribute("data-ab-section");
|
|
1082
1095
|
}
|
|
1096
|
+
for (const el of document.querySelectorAll("[data-ab-heading]")) {
|
|
1097
|
+
el.removeAttribute("data-ab-heading");
|
|
1098
|
+
if (el instanceof HTMLElement) {
|
|
1099
|
+
el.style.display = "";
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1083
1102
|
});
|
|
1084
1103
|
}
|
|
1085
1104
|
function sanitizeSectionLabel(label) {
|
|
@@ -1395,12 +1414,16 @@ async function captureAutoSections(afterPage, beforePage, parentPrefix, parentLa
|
|
|
1395
1414
|
const sectionAfterPath = join6(outputDir, `${sectionPrefix}-after.png`);
|
|
1396
1415
|
const sectionBeforePath = join6(outputDir, `${sectionPrefix}-before.png`);
|
|
1397
1416
|
try {
|
|
1417
|
+
await hideSectionHeading(afterPage, section.index);
|
|
1398
1418
|
const afterEl = afterPage.locator(`[data-ab-section="${section.index}"]`).first();
|
|
1399
1419
|
await afterEl.screenshot({ path: sectionAfterPath });
|
|
1420
|
+
await showSectionHeading(afterPage, section.index);
|
|
1400
1421
|
const found = await tagSectionOnPage(beforePage, section.label, section.index);
|
|
1401
1422
|
if (found) {
|
|
1423
|
+
await hideSectionHeading(beforePage, section.index);
|
|
1402
1424
|
const beforeEl = beforePage.locator(`[data-ab-section="${section.index}"]`).first();
|
|
1403
1425
|
await beforeEl.screenshot({ path: sectionBeforePath });
|
|
1426
|
+
await showSectionHeading(beforePage, section.index);
|
|
1404
1427
|
} else {
|
|
1405
1428
|
continue;
|
|
1406
1429
|
}
|
|
@@ -1879,7 +1902,7 @@ async function runPipeline(options) {
|
|
|
1879
1902
|
const outputDir = resolve4(cwd, output, sessionName);
|
|
1880
1903
|
const startTime = Date.now();
|
|
1881
1904
|
try {
|
|
1882
|
-
const version = true ? "0.1.
|
|
1905
|
+
const version = true ? "0.1.11" : "dev";
|
|
1883
1906
|
console.log(`
|
|
1884
1907
|
afterbefore v${version} \xB7 Comparing against ${base}
|
|
1885
1908
|
`);
|
|
@@ -2024,7 +2047,7 @@ afterbefore v${version} \xB7 Comparing against ${base}
|
|
|
2024
2047
|
var program = new Command();
|
|
2025
2048
|
program.name("afterbefore").description(
|
|
2026
2049
|
"Automatic before/after screenshot capture for PRs. Git diff is the config."
|
|
2027
|
-
).version("0.1.
|
|
2050
|
+
).version("0.1.11").option("--base <ref>", "Base branch or ref to compare against", "main").option("--output <dir>", "Output directory for screenshots", ".afterbefore").option("--post", "Post results as a PR comment via gh CLI", false).option(
|
|
2028
2051
|
"--threshold <percent>",
|
|
2029
2052
|
"Diff threshold percentage (changes below this are ignored)",
|
|
2030
2053
|
"0.1"
|