vitest-plugin-vis 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm/client/ctx.d.ts +6 -0
- package/esm/client/ctx.d.ts.map +1 -0
- package/esm/client/ctx.js +7 -0
- package/esm/client/expect/expectation_result.d.ts +3 -0
- package/esm/client/expect/expectation_result.d.ts.map +1 -0
- package/esm/client/expect/expectation_result.js +5 -0
- package/esm/client/expect/extend.d.ts +8 -0
- package/esm/client/expect/extend.d.ts.map +1 -0
- package/esm/client/expect/extend.js +3 -0
- package/esm/client/expect/to_match_image_snapshot.d.ts +9 -0
- package/esm/client/expect/to_match_image_snapshot.d.ts.map +1 -0
- package/esm/client/expect/to_match_image_snapshot.js +32 -0
- package/esm/client/expect/to_match_image_snapshot.logic.d.ts +2 -0
- package/esm/client/expect/to_match_image_snapshot.logic.d.ts.map +1 -0
- package/esm/client/expect/to_match_image_snapshot.logic.js +11 -0
- package/esm/client/expect/to_match_image_snapshot.types.d.ts +7 -0
- package/esm/client/expect/to_match_image_snapshot.types.d.ts.map +1 -0
- package/esm/client/expect/to_match_image_snapshot.types.js +1 -0
- package/esm/client/page/extend.d.ts +6 -0
- package/esm/client/page/extend.d.ts.map +1 -0
- package/esm/client/page/extend.js +3 -0
- package/esm/client/page/has_image_snapshot.d.ts +10 -0
- package/esm/client/page/has_image_snapshot.d.ts.map +1 -0
- package/esm/client/page/has_image_snapshot.js +23 -0
- package/esm/client/selector.d.ts +9 -0
- package/esm/client/selector.d.ts.map +1 -0
- package/esm/client/selector.js +104 -0
- package/esm/client/should_take_snapshot.d.ts +10 -0
- package/esm/client/should_take_snapshot.d.ts.map +1 -0
- package/esm/client/should_take_snapshot.js +13 -0
- package/esm/client/snapshot_options.d.ts +34 -0
- package/esm/client/snapshot_options.d.ts.map +1 -0
- package/esm/client/snapshot_options.internal.d.ts +3 -0
- package/esm/client/snapshot_options.internal.d.ts.map +1 -0
- package/esm/client/snapshot_options.internal.js +20 -0
- package/esm/client/snapshot_options.js +16 -0
- package/esm/client/task_id.d.ts +7 -0
- package/esm/client/task_id.d.ts.map +1 -0
- package/esm/client/task_id.js +10 -0
- package/esm/client.d.ts +8 -0
- package/esm/client.d.ts.map +1 -0
- package/esm/client.js +5 -0
- package/esm/commands.d.ts +5 -0
- package/esm/commands.d.ts.map +1 -0
- package/esm/commands.js +4 -0
- package/esm/config/types.d.ts +35 -0
- package/esm/config/types.d.ts.map +1 -0
- package/esm/config/types.js +1 -0
- package/esm/config/vis.d.ts +25 -0
- package/esm/config/vis.d.ts.map +1 -0
- package/esm/config/vis.js +27 -0
- package/esm/config.d.ts +4 -0
- package/esm/config.d.ts.map +1 -0
- package/esm/config.js +2 -0
- package/esm/index.d.ts +2 -0
- package/esm/index.d.ts.map +1 -0
- package/esm/index.js +2 -0
- package/esm/presets/auto.d.ts +2 -0
- package/esm/presets/auto.d.ts.map +1 -0
- package/esm/presets/auto.js +3 -0
- package/esm/presets/manual.d.ts +2 -0
- package/esm/presets/manual.d.ts.map +1 -0
- package/esm/presets/manual.js +3 -0
- package/esm/server/browser_provider/browser_api.d.ts +3 -0
- package/esm/server/browser_provider/browser_api.d.ts.map +1 -0
- package/esm/server/browser_provider/browser_api.js +11 -0
- package/esm/server/browser_provider/playwright.d.ts +4 -0
- package/esm/server/browser_provider/playwright.d.ts.map +1 -0
- package/esm/server/browser_provider/playwright.js +13 -0
- package/esm/server/browser_provider/types.d.ts +6 -0
- package/esm/server/browser_provider/types.d.ts.map +1 -0
- package/esm/server/browser_provider/types.js +1 -0
- package/esm/server/browser_provider/webdriverio.d.ts +4 -0
- package/esm/server/browser_provider/webdriverio.d.ts.map +1 -0
- package/esm/server/browser_provider/webdriverio.js +10 -0
- package/esm/server/commands/extend.d.ts +15 -0
- package/esm/server/commands/extend.d.ts.map +1 -0
- package/esm/server/commands/extend.js +10 -0
- package/esm/server/commands/has_image_snapshot.d.ts +6 -0
- package/esm/server/commands/has_image_snapshot.d.ts.map +1 -0
- package/esm/server/commands/has_image_snapshot.js +7 -0
- package/esm/server/commands/image_snapshot_next_index.d.ts +9 -0
- package/esm/server/commands/image_snapshot_next_index.d.ts.map +1 -0
- package/esm/server/commands/image_snapshot_next_index.js +7 -0
- package/esm/server/commands/is_ci.d.ts +2 -0
- package/esm/server/commands/is_ci.d.ts.map +1 -0
- package/esm/server/commands/is_ci.js +6 -0
- package/esm/server/commands/match_image_snapshot.d.ts +17 -0
- package/esm/server/commands/match_image_snapshot.d.ts.map +1 -0
- package/esm/server/commands/match_image_snapshot.js +88 -0
- package/esm/server/commands/setup_vis_suite.d.ts +13 -0
- package/esm/server/commands/setup_vis_suite.d.ts.map +1 -0
- package/esm/server/commands/setup_vis_suite.js +4 -0
- package/esm/server/compare_image.d.ts +8 -0
- package/esm/server/compare_image.d.ts.map +1 -0
- package/esm/server/compare_image.js +16 -0
- package/esm/server/file.d.ts +6 -0
- package/esm/server/file.d.ts.map +1 -0
- package/esm/server/file.js +14 -0
- package/esm/server/snapshot_path.d.ts +4 -0
- package/esm/server/snapshot_path.d.ts.map +1 -0
- package/esm/server/snapshot_path.js +9 -0
- package/esm/server/vis_context.ctx.d.ts +29 -0
- package/esm/server/vis_context.ctx.d.ts.map +1 -0
- package/esm/server/vis_context.ctx.js +11 -0
- package/esm/server/vis_context.d.ts +33 -0
- package/esm/server/vis_context.d.ts.map +1 -0
- package/esm/server/vis_context.js +2 -0
- package/esm/server/vis_context.logic.d.ts +63 -0
- package/esm/server/vis_context.logic.d.ts.map +1 -0
- package/esm/server/vis_context.logic.js +116 -0
- package/esm/server/vis_context.types.d.ts +20 -0
- package/esm/server/vis_context.types.d.ts.map +1 -0
- package/esm/server/vis_context.types.js +1 -0
- package/esm/setup/create_vis.d.ts +39 -0
- package/esm/setup/create_vis.d.ts.map +1 -0
- package/esm/setup/create_vis.js +96 -0
- package/esm/setup/vis.d.ts +18 -0
- package/esm/setup/vis.d.ts.map +1 -0
- package/esm/setup/vis.js +6 -0
- package/esm/setup.d.ts +5 -0
- package/esm/setup.d.ts.map +1 -0
- package/esm/setup.js +7 -0
- package/esm/shared/base64.d.ts +2 -0
- package/esm/shared/base64.d.ts.map +1 -0
- package/esm/shared/base64.js +3 -0
- package/esm/shared/constants.d.ts +5 -0
- package/esm/shared/constants.d.ts.map +1 -0
- package/esm/shared/constants.js +4 -0
- package/esm/shared/convert_threshold_unit.d.ts +6 -0
- package/esm/shared/convert_threshold_unit.d.ts.map +1 -0
- package/esm/shared/convert_threshold_unit.js +10 -0
- package/esm/shared/get_max_size.d.ts +11 -0
- package/esm/shared/get_max_size.d.ts.map +1 -0
- package/esm/shared/get_max_size.js +5 -0
- package/esm/shared/is_same_size.d.ts +8 -0
- package/esm/shared/is_same_size.d.ts.map +1 -0
- package/esm/shared/is_same_size.js +3 -0
- package/esm/shared/trim_common_folder.d.ts +6 -0
- package/esm/shared/trim_common_folder.d.ts.map +1 -0
- package/esm/shared/trim_common_folder.js +10 -0
- package/esm/shared/types.d.ts +37 -0
- package/esm/shared/types.d.ts.map +1 -0
- package/esm/shared/types.js +1 -0
- package/esm/testing/constants.d.ts +9 -0
- package/esm/testing/constants.d.ts.map +1 -0
- package/esm/testing/constants.js +1933 -0
- package/esm/testing.d.ts +2 -0
- package/esm/testing.d.ts.map +1 -0
- package/esm/testing.js +1 -0
- package/package.json +115 -0
- package/readme.md +264 -0
- package/src/client/ctx.ts +8 -0
- package/src/client/expect/expectation_result.ts +7 -0
- package/src/client/expect/extend.ts +12 -0
- package/src/client/expect/to_match_image_snapshot.logic.ts +11 -0
- package/src/client/expect/to_match_image_snapshot.ts +43 -0
- package/src/client/expect/to_match_image_snapshot.types.ts +14 -0
- package/src/client/page/extend.ts +8 -0
- package/src/client/page/has_image_snapshot.ts +33 -0
- package/src/client/selector.ts +118 -0
- package/src/client/should_take_snapshot.ts +15 -0
- package/src/client/snapshot_options.internal.ts +22 -0
- package/src/client/snapshot_options.ts +53 -0
- package/src/client/task_id.ts +16 -0
- package/src/client.ts +7 -0
- package/src/commands.ts +4 -0
- package/src/config/readme.md +4 -0
- package/src/config/types.ts +35 -0
- package/src/config/vis.ts +30 -0
- package/src/config.ts +3 -0
- package/src/index.ts +2 -0
- package/src/presets/auto.ts +4 -0
- package/src/presets/manual.ts +4 -0
- package/src/server/browser_provider/browser_api.ts +13 -0
- package/src/server/browser_provider/playwright.ts +16 -0
- package/src/server/browser_provider/types.ts +11 -0
- package/src/server/browser_provider/webdriverio.ts +13 -0
- package/src/server/commands/extend.ts +19 -0
- package/src/server/commands/has_image_snapshot.ts +18 -0
- package/src/server/commands/image_snapshot_next_index.ts +17 -0
- package/src/server/commands/is_ci.ts +7 -0
- package/src/server/commands/match_image_snapshot.ts +139 -0
- package/src/server/commands/setup_vis_suite.ts +17 -0
- package/src/server/compare_image.ts +34 -0
- package/src/server/file.ts +15 -0
- package/src/server/readme.md +5 -0
- package/src/server/snapshot_path.ts +12 -0
- package/src/server/vis_context.ctx.ts +12 -0
- package/src/server/vis_context.logic.ts +141 -0
- package/src/server/vis_context.ts +3 -0
- package/src/server/vis_context.types.ts +25 -0
- package/src/setup/create_vis.ts +98 -0
- package/src/setup/vis.ts +7 -0
- package/src/setup.ts +9 -0
- package/src/shared/base64.ts +3 -0
- package/src/shared/constants.ts +4 -0
- package/src/shared/convert_threshold_unit.ts +13 -0
- package/src/shared/get_max_size.ts +5 -0
- package/src/shared/is_same_size.ts +3 -0
- package/src/shared/trim_common_folder.ts +10 -0
- package/src/shared/types.ts +39 -0
- package/src/testing/constants.ts +1936 -0
- package/src/testing.ts +1 -0
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { join, relative } from 'pathe'
|
|
2
|
+
import type { VisOptions } from '../config/types.ts'
|
|
3
|
+
import { DIFF_DIR, RESULT_DIR } from '../shared/constants.ts'
|
|
4
|
+
import { file } from './file.ts'
|
|
5
|
+
import { getSnapshotSubpath, resolveSnapshotRootDir } from './snapshot_path.ts'
|
|
6
|
+
import { ctx } from './vis_context.ctx.ts'
|
|
7
|
+
import type { VisState } from './vis_context.types.ts'
|
|
8
|
+
|
|
9
|
+
export type PartialBrowserCommandContext = {
|
|
10
|
+
project: {
|
|
11
|
+
config: {
|
|
12
|
+
root: string
|
|
13
|
+
snapshotOptions: {
|
|
14
|
+
updateSnapshot: 'all' | 'new' | 'none'
|
|
15
|
+
}
|
|
16
|
+
testTimeout: number
|
|
17
|
+
hookTimeout: number
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
testPath: string | undefined
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function createVisContext() {
|
|
24
|
+
let visOptions: VisOptions = {}
|
|
25
|
+
let state: VisState
|
|
26
|
+
let globalStateReady: Promise<VisState>
|
|
27
|
+
|
|
28
|
+
const context = {
|
|
29
|
+
setOptions(options: VisOptions = {}) {
|
|
30
|
+
visOptions = options
|
|
31
|
+
},
|
|
32
|
+
__test__getOptions() {
|
|
33
|
+
return visOptions
|
|
34
|
+
},
|
|
35
|
+
__test__reset() {
|
|
36
|
+
visOptions = undefined as any
|
|
37
|
+
},
|
|
38
|
+
__test__getState() {
|
|
39
|
+
return state
|
|
40
|
+
},
|
|
41
|
+
/**
|
|
42
|
+
* Setup suite is called on each test file's beforeAll hook.
|
|
43
|
+
* Test files include vitest test files and storybook story files.
|
|
44
|
+
* It needs to make sure there is no race condition between the test files.
|
|
45
|
+
*/
|
|
46
|
+
async setupSuite(context: PartialBrowserCommandContext) {
|
|
47
|
+
if (!globalStateReady) {
|
|
48
|
+
globalStateReady = setupState(context, visOptions)
|
|
49
|
+
state = await globalStateReady
|
|
50
|
+
} else {
|
|
51
|
+
await globalStateReady
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const { suiteId, suite } = createSuite(state, context.testPath!, visOptions)
|
|
55
|
+
state.suites[suiteId] = suite
|
|
56
|
+
await Promise.allSettled([ctx.rimraf(suite.diffDir), ctx.rimraf(suite.resultDir)])
|
|
57
|
+
},
|
|
58
|
+
getSnapshotInfo(testPath: string, name: string, options?: { snapshotFileId?: string | undefined }) {
|
|
59
|
+
const info = context.getSuiteInfo(testPath, name)
|
|
60
|
+
const snapshotFilename = context.getSnapshotFilename(info, options?.snapshotFileId)
|
|
61
|
+
|
|
62
|
+
const { baselineDir, resultDir, diffDir, task } = info
|
|
63
|
+
|
|
64
|
+
task.count = task.count + 1
|
|
65
|
+
const baselinePath = join(baselineDir, snapshotFilename)
|
|
66
|
+
const resultPath = join(resultDir, snapshotFilename)
|
|
67
|
+
const diffPath = join(diffDir, snapshotFilename)
|
|
68
|
+
|
|
69
|
+
return {
|
|
70
|
+
baselinePath,
|
|
71
|
+
resultPath,
|
|
72
|
+
diffPath,
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
getTaskCount(testPath: string, taskId: string) {
|
|
76
|
+
return context.getSuiteInfo(testPath, taskId).task.count
|
|
77
|
+
},
|
|
78
|
+
hasImageSnapshot(testPath: string, taskId: string, snapshotFileId: string | undefined) {
|
|
79
|
+
const info = context.getSuiteInfo(testPath, taskId)
|
|
80
|
+
return file.existFile(join(info.baselineDir, context.getSnapshotFilename(info, snapshotFileId)))
|
|
81
|
+
},
|
|
82
|
+
getSnapshotFilename(info: { taskId: string; task: { count: number } }, snapshotFileId: string | undefined) {
|
|
83
|
+
if (snapshotFileId) return `${snapshotFileId}.png`
|
|
84
|
+
|
|
85
|
+
const customizeSnapshotId = visOptions.customizeSnapshotId ?? ((id, index) => `${id}-${index}`)
|
|
86
|
+
return `${customizeSnapshotId(info.taskId, info.task.count)}.png`
|
|
87
|
+
},
|
|
88
|
+
getSuiteInfo(testPath: string, taskId: string) {
|
|
89
|
+
const suiteId = getSuiteId(state, testPath, visOptions)
|
|
90
|
+
const suite = state.suites[suiteId]!
|
|
91
|
+
const task = (suite.tasks[taskId] = suite.tasks[taskId] ?? { count: 1 })
|
|
92
|
+
return {
|
|
93
|
+
suiteId,
|
|
94
|
+
taskId,
|
|
95
|
+
baselineDir: suite.baselineDir,
|
|
96
|
+
resultDir: suite.resultDir,
|
|
97
|
+
diffDir: suite.diffDir,
|
|
98
|
+
task,
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
}
|
|
102
|
+
return context
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
async function setupState(suite: PartialBrowserCommandContext, visOptions: VisOptions) {
|
|
106
|
+
const snapshotRootDir = resolveSnapshotRootDir(visOptions)
|
|
107
|
+
const projectPath = suite.project.config.root
|
|
108
|
+
const platform = ctx.getSnapshotPlatform()
|
|
109
|
+
|
|
110
|
+
const state = {
|
|
111
|
+
projectPath,
|
|
112
|
+
platform,
|
|
113
|
+
testTimeout: suite.project.config.testTimeout,
|
|
114
|
+
hookTimeout: suite.project.config.hookTimeout,
|
|
115
|
+
snapshotRootDir,
|
|
116
|
+
snapshotBaselineDir: join(snapshotRootDir, platform),
|
|
117
|
+
snapshotResultDir: join(snapshotRootDir, RESULT_DIR),
|
|
118
|
+
snapshotDiffDir: join(snapshotRootDir, DIFF_DIR),
|
|
119
|
+
snapshotRootPath: join(projectPath, snapshotRootDir),
|
|
120
|
+
suites: {},
|
|
121
|
+
}
|
|
122
|
+
await Promise.allSettled([ctx.rimraf(join(state.snapshotDiffDir)), ctx.rimraf(join(state.snapshotResultDir))])
|
|
123
|
+
return state
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export function getSuiteId(state: VisState, testPath: string, options: VisOptions) {
|
|
127
|
+
return getSnapshotSubpath(relative(state.projectPath, testPath), options)
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export function createSuite(state: VisState, testPath: string, options: VisOptions) {
|
|
131
|
+
const suiteId = getSuiteId(state, testPath, options)
|
|
132
|
+
return {
|
|
133
|
+
suiteId,
|
|
134
|
+
suite: {
|
|
135
|
+
baselineDir: join(state.snapshotBaselineDir, suiteId),
|
|
136
|
+
resultDir: join(state.snapshotResultDir, suiteId),
|
|
137
|
+
diffDir: join(state.snapshotDiffDir, suiteId),
|
|
138
|
+
tasks: {},
|
|
139
|
+
},
|
|
140
|
+
}
|
|
141
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export type VisState = {
|
|
2
|
+
projectPath: string
|
|
3
|
+
platform: string
|
|
4
|
+
testTimeout: number
|
|
5
|
+
hookTimeout: number
|
|
6
|
+
snapshotRootDir: string
|
|
7
|
+
snapshotBaselineDir: string
|
|
8
|
+
snapshotResultDir: string
|
|
9
|
+
snapshotDiffDir: string
|
|
10
|
+
snapshotRootPath: string
|
|
11
|
+
suites: Record<
|
|
12
|
+
string,
|
|
13
|
+
{
|
|
14
|
+
baselineDir: string
|
|
15
|
+
resultDir: string
|
|
16
|
+
diffDir: string
|
|
17
|
+
tasks: Record<
|
|
18
|
+
string,
|
|
19
|
+
{
|
|
20
|
+
count: number
|
|
21
|
+
}
|
|
22
|
+
>
|
|
23
|
+
}
|
|
24
|
+
>
|
|
25
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import dedent from 'dedent'
|
|
2
|
+
import { afterEach, beforeAll, expect } from 'vitest'
|
|
3
|
+
import { toTaskId } from '../client.ts'
|
|
4
|
+
import { ctx } from '../client/ctx.ts'
|
|
5
|
+
import { shouldTakeSnapshot } from '../client/should_take_snapshot.ts'
|
|
6
|
+
import { getAutoSnapshotOptions } from '../client/snapshot_options.internal.js'
|
|
7
|
+
import type { SetupVisSuiteCommand } from '../server/commands/setup_vis_suite.ts'
|
|
8
|
+
|
|
9
|
+
export function createVis(commands: SetupVisSuiteCommand) {
|
|
10
|
+
/**
|
|
11
|
+
* Visual test configuration on the client side.
|
|
12
|
+
*/
|
|
13
|
+
const vis = {
|
|
14
|
+
presets: {
|
|
15
|
+
/**
|
|
16
|
+
* Enable manual visual testing.
|
|
17
|
+
*/
|
|
18
|
+
manual() {
|
|
19
|
+
beforeAll(vis.beforeAll.setup)
|
|
20
|
+
},
|
|
21
|
+
/**
|
|
22
|
+
* Enable automatic visual testing.
|
|
23
|
+
*
|
|
24
|
+
* This will take a snapshot after each test.
|
|
25
|
+
*/
|
|
26
|
+
auto() {
|
|
27
|
+
beforeAll(vis.beforeAll.setup)
|
|
28
|
+
afterEach(vis.afterEach.matchImageSnapshot)
|
|
29
|
+
},
|
|
30
|
+
/**
|
|
31
|
+
* Enable automatic visual testing with multiple themes.
|
|
32
|
+
*
|
|
33
|
+
* This will take a snapshot after each test for each theme.
|
|
34
|
+
*
|
|
35
|
+
* @param themes A record of theme names and their setup functions.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```ts
|
|
39
|
+
* vis().presets.theme({
|
|
40
|
+
* light() { document.body.classList.add('light') },
|
|
41
|
+
* dark() { document.body.classList.add('dark') },
|
|
42
|
+
* })
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
theme(themes: Record<string, () => void | Promise<void>>) {
|
|
46
|
+
beforeAll(vis.beforeAll.setup)
|
|
47
|
+
afterEach(vis.afterEach.matchPerTheme(themes))
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
beforeAll: {
|
|
51
|
+
async setup() {
|
|
52
|
+
await commands.setupVisSuite()
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
afterEach: {
|
|
56
|
+
async matchImageSnapshot() {
|
|
57
|
+
const meta = getAutoSnapshotOptions(ctx.getCurrentTest())
|
|
58
|
+
if (!shouldTakeSnapshot(meta)) return
|
|
59
|
+
await expect(document.body).toMatchImageSnapshot(meta)
|
|
60
|
+
},
|
|
61
|
+
matchPerTheme(themes: Record<string, () => Promise<void> | void>) {
|
|
62
|
+
return async function matchImageSnapshot() {
|
|
63
|
+
const test = ctx.getCurrentTest()
|
|
64
|
+
const meta = getAutoSnapshotOptions(test)
|
|
65
|
+
if (!shouldTakeSnapshot(meta)) return
|
|
66
|
+
|
|
67
|
+
const errors: any[] = []
|
|
68
|
+
for (const themeId in themes) {
|
|
69
|
+
try {
|
|
70
|
+
await themes[themeId]!()
|
|
71
|
+
await expect(document.body).toMatchImageSnapshot({
|
|
72
|
+
...meta,
|
|
73
|
+
customizeSnapshotId: (id) => `${id}-${themeId}`,
|
|
74
|
+
})
|
|
75
|
+
} catch (error) {
|
|
76
|
+
errors.push([themeId, error])
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (errors.length > 0) {
|
|
80
|
+
if (errors.length === 1) throw errors[0][1]
|
|
81
|
+
const taskId = toTaskId(test!)
|
|
82
|
+
throw new AggregateError(
|
|
83
|
+
errors,
|
|
84
|
+
dedent`Snapshot \`${taskId}\` mismatched
|
|
85
|
+
|
|
86
|
+
${errors
|
|
87
|
+
.map(([themeId, error]) => {
|
|
88
|
+
return `Theme \`${themeId}\` failed: ${error.message}`
|
|
89
|
+
})
|
|
90
|
+
.join('\n')}`,
|
|
91
|
+
)
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
}
|
|
97
|
+
return vis
|
|
98
|
+
}
|
package/src/setup/vis.ts
ADDED
package/src/setup.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// `vitest-plugin-vis/setup` provides code needed in `vitest.setup.ts`.
|
|
2
|
+
import './client/expect/extend.ts'
|
|
3
|
+
import './client/page/extend.ts'
|
|
4
|
+
|
|
5
|
+
export * from './setup/vis.ts'
|
|
6
|
+
|
|
7
|
+
// This is exported for main/app boundary separation
|
|
8
|
+
// They can co-exist in the same export file thanks to ESM.
|
|
9
|
+
export * from './setup/create_vis.ts'
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export function convertThresholdUnit(
|
|
2
|
+
{ failureThresholdType, width, height }: { failureThresholdType: 'pixel' | 'percent'; width: number; height: number },
|
|
3
|
+
pixelDiff: number,
|
|
4
|
+
): number {
|
|
5
|
+
switch (failureThresholdType) {
|
|
6
|
+
case 'pixel':
|
|
7
|
+
return pixelDiff
|
|
8
|
+
case 'percent':
|
|
9
|
+
return (pixelDiff / (width * height)) * 100
|
|
10
|
+
default:
|
|
11
|
+
throw new Error(`Invalid failureThresholdType: ${failureThresholdType}`)
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trim off common folder such as `src` or `tests` from the test file path.
|
|
3
|
+
* This is used to generate the default snapshot sub-path.
|
|
4
|
+
*/
|
|
5
|
+
export function trimCommonFolder(suiteName: string) {
|
|
6
|
+
const suiteDir = suiteName.split('/', 1)[0]!
|
|
7
|
+
if (['tests', 'test', 'src', 'source', 'js', 'ts', 'lib'].includes(suiteDir))
|
|
8
|
+
return suiteName.slice(suiteDir.length + 1)
|
|
9
|
+
return suiteName
|
|
10
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { PixelmatchOptions } from 'pixelmatch'
|
|
2
|
+
|
|
3
|
+
export interface ImageSnapshotTimeoutOptions {
|
|
4
|
+
/**
|
|
5
|
+
* Timeout for taking the snapshot.
|
|
6
|
+
*
|
|
7
|
+
* Default: 5000 ms locally, 30000 ms on CI.
|
|
8
|
+
*/
|
|
9
|
+
timeout?: number | undefined
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface ImageSnapshotIdOptions {
|
|
13
|
+
/**
|
|
14
|
+
* Customize the snapshot id. This is used as the filename of the snapshot: `${snapshotId}.png`
|
|
15
|
+
*
|
|
16
|
+
* @param id The id of the snapshot.
|
|
17
|
+
* @param index The index of the snapshot.
|
|
18
|
+
*/
|
|
19
|
+
customizeSnapshotId?: (id: string, index: number) => string
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface ImageSnapshotCompareOptions {
|
|
23
|
+
/**
|
|
24
|
+
* Custom options passed to 'pixelmatch'
|
|
25
|
+
*/
|
|
26
|
+
diffOptions?: PixelmatchOptions | undefined
|
|
27
|
+
/**
|
|
28
|
+
* Failure threshold should measure in `pixel` or `percent`.
|
|
29
|
+
*
|
|
30
|
+
* Default is `pixel`.
|
|
31
|
+
*/
|
|
32
|
+
failureThresholdType?: 'pixel' | 'percent' | undefined
|
|
33
|
+
/**
|
|
34
|
+
* Failure tolerance threshold.
|
|
35
|
+
*
|
|
36
|
+
* Default is `0`.
|
|
37
|
+
*/
|
|
38
|
+
failureThreshold?: number | undefined
|
|
39
|
+
}
|