Skip to content

feat: hide, remove and mask regions from every SDK - #403

Merged
gregberge merged 8 commits into
mainfrom
greg/arg-520-ignore-regions-in-screenshot-comparisons
Oct 21, 2026
Merged

gregberge merged 8 commits into
mainfrom
greg/arg-520-ignore-regions-in-screenshot-comparisons

Conversation

@gregberge

@gregberge gregberge commented Oct 21, 2026 •

Copy link
Copy Markdown
Member

Description

Part of ARG-520. You can now hide, remove or mask dynamic elements straight from argosScreenshot, without adding data-visual-test attributes to the application, in every SDK:

argosScreenshot(page, "dashboard", {
  hide: ["#clock", page.getByTestId("avatar")], // like data-visual-test="transparent": keeps its space
  remove: [".cookie-banner"], // like data-visual-test="removed": takes no space
  mask: ["#map"], // like data-visual-test="blackout": covered with a box
});
SDK hide / remove mask (+ maskColor) data-visual-test helpers
Playwright selectors or Locators selectors or Locators (native option, extended) all
Puppeteer selectors or ElementHandles selectors or ElementHandles (new: overlay boxes) all, blackout new
Cypress selectors native blackout (selectors) all
WebdriverIO selectors selectors or rectangles (new: selectors) all (new)
Vitest selectors (per-call options) selectors (per-call options) all
Storybook inherited from the Playwright options inherited all

How it works:

  • hide / remove: a new browser global, __ARGOS__.applyHelper(elements, helper), sets the data-visual-test attribute on the elements each SDK resolved with its own selector engine. The argosHelpers core plugin's beforeEach cleanup restores the original values, including an existing data-visual-test="blackout". Helpers are applied before beforeEach, so plugins that measure layout see the same page as with markup attributes. They are applied again for each viewport. When an element is both hidden and removed, remove wins, whatever the call order.
  • mask in Puppeteer, which has no native mask: __ARGOS__.mask(elements, color) draws a top-layer overlay that follows the elements. It works for full-page and element screenshots and above modal dialogs, and the same cleanup removes it.
  • WebdriverIO now injects the Argos browser script with only the core plugins (no stabilization waits). The data-visual-test helpers and argosCSS now apply there. Masks are composited onto the PNG with sharp, using element rects scaled by devicePixelRatio. In an Appium native-app context, where no script can run, it captures the screen as before (rectangle masks only), and the options that need a page throw a clear error.

Behavior changes:

  • Selectors that match nothing are ignored.
  • Playwright: passing mask used to replace the mask on [data-visual-test="blackout"] elements; it now adds to it (fix(playwright) commit). The same Cypress blackout bug was fixed on main in f72211e.
  • WebdriverIO: screenshots of pages that use data-visual-test attributes will change, because the helpers now apply.

Type of changes

enhancement

Checklist

  • I have read the CONTRIBUTING doc
  • The commits message follows the Conventional Commits' policy
  • Lint and unit tests pass locally
  • I have added tests if needed

Optional checks:

Further comments

Tests. Every SDK has e2e tests that check pixels in the captured PNGs, or attributes for Cypress, during and after the screenshot. They cover hide, remove, precedence, restoring the page, the merged blackout mask, maskColor, and for Puppeteer full-page, element and modal-dialog masks. Locally: Playwright 28, Puppeteer 17, Cypress 9, WebdriverIO 9 and Vitest 21 pass, plus types, lint, format and unit tests for the seven packages.

Merging. Prefer Rebase and merge. Each commit is a conventional commit scoped to its packages (fix(playwright), feat(puppeteer), feat(webdriverio), …), so the changelogs list each change. A squash would collapse them into one entry.

Not covered: the wider ARG-520 idea of diff-time ignore regions (stored in metadata or set in the review UI) is backend and app work, so the issue stays open.

🤖 Generated with Claude Code

@gregberge gregberge added the enhancement New feature or request label Oct 21, 2026
@linear-code

linear-code Bot commented Oct 21, 2026

Copy link
Copy Markdown

ARG-520

@vercel

vercel Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
argos-js-sdk-reference Ready Ready Preview Oct 21, 2026 9:10am UTC

Request Review

