Skip to main content
Transform your testing process with: Company-wide Licences, Test Observability & App Percy

Percy SDKs and screenshot capture workflow

This guide explains how the Percy infrastructure works with SDKs

To debug Percy builds, a comprehensive understanding of Percy’s workflow, spanning from SDKs to screenshot capture, is essential. This document explains the operations of both the SDKs and the Percy infrastructure.

At a high level, Percy works by capturing a snapshot of the DOM within the test browser. Subsequently, the DOM is transmitted to Percy’s API to be concurrently rendered across various browsers and widths for screenshots. The SDKs are responsible for capturing the DOM and assets, while the APIs handle the proxying and rendering of these snapshots in browsers for screenshots. It is important to note that screenshots are not captured within your test suite but within Percy’s infrastructure.

How Percy Works

How SDKs work

There are two major steps in the Percy SDK to know about:

  1. Capturing the DOM state
  2. Asset discovery

Capturing the DOM state

When percySnapshot is called, Percy’s SDKs capture the exact state of the DOM. The SDK serializes the current page state into the DOM by applying form element values, capturing CSSOM, including accessible iframes, and converting canvas elements into images. This process is handled by the @percy/dom package. We serialize these elements because their state is stored in the page’s memory and is not encoded into the DOM. Without this serialization, that content would be missing from the snapshot.

  • Firefox/Chromium are the supported test browsers for capturing the DOM state.
  • Shadow DOM capturing is currently supported only in the Chrome browser. This feature is unavailable on Firefox due to a lack of serialization support.

Input elements

Input elements (input, textarea, select) are serialized by setting respective DOM attributes to their matching JavaScript property counterparts. For example, checked, selected, and value.

Frame elements

Frame elements are serialized when they are CORS accessible and if they haven’t been built by JavaScript when JavaScript is enabled. They are serialized by recursively serializing the iframe’s document element with the @percy/dom library.

CSSOM rules

When JavaScript is not enabled, CSSOM rules are serialized by iterating over and appending each rule to a new stylesheet inserted into the document’s head.

Canvas elements

Canvas elements drawing buffers are serialized as data URIs and the canvas elements are replaced with image elements. The image elements reference the serialized data URI and have the same HTML attributes as their respective canvas elements. The image elements also have a max-width of 100% to accommodate responsive layouts in situations where canvases may be expected to resize with JS.

Video elements

Videos without a poster attribute undergo automatic serialization of the current frame, and the resulting image is set as the poster attribute. This ensures that videos consistently display a stable image when screenshots are captured.

Asset discovery

Once the DOM is captured & serialized, it gets sent to @percy/core for asset discovery. Asset discovery renders the captured DOM in a Chromium browser, where the SDK intercepts all network requests the DOM makes. This captures assets needed to render the page in Percy’s infrastructure for a screenshot. By default, all assets served on the same hostname as the tests are captured. You can capture more hostnames with the allowed-hostnames config key. Asset discovery also resizes the viewport to the passed widths to ensure assets are captured for the right screen sizes.

Asset discovery by default will wait 100ms for no new network requests to be made by the captured DOM. Once that timeout has been reached asset discovery will close for the given snapshot. It’s not uncommon to have to increase the network-idle-timeout to allow for more network requests to be made.

Since Percy re-renders the DOM in a browser outside of your test suite, you may need to provide authentication to the requests this browser is making. The discovery configuration key in Percy’s SDKs provides a few ways to authenticate requests like request-headers, authorization, and cookies.

Chromium is supported browser for Asset discovery, we manage its ourselves in @percy/core package, you could skip the asset discovery browser download by providing your own.

How the infrastructure works

With the DOM captured and the right assets gathered to render the page, it’s time to capture the screenshot. Percy re-renders the page concurrently across browsers/widths for screenshots.

By default, Percy renders all snapshots with JavaScript disabled. This choice stems from the fact that JavaScript has already executed and modified the page before the DOM is captured. Although enabling JavaScript in Percy’s infrastructure is possible, it often leads to unexpected issues. Most web pages are not designed to handle rendering with an already fully formed DOM, potentially resulting in issues such as redirects or the loss of serialized states (clearing inputs, etc.).

When the page is re-rendered, Percy modifies the captured DOM slightly to do things like remove <noscript> tags and freeze CSS animations.

For a list of browers we support in Infrastructure, click here

If you suspect an infrastructure issue, check Percy Common - FAQs page. Otherwise, feel free to contact our support team.

Debugging SDK’s

All Percy SDKs use @percy/cli, ensuring a consistent approach to debugging snapshot issues across all SDKs.

Debug vs verbose logging

If you are certain you are debugging an asset issue, avoid consuming Percy screenshots during the troubleshooting process. Utilize the --debug CLI flag, which performs all SDK functions except creating build and uploading snapshots. This includes capturing the DOM, running asset discovery over the captured DOM, and enabling verbose logs.

Copy icon Copy snippet

If you still like to create a Percy build, utilize the --verbose CLI flag. This enables verbose logs and simultaneously uploads the captured snapshots to Percy’s API.

Copy icon Copy snippet

Understanding SDK debugging often requires reading the detailed verbose logs provided by the SDKs. Percy’s logs are labeled to specify the originating package for clarity.

Copy icon Copy snippet

For example [percy:core] means the log is coming from the @percy/core package. This helps figure out if the log is from the client SDK or one of the packages that constitute @percy/cli.

Display the asset discovery browser

At times, it’s more straightforward to understand the process by observing the asset discovery browser rendered on your captured page. Achieve this by configuring headless: false in the discovery.launch-options.

Copy icon Copy snippet

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

Is this page helping you?


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!

Talk to an Expert
Download Copy