Skip to content

vis (setup)

The vis object from vitest-plugin-vis/setup provides the API to set up the plugin on the client side. This is not the same vis as the Vitest plugin exported from vitest-plugin-vis/config.

vitest.setup.ts
import { vis } from 'vitest-plugin-vis/setup'
// Basic setup - enables visual testing without auto snapshots
vis.setup()
// Enable auto snapshots for all tests
vis.setup({ auto: true })
// Disable auto snapshots (same as `vis.setup()`)
vis.setup({ auto: false })

With vis.setup({ auto: false }), a test that renders content takes no auto snapshot, and page.hasImageSnapshot() returns false for it.

Control when auto snapshots are taken based on test metadata:

vitest.setup.ts
import { vis } from 'vitest-plugin-vis/setup'
// Take snapshots only for tests with specific metadata
vis.setup({
auto: async ({ meta }) => meta['visualTest'] === true,
})
// Skip snapshots for tests marked as 'skipSnapshot'
vis.setup({
auto: async ({ meta }) => !meta['skipSnapshot'],
})

The function is called during the afterEach() phase of the test.

Pass an object to auto to take one snapshot per theme. Each key is the theme name, and each value is a handler that prepares the page for that theme.

vitest.setup.ts
import { vis } from 'vitest-plugin-vis/setup'
vis.setup({
auto: {
light: async () => {
document.body.classList.remove('dark')
document.body.classList.add('light')
},
dark: async () => {
document.body.classList.add('dark')
document.body.classList.remove('light')
},
},
})

The behavior of the per-theme matcher that backs this form is covered by a spec:

  • Every handler runs and takes its snapshot, even if an earlier handler throws.

  • When handlers fail, the errors are aggregated into one message:

    Snapshot `matchpertheme/should-aggregate-all-errors` mismatched
    Theme `theme1` failed: theme1 failed
    Theme `theme2` failed: theme2 failed
  • A handler receives the snapshot options (the meta) of the test, for example { enable: true }.

A handler can skip its theme by returning false:

vitest.setup.ts
import { vis } from 'vitest-plugin-vis/setup'
vis.setup({
auto: {
light: async ({ meta }) => {
if (meta['skipLight']) return false
document.body.classList.remove('dark')
},
dark: async ({ meta }) => {
if (meta['skipDark']) return false
document.body.classList.add('dark')
},
},
})

Theme names are free-form, so you can model viewports and combinations:

vitest.setup.ts
import { vis } from 'vitest-plugin-vis/setup'
vis.setup({
auto: {
desktop: async () => {
document.body.style.width = '1200px'
document.body.classList.add('desktop')
},
tablet: async () => {
document.body.style.width = '768px'
document.body.classList.add('tablet')
},
mobile: async () => {
document.body.style.width = '375px'
document.body.classList.add('mobile')
},
'dark-desktop': async ({ meta }) => {
if (meta['skipDark']) return false
document.body.style.width = '1200px'
document.body.classList.add('desktop', 'dark')
},
},
})