Skip to content

feat(webdriverio): add hide, remove and selector masks - #406

Merged
gregberge merged 1 commit into
greg/arg-520-ignore-regions-in-screenshot-comparisonsfrom
claude/webdriverio-hide-remove
Oct 21, 2026
Merged

gregberge merged 1 commit into
greg/arg-520-ignore-regions-in-screenshot-comparisonsfrom
claude/webdriverio-hide-remove

Conversation

@gregberge

@gregberge gregberge commented Oct 21, 2026 •

Copy link
Copy Markdown
Member

Stacked on #403. Brings @argos-ci/webdriverio to parity with the other SDKs for hiding regions (ARG-520).

⚠️ Behaviour change (not an API break)

Before this PR, the WebdriverIO SDK never injected the Argos browser script, so data-visual-test attributes did nothing. Now they take effect:

  • data-visual-test="transparent" hides the element
  • data-visual-test="removed" removes the element from the layout
  • data-visual-test="blackout" masks the element with maskColor

Existing WebdriverIO users whose pages already use these attributes will see their screenshots change. This is worth mentioning in the release notes.

Changes

  • argosScreenshot injects the global script and runs the lifecycle with options: false, so only the core plugins run (__argos__ class, argosCSS, helper CSS) and no stabilization waits are added. The order matches the other SDKs: beforeAll → applyHelper → beforeEach → capture → afterEach/afterAll.
  • hide?: string[] and remove?: string[]: selectors are resolved with browser.$$, so every WebdriverIO selector strategy works, and the matches go to __ARGOS__.applyHelper, which keeps the strongest helper per element. Selectors that match nothing are ignored.
  • mask also accepts selectors ((string | { x, y, width, height })[]). Element areas come from getBoundingClientRect(), which is relative to the viewport (all saveScreenshot captures), and are scaled by devicePixelRatio. They are measured after hide/remove apply, since removal shifts the layout. [data-visual-test="blackout"] is always masked, as with Playwright's mask and Cypress's blackout. All areas are now clipped to the image, so an element taller than the viewport no longer makes sharp throw.
  • argosCSS is exposed, since the core addArgosCSS plugin already runs.
  • @argos-ci/browser is added as a dependency.

Round trips

WebdriverIO commands are remote round trips (often to a grid), so they are batched:

  • the injection is checked in the page, so injecting is a single command
  • the hide/remove selectors are resolved while the script is injected
  • beforeAll, the helpers and beforeEach run in one execute
  • teardown runs while sharp masks the screenshot

A screenshot with no options now sends 5 commands (inject, setup, find blackout, take screenshot, teardown). Before this PR it sent 1. With hide/remove/mask selectors, it takes 6 sequential round trips.

Masks are composited onto the screenshot in a single sharp pass, and the file is written as-is, with no re-encode.

Tests

New e2e specs in test/specs/test.e2e.ts with a fixtures/helpers.html page. They read pixels from the saved PNGs to check:

  • the data-visual-test helpers apply, and the page is restored afterwards (class, attributes, CSS)
  • hide/remove, including "remove wins" and selectors that match nothing
  • selector and rectangle masks, including the blackout helper and a custom maskColor
  • a scrolled page, where coordinates are relative to the viewport
  • a 2× device pixel ratio, via browser.setViewport
  • argosCSS

wdio.conf.ts points tsx at the root tsconfig.build.json, which clears the paths alias. Without it, tsx loads @argos-ci/browser from src, where getGlobalScript() is undefined because the script is only embedded at build time. Turbo already builds the package before e2e.

Verified locally:

  • pnpm exec turbo run check-types lint check-format test --filter=@argos-ci/webdriverio: green
  • pnpm run test-e2e: 9 passing (WebDriver BiDi, Chrome 156)
  • the same suite with wdio:enforceWebDriverClassic: true: 8 passing (the 2× test needs BiDi's setViewport). This covers the classic execute argument serialization used by wdio 6–8.

Open question: sharp masks vs the __ARGOS__.mask overlay (#404)

#404 adds an in-page __ARGOS__.mask(elements, color) overlay for Puppeteer. Masking in the page would remove the viewport/DPR/clipping logic here, would work inside iframes and with drivers that capture more than the viewport, and would keep blackout consistent across SDKs. If WebdriverIO later moves from sharp to that overlay, masked areas will change slightly (whole-pixel vs anti-aliased edges), so users would see diffs twice. Consider landing #404 first and switching selector and blackout masks to it here before release.

Not included

  • WebdriverIO Element objects in hide/remove/mask (Puppeteer and Playwright accept handles); only selectors for now.
  • Full stabilization (stabilize, waits, viewports, metadata) is still Playwright/Puppeteer only.
  • Docs (sdks-reference/webdriverio, argos-helpers) should be updated with the other SDKs once this ships.

🤖 Generated with Claude Code

@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 8:25am UTC

Request Review

@gregberge
gregberge force-pushed the greg/arg-520-ignore-regions-in-screenshot-comparisons branch from cd9b9f3 to 8d11d98 Compare October 21, 2026 08:16
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
gregberge force-pushed the claude/webdriverio-hide-remove branch from ccd41e9 to 99afa73 Compare October 21, 2026 08:25
@gregberge
gregberge requested a review from jsfez October 21, 2026 08:52
@gregberge
gregberge merged commit 612ffe5 into greg/arg-520-ignore-regions-in-screenshot-comparisons Oct 21, 2026
2 checks passed
@gregberge
gregberge deleted the claude/webdriverio-hide-remove branch October 21, 2026 08:59

This branch was successfully deployed

1 active deployment
Preview — 99afa73d 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

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant