In order to create snapshots in Phoenix, you'll need to use the library ex_snappy
There's currently a little bit of ceremony to get the service running, due to a couple of quirks in how testing works for components and LiveView in the testing environment.
When a live view is rendered with the live(...)
function, you get back the full HTML, which includes the necessary <head>
content which loads your CSS.
Unfortunately if you use any of the render_x(...)
calls, you only get back a subset of the HTML, similarly if you use render_component
you get the HTML from the individual component, but none of the HTML responsible for loading styles.
Currently the way to deal with this is to provide wrapper_fn
function in test.exs
. In future we aim to provide a more ergonomic way using your application's templates directly.
This is essentially the contents of your root.html.heex
, plus the content of app.html.heex
.
NOTE Don't add references to load JavaScript. The reason for this is you don't really want to connect the websocket and have a second page render or deal with things like the 'topbar', which will cause you to have inconsistent images due to timing issues.
If you're running tests locally, you likely don't want to be running the visual regression tests, so we only execute if you explicitly enable things. Suggested way of dealing with this below
If you don't wish your screenshots to be full_page you can turn this off globally
To execute the visual regression tests, you'll need to add some configuration data by creating a .get-snappy.yml
file
For example:
The local_dist_dir
is use to allow the rendering service to know where your static assets are. For most Phoenix projects, this would be priv/static
snappy_workers
are the number of workers per browser. This allows faster rendering of snapshots, but can be reduced if you are resource limited. In the example below there would be a total of 12 browser instances (4 x 3 browser).
browsers
Are the browsers you wish to render in
test_command
is the shell command you wish to run to execute your test suite.
You'll also need to set some environment variables, an example of this is below, but you'd likely get the COMMIT and BRANCH from your CI provider.
Finally, execute the tests you'd run something like this (further information on EX_SNAPPY_ENABLED
below):
EX_SNAPPY_ENABLED=true get-snappy snapshot-run
The snap
macro can be used in three forms. See ExSnappy
module for further details.
Key steps:
import ExSnappy
to make the snap
macro available
Use the snap
function to capture screenshots.
Screenshot names are automatically generated based on the name of the test
function, but if you take multiple screenshots in a single test, you'll need to provide an explicit name to be appended to the test name.
Then to use in tests, you need send HTML. This can be achieved by calling render
only your live
process, passing the html
generated from a live()
call, or the html
generated from the render_component
function.
live()
render()
render_component()
Simply provide an explicit name for all but the first call to snap
.
You can pass :playwright_options
to set options for Playwright.
:full_page
, which defaults to true. You can globally set whether to enable full page screenshots by setting the :full_page
option in your config file to false.
:dark_mode
, which defaults to false.
:locator
, which can be a CSS selector which should target a single element. This will limit the screenshot size to the bounding box of the element. This is useful for testing specific elements and components.
:dimensions
, which can be a list of maps with :width and :height keys.
Where dimensions aren't specified, the default will be 1920x1080
Example