Skip to content

Export editable screenshot layers - #2049

Merged
stefan-burke merged 20 commits into
mainfrom
screenshot-layers
Aug 8, 2026
Merged

stefan-burke merged 20 commits into
mainfrom
screenshot-layers

Conversation

@stefan-burke

@stefan-burke stefan-burke commented Aug 7, 2026

Copy link
Copy Markdown
Member

What changed

External screenshot scenarios can export separate background, controls, and text PNG files. The files reproduce the companion normal screenshot when stacked, so each part can be edited without changing the final image.

Layering handles native and hidden controls, selection highlights, generated text and images, clipped paint, border images, scrollbars, SVG and embedded content, open shadow roots, CSS masks, and grouped paint such as opacity, filters, backdrop filters, and blend modes. Pages with modal dialogs or popovers stay together so translucent overlays keep the browser paint order. Direct text under page and shadow roots also stays unchanged without adding styleable wrapper elements.

Capture waits for pending page requests before it starts. Page timers, animation callbacks, CSS animations, and transitions pause while the three editable layers are captured. Paint marks are installed once for the complete sequence, so page observers cannot change visible state between frames. The companion normal PNG is built from those exact frames, so video, animated images, and other media cannot show a different moment. Element captures use one preliminary image only to calculate shared crop bounds.

Temporary screenshot styles load from the same site under the production content security policy and inside open shadow roots. Cleanup runs after success or failure, and reports both the capture and cleanup errors when both fail. Scenarios can capture the site before admin setup without starting Stripe, and app ports stay reserved until each process starts.

Checks

  • nix develop -c deno task test:screenshot-contract (59 browser steps)
  • nix develop -c deno task precommit
  • nix develop -c deno task mutation src/shared/db/built-sites/blob.ts test/shared/db/built-sites/blob.test.ts --harness (17/17 mutants killed)

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Screenshot scenarios can skip admin setup and optionally generate transparent background, controls, and text layers. The capture pipeline adds layer masking, deterministic timing, element cropping, PNG padding, CLI validation, lazy server startup, and schema validation.

Changes

Screenshot layering

