Jump to content

Connect Leeroopedia MCP: Equip your AI agents to search best practices, build plans, verify code, diagnose failures, and look up hyperparameter defaults.

Heuristic:Teamcapybara Capybara Animation Disabling For Tests

From Leeroopedia
Knowledge Sources
Domains Testing, Optimization, Best_Practices
Last Updated 2026-02-12 06:00 GMT

Overview

Disable CSS transitions, animations, and scroll behavior in tests via `Capybara.disable_animation` to eliminate timing-dependent flakiness.

Description

CSS animations and transitions introduce non-deterministic timing into browser-based tests. An element that is animating into position may not be clickable, visible, or at its expected coordinates during the animation. Capybara provides a built-in `AnimationDisabler` Rack middleware that injects CSS rules to disable all transitions and animations, and a JavaScript snippet to disable jQuery animations (`jQuery.fx.off = true`). This middleware is activated by setting `Capybara.disable_animation = true` (for all elements) or `Capybara.disable_animation = '.my-selector'` (for specific elements).

Usage

Apply this heuristic when your test suite experiences intermittent failures related to element clicking, visibility, or position — especially when elements use CSS transitions, animations, or smooth scrolling. This is a common source of flakiness in Selenium-based tests.

The Insight (Rule of Thumb)

  • Action: Set `Capybara.disable_animation = true` in your test configuration (e.g., `spec_helper.rb` or `rails_helper.rb`).
  • Value: Boolean `true` disables all animations. A CSS selector string (e.g., `'.modal, .dropdown'`) targets specific elements only.
  • Trade-off: Tests no longer verify animation behavior. If animation correctness matters, test it separately with `disable_animation = false`.
  • Scope: Applies only to the embedded test server responses — it injects CSS/JS into HTML responses served by Capybara's Rack middleware.

Reasoning

The AnimationDisabler works by injecting a `<style>` tag before `</head>` and a `<script>` tag before `</body>` into every HTML response. The CSS rules set `transition: none !important`, `animation-duration: 0s !important`, `animation-delay: 0s !important`, and `scroll-behavior: auto !important` on the selected elements and their `::before`/`::after` pseudo-elements. The JavaScript disables jQuery's animation queue entirely. This approach is reliable because it uses `!important` declarations that override any application CSS, and it operates at the server middleware level so it affects all pages served during tests.

The middleware also respects Content-Security-Policy nonces: it extracts `style-src` and `script-src` nonces from the CSP header and adds them to the injected tags, ensuring the injected code is not blocked by the application's security policy.

Code Evidence

CSS injection template from `lib/capybara/server/animation_disabler.rb:64-71`:

DISABLE_CSS_MARKUP_TEMPLATE = <<~CSS
  %<selector>s, %<selector>s::before, %<selector>s::after {
     transition: none !important;
     animation-duration: 0s !important;
     animation-delay: 0s !important;
     scroll-behavior: auto !important;
  }
CSS

jQuery animation disabling from `lib/capybara/server/animation_disabler.rb:73-77`:

DISABLE_JS_MARKUP_TEMPLATE = <<~SCRIPT
  //<![CDATA[
    (typeof jQuery !== 'undefined') && (jQuery.fx.off = true);
  //]]>
SCRIPT

CSP nonce extraction from `lib/capybara/server/animation_disabler.rb:50-61`:

def directive_nonces(headers)
  headers.fetch('Content-Security-Policy', '')
         .split(';')
         .map(&:split)
         .to_h do |s|
           [
             s[0], s[1..].filter_map do |value|
               /^'nonce-(?<nonce>.+)'/ =~ value
               nonce
             end[0]
           ]
         end
end

HTML injection from `lib/capybara/server/animation_disabler.rb:45-47`:

def insert_disable(html, nonces)
  html.sub(%r{(</head>)}, "<style #{nonces['style-src']}>#{disable_css_markup}</style>\\1")
      .sub(%r{(</body>)}, "<script #{nonces['script-src']}>#{disable_js_markup}</script>\\1")
end

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment