Integrating Percy visual testing into a new framework is simple using Percy Agent. In this document, we walk you through the necessary steps and provide pointers to examples you can use as a starting point.
If you're unfamiliar with Percy as a user, we strongly suggest that you first start with one of our [2-minute tutorials](🔗). This will help you better understand the steps involved in visual testing with Percy.
# Overview
The [@percy/agent package](🔗) provides a binary that does the heavy lifting needed for a successful visual snapshot. It will also take care of detecting your Percy credentials and uploading the results to your Percy project.
The agent also provides a JavaScript library that acts as the bridge between the agent and your code. This library is provided in a couple of forms:
As a JavaScript library which you can `
require
` and use in the usual way.As a one-file `
percy-agent.js
`, which you can inject into the web page that you want to snapshot. This format is useful for the situations where the only way you have to interface with your framework is by injecting JavaScript directly into an existing browser window. This is likely also your only option if you are using a programming language other than JavaScript.As a one-file `
percy-agent.js
`, available over HTTP if Percy Agent is running, at `http://localhost:5338/percy-agent.js
`.
To integrate with the Percy Agent, you will need the following steps:
Make the `
PercyAgent
` class available inside the browser windows or webpages that you want to snapshot. Depending on your circumstances, this will look like requiring the `PercyAgent
` class from `@percy/agent
`, or injecting `percy-agent.js
` into those pages.Provide a way to instantiate a `
PercyAgent
` and call its `snapshot
` method, within the context of the web page to snapshot.Wrap the execution of your code in a `
percy exec --
` call.
Below we'll go through these steps in detail.
# Making the PercyAgent class available
The [PercyAgent](🔗) JavaScript class exposes the `snapshot
` method that will capture a snapshot of your web page and communicate the data to the locally-running Percy agent service.
This class needs to be instantiated and executed within the context of the page that we are snapshotting. We offer you two different avenues to do this. The best method will depend on the capabilities of the framework you're working with.
## Using @percy/agent as a library in your code
If your framework allows you to include arbitrary JavaScript code, you might be able to add `require('@percy/agent')
` in the right place, and then expose the underlying `snapshot
` call in whichever may makes sense for your use case. Your code will might end up looking something like:
This code has to be executed within the browser context of the page you want to snapshot.
For an example of this approach, see our `@percy/cypress
` SDK implementation: https://github.com/percy/percy-cypress/blob/master/lib/index.ts
## Injecting percy-agent.js into the browser
If your framework doesn't offer a good way to use the approach above, you can integrate Percy by injecting it directly into the browser window from which you want to take snapshots.
For this approach, we provide `percy-agent.js
`, a one-file version of the libraries that are needed by the `PercyAgent
` class. The full path to the `percy-agent.js
` file is available through the function `agentJsFilename
` that `@percy/agent
` exposes.
Another alternative for accessing the `percy-agent.js
` is HTTP. Percy Agent exposes the file over HTTP at http://localhost:5338/percy-agent.js.
You'll need to find a way to inject JavaScript into your browser window or webpage, and then use that ability to:
Inject `
percy-agent.js
` into the pageWithin the page, instantiate `
PercyAgent
` and call its `snapshot
` method.
Many browser automation frameworks offer methods to execute arbitrary JavaScript in the underlying browser (often called, 'inject', 'addScriptTag', `evaluate
` or `execute
`). For example, to integrate with [NightmareJS](🔗) using this method, you can build a Percy library like this:
For an example of this approach, see our `@percy/puppeteer
` SDK implementation: https://github.com/percy/percy-puppeteer/blob/master/lib/index.ts.
The `
agentJsFilename
` function is only available in `@percy/agent
` version 0.1.7 and above.
## Injecting percy-agent.js in languages other than JavaScript
If you are working in a language other than JavaScript, you can use vendorize a copy of `percy-agent.js
` in a location of your choice inside your project, and use that copy to inject directly in the browser.
The `percy-agent.js
` file is available at the location `dist/public/percy-agent.js
` inside the npm `@percy/agent
` package, which you can get by using `npm install @percy/agent
`, or else download directly from npm [here](🔗).
For an example of such an implementation, see the implementation of our Java Selenium SDK and, in particular, the [Percy class](🔗).
# Wrapping execution in 'percy exec -- '
The final step in the integration is to provide a way for your execution command to be wrapped in a `percy exec
` command. This will make the Percy Agent run your code and listen for snapshots to be processed and uploaded.
You will need to set the `PERCY_TOKEN
` environment variable for the agent to know what project to upload snapshots to. If the `PERCY_TOKEN
` variable is not found, the agent will emit a warning and no snapshots will be produced (you can use this to your advantage, e.g. to turn off snapshot uploads during development).
If you were integrating Percy into a test runner that you invoke by calling `run-my-tests
`, the new way to run your tests might look like:
(Don't forget the spaces around `--
` !)
For an example, see how we wrap the `npm run test
` command with `percy exec --
` for our our `@percy/puppeteer
` tests: https://github.com/percy/percy-puppeteer/blob/master/package.json#L25
# PercyAgent usage
`options
` is an optional hash that can include:
`
clientInfo
`: A string identifying the Percy client implementation, e.g. `my-percy-integration/v0.0.1
`.`
environmentInfo
`: A string identifying the operating system, browser and other useful environment information, e.g. `Windows; chrome
`.
Both `clientInfo
` and `environmentInfo
` might appear under the "Environment" section of a build's metadata in the Percy.io user interface.
`snapshotName
` is a required string that will be used as the snapshot name. It can be any string that makes sense to identify the page state. It should be unique and remain the same across builds. If you're providing your SDK as a library for others, this parameter will typically be provided by your users. You might also be able to automatically generate this string, easing the burden on your users; see [Autogenerated snapshot names](🔗) for more details on this.
`options
` is an optional hash that can include:
`
widths
`: An array of integers representing the browser widths at which you want to take snapshots.`
minHeight
`: An integer specifying the minimum height of the resulting snapshot, in pixels. Defaults to 1024px.
## Examples
# Use debug logs to inspect what happens within the agent
You can turn on verbose debug logging when running the `percy exec
` by setting the environment variable `LOG_LEVEL=debug
`. This will let you see in detail what is happening inside the agent.
These debug logs will include, among other things, the full request that the agent is receiving from your SDK, which will help you troubleshoot any issues. Look for a set of logs that look like:
# Global Configuration
You can configure Percy to use the same options over all snapshots. To see supported configuration including widths read our [Configuration doc](🔗).