feat: add --color-scheme so themed sites can be captured as authored - #7
Conversation
A site that follows the OS theme has no theme of its own to report, and headless Chromium resolves `prefers-color-scheme` to light. Every capture of such a site therefore came back light, whatever its authors actually look at all day. There was no way to ask for the other face. `--color-scheme <light|dark|no-preference>` sets what the browser reports. It is applied to both context-creation sites — the screenshot workers in `service.ts` and the video recorder in `video.ts` — so a run's stills and its footage cannot disagree with each other. The default is `light`, matching Playwright's own default, so existing captures are byte-for-byte unaffected. Verified end to end against a next-themes app on `system`: the same route captured at 1280x800 has a mean grey level of 0.94 under `--color-scheme light` and 0.08 under `--color-scheme dark`. Note for a follow-up: `CaptureConfigOverrides` in schemas.ts is a hand-written Partial that duplicates `CaptureConfigFields`, and adding a field to one without the other type-errors only at the call site. Deriving it would remove that step. Left alone here to keep this change to one subject.
|
👋 Hi @WomB0ComB0, thanks for the pull request! A scan flagged some concerns with it. Could you please take a look? [pr-task-completion] This PR's body is missing
Repositories often provide a set of tasks that pull request authors are expected to complete. Those tasks should be marked as completed with a [pr-linked-issue] This pull request is not linked as closing any issues. This repository keeps to GitHub issues for discussing potential changes. Most or all changes should be marked as approved in an issue before a pull request is sent to resolve them. To resolve this report:
|
The problem
A site that follows the OS theme has no theme of its own to report, and headless Chromium resolves
prefers-color-schemeto light. Every capture of such a site came back light — whatever its authors actually look at all day — and there was no way to ask for the other face.I hit this capturing a
next-themesapp that defaults tosystem. The screenshots were unusable for showing the team, because they showed a version of the product nobody on it has ever seen.The change
--color-scheme <light|dark|no-preference>sets what the browser reports.It is applied at both context-creation sites — the screenshot workers in
service.tsand the video recorder invideo.ts— so a run's stills and its footage cannot disagree with each other.The default is
light, matching Playwright's own default, so existing captures are byte-for-byte unaffected.Verification
Beyond the unit tests, I checked that the flag reaches the pixels. Same route, same viewport (1280x800), same server, only the flag differs:
--color-schemelightdarkTests
Three cases in
runner.test.ts: the default stays unset soCaptureConfig.Defaultapplies, each of the three schemes parses, and a scheme Playwright would reject (midnight) throws rather than reaching the browser.tsc,biome check,markdownlint, and the full suite (55 passed, 1 skipped) are green.One thing I noticed but did not fix
CaptureConfigOverridesinschemas.tsis a hand-writtenPartial<{...}>that duplicatesCaptureConfigFields. Adding a field to the schema without adding it there compiles fine until a call site uses it — which is exactly how this change failed first. Deriving the type from the fields object would remove that step. Left alone to keep this PR to one subject; happy to follow up.Possible follow-up
Capturing both schemes in one run would be more useful than running twice with two
--output-dirs, but the output paths ({viewport}_{w}x{h}_{timestamp}) have no room for a scheme segment, so it would change the on-disk layout and the report shape. That felt like a separate decision that is yours to make.