@wasao/kagemusha 0.2.0 → 0.3.4
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/README.md +103 -453
- package/dist/commands/capture.js +57 -35
- package/dist/commands/capture.js.map +1 -1
- package/dist/commands/edit.d.ts +1 -1
- package/dist/commands/edit.d.ts.map +1 -1
- package/dist/commands/edit.js +43 -7
- package/dist/commands/edit.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +75 -44
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/login.js +3 -14
- package/dist/commands/login.js.map +1 -1
- package/dist/editor/inject-script/annotations.d.ts +11 -0
- package/dist/editor/inject-script/annotations.d.ts.map +1 -0
- package/dist/editor/inject-script/annotations.js +409 -0
- package/dist/editor/inject-script/annotations.js.map +1 -0
- package/dist/editor/inject-script/bridge.d.ts +13 -0
- package/dist/editor/inject-script/bridge.d.ts.map +1 -0
- package/dist/editor/inject-script/bridge.js +33 -0
- package/dist/editor/inject-script/bridge.js.map +1 -0
- package/dist/editor/inject-script/crop.d.ts +9 -0
- package/dist/editor/inject-script/crop.d.ts.map +1 -0
- package/dist/editor/inject-script/crop.js +236 -0
- package/dist/editor/inject-script/crop.js.map +1 -0
- package/dist/editor/inject-script/dom.d.ts +7 -0
- package/dist/editor/inject-script/dom.d.ts.map +1 -0
- package/dist/editor/inject-script/dom.js +32 -0
- package/dist/editor/inject-script/dom.js.map +1 -0
- package/dist/editor/inject-script/index.d.ts +2 -0
- package/dist/editor/inject-script/index.d.ts.map +1 -0
- package/dist/editor/inject-script/index.js +56 -0
- package/dist/editor/inject-script/index.js.map +1 -0
- package/dist/editor/inject-script/record.d.ts +5 -0
- package/dist/editor/inject-script/record.d.ts.map +1 -0
- package/dist/editor/inject-script/record.js +398 -0
- package/dist/editor/inject-script/record.js.map +1 -0
- package/dist/editor/inject-script/selector.d.ts +6 -0
- package/dist/editor/inject-script/selector.d.ts.map +1 -0
- package/dist/editor/inject-script/selector.js +112 -0
- package/dist/editor/inject-script/selector.js.map +1 -0
- package/dist/editor/inject-script/state.d.ts +27 -0
- package/dist/editor/inject-script/state.d.ts.map +1 -0
- package/dist/editor/inject-script/state.js +26 -0
- package/dist/editor/inject-script/state.js.map +1 -0
- package/dist/editor/inject-script/svg.d.ts +7 -0
- package/dist/editor/inject-script/svg.d.ts.map +1 -0
- package/dist/editor/inject-script/svg.js +39 -0
- package/dist/editor/inject-script/svg.js.map +1 -0
- package/dist/editor/inject-script/toolbar.d.ts +14 -0
- package/dist/editor/inject-script/toolbar.d.ts.map +1 -0
- package/dist/editor/inject-script/toolbar.js +240 -0
- package/dist/editor/inject-script/toolbar.js.map +1 -0
- package/dist/editor/inject-script/types.d.ts +102 -0
- package/dist/editor/inject-script/types.d.ts.map +1 -0
- package/dist/editor/inject-script/types.js +5 -0
- package/dist/editor/inject-script/types.js.map +1 -0
- package/dist/editor/inject-script.js +1248 -699
- package/dist/index.js +9 -2
- package/dist/index.js.map +1 -1
- package/dist/lib/canonical.d.ts +35 -3
- package/dist/lib/canonical.d.ts.map +1 -1
- package/dist/lib/canonical.js +85 -25
- package/dist/lib/canonical.js.map +1 -1
- package/dist/lib/diff.d.ts +23 -4
- package/dist/lib/diff.d.ts.map +1 -1
- package/dist/lib/diff.js +5 -6
- package/dist/lib/diff.js.map +1 -1
- package/dist/lib/page-ready.d.ts +18 -0
- package/dist/lib/page-ready.d.ts.map +1 -0
- package/dist/lib/page-ready.js +19 -0
- package/dist/lib/page-ready.js.map +1 -0
- package/dist/lib/screenshot.d.ts +4 -1
- package/dist/lib/screenshot.d.ts.map +1 -1
- package/dist/lib/screenshot.js +31 -5
- package/dist/lib/screenshot.js.map +1 -1
- package/dist/lib/staging.d.ts +0 -1
- package/dist/lib/staging.d.ts.map +1 -1
- package/dist/lib/staging.js +0 -3
- package/dist/lib/staging.js.map +1 -1
- package/dist/types.d.ts +5 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +20 -10
- package/dist/editor/inject-script.d.ts +0 -2
- package/dist/editor/inject-script.d.ts.map +0 -1
- package/dist/editor/inject-script.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
2
4
|
import chalk from "chalk";
|
|
3
5
|
import { Command } from "commander";
|
|
4
6
|
import { addCommand } from "./commands/add.js";
|
|
@@ -9,8 +11,13 @@ import { initCommand } from "./commands/init.js";
|
|
|
9
11
|
import { listCommand } from "./commands/list.js";
|
|
10
12
|
import { loginCommand } from "./commands/login.js";
|
|
11
13
|
import { validateCommand } from "./commands/validate.js";
|
|
14
|
+
// Read version from package.json at runtime so release-please only needs to
|
|
15
|
+
// update one file (= package.json) on every bump. dist/index.js sits next
|
|
16
|
+
// to dist/, so package.json is two levels up (= ../package.json).
|
|
17
|
+
const pkgPath = fileURLToPath(new URL("../package.json", import.meta.url));
|
|
18
|
+
const VERSION = JSON.parse(readFileSync(pkgPath, "utf-8")).version;
|
|
12
19
|
const BANNER = `
|
|
13
|
-
${chalk.bold("kagemusha")} ${chalk.gray(
|
|
20
|
+
${chalk.bold("kagemusha")} ${chalk.gray(`v${VERSION}`)}
|
|
14
21
|
${chalk.dim("The shadow warrior for your documentation.")}
|
|
15
22
|
|
|
16
23
|
${chalk.white("Auto-update help center screenshots")}
|
|
@@ -19,7 +26,7 @@ const BANNER = `
|
|
|
19
26
|
const program = new Command();
|
|
20
27
|
program
|
|
21
28
|
.name("kagemusha")
|
|
22
|
-
.version(
|
|
29
|
+
.version(VERSION)
|
|
23
30
|
.addHelpText("beforeAll", BANNER)
|
|
24
31
|
.configureHelp({
|
|
25
32
|
sortSubcommands: false,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,MAAM,MAAM,GAAG;IACX,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/canonical.d.ts
CHANGED
|
@@ -2,6 +2,18 @@ import type { KagemushaConfig } from "../types.js";
|
|
|
2
2
|
export declare const getOutputDir: (config: KagemushaConfig, projectRoot: string) => string;
|
|
3
3
|
export declare const getCanonicalPath: (config: KagemushaConfig, projectRoot: string, id: string) => string;
|
|
4
4
|
export type FetchResult = "ok" | "not-found";
|
|
5
|
+
/**
|
|
6
|
+
* URLs returned by `push()` so callers can include them in summary.json
|
|
7
|
+
* for downstream notification consumers (Slack, PR comments, etc.).
|
|
8
|
+
*
|
|
9
|
+
* - `after`: the new `latest.png` we just uploaded
|
|
10
|
+
* - `before`: the previous `latest.png`, copied to `previous.png` before
|
|
11
|
+
* being overwritten. Undefined when no prior version existed (= first push)
|
|
12
|
+
*/
|
|
13
|
+
export interface PushUrls {
|
|
14
|
+
after: string;
|
|
15
|
+
before?: string;
|
|
16
|
+
}
|
|
5
17
|
/**
|
|
6
18
|
* S3-backed canonical store.
|
|
7
19
|
* Local mode has no remote — outputDir itself is the source of truth.
|
|
@@ -11,11 +23,31 @@ export declare class S3Canonical {
|
|
|
11
23
|
private readonly cdnBaseUrl?;
|
|
12
24
|
private readonly client;
|
|
13
25
|
constructor(bucket: string, cdnBaseUrl?: string | undefined);
|
|
14
|
-
private
|
|
26
|
+
private latestKey;
|
|
27
|
+
private previousKey;
|
|
28
|
+
private historyKey;
|
|
29
|
+
private urlFor;
|
|
15
30
|
/** Download canonical for `id` to `localPath`. Returns "not-found" if absent. */
|
|
16
31
|
fetch(id: string, localPath: string): Promise<FetchResult>;
|
|
17
|
-
/**
|
|
18
|
-
|
|
32
|
+
/**
|
|
33
|
+
* Upload `localPath` as the canonical for `id`.
|
|
34
|
+
*
|
|
35
|
+
* Side effects on S3 for a single push:
|
|
36
|
+
* 1. Copy existing latest.png → previous.png (no-op if missing)
|
|
37
|
+
* 2. Upload localPath → latest.png
|
|
38
|
+
* 3. Upload localPath → history/<timestamp>.png
|
|
39
|
+
*
|
|
40
|
+
* Step 1 must complete first (otherwise the soon-to-be-overwritten latest
|
|
41
|
+
* would be replaced before the snapshot is taken). Steps 2-3 target
|
|
42
|
+
* different keys and run in parallel.
|
|
43
|
+
*
|
|
44
|
+
* Returns URLs (`before` / `after`) so callers can surface them in
|
|
45
|
+
* `reports/summary.json` (= public API). Consumers compare before vs after
|
|
46
|
+
* visually; kagemusha intentionally does not publish a pre-generated diff
|
|
47
|
+
* image (= pixelmatch's red overlay is alarming and adds little vs the
|
|
48
|
+
* raw pair).
|
|
49
|
+
*/
|
|
50
|
+
push(id: string, localPath: string): Promise<PushUrls>;
|
|
19
51
|
label(): string;
|
|
20
52
|
}
|
|
21
53
|
export declare const createS3Canonical: (config: KagemushaConfig) => S3Canonical | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"canonical.d.ts","sourceRoot":"","sources":["../../src/lib/canonical.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"canonical.d.ts","sourceRoot":"","sources":["../../src/lib/canonical.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAInD,eAAO,MAAM,YAAY,GACxB,QAAQ,eAAe,EACvB,aAAa,MAAM,KACjB,MAKF,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAC5B,QAAQ,eAAe,EACvB,aAAa,MAAM,EACnB,IAAI,MAAM,KACR,MAAmE,CAAC;AAEvE,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,WAAW,CAAC;AAE7C;;;;;;;GAOG;AACH,MAAM,WAAW,QAAQ;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAUD;;;GAGG;AAEH,qBAAa,WAAW;IAItB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC;IAJ7B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAW;gBAGhB,MAAM,EAAE,MAAM,EACd,UAAU,CAAC,EAAE,MAAM,YAAA;IAMrC,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,UAAU;IAOlB,OAAO,CAAC,MAAM;IAKd,iFAAiF;IAC3E,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAgBhE;;;;;;;;;;;;;;;;;OAiBG;IACG,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAuD5D,KAAK,IAAI,MAAM;CAGf;AASD,eAAO,MAAM,iBAAiB,GAC7B,QAAQ,eAAe,KACrB,WAAW,GAAG,IAOhB,CAAC"}
|
package/dist/lib/canonical.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import { GetObjectCommand, NoSuchKey, PutObjectCommand, S3Client, } from "@aws-sdk/client-s3";
|
|
3
|
+
import { CopyObjectCommand, GetObjectCommand, NoSuchKey, PutObjectCommand, S3Client, } from "@aws-sdk/client-s3";
|
|
4
4
|
const DEFAULT_OUTPUT_DIR = "screenshots";
|
|
5
5
|
export const getOutputDir = (config, projectRoot) => {
|
|
6
6
|
const configured = config.publish?.outputDir ?? DEFAULT_OUTPUT_DIR;
|
|
@@ -31,13 +31,26 @@ export class S3Canonical {
|
|
|
31
31
|
const region = extractRegionFromCdnBase(cdnBaseUrl);
|
|
32
32
|
this.client = new S3Client(region ? { region } : {});
|
|
33
33
|
}
|
|
34
|
-
|
|
34
|
+
latestKey(id) {
|
|
35
35
|
return `${id}/latest.png`;
|
|
36
36
|
}
|
|
37
|
+
previousKey(id) {
|
|
38
|
+
return `${id}/previous.png`;
|
|
39
|
+
}
|
|
40
|
+
historyKey(id, timestamp) {
|
|
41
|
+
// Group history snapshots under a sub-prefix so the bucket list
|
|
42
|
+
// shows `latest.png` / `previous.png` cleanly without historical
|
|
43
|
+
// snapshots interleaved alphabetically.
|
|
44
|
+
return `${id}/history/${timestamp}.png`;
|
|
45
|
+
}
|
|
46
|
+
urlFor(key) {
|
|
47
|
+
const base = this.cdnBaseUrl ?? `s3://${this.bucket}`;
|
|
48
|
+
return `${base.replace(/\/$/, "")}/${key}`;
|
|
49
|
+
}
|
|
37
50
|
/** Download canonical for `id` to `localPath`. Returns "not-found" if absent. */
|
|
38
51
|
async fetch(id, localPath) {
|
|
39
52
|
try {
|
|
40
|
-
const res = await this.client.send(new GetObjectCommand({ Bucket: this.bucket, Key: this.
|
|
53
|
+
const res = await this.client.send(new GetObjectCommand({ Bucket: this.bucket, Key: this.latestKey(id) }));
|
|
41
54
|
const bytes = await res.Body?.transformToByteArray();
|
|
42
55
|
if (!bytes)
|
|
43
56
|
return "not-found";
|
|
@@ -46,40 +59,87 @@ export class S3Canonical {
|
|
|
46
59
|
return "ok";
|
|
47
60
|
}
|
|
48
61
|
catch (e) {
|
|
49
|
-
if (e
|
|
50
|
-
return "not-found";
|
|
51
|
-
if (e?.name === "NoSuchKey")
|
|
52
|
-
return "not-found";
|
|
53
|
-
if (e?.Code === "NoSuchKey")
|
|
62
|
+
if (isNoSuchKey(e))
|
|
54
63
|
return "not-found";
|
|
55
64
|
throw e;
|
|
56
65
|
}
|
|
57
66
|
}
|
|
58
|
-
/**
|
|
67
|
+
/**
|
|
68
|
+
* Upload `localPath` as the canonical for `id`.
|
|
69
|
+
*
|
|
70
|
+
* Side effects on S3 for a single push:
|
|
71
|
+
* 1. Copy existing latest.png → previous.png (no-op if missing)
|
|
72
|
+
* 2. Upload localPath → latest.png
|
|
73
|
+
* 3. Upload localPath → history/<timestamp>.png
|
|
74
|
+
*
|
|
75
|
+
* Step 1 must complete first (otherwise the soon-to-be-overwritten latest
|
|
76
|
+
* would be replaced before the snapshot is taken). Steps 2-3 target
|
|
77
|
+
* different keys and run in parallel.
|
|
78
|
+
*
|
|
79
|
+
* Returns URLs (`before` / `after`) so callers can surface them in
|
|
80
|
+
* `reports/summary.json` (= public API). Consumers compare before vs after
|
|
81
|
+
* visually; kagemusha intentionally does not publish a pre-generated diff
|
|
82
|
+
* image (= pixelmatch's red overlay is alarming and adds little vs the
|
|
83
|
+
* raw pair).
|
|
84
|
+
*/
|
|
59
85
|
async push(id, localPath) {
|
|
60
86
|
const body = fs.readFileSync(localPath);
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
87
|
+
// 1. Snapshot the soon-to-be-overwritten latest as `previous`.
|
|
88
|
+
// Uses CopyObject (= S3-side copy, no local round-trip). First push for
|
|
89
|
+
// this id has no latest yet — we swallow NoSuchKey and report `before:
|
|
90
|
+
// undefined` to the caller.
|
|
91
|
+
let beforeUrl;
|
|
92
|
+
try {
|
|
93
|
+
await this.client.send(new CopyObjectCommand({
|
|
94
|
+
Bucket: this.bucket,
|
|
95
|
+
CopySource: `${this.bucket}/${this.latestKey(id)}`,
|
|
96
|
+
Key: this.previousKey(id),
|
|
97
|
+
MetadataDirective: "REPLACE",
|
|
98
|
+
ContentType: "image/png",
|
|
99
|
+
CacheControl: "no-cache",
|
|
100
|
+
}));
|
|
101
|
+
beforeUrl = this.urlFor(this.previousKey(id));
|
|
102
|
+
}
|
|
103
|
+
catch (e) {
|
|
104
|
+
if (!isNoSuchKey(e))
|
|
105
|
+
throw e;
|
|
106
|
+
// first push for this id — no previous yet, leave beforeUrl undefined
|
|
107
|
+
}
|
|
108
|
+
// 2-3. Independent uploads — run in parallel (= ~2x faster than serial).
|
|
70
109
|
const timestamp = new Date().toISOString().replaceAll(":", "-");
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
110
|
+
await Promise.all([
|
|
111
|
+
// 2. latest
|
|
112
|
+
this.client.send(new PutObjectCommand({
|
|
113
|
+
Bucket: this.bucket,
|
|
114
|
+
Key: this.latestKey(id),
|
|
115
|
+
Body: body,
|
|
116
|
+
ContentType: "image/png",
|
|
117
|
+
CacheControl: "no-cache",
|
|
118
|
+
})),
|
|
119
|
+
// 3. history snapshot
|
|
120
|
+
this.client.send(new PutObjectCommand({
|
|
121
|
+
Bucket: this.bucket,
|
|
122
|
+
Key: this.historyKey(id, timestamp),
|
|
123
|
+
Body: body,
|
|
124
|
+
ContentType: "image/png",
|
|
125
|
+
})),
|
|
126
|
+
]);
|
|
127
|
+
return {
|
|
128
|
+
after: this.urlFor(this.latestKey(id)),
|
|
129
|
+
before: beforeUrl,
|
|
130
|
+
};
|
|
78
131
|
}
|
|
79
132
|
label() {
|
|
80
133
|
return this.cdnBaseUrl ?? `s3://${this.bucket}`;
|
|
81
134
|
}
|
|
82
135
|
}
|
|
136
|
+
const isNoSuchKey = (e) => {
|
|
137
|
+
if (e instanceof NoSuchKey)
|
|
138
|
+
return true;
|
|
139
|
+
const name = e?.name;
|
|
140
|
+
const code = e?.Code;
|
|
141
|
+
return name === "NoSuchKey" || code === "NoSuchKey";
|
|
142
|
+
};
|
|
83
143
|
export const createS3Canonical = (config) => {
|
|
84
144
|
const publish = config.publish;
|
|
85
145
|
if (publish?.destination !== "s3")
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"canonical.js","sourceRoot":"","sources":["../../src/lib/canonical.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EACN,gBAAgB,EAChB,SAAS,EACT,gBAAgB,EAChB,QAAQ,GACR,MAAM,oBAAoB,CAAC;AAG5B,MAAM,kBAAkB,GAAG,aAAa,CAAC;AAEzC,MAAM,CAAC,MAAM,YAAY,GAAG,CAC3B,MAAuB,EACvB,WAAmB,EACV,EAAE;IACX,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,EAAE,SAAS,IAAI,kBAAkB,CAAC;IACnE,OAAO,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;QACjC,CAAC,CAAC,UAAU;QACZ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;AACvC,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC/B,MAAuB,EACvB,WAAmB,EACnB,EAAU,EACD,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"canonical.js","sourceRoot":"","sources":["../../src/lib/canonical.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EACN,iBAAiB,EACjB,gBAAgB,EAChB,SAAS,EACT,gBAAgB,EAChB,QAAQ,GACR,MAAM,oBAAoB,CAAC;AAG5B,MAAM,kBAAkB,GAAG,aAAa,CAAC;AAEzC,MAAM,CAAC,MAAM,YAAY,GAAG,CAC3B,MAAuB,EACvB,WAAmB,EACV,EAAE;IACX,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,EAAE,SAAS,IAAI,kBAAkB,CAAC;IACnE,OAAO,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;QACjC,CAAC,CAAC,UAAU;QACZ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;AACvC,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC/B,MAAuB,EACvB,WAAmB,EACnB,EAAU,EACD,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;AAiBvE,+FAA+F;AAC/F,qFAAqF;AACrF,MAAM,wBAAwB,GAAG,CAAC,UAAmB,EAAsB,EAAE;IAC5E,IAAI,CAAC,UAAU;QAAE,OAAO,SAAS,CAAC;IAClC,MAAM,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC;IACpE,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACf,CAAC,CAAC;AAEF;;;GAGG;AAEH,MAAM,OAAO,WAAW;IAIL;IACA;IAJD,MAAM,CAAW;IAElC,YACkB,MAAc,EACd,UAAmB;QADnB,WAAM,GAAN,MAAM,CAAQ;QACd,eAAU,GAAV,UAAU,CAAS;QAEpC,MAAM,MAAM,GAAG,wBAAwB,CAAC,UAAU,CAAC,CAAC;QACpD,IAAI,CAAC,MAAM,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACtD,CAAC;IAEO,SAAS,CAAC,EAAU;QAC3B,OAAO,GAAG,EAAE,aAAa,CAAC;IAC3B,CAAC;IAEO,WAAW,CAAC,EAAU;QAC7B,OAAO,GAAG,EAAE,eAAe,CAAC;IAC7B,CAAC;IAEO,UAAU,CAAC,EAAU,EAAE,SAAiB;QAC/C,gEAAgE;QAChE,iEAAiE;QACjE,wCAAwC;QACxC,OAAO,GAAG,EAAE,YAAY,SAAS,MAAM,CAAC;IACzC,CAAC;IAEO,MAAM,CAAC,GAAW;QACzB,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,IAAI,QAAQ,IAAI,CAAC,MAAM,EAAE,CAAC;QACtD,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC;IAC5C,CAAC;IAED,iFAAiF;IACjF,KAAK,CAAC,KAAK,CAAC,EAAU,EAAE,SAAiB;QACxC,IAAI,CAAC;YACJ,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CACjC,IAAI,gBAAgB,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,CACtE,CAAC;YACF,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,oBAAoB,EAAE,CAAC;YACrD,IAAI,CAAC,KAAK;gBAAE,OAAO,WAAW,CAAC;YAC/B,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC3D,EAAE,CAAC,aAAa,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;YACnC,OAAO,IAAI,CAAC;QACb,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACZ,IAAI,WAAW,CAAC,CAAC,CAAC;gBAAE,OAAO,WAAW,CAAC;YACvC,MAAM,CAAC,CAAC;QACT,CAAC;IACF,CAAC;IAED;;;;;;;;;;;;;;;;;OAiBG;IACH,KAAK,CAAC,IAAI,CAAC,EAAU,EAAE,SAAiB;QACvC,MAAM,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;QAExC,+DAA+D;QAC/D,wEAAwE;QACxE,uEAAuE;QACvE,4BAA4B;QAC5B,IAAI,SAA6B,CAAC;QAClC,IAAI,CAAC;YACJ,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CACrB,IAAI,iBAAiB,CAAC;gBACrB,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,UAAU,EAAE,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE;gBAClD,GAAG,EAAE,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;gBACzB,iBAAiB,EAAE,SAAS;gBAC5B,WAAW,EAAE,WAAW;gBACxB,YAAY,EAAE,UAAU;aACxB,CAAC,CACF,CAAC;YACF,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;QAC/C,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACZ,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;gBAAE,MAAM,CAAC,CAAC;YAC7B,sEAAsE;QACvE,CAAC;QAED,yEAAyE;QACzE,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAChE,MAAM,OAAO,CAAC,GAAG,CAAC;YACjB,YAAY;YACZ,IAAI,CAAC,MAAM,CAAC,IAAI,CACf,IAAI,gBAAgB,CAAC;gBACpB,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;gBACvB,IAAI,EAAE,IAAI;gBACV,WAAW,EAAE,WAAW;gBACxB,YAAY,EAAE,UAAU;aACxB,CAAC,CACF;YACD,sBAAsB;YACtB,IAAI,CAAC,MAAM,CAAC,IAAI,CACf,IAAI,gBAAgB,CAAC;gBACpB,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,EAAE,EAAE,SAAS,CAAC;gBACnC,IAAI,EAAE,IAAI;gBACV,WAAW,EAAE,WAAW;aACxB,CAAC,CACF;SACD,CAAC,CAAC;QAEH,OAAO;YACN,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;YACtC,MAAM,EAAE,SAAS;SACjB,CAAC;IACH,CAAC;IAED,KAAK;QACJ,OAAO,IAAI,CAAC,UAAU,IAAI,QAAQ,IAAI,CAAC,MAAM,EAAE,CAAC;IACjD,CAAC;CACD;AAED,MAAM,WAAW,GAAG,CAAC,CAAU,EAAW,EAAE;IAC3C,IAAI,CAAC,YAAY,SAAS;QAAE,OAAO,IAAI,CAAC;IACxC,MAAM,IAAI,GAAI,CAAuB,EAAE,IAAI,CAAC;IAC5C,MAAM,IAAI,GAAI,CAAuB,EAAE,IAAI,CAAC;IAC5C,OAAO,IAAI,KAAK,WAAW,IAAI,IAAI,KAAK,WAAW,CAAC;AACrD,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAChC,MAAuB,EACF,EAAE;IACvB,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;IAC/B,IAAI,OAAO,EAAE,WAAW,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAC/C,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACrE,CAAC;IACD,OAAO,IAAI,WAAW,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;AAC/D,CAAC,CAAC"}
|
package/dist/lib/diff.d.ts
CHANGED
|
@@ -2,12 +2,29 @@ export interface Dimensions {
|
|
|
2
2
|
width: number;
|
|
3
3
|
height: number;
|
|
4
4
|
}
|
|
5
|
+
/**
|
|
6
|
+
* URLs of the canonical artifacts on the remote (= S3). Only populated when
|
|
7
|
+
* `capture` actually pushed (= default mode, S3 destination). `--dry-run` and
|
|
8
|
+
* `local` destination leave this undefined.
|
|
9
|
+
*
|
|
10
|
+
* - `after`: the new `latest.png` URL
|
|
11
|
+
* - `before`: the previous `latest.png` URL (= `previous.png`). Undefined on
|
|
12
|
+
* the first push for this id (no prior version existed).
|
|
13
|
+
*
|
|
14
|
+
* No `diff` URL — kagemusha intentionally does not publish a pre-generated
|
|
15
|
+
* diff visualization. Consumers compare before vs after raw images instead.
|
|
16
|
+
*/
|
|
17
|
+
export interface ResultUrls {
|
|
18
|
+
after: string;
|
|
19
|
+
before?: string;
|
|
20
|
+
}
|
|
5
21
|
export type DiffStatus = {
|
|
6
22
|
id: string;
|
|
7
23
|
status: "unchanged";
|
|
8
24
|
} | {
|
|
9
25
|
id: string;
|
|
10
26
|
status: "new";
|
|
27
|
+
urls?: ResultUrls;
|
|
11
28
|
} | {
|
|
12
29
|
id: string;
|
|
13
30
|
status: "missing";
|
|
@@ -17,13 +34,14 @@ export type DiffStatus = {
|
|
|
17
34
|
status: "changed";
|
|
18
35
|
reason: "pixel-diff";
|
|
19
36
|
diffPercentage: number;
|
|
20
|
-
|
|
37
|
+
urls?: ResultUrls;
|
|
21
38
|
} | {
|
|
22
39
|
id: string;
|
|
23
40
|
status: "changed";
|
|
24
41
|
reason: "layout-diff";
|
|
25
42
|
canonical: Dimensions;
|
|
26
43
|
staging: Dimensions;
|
|
44
|
+
urls?: ResultUrls;
|
|
27
45
|
};
|
|
28
46
|
export interface DiffOptions {
|
|
29
47
|
/** Color difference threshold per pixel (0-1). Lower = stricter. Default 0.1 */
|
|
@@ -45,8 +63,9 @@ export type DiffResult = {
|
|
|
45
63
|
diffPercentage: number;
|
|
46
64
|
};
|
|
47
65
|
/**
|
|
48
|
-
* Compare two PNG files using pixelmatch
|
|
49
|
-
*
|
|
66
|
+
* Compare two PNG files using pixelmatch. Returns a structured result with
|
|
67
|
+
* the diff percentage; we deliberately don't write a diff PNG anywhere
|
|
68
|
+
* (= the red overlay is alarming + adds little value over the raw pair).
|
|
50
69
|
*/
|
|
51
|
-
export declare const diffImages: (baseline: string, current: string,
|
|
70
|
+
export declare const diffImages: (baseline: string, current: string, options?: DiffOptions) => Promise<DiffResult>;
|
|
52
71
|
//# sourceMappingURL=diff.d.ts.map
|
package/dist/lib/diff.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/lib/diff.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/lib/diff.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,UAAU;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,UAAU;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,UAAU,GACnB;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,WAAW,CAAA;CAAE,GACnC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,KAAK,CAAC;IAAC,IAAI,CAAC,EAAE,UAAU,CAAA;CAAE,GAChD;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,SAAS,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAClD;IACA,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,SAAS,CAAC;IAClB,MAAM,EAAE,YAAY,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,UAAU,CAAC;CACjB,GACD;IACA,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,SAAS,CAAC;IAClB,MAAM,EAAE,aAAa,CAAC;IACtB,SAAS,EAAE,UAAU,CAAC;IACtB,OAAO,EAAE,UAAU,CAAC;IACpB,IAAI,CAAC,EAAE,UAAU,CAAC;CACjB,CAAC;AAEL,MAAM,WAAW,WAAW;IAC3B,gFAAgF;IAChF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,qEAAqE;IACrE,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,MAAM,UAAU,GACnB;IAAE,KAAK,EAAE,IAAI,CAAA;CAAE,GACf;IACA,KAAK,EAAE,KAAK,CAAC;IACb,MAAM,EAAE,aAAa,CAAC;IACtB,SAAS,EAAE,UAAU,CAAC;IACtB,OAAO,EAAE,UAAU,CAAC;CACnB,GACD;IACA,KAAK,EAAE,KAAK,CAAC;IACb,MAAM,EAAE,YAAY,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;CACtB,CAAC;AAKL;;;;GAIG;AACH,eAAO,MAAM,UAAU,GACtB,UAAU,MAAM,EAChB,SAAS,MAAM,EACf,UAAS,WAAgB,KACvB,OAAO,CAAC,UAAU,CAkCpB,CAAC"}
|
package/dist/lib/diff.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
|
-
import path from "node:path";
|
|
3
2
|
import pixelmatch from "pixelmatch";
|
|
4
3
|
import { PNG } from "pngjs";
|
|
5
4
|
const readPng = (filePath) => PNG.sync.read(fs.readFileSync(filePath));
|
|
6
5
|
/**
|
|
7
|
-
* Compare two PNG files using pixelmatch
|
|
8
|
-
*
|
|
6
|
+
* Compare two PNG files using pixelmatch. Returns a structured result with
|
|
7
|
+
* the diff percentage; we deliberately don't write a diff PNG anywhere
|
|
8
|
+
* (= the red overlay is alarming + adds little value over the raw pair).
|
|
9
9
|
*/
|
|
10
|
-
export const diffImages = async (baseline, current,
|
|
10
|
+
export const diffImages = async (baseline, current, options = {}) => {
|
|
11
11
|
const a = readPng(baseline);
|
|
12
12
|
const b = readPng(current);
|
|
13
13
|
if (a.width !== b.width || a.height !== b.height) {
|
|
@@ -19,6 +19,7 @@ export const diffImages = async (baseline, current, diffPath, options = {}) => {
|
|
|
19
19
|
};
|
|
20
20
|
}
|
|
21
21
|
const { width, height } = a;
|
|
22
|
+
// pixelmatch requires an output buffer even though we discard it.
|
|
22
23
|
const diff = new PNG({ width, height });
|
|
23
24
|
const diffCount = pixelmatch(a.data, b.data, diff.data, width, height, {
|
|
24
25
|
threshold: options.pixelThreshold ?? 0.1,
|
|
@@ -29,8 +30,6 @@ export const diffImages = async (baseline, current, diffPath, options = {}) => {
|
|
|
29
30
|
if (diffCount === 0) {
|
|
30
31
|
return { match: true };
|
|
31
32
|
}
|
|
32
|
-
fs.mkdirSync(path.dirname(diffPath), { recursive: true });
|
|
33
|
-
fs.writeFileSync(diffPath, PNG.sync.write(diff));
|
|
34
33
|
return {
|
|
35
34
|
match: false,
|
|
36
35
|
reason: "pixel-diff",
|
package/dist/lib/diff.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/lib/diff.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,
|
|
1
|
+
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/lib/diff.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAkE5B,MAAM,OAAO,GAAG,CAAC,QAAgB,EAAO,EAAE,CACzC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC;AAE1C;;;;GAIG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,EAC9B,QAAgB,EAChB,OAAe,EACf,UAAuB,EAAE,EACH,EAAE;IACxB,MAAM,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC5B,MAAM,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAE3B,IAAI,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC;QAClD,OAAO;YACN,KAAK,EAAE,KAAK;YACZ,MAAM,EAAE,aAAa;YACrB,SAAS,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;YAC/C,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;SAC7C,CAAC;IACH,CAAC;IAED,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,kEAAkE;IAClE,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IAExC,MAAM,SAAS,GAAG,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE;QACtE,SAAS,EAAE,OAAO,CAAC,cAAc,IAAI,GAAG;QACxC,wEAAwE;QACxE,oEAAoE;QACpE,SAAS,EAAE,OAAO,CAAC,kBAAkB,KAAK,KAAK;KAC/C,CAAC,CAAC;IAEH,IAAI,SAAS,KAAK,CAAC,EAAE,CAAC;QACrB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IACxB,CAAC;IAED,OAAO;QACN,KAAK,EAAE,KAAK;QACZ,MAAM,EAAE,YAAY;QACpB,SAAS;QACT,cAAc,EAAE,CAAC,SAAS,GAAG,CAAC,KAAK,GAAG,MAAM,CAAC,CAAC,GAAG,GAAG;KACpD,CAAC;AACH,CAAC,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
type Page = import("playwright-chromium").Page;
|
|
2
|
+
/**
|
|
3
|
+
* After `page.goto({ waitUntil: "load" })`, wait for the SPA to settle before
|
|
4
|
+
* capturing or letting the user edit. Strategy:
|
|
5
|
+
*
|
|
6
|
+
* 1. Best-effort `networkidle` with a 3s cap — succeeds quickly on pages
|
|
7
|
+
* whose initial API fetches complete fast. SPAs with permanent socket
|
|
8
|
+
* connections never reach networkidle, but we cap the wait so they don't
|
|
9
|
+
* hang the run.
|
|
10
|
+
* 2. 500ms hydration buffer so React / Vue have time to mount after the
|
|
11
|
+
* initial render.
|
|
12
|
+
*
|
|
13
|
+
* Pages that need more than this should add a per-definition
|
|
14
|
+
* `beforeCapture: [{action:"waitForSelector",selector:"..."}]`.
|
|
15
|
+
*/
|
|
16
|
+
export declare const waitForPageReady: (page: Page) => Promise<void>;
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=page-ready.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-ready.d.ts","sourceRoot":"","sources":["../../src/lib/page-ready.ts"],"names":[],"mappings":"AAAA,KAAK,IAAI,GAAG,OAAO,qBAAqB,EAAE,IAAI,CAAC;AAE/C;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,gBAAgB,GAAU,MAAM,IAAI,KAAG,OAAO,CAAC,IAAI,CAG/D,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* After `page.goto({ waitUntil: "load" })`, wait for the SPA to settle before
|
|
3
|
+
* capturing or letting the user edit. Strategy:
|
|
4
|
+
*
|
|
5
|
+
* 1. Best-effort `networkidle` with a 3s cap — succeeds quickly on pages
|
|
6
|
+
* whose initial API fetches complete fast. SPAs with permanent socket
|
|
7
|
+
* connections never reach networkidle, but we cap the wait so they don't
|
|
8
|
+
* hang the run.
|
|
9
|
+
* 2. 500ms hydration buffer so React / Vue have time to mount after the
|
|
10
|
+
* initial render.
|
|
11
|
+
*
|
|
12
|
+
* Pages that need more than this should add a per-definition
|
|
13
|
+
* `beforeCapture: [{action:"waitForSelector",selector:"..."}]`.
|
|
14
|
+
*/
|
|
15
|
+
export const waitForPageReady = async (page) => {
|
|
16
|
+
await page.waitForLoadState("networkidle", { timeout: 3000 }).catch(() => { });
|
|
17
|
+
await page.waitForTimeout(500);
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=page-ready.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-ready.js","sourceRoot":"","sources":["../../src/lib/page-ready.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,EAAE,IAAU,EAAiB,EAAE;IACnE,MAAM,IAAI,CAAC,gBAAgB,CAAC,aAAa,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAC9E,MAAM,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;AAChC,CAAC,CAAC"}
|
package/dist/lib/screenshot.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { KagemushaConfig, ScreenshotDefinition } from "../types.js";
|
|
1
|
+
import type { CaptureAction, KagemushaConfig, ScreenshotDefinition } from "../types.js";
|
|
2
|
+
type Page = import("playwright-chromium").Page;
|
|
2
3
|
export interface CaptureFailure {
|
|
3
4
|
id: string;
|
|
4
5
|
reason: string;
|
|
@@ -6,4 +7,6 @@ export interface CaptureFailure {
|
|
|
6
7
|
export declare const captureScreenshots: (config: KagemushaConfig, definitions: ScreenshotDefinition[], projectRoot: string, options?: {
|
|
7
8
|
outputDir?: string;
|
|
8
9
|
}) => Promise<CaptureFailure[]>;
|
|
10
|
+
export declare const executeActions: (page: Page, actions: CaptureAction[]) => Promise<void>;
|
|
11
|
+
export {};
|
|
9
12
|
//# sourceMappingURL=screenshot.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"screenshot.d.ts","sourceRoot":"","sources":["../../src/lib/screenshot.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"screenshot.d.ts","sourceRoot":"","sources":["../../src/lib/screenshot.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACX,aAAa,EACb,eAAe,EACf,oBAAoB,EACpB,MAAM,aAAa,CAAC;AAMrB,KAAK,IAAI,GAAG,OAAO,qBAAqB,EAAE,IAAI,CAAC;AAc/C,MAAM,WAAW,cAAc;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,kBAAkB,GAC9B,QAAQ,eAAe,EACvB,aAAa,oBAAoB,EAAE,EACnC,aAAa,MAAM,EACnB,UAAS;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,KAClC,OAAO,CAAC,cAAc,EAAE,CA6B1B,CAAC;AA8EF,eAAO,MAAM,cAAc,GAC1B,MAAM,IAAI,EACV,SAAS,aAAa,EAAE,KACtB,OAAO,CAAC,IAAI,CAqDd,CAAC"}
|
package/dist/lib/screenshot.js
CHANGED
|
@@ -3,6 +3,7 @@ import path from "node:path";
|
|
|
3
3
|
import { drawAnnotations } from "./annotate.js";
|
|
4
4
|
import { defaultContextOptions } from "./auth.js";
|
|
5
5
|
import { getOutputDir } from "./canonical.js";
|
|
6
|
+
import { waitForPageReady } from "./page-ready.js";
|
|
6
7
|
const loadPlaywright = async () => {
|
|
7
8
|
try {
|
|
8
9
|
return await import("playwright-chromium");
|
|
@@ -46,7 +47,8 @@ const captureOne = async (context, config, def, outputDir) => {
|
|
|
46
47
|
});
|
|
47
48
|
}
|
|
48
49
|
const url = resolveUrl(config.app.baseUrl, def.url, def.urlParams);
|
|
49
|
-
await page.goto(url, { waitUntil: "
|
|
50
|
+
await page.goto(url, { waitUntil: "load", timeout: 60000 });
|
|
51
|
+
await waitForPageReady(page);
|
|
50
52
|
if (def.hideElements?.length) {
|
|
51
53
|
await hideElements(page, def.hideElements);
|
|
52
54
|
}
|
|
@@ -84,19 +86,34 @@ const takeScreenshotBuffer = async (page, def) => {
|
|
|
84
86
|
return await page.screenshot({ fullPage: true });
|
|
85
87
|
}
|
|
86
88
|
};
|
|
87
|
-
|
|
89
|
+
// Returns false (= skip the step) when `optional: true` and the selector
|
|
90
|
+
// doesn't match anything on the page. The page.$ probe completes
|
|
91
|
+
// instantly — no Playwright timeout involved.
|
|
92
|
+
const isPresent = async (page, selector) => (await page.$(selector)) !== null;
|
|
93
|
+
// Exported so the `edit` command can replay beforeCapture before injecting
|
|
94
|
+
// the editor — that way users author annotations on the same page state
|
|
95
|
+
// kagemusha will eventually screenshot.
|
|
96
|
+
export const executeActions = async (page, actions) => {
|
|
88
97
|
for (const action of actions) {
|
|
89
98
|
switch (action.action) {
|
|
90
99
|
case "click":
|
|
100
|
+
if (action.optional && !(await isPresent(page, action.selector)))
|
|
101
|
+
break;
|
|
91
102
|
await page.click(action.selector);
|
|
92
103
|
break;
|
|
93
104
|
case "type":
|
|
105
|
+
if (action.optional && !(await isPresent(page, action.selector)))
|
|
106
|
+
break;
|
|
94
107
|
await page.fill(action.selector, action.text);
|
|
95
108
|
break;
|
|
96
109
|
case "select":
|
|
110
|
+
if (action.optional && !(await isPresent(page, action.selector)))
|
|
111
|
+
break;
|
|
97
112
|
await page.selectOption(action.selector, action.value);
|
|
98
113
|
break;
|
|
99
114
|
case "hover":
|
|
115
|
+
if (action.optional && !(await isPresent(page, action.selector)))
|
|
116
|
+
break;
|
|
100
117
|
await page.hover(action.selector);
|
|
101
118
|
break;
|
|
102
119
|
case "scroll":
|
|
@@ -113,9 +130,18 @@ const executeActions = async (page, actions) => {
|
|
|
113
130
|
await page.waitForTimeout(action.ms);
|
|
114
131
|
break;
|
|
115
132
|
case "waitForSelector":
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
133
|
+
try {
|
|
134
|
+
await page.waitForSelector(action.selector, {
|
|
135
|
+
timeout: action.timeout ?? 10000,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
catch (e) {
|
|
139
|
+
// `optional: true` turns wait-for-selector failures into a
|
|
140
|
+
// no-op (= the rest of beforeCapture continues). Without
|
|
141
|
+
// optional, the timeout bubbles up and fails the capture.
|
|
142
|
+
if (!action.optional)
|
|
143
|
+
throw e;
|
|
144
|
+
}
|
|
119
145
|
break;
|
|
120
146
|
case "waitForNavigation":
|
|
121
147
|
await page.waitForLoadState("networkidle", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"screenshot.js","sourceRoot":"","sources":["../../src/lib/screenshot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAM7B,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"screenshot.js","sourceRoot":"","sources":["../../src/lib/screenshot.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/staging.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
export declare const getStagingDir: (projectRoot: string) => string;
|
|
2
2
|
export declare const getStagingPath: (projectRoot: string, id: string) => string;
|
|
3
|
-
export declare const getReportDiffPath: (projectRoot: string, id: string) => string;
|
|
4
3
|
export declare const ensureStagingDirs: (projectRoot: string) => void;
|
|
5
4
|
/** Move staging file to canonical location, overwriting if it exists. */
|
|
6
5
|
export declare const promoteToCanonical: (stagingPath: string, canonicalPath: string) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"staging.d.ts","sourceRoot":"","sources":["../../src/lib/staging.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"staging.d.ts","sourceRoot":"","sources":["../../src/lib/staging.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,aAAa,GAAI,aAAa,MAAM,KAAG,MAChB,CAAC;AAErC,eAAO,MAAM,cAAc,GAAI,aAAa,MAAM,EAAE,IAAI,MAAM,KAAG,MAChB,CAAC;AAElD,eAAO,MAAM,iBAAiB,GAAI,aAAa,MAAM,KAAG,IAEvD,CAAC;AAEF,yEAAyE;AACzE,eAAO,MAAM,kBAAkB,GAC9B,aAAa,MAAM,EACnB,eAAe,MAAM,KACnB,IAIF,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,aAAa,MAAM,KAAG,IAKpD,CAAC"}
|
package/dist/lib/staging.js
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
const STAGING_DIR = path.join(".kagemusha", ".staging");
|
|
4
|
-
const REPORTS_DIR = path.join("reports", "diff");
|
|
5
4
|
export const getStagingDir = (projectRoot) => path.join(projectRoot, STAGING_DIR);
|
|
6
5
|
export const getStagingPath = (projectRoot, id) => path.join(projectRoot, STAGING_DIR, `${id}.png`);
|
|
7
|
-
export const getReportDiffPath = (projectRoot, id) => path.join(projectRoot, REPORTS_DIR, `${id}.diff.png`);
|
|
8
6
|
export const ensureStagingDirs = (projectRoot) => {
|
|
9
7
|
fs.mkdirSync(getStagingDir(projectRoot), { recursive: true });
|
|
10
|
-
fs.mkdirSync(path.join(projectRoot, REPORTS_DIR), { recursive: true });
|
|
11
8
|
};
|
|
12
9
|
/** Move staging file to canonical location, overwriting if it exists. */
|
|
13
10
|
export const promoteToCanonical = (stagingPath, canonicalPath) => {
|
package/dist/lib/staging.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"staging.js","sourceRoot":"","sources":["../../src/lib/staging.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"staging.js","sourceRoot":"","sources":["../../src/lib/staging.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;AAExD,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,WAAmB,EAAU,EAAE,CAC5D,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;AAErC,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,WAAmB,EAAE,EAAU,EAAU,EAAE,CACzE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;AAElD,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,WAAmB,EAAQ,EAAE;IAC9D,EAAE,CAAC,SAAS,CAAC,aAAa,CAAC,WAAW,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAC/D,CAAC,CAAC;AAEF,yEAAyE;AACzE,MAAM,CAAC,MAAM,kBAAkB,GAAG,CACjC,WAAmB,EACnB,aAAqB,EACd,EAAE;IACT,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/D,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;IAC5C,EAAE,CAAC,MAAM,CAAC,WAAW,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AACzC,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,WAAmB,EAAQ,EAAE;IAC3D,MAAM,GAAG,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC;IACvC,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAClD,CAAC;AACF,CAAC,CAAC"}
|