Layer / File(s) Summary
Scenario controls and capture wiring
scripts/screenshots.ts, scripts/screenshots/options.ts, scripts/screenshots/scenario.ts, test/fixtures/screenshots/scenarios/*, test/scripts/screenshots-options.test.ts, test/scripts/screenshots-scenario.test.ts, README.md, scripts/screenshots/readiness.ts, test/scripts/screenshots-readiness.test.ts, deno.json
Scenario validation uses Valibot and supports adminSetup. The CLI accepts --layers only with a scenario. Scenario capture forwards the option, injects capture CSS when required, waits for networkidle, and writes layer files.
Layer preparation and image output
scripts/screenshots/layers.ts, scripts/screenshots/capture.ts, scripts/screenshots/image.ts, src/ui/static/style.scss, test/scripts/screenshots-capture.test.ts, test/scripts/screenshots-image.test.ts
Layer styles classify and mask page paint across open shadow roots. Prepared captures freeze timers, omit backgrounds, crop element layers, and restore temporary styles and callbacks.
Browser layer contracts
test/scripts/screenshots-browser-helpers.ts, test/scripts/screenshots-browser.contract.ts, test/scripts/screenshots-layers-browser.contract.ts, test/scripts/screenshots-boundaries-browser.contract.ts, test/scripts/screenshots-compositing-browser.contract.ts, test/scripts/screenshots-edge-layers-browser.contract.ts, test/scripts/screenshots-scrollbars-browser.contract.ts
Browser contracts verify layer visibility, compositing, shadow-root behavior, controls, text, SVG, embedded content, CSP pages, imported styles, and scrollbars.

Screenshot runtime infrastructure

Layer / File(s) Summary
Lazy server startup and port reservation
scripts/screenshots/server.ts, scripts/screenshots/app-server.ts, scripts/stripe-mock.ts, test/scripts/screenshots-server.test.ts, test/scripts/stripe-mock/ports.test.ts
The screenshot server reserves application and Stripe ports, starts the Stripe mock on first use, and registers cleanup for started resources.

Built-site blob validation

Layer / File(s) Summary
Scheduled task key validation
src/shared/db/built-sites/blob.ts
The optional scheduled task key uses optionalStringThat for validation.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ScreenshotCLI
  participant captureScenario
  participant capturePreparedLayers
  participant withScreenshotLayer
  participant PNGUtilities
  ScreenshotCLI->>captureScenario: forward layers option
  captureScenario->>capturePreparedLayers: capture configured layers
  capturePreparedLayers->>withScreenshotLayer: apply layer stylesheet and paint markers
  withScreenshotLayer->>capturePreparedLayers: return masked PNG
  capturePreparedLayers->>PNGUtilities: crop element layer
  PNGUtilities-->>captureScenario: return layer PNG record
  captureScenario-->>ScreenshotCLI: write layer PNG files
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the primary change: exporting editable screenshot layers.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch screenshot-layers
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch screenshot-layers

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/screenshots/layers.ts`:
- Around line 12-13: Update CONTROL_LETTERING_SELECTOR to include select so
selected values are excluded from overlapping layers. Extend the text-layer
styling rules to clear relevant visual properties on ::before and ::after,
preventing pseudo-element backgrounds, borders, and shadows from leaking into
the text layer. Add rendering regression cases covering a select control and
pseudo-element decoration, each reproducing the overlap and failing before the
fix.

In `@scripts/screenshots/scenario.ts`:
- Around line 29-30: Update the screenshot scenario loading boundary to define
and use a Valibot schema for the scenario shape, parse loaded.default, and
return the parsed result before passing it to captureScenario. Move the
elementSelector/fullPage cross-field validation to run after parsing, preserving
that existing check against the validated data.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: b3b48288-2169-4439-9ab7-ab00b10b5148

📥 Commits

Reviewing files that changed from the base of the PR and between 32a4257 and cacaee2.

📒 Files selected for processing (13)
  • README.md
  • scripts/screenshots.ts
  • scripts/screenshots/capture.ts
  • scripts/screenshots/image.ts
  • scripts/screenshots/layers.ts
  • scripts/screenshots/options.ts
  • scripts/screenshots/scenario.ts
  • test/fixtures/screenshots/scenarios/invalid-admin-setup.ts
  • test/fixtures/screenshots/scenarios/with-username.ts
  • test/scripts/screenshots-capture.test.ts
  • test/scripts/screenshots-image.test.ts
  • test/scripts/screenshots-options.test.ts
  • test/scripts/screenshots-scenario.test.ts

Comment thread scripts/screenshots/layers.ts Outdated
Comment thread scripts/screenshots/scenario.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cacaee2bc4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/screenshots/layers.ts Outdated
Comment thread scripts/screenshots/layers.ts Outdated
Comment thread scripts/screenshots/layers.ts Outdated
Comment thread scripts/screenshots/layers.ts Outdated
Comment thread scripts/screenshots/layers.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/screenshots/layers.ts`:
- Around line 17-25: Update the masking CSS in scripts/screenshots/layers.ts at
lines 17-25 and 34-39: add transparent -webkit-text-stroke-color and
text-decoration-color alongside the existing text color masking for both body
text and control lettering. Add browser regression cases covering explicit
stroke and decoration colors.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: f8c373b1-a65e-439c-bd27-0ebce30226c4

📥 Commits

Reviewing files that changed from the base of the PR and between cacaee2 and cab8079.

📒 Files selected for processing (4)
  • scripts/screenshots/layers.ts
  • scripts/screenshots/scenario.ts
  • src/shared/db/built-sites/blob.ts
  • test/scripts/screenshots-browser.contract.ts

Comment thread scripts/screenshots/layers.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cab8079281

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/screenshots/layers.ts
Comment thread scripts/screenshots/layers.ts
Comment thread scripts/screenshots/layers.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ac39b84f7c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/screenshots/layers.ts
Comment thread scripts/screenshots/layers.ts
Comment thread scripts/screenshots/layers.ts Outdated
Comment thread scripts/screenshots/layers.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7d3dd1ff8c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/screenshots/layers.ts Outdated
Comment thread scripts/screenshots/image.ts Outdated
Comment thread scripts/screenshots.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8da8c5c68b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/screenshots/layers.ts Outdated
Comment thread scripts/screenshots/layers.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 76d7c6b8a6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/screenshots/layers.ts Outdated
Comment thread scripts/screenshots/layers.ts Outdated
Comment thread scripts/screenshots/layers.ts Outdated
Comment thread scripts/screenshots/layers.ts Outdated
Comment thread scripts/screenshots/layers.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/screenshots/layers.ts`:
- Around line 41-45: Extend the masking selector rule in the screenshot layer
styling to include descendant pseudo-elements via *::before and *::after,
ensuring nested control content such as button span::after is hidden. Add a
browser regression test covering explicit text paint on a descendant
pseudo-element, and verify it fails without the selector change and passes with
it.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 1220010f-b49c-443d-a823-4cdc4bad1e84

📥 Commits

Reviewing files that changed from the base of the PR and between ac39b84 and 2a8ffe5.

📒 Files selected for processing (10)
  • deno.json
  • scripts/screenshots.ts
  • scripts/screenshots/capture.ts
  • scripts/screenshots/image.ts
  • scripts/screenshots/layers.ts
  • test/scripts/screenshots-browser-helpers.ts
  • test/scripts/screenshots-browser.contract.ts
  • test/scripts/screenshots-capture.test.ts
  • test/scripts/screenshots-image.test.ts
  • test/scripts/screenshots-layers-browser.contract.ts

Comment thread scripts/screenshots/layers.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2a8ffe5f7f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/screenshots/layers.ts Outdated
Comment thread scripts/screenshots.ts
Comment thread scripts/screenshots/layers.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 836a890c3b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/screenshots/layers.ts Outdated
Comment thread scripts/screenshots/layers.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a46121d57a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/screenshots/layers.ts Outdated
Comment thread scripts/screenshots/layers.ts Outdated
Comment thread scripts/screenshots/layers.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4b644ade1b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/screenshots/layers.ts Outdated
Comment thread scripts/screenshots/layers.ts Outdated
Comment thread scripts/screenshots/layers.ts Outdated
Comment thread scripts/screenshots/layers.ts Outdated
Comment thread scripts/screenshots/app-server.ts Outdated
Comment thread scripts/screenshots/layers.ts Outdated
@stefan-burke
stefan-burke added this pull request to the merge queue Aug 7, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b76140c524

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/screenshots/layers.ts Outdated
Comment thread scripts/screenshots/layers.ts Outdated
Comment thread scripts/screenshots/layers.ts Outdated
Comment thread scripts/screenshots/layers.ts Outdated
Comment thread scripts/screenshots/layers.ts Outdated
Comment thread scripts/screenshots/capture.ts
Comment thread scripts/screenshots/layers.ts
Comment thread scripts/screenshots/layers.ts
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Aug 7, 2026
@stefan-burke stefan-burke changed the title Add editable screenshot layers Export editable screenshot layers Aug 7, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b33a4e2390

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/screenshots/layers.ts
Comment thread scripts/screenshots/capture.ts
Comment thread scripts/screenshots/layers.ts Outdated
Comment thread scripts/screenshots/capture.ts Outdated
Comment thread scripts/screenshots/layers.ts Outdated
Comment thread scripts/screenshots/capture.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 15

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/screenshots/layers.ts`:
- Around line 327-344: Update visitRoot so shadow-root traversal passes the
effective paint mark, falling back to inheritedPaint when paintMark(element)
returns null; preserve the host’s own mark when present. Add a layer contract
case covering an opacity group containing a shadow host and assert the shadow
content receives the inherited mark.
- Line 52: Update the controls background reset rule in the layer stylesheet to
append the existing LAYER_PRIORITY suffix to the html/body selector, matching
the other rules and ensuring it outranks competing important cascade-layer
rules.

In `@src/ui/static/style.scss`:
- Line 5: Document the required coupling above the `@layer` declaration by adding
a short comment stating that the literal __screenshot_layer__ must remain
identical to SCREENSHOT_LAYER in scripts/screenshots/layers.ts. Leave the layer
name and declaration unchanged.

In `@test/scripts/screenshots-boundaries-browser.contract.ts`:
- Around line 34-44: Update the shadowStyle layer parameter to use the existing
exported ScreenshotLayerName type from screenshots-browser-helpers.ts instead of
the duplicated inline union. Confirm the type’s export and import path, then
reuse it without changing the helper’s behavior.

In `@test/scripts/screenshots-browser-helpers.ts`:
- Around line 20-38: Update countRgbPixels to include the alpha channel in its
per-pixel match, counting a pixel only when its alpha value is nonzero in
addition to matching the requested RGB values. Preserve the existing RGB
matching and channel iteration behavior.

In `@test/scripts/screenshots-capture.test.ts`:
- Around line 145-152: Update the document mock’s querySelectorAll
implementation to retain only the "*" branch returning elements and the
link[...] branch returning an empty array; remove the unreachable "html, body,
body *" condition and the attributes-based fallback.
- Around line 235-248: Update the screenshot assertions to import and reuse the
production SCREENSHOT_LAYER_NAMES constant: replace the hard-coded expected
layer-name array with [...SCREENSHOT_LAYER_NAMES], and derive the style-removal
expectation from SCREENSHOT_LAYER_NAMES.length + 1. Keep the existing assertion
ordering and other expectations unchanged.

In `@test/scripts/screenshots-compositing-browser.contract.ts`:
- Around line 211-217: Replace the fixed setTimeout delay between the two ticks
reads with page.waitForFunction that polls until globalThis.ticks differs from
beforeAdvance. Preserve the existing beforeAdvance capture and final inequality
assertion, and avoid any real-time sleep.
- Around line 152-155: Replace the setTimeout-based delay in the page.route
handler for the screenshots.test/value request with a manually controlled
promise gate that keeps the request pending until the test explicitly releases
it. Add a concise comment documenting that the gate is required to validate the
networkidle contract, while preserving the existing Ready response after
release.

In `@test/scripts/screenshots-layers-browser.contract.ts`:
- Around line 136-141: Update the color assertion in the CSP test callback
around layerStyle to use toBe with the deterministic masked color value instead
of not.toBe("rgb(255, 0, 0)"). Preserve the existing layerStyle invocation and
assert the exact expected result.
- Around line 265-297: Extract the duplicated
addScreenshotStyle/assert/layerStyle/cleanup flow from the tests into a shared
helper accepting the CSS text and expected colour. Update both “preserves
imports in screenshot CSS” and “adds screenshot CSS on a page with a URL
fragment” to invoke that helper while preserving their existing page setup and
assertions.

In `@test/scripts/screenshots-layers.test.ts`:
- Around line 155-190: Move global restoration out of the mocked page.unroute
implementation: have setupPage return the created globals stash alongside its
existing page and observable helpers, then restore that stash from an afterEach
hook covering the tests. Keep unroute focused on setting removedRoute and
returning its promise, preserving unrouted as the signal that cleanup ran.

In `@test/scripts/screenshots-scrollbars-browser.contract.ts`:
- Around line 12-18: Replace the local Chromium launch in the scrollbar contract
with a launcher exported from screenshots-browser-helpers.ts. Extend
defineScreenshotBrowserLauncher to accept the ignoreDefaultArgs override, create
a second shared launcher configured with ["--hide-scrollbars"], and have this
test use it while preserving the standard launchScreenshotBrowser behavior.

In `@test/scripts/screenshots-server.test.ts`:
- Line 47: In the cleanup sequence, replace the optional invocation of
cleanups[0] with a direct call, since the preceding setup guarantees it exists.
Preserve the existing cleanup ordering while allowing invalid state to fail
immediately.

In `@test/scripts/stripe-mock/ports.test.ts`:
- Around line 28-40: Update the “keeps a reserved port unavailable until
release” test to call reserved.release() twice before rebinding. Store the
Deno.listen result and close it in a finally block, then release the reservation
there as cleanup, while preserving the existing assertion that binding fails
before release.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 8a99039f-4165-44ca-a23e-b7d5992f6ea0

📥 Commits

Reviewing files that changed from the base of the PR and between 2a8ffe5 and 5d6f1a4.

📒 Files selected for processing (21)
  • scripts/screenshots.ts
  • scripts/screenshots/app-server.ts
  • scripts/screenshots/capture.ts
  • scripts/screenshots/layers.ts
  • scripts/screenshots/readiness.ts
  • scripts/screenshots/server.ts
  • scripts/stripe-mock.ts
  • src/ui/static/style.scss
  • test/scripts/screenshots-boundaries-browser.contract.ts
  • test/scripts/screenshots-browser-helpers.ts
  • test/scripts/screenshots-browser.contract.ts
  • test/scripts/screenshots-capture-clock.test.ts
  • test/scripts/screenshots-capture.test.ts
  • test/scripts/screenshots-compositing-browser.contract.ts
  • test/scripts/screenshots-edge-layers-browser.contract.ts
  • test/scripts/screenshots-layers-browser.contract.ts
  • test/scripts/screenshots-layers.test.ts
  • test/scripts/screenshots-readiness.test.ts
  • test/scripts/screenshots-scrollbars-browser.contract.ts
  • test/scripts/screenshots-server.test.ts
  • test/scripts/stripe-mock/ports.test.ts

Comment thread scripts/screenshots/layers.ts Outdated
Comment thread scripts/screenshots/layers.ts
Comment thread src/ui/static/style.scss
Comment thread test/scripts/screenshots-boundaries-browser.contract.ts Outdated
Comment thread test/scripts/screenshots-browser-helpers.ts
Comment thread test/scripts/screenshots-layers-browser.contract.ts
Comment thread test/scripts/screenshots-layers.test.ts
Comment thread test/scripts/screenshots-scrollbars-browser.contract.ts Outdated
Comment thread test/scripts/screenshots-server.test.ts Outdated
Comment thread test/scripts/stripe-mock/ports.test.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5d6f1a44bf

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/screenshots/layers.ts
Comment thread scripts/screenshots/capture.ts Outdated
Comment thread scripts/screenshots/layers.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7e78e7dfea

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/screenshots/capture.ts Outdated
Comment thread scripts/screenshots/capture.ts
Comment thread scripts/screenshots/layers.ts
Comment thread scripts/screenshots/layers.ts
Comment thread scripts/screenshots/layers.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 388c8c72d7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/screenshots/image.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 66570ddb1b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/screenshots/layers.ts Outdated
Comment thread scripts/screenshots/layers.ts
Comment thread scripts/screenshots/layers.ts
Comment thread scripts/screenshots/capture.ts Outdated
Comment thread scripts/screenshots/layers.ts Outdated
@stefan-burke
stefan-burke added this pull request to the merge queue Aug 8, 2026
Merged via the queue into main with commit 604fc28 Aug 8, 2026
3 checks passed
@stefan-burke
stefan-burke deleted the screenshot-layers branch August 8, 2026 04:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant