@juangadm/pre-post 1.0.0 → 1.2.0

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.
Files changed (104) hide show
  1. package/README.md +99 -20
  2. package/dist/baseline.d.ts +208 -0
  3. package/dist/baseline.d.ts.map +1 -0
  4. package/dist/baseline.js +413 -0
  5. package/dist/baseline.js.map +1 -0
  6. package/dist/bin/cli.js +87 -42
  7. package/dist/bin/cli.js.map +1 -1
  8. package/dist/browser.d.ts +31 -3
  9. package/dist/browser.d.ts.map +1 -1
  10. package/dist/browser.js +291 -97
  11. package/dist/browser.js.map +1 -1
  12. package/dist/commands/compare.d.ts.map +1 -1
  13. package/dist/commands/compare.js +21 -3
  14. package/dist/commands/compare.js.map +1 -1
  15. package/dist/commands/detect.d.ts +5 -0
  16. package/dist/commands/detect.d.ts.map +1 -1
  17. package/dist/commands/detect.js +4 -1
  18. package/dist/commands/detect.js.map +1 -1
  19. package/dist/commands/doctor.d.ts +32 -0
  20. package/dist/commands/doctor.d.ts.map +1 -1
  21. package/dist/commands/doctor.js +90 -9
  22. package/dist/commands/doctor.js.map +1 -1
  23. package/dist/commands/login.js +1 -1
  24. package/dist/commands/pr.d.ts +4 -0
  25. package/dist/commands/pr.d.ts.map +1 -1
  26. package/dist/commands/pr.js +157 -51
  27. package/dist/commands/pr.js.map +1 -1
  28. package/dist/commands/prune.js +1 -1
  29. package/dist/commands/prune.js.map +1 -1
  30. package/dist/comparison.d.ts +104 -0
  31. package/dist/comparison.d.ts.map +1 -0
  32. package/dist/comparison.js +241 -0
  33. package/dist/comparison.js.map +1 -0
  34. package/dist/config.d.ts +12 -2
  35. package/dist/config.d.ts.map +1 -1
  36. package/dist/config.js +25 -3
  37. package/dist/config.js.map +1 -1
  38. package/dist/deployments.d.ts +71 -0
  39. package/dist/deployments.d.ts.map +1 -0
  40. package/dist/deployments.js +204 -0
  41. package/dist/deployments.js.map +1 -0
  42. package/dist/diff-pool.d.ts.map +1 -1
  43. package/dist/diff-pool.js +5 -2
  44. package/dist/diff-pool.js.map +1 -1
  45. package/dist/diff-worker.d.ts +3 -0
  46. package/dist/diff-worker.d.ts.map +1 -1
  47. package/dist/diff-worker.js +1 -0
  48. package/dist/diff-worker.js.map +1 -1
  49. package/dist/diff.d.ts +10 -0
  50. package/dist/diff.d.ts.map +1 -1
  51. package/dist/diff.js +117 -7
  52. package/dist/diff.js.map +1 -1
  53. package/dist/doctor.d.ts +42 -1
  54. package/dist/doctor.d.ts.map +1 -1
  55. package/dist/doctor.js +73 -7
  56. package/dist/doctor.js.map +1 -1
  57. package/dist/git.d.ts +41 -3
  58. package/dist/git.d.ts.map +1 -1
  59. package/dist/git.js +103 -7
  60. package/dist/git.js.map +1 -1
  61. package/dist/github.d.ts +92 -2
  62. package/dist/github.d.ts.map +1 -1
  63. package/dist/github.js +191 -20
  64. package/dist/github.js.map +1 -1
  65. package/dist/landing.d.ts +48 -0
  66. package/dist/landing.d.ts.map +1 -0
  67. package/dist/landing.js +93 -0
  68. package/dist/landing.js.map +1 -0
  69. package/dist/pkg.d.ts +9 -0
  70. package/dist/pkg.d.ts.map +1 -1
  71. package/dist/pkg.js +14 -0
  72. package/dist/pkg.js.map +1 -1
  73. package/dist/report.d.ts.map +1 -1
  74. package/dist/report.js +59 -28
  75. package/dist/report.js.map +1 -1
  76. package/dist/routes.d.ts +27 -0
  77. package/dist/routes.d.ts.map +1 -1
  78. package/dist/routes.js +98 -23
  79. package/dist/routes.js.map +1 -1
  80. package/dist/run.d.ts +88 -8
  81. package/dist/run.d.ts.map +1 -1
  82. package/dist/run.js +224 -28
  83. package/dist/run.js.map +1 -1
  84. package/dist/sameness.d.ts +91 -0
  85. package/dist/sameness.d.ts.map +1 -0
  86. package/dist/sameness.js +157 -0
  87. package/dist/sameness.js.map +1 -0
  88. package/dist/sessions.d.ts.map +1 -1
  89. package/dist/sessions.js +7 -1
  90. package/dist/sessions.js.map +1 -1
  91. package/dist/shift.d.ts +67 -0
  92. package/dist/shift.d.ts.map +1 -0
  93. package/dist/shift.js +184 -0
  94. package/dist/shift.js.map +1 -0
  95. package/dist/types.d.ts +83 -5
  96. package/dist/types.d.ts.map +1 -1
  97. package/dist/types.js +17 -0
  98. package/dist/types.js.map +1 -1
  99. package/dist/url.d.ts +12 -0
  100. package/dist/url.d.ts.map +1 -0
  101. package/dist/url.js +30 -0
  102. package/dist/url.js.map +1 -0
  103. package/package.json +1 -1
  104. package/skill/SKILL.md +40 -7
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/bin/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/bin/cli.ts"],"names":[],"mappings":"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"}
package/dist/browser.d.ts CHANGED
@@ -1,14 +1,24 @@
1
1
  /**
2
2
  * Browser automation via Playwright (playwright-core + Chromium headless shell).
3
3
  *
4
- * One browser per process, one context per viewport/auth combination, and a
5
- * small page pool. Captures are deterministic: fixed clock, reduced motion,
6
- * animations finished, caret hidden, fonts and images settled, layout stable.
4
+ * One browser per process, a fresh context per capture, and a small page pool.
5
+ * Captures are deterministic: the page's own timeline is held still and
6
+ * advanced by a fixed budget, reduced motion, animations finished, caret
7
+ * hidden, fonts and images settled, layout stable.
7
8
  */
