Replace resemble.js with pixelmatch as the comparison engine#1151
Draft
wswebcreation wants to merge 10 commits into
Draft
Replace resemble.js with pixelmatch as the comparison engine#1151wswebcreation wants to merge 10 commits into
wswebcreation wants to merge 10 commits into
Conversation
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Users have been seeing flaky visual tests caused by minor rendering differences that are invisible to the human eye, things like sub-pixel font hinting, 1px anti-aliasing variations at element edges, and slight shadow rendering changes between test runs. These aren't real regressions, but they cause tests to fail intermittently, which erodes confidence in the visual test suite.
The root cause is that the current resemble.js engine compares images using per-channel RGB tolerance. RGB is not a perceptually uniform colour space, so a tolerance of 32/255 on the red channel has a completely different visual meaning than the same tolerance on the blue channel. It also has a large-image sampling optimisation that silently skips about 31% of pixels (every 6th row and column) on full-page screenshots, including the entire first row.
pixelmatch, compares images in the YIQ colour space. The weights in that space reflect how sensitive the human eye actually is: luminance matters most, then the orange-blue axis, then the purple-green axis. Its anti-aliasing detector cross-validates against both images at once, so it only skips a pixel if both the baseline and the actual look like an anti-aliased edge there. The net result is that invisible rendering noise passes, and real regressions don't.
What changed
A
compareEngineoption has been added to the service configuration. Setting it to'pixelmatch'routes comparisons through the new adapter;'resemble'(the default) keeps the existing behaviour unchanged.The pixelmatch adapter has the same interface as the resemble adapter, so all downstream behaviour, diff images, JSON reports,
diffPixelsbounding boxes, mismatch percentages works identically regardless of which engine is used.A few bugs were found and fixed in the process:
contain()was being used to normalise images to the same canvas size.contain()centers the image, which shifts content by 1px and creates a false diff across the top row. Replaced with buffer-level padding that anchors content at (0,0).Math.floor, which can lose a pixel whencssSize × DPRhas a fractional part. Changed toMath.ceilfor width and height so the full element area is always covered.Notes
The
compareEngineoption is marked beta. The resemble engine remains the default and nothing changes for existing users unless they explicitly opt in. It might be that we will remove it when we release it as a large breaking change.