Conversation
SVG SMIL animations (`<animate>`, `<animateTransform>`, `<animateMotion>`, `<set>`) run on their `<svg>`'s own clock. Neither CSS rules nor Playwright's `animations: "disabled"` stop them, so an SVG spinner is captured on whichever frame its loop has reached, and the screenshot changes from run to run. The new plugin, on by default like `pauseGifs`, pauses every `<svg>` that holds an animation repeating forever (`repeatCount` or `repeatDur` set to `indefinite`) and seeks it to 0 before each screenshot. Cleanup seeks each clock back and unpauses it. It pauses the whole chain of `<svg>` ancestors, because Chromium runs an animation on its nearest `<svg>`'s clock, where the spec and Firefox use the outermost one's. Animations that end are left alone. They settle by themselves, and a seek to 0 would capture a finished one at its start: in Chromium, a `fill="freeze"` animation that had ended came back to its first value, whether it had run at load, from `beginElement()` or from a click. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This branch was successfully deployed
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.
Adds a
pauseSvgAnimationsstabilization plugin, on by default likepauseGifs. For each screenshot, it holds SVG animations that repeat forever, such as a spinning SVG loader, on their first frame.SVG SMIL animations (
<animate>,<animateTransform>,<animateMotion>,<set>) run on their<svg>'s own clock. Neither CSS rules nor Playwright'sanimations: "disabled"stop them, so today a spinner is captured on whichever frame its loop has reached. This showed up in Argos's own Storybook: the stories with a pending button were the only screenshots whose bytes changed between runs, and Argos putsui-button--defaultat a flakiness of 0.18 over 90 days (argos-ci/argos#2621).Changes
repeatCount="indefinite"orrepeatDur="indefinite", pauses the<svg>elements above them and seeks them to 0. Cleanup seeks each clock back to where it was and unpauses the ones it paused. Opt out withstabilize: { pauseSvgAnimations: false }.<svg>above the animation. Chromium runs an animation on the clock of its nearest<svg>, where the spec and Firefox use the outermost one's. In Chromium 151, pausing only the outermost<svg>left an animation inside a nested one running.fill="freeze"animation that had ended went back to its first value on the seek, whether it had run at load, frombeginElement()or from a click. Restoring the clock brought all three back.<svg>, and a finite animation. Three e2e tests check that the loops are held on their first frame and handed back running, that the finite animation is left alone, and that the option turns the plugin off.Verification
check-types,lint,check-formatand the unit tests pass for@argos-ci/browserand@argos-ci/playwright.@argos-ci/browser(6.4.5 plus this commit) into the Argos repository. Then I ran its Storybook suite without the workaround that chore(storybook): hold the Loader spinner on its first frame argos#2621 adds, comparing the md5 of every screenshot:ui-button--defaultui-dialog--open-pendingThe other 88 screenshots were byte-identical throughout. The Dialog's leftover sits inside the spinner's box: one colour level, for example
(196, 186, 233)against(195, 186, 232). It only appears when the spinner had moved before the seek, so it comes from the repaint the seek causes. Argos's own comparison ignores it, since its colour-sensitive pass uses odiff with a threshold of 0.0225. A byte comparison does not.Review notes
begin="0s;a.end") rather thanrepeatCount. It also can't reach SVGs rendered through<img>or CSS, or shadow DOM, since it queriesdocumentlike the other plugins.pause-gifs.md, and a line in each SDK reference'sstabilizelist. That PR isn't open yet.🤖 Generated with Claude Code