Freezing animations
Learn how to freeze animations on a page during visual testing
A big challenge of visual testing is reducing false-positive visual diffs. False-positives can be caused by many variables (including system and hardware differences between browser environments), but are commonly caused by page animations.
For example, this awesome pure-CSS animation.
If you captured a page with this animation multiple times, you would end up with noisy and false-positive visual diffs:
Though fun to look at, this doesn’t really help us identify visual regressions!
Automatic animation freezing in Percy
Percy does a lot of work behind the scenes to make sure that pages are rendered consistently and deterministically. One of the things we do is freeze different kinds of animations that can cause false-positive visual diffs.
Percy will automatically:
- Freeze animated GIFs on the first frame.
- Freeze most CSS
animation
andtransition
styles.
Other than animations, Percy does other server-side tricks to create a consistent rendering environment and avoid other kinds of false-positives (such as font rendering differences, sub-pixel antialiasing, width and height changes, etc.)
Freezing other animations
Freeze jQuery animations
Percy does not by default execute JavaScript in our rendering pipeline, but JavaScript is likely enabled in the browser that runs your acceptance tests locally or on CI. You might be unknowingly running jQuery animations in tests simply by using them in your app.
In addition to causing false-positives if the DOM is captured in the middle of animation, jQuery animations can also have the adverse effect of slowing down your acceptance tests—assertions might wait for animations to complete before an element exists on the page. Temporarily disabling jQuery animations might help speed up your acceptance tests, as well as will help Percy avoid capturing the DOM state while elements are still animating.
You can set a jQuery config to disable animations:
$.fx.off = true;
NOTE You should only include this snippet in your testing environment!
As the jQuery docs say: “When this property is set to true
all animation methods will immediately set elements to their final state when called, rather than displaying an effect.”
Freeze SVG animations
SVGs can be animated using animateTransform
and will not be frozen by Percy in all browsers. To freeze these animations you must utilize Percy specific CSS.
Let’s go through an example. The following page has an SVG loading animation that spins using the transform
attribute. To freeze this in Percy, we’ve added some Percy specific CSS in the head.
<html>
<head>
<style type="text/css">
@media only percy {
.loading-spinner {
transform: rotate(0);
}
}
</style>
</head>
<body>
<svg width="21" height="21" viewBox="0 0 21 21">
<g fill="none">
<path
stroke="#9E66BF"
stroke-width="2"
d="M1,10 C1.14147949,5.49999934 5.00437084,0.956663874 10.5013061,1.00031374 C15.9982414,1.04396361 19.8972168,5.49999934 19.9998888,10"
class="loading-spinner"
>
<animateTransform
attributeType="xml"
attributeName="transform"
type="rotate"
from="0 10.5 10.5"
to="360 10.5 10.5"
dur="1s"
repeatCount="indefinite" />
</path>
</g>
</svg>
</body>
</html>
The CSS property used to freeze this animation must be the same as what’s used in animateTransform
. In this example we are using type="rotate"
so the corresponding freeze for this is transform: rotate(0);
. Using transform: none;
will not freeze the animation here.
Freeze Highcharts animations
Highcharts.setOptions({
chart: {
animation: false
},
plotOptions: {
series: {
animation: false
}
}
});
- https://api.highcharts.com/highcharts/chart.animation
- https://api.highcharts.com/highcharts/plotOptions.series.animation
Freeze Velocity animations
If you are using the Velocity animation accelerator, you can mock time when animating elements to disable the animation tweening entirely. This allows you to snapshot the end state of your animation. To do so, add the following to your Velocity config to disable animations:
$.Velocity.mock = true;
This will force all Velocity animations to run with 0ms duration and 0ms delay on the next animation tick. For more information on how this works, see the Velocity documentation.
Freeze Greensock animations
Greensock is relies on requestAnimationFrame
under the hood. If you use TweenMax
you can set the globalTimeScale to 0
in your test environment to pause animations on all timelines:
TweenMax.globalTimeScale(0)
TimelineLite
also has a way to adjust time scale via exportRoot.
We're sorry to hear that. Please share your feedback so we can do better
Contact our Support team for immediate help while we work on improving our docs.
We're continuously improving our docs. We'd love to know what you liked
We're sorry to hear that. Please share your feedback so we can do better
Contact our Support team for immediate help while we work on improving our docs.
We're continuously improving our docs. We'd love to know what you liked
Thank you for your valuable feedback!