8
9
  import { Browser } from 'playwright-core';
9
10
  import { AuthOptions, CaptureResult, ViewportSize } from './types.js';
10
11
  /** Every capture sees the same wall clock, so dates and "x minutes ago" never drift. */
11
12
  export declare const FIXED_TIME: Date;
13
+ /**
14
+ * How much of the page's own timeline to run before capturing.
15
+ *
16
+ * The clock is frozen while the page loads, so this is the *only* time a
17
+ * timer-driven animation gets, and it is the same on both sides of a
18
+ * comparison however fast each host answered. Long enough for entrance
19
+ * animations to land, short enough to stay cheap.
20
+ */
21
+ export declare const TIMELINE_BUDGET_MS = 600;
12
22
  export interface ScreenshotOptions {
13
23
  viewport: ViewportSize;
14
24
  fullPage?: boolean;
@@ -24,6 +34,24 @@ export declare function playwrightCoreDir(): string;
24
34
  export interface LaunchOptions {
25
35
  headless?: boolean;
26
36
  }
37
+ /**
38
+ * Proxy settings for the capture browser, from the environment.
39
+ *
40
+ * Node's fetch and Chromium each ignore the standard proxy variables unless
41
+ * told, so on a corporate network or in a sandboxed container the probes can
42
+ * succeed while every capture times out.
43
+ *
44
+ * Playwright appends `<-loopback>` to Chromium's bypass list whenever a launch
45
+ * proxy is set, which forces localhost *through* the proxy however NO_PROXY is
46
+ * written. A proxy that refuses localhost then serves its own error page on
47
+ * both sides of a comparison, the diff comes out byte-identical, and the run
48
+ * reports "no visual changes" for a PR that changed plenty. So loopback is
49
+ * named in the bypass list and the forcing is switched off at launch.
50
+ */
51
+ export declare function proxyFromEnv(env?: NodeJS.ProcessEnv): {
52
+ server: string;
53
+ bypass?: string;
54
+ } | undefined;
27
55
  /**
28
56
  * Launch Chromium with a fallback chain:
29
57
  * 1. Explicit custom path (PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH) — override, fails hard
@@ -1 +1 @@
1
- {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAY,OAAO,EAAwB,MAAM,iBAAiB,CAAC;AAK1E,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAKtE,wFAAwF;AACxF,eAAO,MAAM,UAAU,MAAuC,CAAC;AAyB/D,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,YAAY,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,WAAW,CAAC;CACpB;AAMD,gFAAgF;AAChF,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AA4DD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;GAMG;AACH,wBAAsB,aAAa,CAAC,IAAI,GAAE,aAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,CAwC9E;AAED,MAAM,MAAM,WAAW,GAAG,yBAAyB,GAAG,UAAU,CAAC;AAEjE,gFAAgF;AAChF,wBAAgB,cAAc,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAIzD;AAED;;;GAGG;AACH,wBAAsB,sBAAsB,CAAC,IAAI,GAAE,aAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,CAcvF;AAED,gFAAgF;AAChF,wBAAsB,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC,CAMnD;AAED,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAoLD;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,aAAa,CAAC,CA2DvG;AAUD;;GAEG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAOlD"}
1
+ {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAY,OAAO,EAAwB,MAAM,iBAAiB,CAAC;AAK1E,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAMtE,wFAAwF;AACxF,eAAO,MAAM,UAAU,MAAuC,CAAC;AAE/D;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,MAAM,CAAC;AAkCtC,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,YAAY,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,WAAW,CAAC;CACpB;AAMD,gFAAgF;AAChF,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AA4DD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAWlH;AAED;;;;;;GAMG;AACH,wBAAsB,aAAa,CAAC,IAAI,GAAE,aAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,CA6C9E;AAED,MAAM,MAAM,WAAW,GAAG,yBAAyB,GAAG,UAAU,CAAC;AAEjE,gFAAgF;AAChF,wBAAgB,cAAc,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAIzD;AAED;;;GAGG;AACH,wBAAsB,sBAAsB,CAAC,IAAI,GAAE,aAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,CAcvF;AAED,gFAAgF;AAChF,wBAAsB,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC,CAgBnD;AAED,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAgRD;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,aAAa,CAAC,CAoGvG;AAUD;;GAEG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAOlD"}
package/dist/browser.js CHANGED
@@ -1,9 +1,10 @@
1
1
  /**
2
2
  * Browser automation via Playwright (playwright-core + Chromium headless shell).
3
3
  *
4
- * One browser per process, one context per viewport/auth combination, and a
5
- * small page pool. Captures are deterministic: fixed clock, reduced motion,
6
- * animations finished, caret hidden, fonts and images settled, layout stable.
4
+ * One browser per process, a fresh context per capture, and a small page pool.
5
+ * Captures are deterministic: the page's own timeline is held still and
6
+ * advanced by a fixed budget, reduced motion, animations finished, caret
7
+ * hidden, fonts and images settled, layout stable.
7
8
  */
8
9
  import { chromium } from 'playwright-core';
9
10
  import fs from 'fs';
@@ -14,11 +15,26 @@ import { BrowserNotFoundError, HttpStatusError, NavigationError, isVercelRespons
14
15
  const require = createRequire(import.meta.url);
15
16
  /** Every capture sees the same wall clock, so dates and "x minutes ago" never drift. */
16
17
  export const FIXED_TIME = new Date('2026-01-15T12:00:00.000Z');
18
+ /**
19
+ * How much of the page's own timeline to run before capturing.
20
+ *
21
+ * The clock is frozen while the page loads, so this is the *only* time a
22
+ * timer-driven animation gets, and it is the same on both sides of a
23
+ * comparison however fast each host answered. Long enough for entrance
24
+ * animations to land, short enough to stay cheap.
25
+ */
26
+ export const TIMELINE_BUDGET_MS = 600;
27
+ /** One animation frame of that budget. */
28
+ const FRAME_MS = 16;
29
+ /** Real-time gap between layout-stability polls (page timers are frozen). */
30
+ const STABILITY_POLL_MS = 30;
31
+ /** Hosts that are always served from this machine. */
32
+ const LOOPBACK_HOSTS = ['localhost', '127.0.0.1', '::1'];
17
33
  const MAX_CONCURRENT_PAGES = Number(process.env.PRE_POST_CONCURRENCY) || 6;
18
34
  const NAVIGATION_TIMEOUT = 30_000;
19
35
  let browser = null;
36
+ let launching = null;
20
37
  let browserLabel = '';
21
- const contexts = new Map();
22
38
  let activePages = 0;
23
39
  const pageQueue = [];
24
40
  async function acquireSlot() {
@@ -94,6 +110,35 @@ const LAUNCH_ARGS = [
94
110
  '--force-color-profile=srgb',
95
111
  '--font-render-hinting=none',
96
112
  ];
113
+ /**
114
+ * Proxy settings for the capture browser, from the environment.
115
+ *
116
+ * Node's fetch and Chromium each ignore the standard proxy variables unless
117
+ * told, so on a corporate network or in a sandboxed container the probes can
118
+ * succeed while every capture times out.
119
+ *
120
+ * Playwright appends `<-loopback>` to Chromium's bypass list whenever a launch
121
+ * proxy is set, which forces localhost *through* the proxy however NO_PROXY is
122
+ * written. A proxy that refuses localhost then serves its own error page on
123
+ * both sides of a comparison, the diff comes out byte-identical, and the run
124
+ * reports "no visual changes" for a PR that changed plenty. So loopback is
125
+ * named in the bypass list and the forcing is switched off at launch.
126
+ */
127
+ export function proxyFromEnv(env = process.env) {
128
+ const server = env.HTTPS_PROXY || env.https_proxy || env.HTTP_PROXY || env.http_proxy;
129
+ if (!server)
130
+ return undefined;
131
+ const noProxy = env.NO_PROXY || env.no_proxy;
132
+ // Playwright wants a comma-separated bypass list and always resolves
133
+ // loopback directly, so only non-empty custom entries are worth passing.
134
+ const entries = (noProxy ?? '').split(',').map(h => h.trim()).filter(Boolean);
135
+ // Loopback is always direct: it is a dev server on this machine, never
136
+ // something the proxy could route to.
137
+ for (const host of LOOPBACK_HOSTS)
138
+ if (!entries.includes(host))
139
+ entries.push(host);
140
+ return { server, bypass: entries.join(',') };
141
+ }
97
142
  /**
98
143
  * Launch Chromium with a fallback chain:
99
144
  * 1. Explicit custom path (PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH) — override, fails hard
@@ -103,10 +148,16 @@ const LAUNCH_ARGS = [
103
148
  */
104
149
  export async function launchBrowser(opts = {}) {
105
150
  const headless = opts.headless ?? true;
151
+ const proxy = proxyFromEnv();
152
+ // Checked in Playwright's own process, so it has to be set here rather than
153
+ // passed to the browser. Without it the bypass list above is ignored for
154
+ // loopback.
155
+ if (proxy)
156
+ process.env.PLAYWRIGHT_DISABLE_FORCED_CHROMIUM_PROXIED_LOOPBACK = '1';
106
157
  const customPath = process.env.PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH;
107
158
  if (customPath) {
108
159
  try {
109
- const b = await chromium.launch({ headless, executablePath: customPath, args: LAUNCH_ARGS });
160
+ const b = await chromium.launch({ headless, executablePath: customPath, args: LAUNCH_ARGS, proxy });
110
161
  browserLabel = `custom (${customPath})`;
111
162
  return b;
112
163
  }
@@ -117,15 +168,15 @@ export async function launchBrowser(opts = {}) {
117
168
  }
118
169
  }
119
170
  const strategies = [
120
- { label: 'bundled', options: { headless, args: LAUNCH_ARGS } },
171
+ { label: 'bundled', options: { headless, args: LAUNCH_ARGS, proxy } },
121
172
  ];
122
173
  if (headless) {
123
174
  for (const cachedPath of findCachedChromium()) {
124
- strategies.push({ label: `cached (${cachedPath})`, options: { headless, executablePath: cachedPath, args: LAUNCH_ARGS } });
175
+ strategies.push({ label: `cached (${cachedPath})`, options: { headless, executablePath: cachedPath, args: LAUNCH_ARGS, proxy } });
125
176
  }
126
177
  }
127
- strategies.push({ label: 'system chrome', options: { headless, channel: 'chrome', args: LAUNCH_ARGS } });
128
- strategies.push({ label: 'system edge', options: { headless, channel: 'msedge', args: LAUNCH_ARGS } });
178
+ strategies.push({ label: 'system chrome', options: { headless, channel: 'chrome', args: LAUNCH_ARGS, proxy } });
179
+ strategies.push({ label: 'system edge', options: { headless, channel: 'msedge', args: LAUNCH_ARGS, proxy } });
129
180
  let lastError = null;
130
181
  for (const { label, options } of strategies) {
131
182
  try {
@@ -171,11 +222,22 @@ export async function launchBrowserOrInstall(opts = {}) {
171
222
  }
172
223
  /** The process-wide headless browser, launched (and installed) on first use. */
173
224
  export async function getBrowser() {
174
- if (!browser) {
175
- browser = await launchBrowserOrInstall();
176
- browser.on('disconnected', () => { browser = null; contexts.clear(); });
225
+ if (browser)
226
+ return browser;
227
+ // Captures start concurrently, so the launch has to be shared from the first
228
+ // call rather than from the first one to finish — otherwise every caller
229
+ // sees a null `browser` and launches a Chromium of its own, and all but the
230
+ // last are left running with nothing referencing them.
231
+ if (!launching) {
232
+ launching = launchBrowserOrInstall()
233
+ .then(b => {
234
+ browser = b;
235
+ b.on('disconnected', () => { browser = null; launching = null; });
236
+ return b;
237
+ })
238
+ .catch(err => { launching = null; throw err; });
177
239
  }
178
- return browser;
240
+ return launching;
179
241
  }
180
242
  export function browserDescription() {
181
243
  return browserLabel;
@@ -183,8 +245,54 @@ export function browserDescription() {
183
245
  // ============================================================
184
246
  // Contexts
185
247
  // ============================================================
186
- function contextKey(viewport, scale, auth) {
187
- return `${viewport.width}x${viewport.height}@${scale}|${auth ? JSON.stringify(auth) : ''}`;
248
+ /**
249
+ * Purely decorative dev-server chrome, safe to hide from page CSS.
250
+ *
251
+ * An error overlay is deliberately NOT in this list. Vite reports a failed
252
+ * transform by pushing `vite-error-overlay` onto a document that still answers
253
+ * 200, so hiding it would publish the blank or stale page underneath — and
254
+ * report "no visual changes" when both sides are equally broken, which is the
255
+ * one answer that makes a reviewer stop looking.
256
+ *
257
+ * Next's dev indicator is not here either, because page CSS cannot reach it:
258
+ * it lives inside `nextjs-portal`'s shadow root, alongside the error dialog.
259
+ * Hiding the host would take the dialog with it. See `hideDevIndicator`.
260
+ */
261
+ const DEV_OVERLAY_SELECTORS = [
262
+ '#__next-build-watcher',
263
+ 'next-route-announcer',
264
+ ];
265
+ /**
266
+ * Hide Next's dev-tools badge without hiding its error dialog.
267
+ *
268
+ * Both render into the same `nextjs-portal` shadow root — measured against
269
+ * Next 16.0.10, a healthy page has only `#devtools-indicator` there and a
270
+ * broken one adds `[data-nextjs-dialog-overlay]` beside it — so the host
271
+ * element cannot be used to tell them apart. Reaching into the shadow root is
272
+ * what lets the badge go while the dialog stays.
273
+ *
274
+ * The badge matters because on the local strategy both sides are dev servers,
275
+ * so it ships in every image published to the PR — something production never
276
+ * shows. It is position: fixed, so a layout shift moves the page under it and
277
+ * leaves it behind, counting as residual change the branch never made.
278
+ *
279
+ * Runs once, just before the screenshot, rather than from the init script: the
280
+ * portal is mounted after hydration, so there is nothing to find at document
281
+ * start.
282
+ */
283
+ async function hideDevIndicator(page) {
284
+ await page.evaluate(() => {
285
+ const hosts = Array.prototype.slice.call(document.querySelectorAll('nextjs-portal'));
286
+ for (const host of hosts) {
287
+ const root = host.shadowRoot;
288
+ if (!root || root.querySelector('[data-pre-post-hidden]'))
289
+ continue;
290
+ const style = document.createElement('style');
291
+ style.setAttribute('data-pre-post-hidden', '');
292
+ style.textContent = '#devtools-indicator, [data-nextjs-toast] { display: none !important; }';
293
+ root.appendChild(style);
294
+ }
295
+ }).catch(() => undefined);
188
296
  }
189
297
  const INIT_SCRIPT = `
190
298
  (() => {
@@ -194,86 +302,130 @@ const INIT_SCRIPT = `
194
302
  // No smooth scrolling: scrollTo() must land immediately.
195
303
  const style = document.createElement('style');
196
304
  style.setAttribute('data-pre-post', '');
197
- style.textContent = 'html, body, * { scroll-behavior: auto !important; } ::-webkit-scrollbar { display: none !important; }';
305
+ style.textContent = 'html, body, * { scroll-behavior: auto !important; }'
306
+ + ' ::-webkit-scrollbar { display: none !important; }'
307
+ + ' ${DEV_OVERLAY_SELECTORS.join(', ')} { display: none !important; }';
198
308
  const attach = () => { (document.head || document.documentElement).appendChild(style); };
199
309
  if (document.head) attach(); else document.addEventListener('DOMContentLoaded', attach, { once: true });
200
310
  })();
201
311
  `;
202
- async function getContext(viewport, scale, auth) {
203
- const key = contextKey(viewport, scale, auth);
204
- let pending = contexts.get(key);
205
- if (!pending) {
206
- pending = (async () => {
207
- const b = await getBrowser();
208
- const ctx = await b.newContext({
209
- viewport,
210
- deviceScaleFactor: scale,
211
- reducedMotion: 'reduce',
212
- colorScheme: 'light',
213
- locale: 'en-US',
214
- timezoneId: 'UTC',
215
- ignoreHTTPSErrors: true,
216
- serviceWorkers: 'block',
217
- extraHTTPHeaders: auth?.headers,
218
- bypassCSP: true,
219
- });
220
- await ctx.clock.setFixedTime(FIXED_TIME);
221
- await ctx.addInitScript(INIT_SCRIPT);
222
- if (auth?.cookies?.length) {
223
- await ctx.addCookies(auth.cookies.map(c => ({
224
- name: c.name,
225
- value: c.value,
226
- ...(c.url ? { url: c.url } : { domain: c.domain, path: c.path || '/' }),
227
- })));
228
- }
229
- ctx.setDefaultNavigationTimeout(NAVIGATION_TIMEOUT);
230
- ctx.setDefaultTimeout(10_000);
231
- return ctx;
232
- })();
233
- contexts.set(key, pending);
312
+ /**
313
+ * A context per capture, not per viewport.
314
+ *
315
+ * Playwright's clock belongs to the browser context and is replayed into every
316
+ * page opened in it, so pages that share a context do not share a starting
317
+ * point: the second page inherits the timeline the first one ran. An animated
318
+ * page then lands on a different frame depending on how many captures came
319
+ * before it. One context per capture makes every page start from the same
320
+ * paused instant — and keeps storage and caches from leaking between the two
321
+ * sides of a comparison.
322
+ */
323
+ async function createContext(viewport, scale, auth) {
324
+ const b = await getBrowser();
325
+ const ctx = await b.newContext({
326
+ viewport,
327
+ deviceScaleFactor: scale,
328
+ reducedMotion: 'reduce',
329
+ colorScheme: 'light',
330
+ locale: 'en-US',
331
+ timezoneId: 'UTC',
332
+ ignoreHTTPSErrors: true,
333
+ serviceWorkers: 'block',
334
+ extraHTTPHeaders: auth?.headers,
335
+ bypassCSP: true,
336
+ });
337
+ // Fake the page's timers and hold them still. `setFixedTime` would only pin
338
+ // what the page *reads* from Date.now(); setTimeout, setInterval and
339
+ // requestAnimationFrame would keep firing, so a timer-driven animation would
340
+ // land on whatever frame the network happened to deliver. With the clock
341
+ // installed and paused, the page's timeline does not move until
342
+ // `advanceTimeline` moves it — by the same amount on both sides.
343
+ await ctx.clock.install({ time: FIXED_TIME });
344
+ await ctx.clock.pauseAt(FIXED_TIME);
345
+ await ctx.addInitScript(INIT_SCRIPT);
346
+ if (auth?.cookies?.length) {
347
+ await ctx.addCookies(auth.cookies.map(c => ({
348
+ name: c.name,
349
+ value: c.value,
350
+ ...(c.url ? { url: c.url } : { domain: c.domain, path: c.path || '/' }),
351
+ })));
234
352
  }
235
- return pending;
353
+ ctx.setDefaultNavigationTimeout(NAVIGATION_TIMEOUT);
354
+ ctx.setDefaultTimeout(10_000);
355
+ return ctx;
236
356
  }
237
357
  // ============================================================
238
358
  // Settle
239
359
  // ============================================================
240
360
  /**
241
- * In-page settle: fonts loaded, images decoded, and layout stable across
242
- * consecutive animation frames. Bounded by `timeout` ms.
361
+ * Wait for everything that arrives on the *real* clock: fonts, images, the
362
+ * network, and the layout work that hydration does. The page's own timers stay
363
+ * frozen throughout, so waiting longer here — on a slow host, a cold cache, a
364
+ * busy machine — never advances an animation. Bounded by `timeout` ms.
243
365
  */
244
366
  async function settlePage(page, timeout, options = {}) {
245
- const settled = page.evaluate(async (timeoutMs) => {
246
- const start = performance.now();
247
- const remaining = () => Math.max(0, timeoutMs - (performance.now() - start));
248
- const sleep = (ms) => new Promise(r => setTimeout(r, ms));
249
- const frame = () => new Promise(r => requestAnimationFrame(() => r()));
250
- const withCap = (p, ms) => Promise.race([p, sleep(ms)]);
367
+ const deadline = Date.now() + timeout;
368
+ const left = () => Math.max(0, deadline - Date.now());
369
+ // Fonts and images resolve off the loading pipeline, not off page timers.
370
+ await withDeadline(page.evaluate(async () => {
251
371
  if (document.fonts?.ready)
252
- await withCap(document.fonts.ready, Math.min(2500, remaining()));
372
+ await document.fonts.ready;
253
373
  const pending = Array.from(document.images).filter(img => !img.complete);
254
- if (pending.length) {
255
- await withCap(Promise.allSettled(pending.map(img => img.decode().catch(() => undefined))), Math.min(3000, remaining()));
256
- }
257
- const signature = () => {
258
- const de = document.documentElement;
259
- return `${de.scrollHeight}:${de.scrollWidth}:${document.body?.childElementCount ?? 0}:${document.getElementsByTagName('*').length}`;
260
- };
261
- let last = signature();
262
- let stable = 0;
263
- while (stable < 2 && remaining() > 0) {
264
- await frame();
265
- await frame();
266
- const now = signature();
267
- if (now === last)
268
- stable++;
269
- else {
270
- stable = 0;
271
- last = now;
272
- }
374
+ if (pending.length)
375
+ await Promise.allSettled(pending.map(img => img.decode().catch(() => undefined)));
376
+ }), Math.min(3500, left()));
377
+ if (options.network !== false)
378
+ await waitForNetworkQuiet(page, 150, Math.min(left(), 2500));
379
+ await waitForStableLayout(page, left());
380
+ }
381
+ /** Resolve when `p` settles or `ms` elapses, whichever comes first. */
382
+ async function withDeadline(p, ms) {
383
+ let timer;
384
+ await Promise.race([
385
+ p.catch(() => undefined),
386
+ new Promise(resolve => { timer = setTimeout(resolve, ms); }),
387
+ ]);
388
+ if (timer)
389
+ clearTimeout(timer);
390
+ }
391
+ /** Cheap description of the page's structure; changes while it is still building itself. */
392
+ const LAYOUT_SIGNATURE = `(() => {
393
+ const de = document.documentElement;
394
+ return de.scrollHeight + ':' + de.scrollWidth + ':' + (document.body ? document.body.childElementCount : 0) + ':' + document.getElementsByTagName('*').length;
395
+ })()`;
396
+ /**
397
+ * Poll until the page stops restructuring itself. Polled from here rather than
398
+ * from a requestAnimationFrame loop in the page: page timers are frozen, so an
399
+ * in-page loop would never get a second frame.
400
+ */
401
+ async function waitForStableLayout(page, timeout) {
402
+ const deadline = Date.now() + timeout;
403
+ let last = null;
404
+ let stable = 0;
405
+ while (stable < 2 && Date.now() < deadline) {
406
+ const signature = await page.evaluate(LAYOUT_SIGNATURE).catch(() => last);
407
+ if (signature !== null && signature === last)
408
+ stable++;
409
+ else {
410
+ stable = 0;
411
+ last = signature;
273
412
  }
274
- }, timeout);
275
- const quiet = options.network === false ? Promise.resolve() : waitForNetworkQuiet(page, 150, Math.min(timeout, 2500));
276
- await Promise.all([settled, quiet]);
413
+ if (stable < 2)
414
+ await new Promise(resolve => setTimeout(resolve, STABILITY_POLL_MS));
415
+ }
416
+ }
417
+ /**
418
+ * Run the page's frozen timeline forward by `ms`, one frame at a time, so
419
+ * timer- and rAF-driven animation advances the same amount on every capture.
420
+ *
421
+ * A timer callback that throws is the page's own bug, not a reason to fail the
422
+ * screenshot: Playwright surfaces it here, so each frame is stepped separately
423
+ * and an error only costs that frame.
424
+ */
425
+ async function advanceTimeline(page, ms) {
426
+ for (let elapsed = 0; elapsed < ms; elapsed += FRAME_MS) {
427
+ await page.clock.runFor(Math.min(FRAME_MS, ms - elapsed)).catch(() => undefined);
428
+ }
277
429
  }
278
430
  /**
279
431
  * Resolve once no request has been in flight for `quietMs`, or after `cap` ms.
@@ -328,20 +480,26 @@ function trackRequests(page) {
328
480
  /**
329
481
  * Scroll through the page once so lazy-loaded and reveal-on-scroll content is
330
482
  * rendered before a full-page capture, then return to the top.
483
+ *
484
+ * Driven from here, a step at a time: the scrolling itself is real, but the
485
+ * frames that let observers and rAF callbacks run come out of the frozen
486
+ * timeline, so two identical pages take the same path down and back.
331
487
  */
332
488
  async function primeLazyContent(page, maxHeight) {
333
- await page.evaluate(async (limitPx) => {
334
- const frame = () => new Promise(r => requestAnimationFrame(() => r()));
489
+ const positions = await page.evaluate((limitPx) => {
335
490
  const step = Math.max(200, window.innerHeight);
336
491
  const limit = Math.min(document.documentElement.scrollHeight, limitPx);
337
- for (let y = step; y < limit + step; y += step) {
338
- window.scrollTo(0, y);
339
- await frame();
340
- await frame();
341
- }
342
- window.scrollTo(0, 0);
343
- await frame();
492
+ const ys = [];
493
+ for (let y = step; y < limit + step; y += step)
494
+ ys.push(y);
495
+ return ys;
344
496
  }, maxHeight);
497
+ for (const y of positions) {
498
+ await page.evaluate((to) => window.scrollTo(0, to), y);
499
+ await advanceTimeline(page, FRAME_MS * 2);
500
+ }
501
+ await page.evaluate(() => window.scrollTo(0, 0));
502
+ await advanceTimeline(page, FRAME_MS);
345
503
  }
346
504
  // ============================================================
347
505
  // Capture
@@ -356,36 +514,59 @@ export async function captureScreenshot(url, options) {
356
514
  const scale = options.scale ?? 2;
357
515
  const settleTimeout = options.settleTimeout ?? 8000;
358
516
  const maxHeight = options.maxHeight ?? options.viewport.height * 3;
359
- const ctx = await getContext(options.viewport, scale, options.auth);
360
517
  await acquireSlot();
361
- const page = await ctx.newPage();
362
- trackRequests(page);
518
+ // Creating the context and the page sits inside the try, so a failure there
519
+ // still releases the slot and closes what was opened. Leaking a slot would
520
+ // eventually stall every later capture waiting for one.
521
+ let ctx;
522
+ let page;
363
523
  try {
524
+ ctx = await createContext(options.viewport, scale, options.auth);
525
+ page = await ctx.newPage();
526
+ trackRequests(page);
364
527
  const response = await page.goto(url, { waitUntil: 'domcontentloaded' }).catch(err => {
365
528
  throw new NavigationError(classifyNavigationError(err), url, err);
366
529
  });
367
530
  const status = response?.status();
531
+ const vercel = response ? isVercelResponse({ get: n => response.headers()[n] ?? null }) : false;
368
532
  if (status === 401 || status === 403)
369
- throw new HttpStatusError(status, url, isVercelResponse({ get: n => response.headers()[n] ?? null }));
533
+ throw new HttpStatusError(status, url, vercel);
370
534
  await settlePage(page, settleTimeout);
371
535
  if (options.fullPage) {
372
536
  await primeLazyContent(page, maxHeight);
373
- await settlePage(page, Math.min(settleTimeout, 2000), { network: false });
537
+ await settlePage(page, Math.min(settleTimeout, 2000));
374
538
  }
539
+ // The page is loaded and quiet; now give its own timeline a fixed run so
540
+ // whatever it animates lands on the same frame here as on the other side.
541
+ await advanceTimeline(page, TIMELINE_BUDGET_MS);
542
+ // Timers that just fired may have asked for more content; let it arrive.
543
+ await settlePage(page, Math.min(settleTimeout, 2000));
544
+ // Only now look for the selector: an element mounted by a timer does not
545
+ // exist until that timer has fired, and with the clock held that is not
546
+ // until the budget above has run.
375
547
  if (options.selector) {
376
548
  const locator = page.locator(options.selector);
377
549
  if ((await locator.count()) === 0)
378
550
  throw new Error(`Element not found: ${options.selector}`);
379
551
  await locator.first().scrollIntoViewIfNeeded();
552
+ await advanceTimeline(page, FRAME_MS * 2);
380
553
  }
381
- if (options.wait)
554
+ // `--wait` means "give this page longer": real time for anything still in
555
+ // flight, and the same again on the page's timeline for anything animating.
556
+ if (options.wait) {
382
557
  await page.waitForTimeout(options.wait);
558
+ await advanceTimeline(page, options.wait);
559
+ }
383
560
  let clip;
384
561
  if (options.fullPage) {
385
562
  const height = await page.evaluate(() => document.documentElement.scrollHeight);
386
563
  if (height > maxHeight)
387
564
  clip = { x: 0, y: 0, width: options.viewport.width, height: maxHeight };
388
565
  }
566
+ // Where the browser actually ended up: a sign-in wall answers with 200
567
+ // after a redirect, so the status says nothing.
568
+ const finalUrl = page.url();
569
+ await hideDevIndicator(page);
389
570
  const image = await page.screenshot({
390
571
  type: 'png',
391
572
  fullPage: options.fullPage ?? false,
@@ -394,17 +575,30 @@ export async function captureScreenshot(url, options) {
394
575
  clip,
395
576
  timeout: 20_000,
396
577
  });
578
+ // What the page calls itself, and what it says: the title recognises a
579
+ // sign-in wall that answered 200, the text tells a redesign of this site
580
+ // from a different site altogether. One round trip, and strictly after the
581
+ // screenshot — reading the page must not be able to influence the pixels
582
+ // the run is about to compare.
583
+ const { title, text } = await page
584
+ .evaluate(() => ({ title: document.title, text: document.body?.innerText ?? '' }))
585
+ .catch(() => ({ title: '', text: '' }));
397
586
  return {
398
587
  image,
399
588
  viewport: options.viewport,
400
589
  url,
401
590
  status,
591
+ finalUrl,
592
+ title,
593
+ text,
594
+ vercel,
402
595
  selector: options.selector,
403
596
  durationMs: Date.now() - started,
404
597
  };
405
598
  }
406
599
  finally {
407
- await page.close().catch(() => undefined);
600
+ await page?.close().catch(() => undefined);
601
+ await ctx?.close().catch(() => undefined);
408
602
  releaseSlot();
409
603
  }
410
604
  }
@@ -424,7 +618,7 @@ function classifyNavigationError(err) {
424
618
  export async function closeBrowser() {
425
619
  const b = browser;
426
620
  browser = null;
427
- contexts.clear();
621
+ launching = null;
428
622
  activePages = 0;
429
623
  pageQueue.length = 0;
430
624
  if (b)