import { Meta, Source } from "@storybook/addon-docs/blocks";

<Meta title="config/vis" />

# `vis`

`vis` from `vitest-plugin-vis/config` is the Vitest plugin of `vitest-plugin-vis`.

```ts
// vitest.config.ts
import { vis } from 'vitest-plugin-vis/config'

export default defineConfig({
	plugins: [vis()],
})
```

It provides a lot of options to customize the behavior of the plugin.
(You can learn more about the default configuration [here](/docs/overview--docs#basic-configuration).)

## `preset`

The `preset` option set up typical visual testing strategies.

### `auto`

The `auto` preset is the default preset.
It will take a snapshot of the page at the end of each rendering test.

```ts
// vitest.config.ts
import { vis } from 'vitest-plugin-vis/config'

export default defineConfig({
	plugins: [vis({ preset: 'auto' })],
})
```

### `manual`

The `manual` preset is for manual testing.
It will not take any snapshot automatically.

```ts
// vitest.config.ts
import { vis } from 'vitest-plugin-vis/config'

export default defineConfig({
	plugins: [vis({ preset: 'manual' })],
})
```

See [Manual Snapshot](/docs/expect-tomatchimagesnapshot--docs) section on how to take an image snapshot manually.

### `custom`

The `custom` preset is for advanced users.
It will not take any snapshot automatically.
You need to set up your own visual testing strategy in `vitest.setup.ts`.

```ts
// vitest.config.ts
import { vis } from 'vitest-plugin-vis/config'

export default defineConfig({
	plugins: [vis({ preset: 'custom' })],
	test: {
		// Set up your own visual testing strategy in `vitest.setup.ts`.
		setupFiles: ['./vitest.setup.ts'],
	}
})
```

When using the `custom` preset,
you need to set up your own visual testing strategy in `vitest.setup.ts` using the [vis](?path=/docs/setup-vis--docs) function from `vitest-plugin-vis/setup`.

## `subject`

By default, the snapshot is taken from the `document.body` element.

If you establish a common pattern in your tests,
you can customize the subject to snapshot by setting the `subject` option.


For example, if you enforce a `data-testid` attribute on the element you want to snapshot,
you can use the `subject` option to specify the selector:

```ts
// vitest.config.ts
import { vis } from 'vitest-plugin-vis/config'

export default defineConfig({
	plugins: [vis({ subject: '[data-testid="subject"]' })]
})
```

## `snapshotRootDir`

By default, the snapshot is saved in the `__vis__` folder relative to the project root.

If you want to save the snapshot in a different folder,
you can set the `snapshotRootDir` option.

```ts
// vitest.config.ts
import { vis } from 'vitest-plugin-vis/config'

export default defineConfig({
	plugins: [
		vis({
			// save the snapshot in the `<projectRoot>/custom` folder
			snapshotRootDir: 'custom'
		})
	]
})
```

Beside providing a static path,
you can also provide a function to dynamically determine the snapshot root directory based on the context.

The function receives the following context:

- `ci`: Whether the code is running in a CI environment
- `platform`: The platform string (e.g., 'linux', 'darwin', 'win32')
- `browserName`: The name of the browser (e.g., 'chromium', 'firefox', etc.)
- `providerName`: The name of the provider (e.g., 'playwright', 'webdriverio', etc.)
- `screenshotFailures`: Whether the screenshot failures are enabled
- `screenshotDirectory`: The directory to save the screenshot

By default, we provide this function:

```ts
({ ci, platform }) => `__vis__/${ci ? platform : 'local'}
```

## `snapshotSubpath`

Customize the snapshot subpath.

By default, we provide this function: `({ subpath }) => trimCommonFolder(subpath)`

The `trimCommonFolder` function is also provided if you want to use it in your own custom function.

## `snapshotKey`

`snapshotKey` specifies the key of the snapshot.
In the context of `vis()`, `snapshotKey` is used to specify the key of the auto snapshot.

By default, the `snapshotKey` is `auto`.

[vitest-plugin-vis]: https://npmjs.org/package/vitest-plugin-vis

## `comparisonMethod`

`comparisonMethod` specifies the method of the comparison.
By default, the `comparisonMethod` is `pixel`.

If you want to use the `ssim` method,
you can set the `comparisonMethod` option.

```ts
// vitest.config.ts
import { vis } from 'vitest-plugin-vis/config'

export default defineConfig({
	plugins: [vis({ comparisonMethod: 'ssim' })]
})
```

## `diffOptions`

`diffOptions` specifies the options of the comparison.
It accepts different options based on the `comparisonMethod`.

### Pixel Comparison

For `pixel` comparison, it accepts the options of `pixelmatch`:

```ts
// vitest.config.ts
import { vis } from 'vitest-plugin-vis/config'

export default defineConfig({
	plugins: [vis({
		comparisonMethod: 'pixelmatch',
		diffOptions: {
			threshold: 0.1,        // Matching threshold (0-1), default: 0.1
			includeAA: false,      // Include anti-aliased pixels in comparison
			alpha: 0.1,            // Blending factor of unchanged pixels
			aaColor: [255, 255, 0], // Color of anti-aliased pixels in diff
			diffColor: [255, 0, 255] // Color of different pixels in diff
		}
	})],
})
```

For option details, please refer to the [pixelmatch documentation](https://github.com/mapbox/pixelmatch?tab=readme-ov-file#pixelmatchimg1-img2-output-width-height-options).

### SSIM Comparison

Sometimes pixel-perfect isn't what you need. If you're working with images that have gradients, shadows, or anti-aliasing, SSIM (Structural Similarity Index) might be a better fit.
It's designed to match how humans actually perceive image differences, which means fewer false positives when minor rendering differences don't actually matter.
For `ssim` comparison, it accepts the options of `ssim`:

```ts
// vitest.config.ts
import { vis } from 'vitest-plugin-vis/config'

export default defineConfig({
	plugins: [vis({
		comparisonMethod: 'ssim',
		diffOptions: {
			ssim: 'bezkrovny',  // 'bezkrovny' (fast, default) | 'fast' (accurate) | 'weber' | 'original'
			windowSize: 11,     // Window size for SSIM calculation (default: 11)
			k1: 0.01,          // First stability constant (default: 0.01)
			k2: 0.03,          // Second stability constant (default: 0.03)
			bitDepth: 8,       // Bits per channel (default: 8)
			downsample: 'original' // 'original' | 'fast' | false
		}
	})],
})
```

For option details, please refer to the [ssim documentation](https://github.com/obartra/ssim).
Note that `ssim.js` repository indicates it is archived.
If there is any issue with `ssim` comparison,
it may not be fixed.

## Failure Thresholds

Sometimes you want a bit of flexibility in your tests. That's where failure thresholds come in! They let you decide how much difference is acceptable before a test fails.

### Pixel-Based Threshold

If you know roughly how many pixels might differ (maybe due to font rendering differences across platforms), you can set a specific pixel count. This is great when you have a good sense of what "acceptable difference" means in pixels.

```ts
// vitest.config.ts
import { vis } from 'vitest-plugin-vis/config'

export default defineConfig({
	plugins: [vis({
		failureThreshold: 100,        // Allow 100 pixels to differ
		failureThresholdType: 'pixel' // Default: 'pixel'
	})],
})
```

### Percentage-Based Threshold

Percentage-based thresholds are often more intuitive, especially when you're working with different image sizes. Instead of thinking "100 pixels," you can think "2% of the image," which scales better across different screen sizes and resolutions.

```ts
// vitest.config.ts
import { vis } from 'vitest-plugin-vis/config'

export default defineConfig({
	plugins: [vis({
		failureThreshold: 0.05,        // Allow 5% of pixels to differ
		failureThresholdType: 'percent'
	})],
})
```

### Pixel-Perfect Comparison

When you need absolute precision—maybe you're testing critical UI components or want to catch the tiniest visual regressions—pixel-perfect comparison is your go-to. This is the default behavior and ensures that any pixel difference will be caught.

```ts
// vitest.config.ts
import { vis } from 'vitest-plugin-vis/config'

export default defineConfig({
	plugins: [vis({
		failureThreshold: 0,
		failureThresholdType: 'pixel'
	})],
})
```

## Timeout Configuration

Sometimes your tests need a bit more time to render, especially if you're working with complex components or slower environments. You can adjust the timeout to give your tests the breathing room they need.

### Custom Timeout

If you find your tests are timing out, or if you're working with particularly complex components that take longer to render, you can increase the timeout. The default is 30 seconds, but feel free to adjust it based on your needs.

```ts
// vitest.config.ts
import { vis } from 'vitest-plugin-vis/config'

export default defineConfig({
	plugins: [vis({
		timeout: 60000 // 60 seconds (default: 30000ms)
	})],
})
```

### Quick Timeout for Fast Tests

On the flip side, if you know your tests are quick and you want faster feedback, you can reduce the timeout. This helps catch issues faster and keeps your test suite snappy!

```ts
// vitest.config.ts
import { vis } from 'vitest-plugin-vis/config'

export default defineConfig({
	plugins: [vis({
		timeout: 5000 // 5 seconds
	})],
})
```
