macOS Window Visual QA
Treat visual QA as a reproducible test, not a screenshot hunt. Produce an identified target, a valid image artifact, measurable layout evidence, and a concise verdict.
Set the inspection contract
Before capturing anything, record:
- app, window, screen, route, or component under inspection;
- exact UI state and required test data;
- viewport size in points and appearance (
light or dark);
- defects or invariants to check;
- evidence output directory.
Use the user's screenshot as the baseline when one exists. Inspect it first; do not recapture the same broken state merely to obtain your own copy.
Choose one capture route
- Source-level render — preferred. For an editable SwiftUI/AppKit project, render the real production view in a fixed-size
NSHostingView attached to an NSWindow. Assert geometry in the same test and export PNG evidence. Read references/swiftui-xctest-rendering.md before implementing this route.
- Exact live window. Use this when window chrome, toolbar integration, launch state, focus, or a non-source app matters. Resolve the window before capture with scripts/macos-window-capture.
- Existing artifact. If the user supplied a screenshot and no post-change evidence is needed, inspect it directly with the image-viewing tool.
Do not use a full-screen screenshot as a substitute for a window-level request. Do not use browser capture for a native macOS window.
Capture an exact live window
First probe candidates without writing an image:
zsh /absolute/path/to/scripts/macos-window-capture list --owner "App Name"
Run live-window probing with WindowServer access. In Codex's restricted shell, an empty result can be a sandbox artifact; if the app process is known to exist, rerun the same probe once with the tool's sandbox escalation instead of changing capture utilities.
Require a layer-0, on-screen candidate with plausible bounds. Refine ambiguous results with --title-contains, --pid, or use the reported --window-id. Prefer --pid for development builds without a stable app bundle name. A missing title can indicate unavailable Screen Recording metadata; PID and window ID remain usable.
Then capture once:
zsh /absolute/path/to/scripts/macos-window-capture capture \
--owner "App Name" \
--title-contains "Document or Page" \
--output /absolute/evidence/window.png
The wrapper supplies an isolated Swift module cache, so it also works in restricted Codex shells. The script rejects zero matches, ambiguous matches, existing output paths, blank or invalid files, implausibly small captures, and dimension mismatches. Use --window-id ID when the target has already been resolved. Run help for all options.
Enforce the retry budget
- Never rerun an unchanged failed capture command.
- Allow at most one attempt per distinct route before diagnosing the failure.
- If no candidate exists, verify app/process state and launch or navigate once. Probe again once; then stop.
- If a known process has no candidates in a restricted shell, request WindowServer access and repeat that probe once. This is a permission diagnosis, not a reason to switch tools.
- If capture fails while a valid candidate exists, treat Screen Recording permission as the likely blocker. Report it and request the required macOS permission; do not cycle through screenshot utilities.
- If the output is blank, corrupt, implausibly small, or the wrong dimensions, reject it. Fix the identified cause before another capture.
- Do not take repeated images hoping one will look right. Multiple captures are allowed only for a declared matrix such as light/dark, breakpoints, or before/after.
Inspect and measure
After the capture command succeeds:
- Open the PNG with the image-viewing tool. A successful command alone is not visual verification.
- Confirm app/window identity, expected state, dimensions, and appearance.
- Check content priority, clipping, overlap, occlusion, line wrapping, scrolling, icon/text centering, contrast, and loading/error states.
- When source is available, turn every objective defect into an assertion: frame relationships, minimum readable width/height, scroll range, insets, hit target bounds, or visibility policy.
- Verify all specified sizes and both appearances when relevant. Do not generalize from a single viewport.
Prefer frame conversion into one coordinate space before comparing geometry. Account for flipped AppKit coordinates explicitly.
Completion gate
Do not claim the visual issue is fixed unless all are true:
- the exact production view or exact live target was captured;
- the PNG was validated and visually inspected;
- relevant geometry assertions pass;
- the required viewport/appearance matrix was checked;
- the evidence path and commands are reported;
- project-required tests and builds pass.
If any item is blocked, name the missing item and the single blocking condition. Never hide the blocker behind more screenshot attempts.
1---2name: macos-window-visual-qa3description: Deterministic visual QA for macOS application windows and SwiftUI/AppKit views. Use when Codex must capture or inspect a specific native app window, reproduce layout defects, verify clipping, overlap, scrolling, alignment, responsive columns, or light/dark appearance, especially when earlier screenshot attempts cannot find the window or keep switching capture methods. Prefer a source-level fixed-size render with geometry assertions; otherwise identify and capture one exact live window, validate the artifact, and stop blind retries.4---56# macOS Window Visual QA78Treat visual QA as a reproducible test, not a screenshot hunt. Produce an identified target, a valid image artifact, measurable layout evidence, and a concise verdict.910## Set the inspection contract1112Before capturing anything, record:1314- app, window, screen, route, or component under inspection;15- exact UI state and required test data;16- viewport size in points and appearance (`light` or `dark`);17- defects or invariants to check;18- evidence output directory.1920Use the user's screenshot as the baseline when one exists. Inspect it first; do not recapture the same broken state merely to obtain your own copy.2122## Choose one capture route23241. **Source-level render — preferred.** For an editable SwiftUI/AppKit project, render the real production view in a fixed-size `NSHostingView` attached to an `NSWindow`. Assert geometry in the same test and export PNG evidence. Read [references/swiftui-xctest-rendering.md](references/swiftui-xctest-rendering.md) before implementing this route.252. **Exact live window.** Use this when window chrome, toolbar integration, launch state, focus, or a non-source app matters. Resolve the window before capture with [scripts/macos-window-capture](scripts/macos-window-capture).263. **Existing artifact.** If the user supplied a screenshot and no post-change evidence is needed, inspect it directly with the image-viewing tool.2728Do not use a full-screen screenshot as a substitute for a window-level request. Do not use browser capture for a native macOS window.2930## Capture an exact live window3132First probe candidates without writing an image:3334```bash35zsh /absolute/path/to/scripts/macos-window-capture list --owner "App Name"36```3738Run live-window probing with WindowServer access. In Codex's restricted shell, an empty result can be a sandbox artifact; if the app process is known to exist, rerun the same probe once with the tool's sandbox escalation instead of changing capture utilities.3940Require a layer-0, on-screen candidate with plausible bounds. Refine ambiguous results with `--title-contains`, `--pid`, or use the reported `--window-id`. Prefer `--pid` for development builds without a stable app bundle name. A missing title can indicate unavailable Screen Recording metadata; PID and window ID remain usable.4142Then capture once:4344```bash45zsh /absolute/path/to/scripts/macos-window-capture capture \46 --owner "App Name" \47 --title-contains "Document or Page" \48 --output /absolute/evidence/window.png49```5051The wrapper supplies an isolated Swift module cache, so it also works in restricted Codex shells. The script rejects zero matches, ambiguous matches, existing output paths, blank or invalid files, implausibly small captures, and dimension mismatches. Use `--window-id ID` when the target has already been resolved. Run `help` for all options.5253## Enforce the retry budget5455- Never rerun an unchanged failed capture command.56- Allow at most one attempt per distinct route before diagnosing the failure.57- If no candidate exists, verify app/process state and launch or navigate once. Probe again once; then stop.58- If a known process has no candidates in a restricted shell, request WindowServer access and repeat that probe once. This is a permission diagnosis, not a reason to switch tools.59- If capture fails while a valid candidate exists, treat Screen Recording permission as the likely blocker. Report it and request the required macOS permission; do not cycle through screenshot utilities.60- If the output is blank, corrupt, implausibly small, or the wrong dimensions, reject it. Fix the identified cause before another capture.61- Do not take repeated images hoping one will look right. Multiple captures are allowed only for a declared matrix such as light/dark, breakpoints, or before/after.6263## Inspect and measure6465After the capture command succeeds:66671. Open the PNG with the image-viewing tool. A successful command alone is not visual verification.682. Confirm app/window identity, expected state, dimensions, and appearance.693. Check content priority, clipping, overlap, occlusion, line wrapping, scrolling, icon/text centering, contrast, and loading/error states.704. When source is available, turn every objective defect into an assertion: frame relationships, minimum readable width/height, scroll range, insets, hit target bounds, or visibility policy.715. Verify all specified sizes and both appearances when relevant. Do not generalize from a single viewport.7273Prefer frame conversion into one coordinate space before comparing geometry. Account for flipped AppKit coordinates explicitly.7475## Completion gate7677Do not claim the visual issue is fixed unless all are true:7879- the exact production view or exact live target was captured;80- the PNG was validated and visually inspected;81- relevant geometry assertions pass;82- the required viewport/appearance matrix was checked;83- the evidence path and commands are reported;84- project-required tests and builds pass.8586If any item is blocked, name the missing item and the single blocking condition. Never hide the blocker behind more screenshot attempts.