Skip to content

feat: leave elements out of a shot with hide - #7

Merged
jackchuka merged 5 commits into
mainfrom
feat/shot-hide
Nov 10, 2026
Merged

jackchuka merged 5 commits into
mainfrom
feat/shot-hide

Conversation

@jackchuka

@jackchuka jackchuka commented Nov 10, 2026 •

Copy link
Copy Markdown
Member

Summary

guide.shot takes a new hide option: locators whose elements are left out of the shot with display: none.

mask keeps an element's box and paints over it, which suits values that change in place. Some elements should not be in the shot at all, such as rows that other tests or earlier runs created. Locale projects that run in parallel against one backend see each other's data, so these rows come and go between runs and change the image every time. A masked row would still leave a grey row behind.

  • A hide locator may match no element or several (elementHandles), unlike a highlight.
  • Each matched element's inline display is set to none, rather than adding a stylesheet:
    • Playwright applies the screenshot's style only while the shot is taken, so the crop would be measured with the elements still there and land in the wrong place.
    • An injected <style> would be blocked by a strict CSP (setting a style property directly is not), and would not reach shadow roots or frames, which locators do.
  • After the shot the same elements get their old display back, in reverse order so an element matched twice ends up as it was, even if the locators match other elements by then. An element that had no style attribute is left without one. If hiding fails partway, the elements hidden so far are restored.
  • Caveat, documented: a page rule with display: ... !important wins over the inline value; hide such an element with style.

Docs

  • hide is added to the guide.shot options table and example.
  • A new recipe, "Keep shots stable", lists what changes between runs and what to do about each: the clock, unique values, data from other tests, toasts and banners, animations, fonts, and rendering noise. It explains when to use mask, hide and style.

Test plan

  • pnpm test: 161 passed
  • pnpm run test:browser: 120 passed, including three new captureShot tests: hidden elements come back as they were (an inline display, an element matched twice, no leftover style attribute); a shadow root; several matches, with the crop measured without them
  • pnpm run typecheck, pnpm run lint, pnpm run check:pkg

guide.shot takes hide: locators whose elements are left out of the shot
with display: none, for data chosen by content such as rows other tests
created. A locator may match no element or several. The rule goes into
the page instead of the screenshot's style, so the crop is measured with
the elements gone.

The README gains a recipe on keeping shots stable between runs.
An injected <style> is blocked by a strict CSP and does not reach shadow
roots or frames, which locators do. Set each matched element's inline
display instead, restore the same elements in reverse order after the
shot, and leave no empty style attribute behind.
@jackchuka
jackchuka marked this pull request as ready for review November 10, 2026 06:28
@jackchuka
jackchuka requested a review from a team as a code owner November 10, 2026 06:28

@IzumiSy IzumiSy 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.

Approving this PR, as I think the hide option is useful. That said, if the goal is to control which data appears in the UI, shouldn't we allow each test to configure its seed or mock data instead, rather than hiding unwanted rows during screenshot capture?

@jackchuka

Copy link
Copy Markdown
Member Author

Thanks @IzumiSy! Agreed: keeping each test's data apart is the real fix, and hide should be the fallback. I reworded the "Keep shots stable" recipe in 2de5550 so it first recommends giving each guide its own data (create it in the test or a fixture, give each locale project its own account or workspace, or answer the requests with page.route), and only then hide for cases where the data cannot be kept apart, such as locale projects that run in parallel against one backend.

I did not add a seed or mock mechanism to e2g itself, since guides are plain Playwright tests and fixtures and page.route already cover that.

@jackchuka
jackchuka merged commit 9660e69 into main Nov 10, 2026
5 checks passed
@jackchuka
jackchuka deleted the feat/shot-hide branch November 10, 2026 07:02
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.

2 participants