gregberge and others added 3 commits October 21, 2026 10:14
Passing `mask` to `argosScreenshot` replaced the mask applied to
`[data-visual-test="blackout"]` elements instead of adding to it, so those
elements were no longer masked.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Hide or remove elements straight from `argosScreenshot`, without adding
`data-visual-test` attributes to the application. The options apply the
`transparent` and `removed` Argos helpers to the matched elements during the
screenshot and restore them afterwards.

- Playwright: `Locator`s or Playwright selectors (also used by the Vitest
  plugin options and Storybook).
- Puppeteer: `ElementHandle`s or Puppeteer selectors.
- Cypress: selectors.
- Vitest: selectors, in the per-call options.

Selectors that match nothing are ignored. When an element is both hidden and
removed, it is removed.

Refs ARG-520

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Keep the strongest helper in `applyHelper` (removed over transparent)
  instead of relying on call order in every SDK, so each SDK applies all
  targets in one batch.
- Restore attributes from the `argosHelpers` core plugin `beforeEach`
  cleanup instead of a wrapper registering it by hand.
- Apply the helpers before `beforeEach`, so plugins measuring the layout
  see it as with the `data-visual-test` attributes.
- Share the Puppeteer in-page callback, skip the Cypress command when there
  is nothing to apply, and drop the redundant Playwright `mask` type.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@gregberge
gregberge force-pushed the greg/arg-520-ignore-regions-in-screenshot-comparisons branch from cd9b9f3 to 8d11d98 Compare October 21, 2026 08:16
Puppeteer has no native mask, so `[data-visual-test="blackout"]` was
silently ignored. Cover masked elements with boxes drawn by the browser
script, like Playwright does: a glass pane in the top layer (above modal
dialogs) whose boxes follow the elements until the screenshot is taken,
since Puppeteer scrolls the element into view for element screenshots.

The boxes are applied once the page is stable and removed by `afterEach`.
`mask` accepts selectors or `ElementHandle`s, and `maskColor` defaults to

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bring the WebdriverIO SDK to parity with the other SDKs for hiding regions.

`argosScreenshot` now injects the Argos browser script and runs its core
plugins only (`__argos__` class, `argosCSS`, `data-visual-test` helpers), so
no stabilization waits are added. The page is restored after the screenshot.

- `hide` and `remove` take WebdriverIO selectors and apply the `transparent`
  and `removed` helpers to the matched elements. Removing wins over hiding.
- `mask` also takes selectors. Their areas are measured in the viewport, which
  is what `saveScreenshot` captures, and scaled by the device pixel ratio.
  Elements with `data-visual-test="blackout"` are always masked, as with
  Playwright and Cypress. Areas are clipped to the screenshot.
- `argosCSS` injects custom CSS during the screenshot.

Existing `data-visual-test` attributes now take effect, so screenshots of
pages using them will change.

The e2e runner resolves the built `@argos-ci/*` packages, as the browser
script is only embedded at build time.

Refs ARG-520

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
gregberge and others added 2 commits October 21, 2026 11:06
…lback

- Remove the mask boxes from the `argosHelpers` core plugin `beforeEach`
  cleanup, like the helpers, instead of registering the cleanup by hand.
- Share the Puppeteer in-page mask callback between selectors and element
  handles, like `applyHelpers` does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`mask` now takes string selectors as well as `Locator`s in the Playwright
SDK, like `hide`, `remove` and `element`, and like `mask` in the Puppeteer
and WebdriverIO SDKs. Vitest gets `mask` and `maskColor` in its per-call
options, so a browser test can mask elements too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@gregberge gregberge changed the title feat: add hide and remove screenshot options feat: hide, remove and mask regions from every SDK Oct 21, 2026
`argosScreenshot` now injects the Argos script to apply the helpers, which
fails in an Appium native app context where no script can run. Detect it
(`isNativeContext`, or `getContext()` before WebdriverIO 9) and capture the
screen as is, with rectangle masks. The options needing a web page throw a
clear error there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@gregberge
gregberge merged commit 5712957 into main Oct 21, 2026
79 checks passed
@gregberge
gregberge deleted the greg/arg-520-ignore-regions-in-screenshot-comparisons branch October 21, 2026 12:26

This branch was successfully deployed

1 active deployment
Preview — 5c5b1755 Deployed Oct 21, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants