Skip to content

feat: add assertScreenshot command#126

Open
kacperzolkiewski wants to merge 2 commits into
devicelab-dev:mainfrom
kacperzolkiewski:feat/assert-screenshot
Open

feat: add assertScreenshot command#126
kacperzolkiewski wants to merge 2 commits into
devicelab-dev:mainfrom
kacperzolkiewski:feat/assert-screenshot

Conversation

@kacperzolkiewski

@kacperzolkiewski kacperzolkiewski commented Jul 20, 2026

Copy link
Copy Markdown

Summary

Hi,
First of all, thank you for all your work on this library!

I'm a maintainer of react-native-enriched-html, and I'd like to use your library for our E2E tests. This PR adds an assertScreenshot command, which is the main feature we were missing to be able to migrate our tests.
I created this feature with the help of AI, so I'd really appreciate it if you could review it and let me know if there are any changes you'd recommend.

I also added support for generating a __diff.png file whenever assertScreenshot fails. The diff image highlights the differences with red rectangles, making it much easier to identify what changed:
image

I've been running our Android E2E tests using the DeviceLab driver, and I noticed they're about three times faster than when running the same tests with Maestro.
Thanks in advance for taking a look!

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update
  • Refactoring (no functional changes)

Changes Made

Related Issues

n/a

Testing

  • Tests pass locally (make test)
  • Linting passes (make lint)
  • Added tests for new functionality
  • Tested manually with sample flows

Checklist

  • Code follows project style guidelines
  • Self-reviewed the code
  • Added/updated documentation as needed
  • No breaking changes (or documented if breaking)
  • CHANGELOG.md updated (for notable changes)

Additional Notes

@omnarayan

Copy link
Copy Markdown
Contributor

Thanks @kacperzolkiewski — this is a genuinely well-built PR, and assertScreenshot is a feature people have wanted for a while.

A few things I appreciated on review:

  • Zero new dependencies. The whole diff engine — PNG decode, per-pixel comparison, connected-component regions, the red-box overlay — is hand-rolled on the Go standard library. That's exactly right for this project's single-binary, dependency-light goal; a lot of visual-regression features reach for a third-party image lib and this one doesn't. Nicely done.
  • Clean structure. Diff engine isolated in pkg/core with its own tests, step → parser → executor wiring, and the Screenshot method added consistently across all the drivers. cropOn to scope the capture to an element is a thoughtful touch.
  • No regression. You kept core.ImageDifference's signature, so the existing waitForAnimationToEnd screenshot-diff path still works.
  • The __diff.png with highlighted regions is a great UX detail.

I built it and ran the touched-package suites locally — green — and the default threshold (95% when unset) is sensible.

One thing I'd like to see before merging — baseline creation

Right now a missing reference image hard-fails (Reference screenshot not found), so a brand-new assertScreenshot always fails on its first run until the reference PNG is captured and placed by hand.

Most visual-regression tools (Playwright's toHaveScreenshot, jest-image-snapshot, Maestro itself) either create the baseline automatically on first run or offer an --update-screenshots-style flag. Could we add that?

Even the simplest version — when the reference is absent, write the captured screenshot as the new baseline and pass — turns the workflow from "fail, then go hunt for the file" into "run once to seed, then assert." A flag-gated update mode for intentional re-baselining would be a nice bonus.

Two smaller notes (non-blocking)

  • Pixel diffing is inherently device/resolution/OS-specific — worth a line in the docs so folks set thresholdPercentage and pin their device config deliberately.
  • If you're able to, a quick make test + make lint run and a manual sample-flow check would be great to tick off the checklist.

Really appreciate the contribution — and thanks for the kind words (and the 3× speedup data point 🙂). Happy to help if you want a hand wiring up the baseline-create path.

@kacperzolkiewski

Copy link
Copy Markdown
Author

Hi @omnarayan,
First of all, thank you for the detailed review!

I've added automatic baseline creation and updated the documentation accordingly.
Unfortunately, I wasn't able to run make lint because I ran into an issue with it:

image

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