Skip to content

Commit e8ce94c

Browse files
authored
fix(snapshot)!: reset snapshot state for retry and repeats (#6817)
1 parent db7a888 commit e8ce94c

31 files changed

+554
-145
lines changed

packages/snapshot/src/client.ts

Lines changed: 44 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,13 @@ export interface Context {
3434

3535
interface AssertOptions {
3636
received: unknown
37-
filepath?: string
38-
name?: string
37+
filepath: string
38+
name: string
39+
/**
40+
* Not required but needed for `SnapshotClient.clearTest` to implement test-retry behavior.
41+
* @default name
42+
*/
43+
testId?: string
3944
message?: string
4045
isInline?: boolean
4146
properties?: object
@@ -50,51 +55,55 @@ export interface SnapshotClientOptions {
5055
}
5156

5257
export class SnapshotClient {
53-
filepath?: string
54-
name?: string
55-
snapshotState: SnapshotState | undefined
5658
snapshotStateMap: Map<string, SnapshotState> = new Map()
5759

5860
constructor(private options: SnapshotClientOptions = {}) {}
5961

60-
async startCurrentRun(
62+
async setup(
6163
filepath: string,
62-
name: string,
6364
options: SnapshotStateOptions,
6465
): Promise<void> {
65-
this.filepath = filepath
66-
this.name = name
67-
68-
if (this.snapshotState?.testFilePath !== filepath) {
69-
await this.finishCurrentRun()
70-
71-
if (!this.getSnapshotState(filepath)) {
72-
this.snapshotStateMap.set(
73-
filepath,
74-
await SnapshotState.create(filepath, options),
75-
)
76-
}
77-
this.snapshotState = this.getSnapshotState(filepath)
66+
if (this.snapshotStateMap.has(filepath)) {
67+
return
7868
}
69+
this.snapshotStateMap.set(
70+
filepath,
71+
await SnapshotState.create(filepath, options),
72+
)
7973
}
8074

81-
getSnapshotState(filepath: string): SnapshotState {
82-
return this.snapshotStateMap.get(filepath)!
75+
async finish(filepath: string): Promise<SnapshotResult> {
76+
const state = this.getSnapshotState(filepath)
77+
const result = await state.pack()
78+
this.snapshotStateMap.delete(filepath)
79+
return result
80+
}
81+
82+
skipTest(filepath: string, testName: string): void {
83+
const state = this.getSnapshotState(filepath)
84+
state.markSnapshotsAsCheckedForTest(testName)
8385
}
8486

85-
clearTest(): void {
86-
this.filepath = undefined
87-
this.name = undefined
87+
clearTest(filepath: string, testId: string): void {
88+
const state = this.getSnapshotState(filepath)
89+
state.clearTest(testId)
8890
}
8991

90-
skipTestSnapshots(name: string): void {
91-
this.snapshotState?.markSnapshotsAsCheckedForTest(name)
92+
getSnapshotState(filepath: string): SnapshotState {
93+
const state = this.snapshotStateMap.get(filepath)
94+
if (!state) {
95+
throw new Error(
96+
`The snapshot state for '${filepath}' is not found. Did you call 'SnapshotClient.setup()'?`,
97+
)
98+
}
99+
return state
92100
}
93101

94102
assert(options: AssertOptions): void {
95103
const {
96-
filepath = this.filepath,
97-
name = this.name,
104+
filepath,
105+
name,
106+
testId = name,
98107
message,
99108
isInline = false,
100109
properties,
@@ -109,6 +118,8 @@ export class SnapshotClient {
109118
throw new Error('Snapshot cannot be used outside of test')
110119
}
111120

121+
const snapshotState = this.getSnapshotState(filepath)
122+
112123
if (typeof properties === 'object') {
113124
if (typeof received !== 'object' || !received) {
114125
throw new Error(
@@ -122,7 +133,7 @@ export class SnapshotClient {
122133
if (!pass) {
123134
throw createMismatchError(
124135
'Snapshot properties mismatched',
125-
this.snapshotState?.expand,
136+
snapshotState.expand,
126137
received,
127138
properties,
128139
)
@@ -139,9 +150,8 @@ export class SnapshotClient {
139150

140151
const testName = [name, ...(message ? [message] : [])].join(' > ')
141152

142-
const snapshotState = this.getSnapshotState(filepath)
143-
144153
const { actual, expected, key, pass } = snapshotState.match({
154+
testId,
145155
testName,
146156
received,
147157
isInline,
@@ -153,7 +163,7 @@ export class SnapshotClient {
153163
if (!pass) {
154164
throw createMismatchError(
155165
`Snapshot \`${key || 'unknown'}\` mismatched`,
156-
this.snapshotState?.expand,
166+
snapshotState.expand,
157167
actual?.trim(),
158168
expected?.trim(),
159169
)
@@ -165,7 +175,7 @@ export class SnapshotClient {
165175
throw new Error('Raw snapshot is required')
166176
}
167177

168-
const { filepath = this.filepath, rawSnapshot } = options
178+
const { filepath, rawSnapshot } = options
169179

170180
if (rawSnapshot.content == null) {
171181
if (!filepath) {
@@ -189,16 +199,6 @@ export class SnapshotClient {
189199
return this.assert(options)
190200
}
191201

192-
async finishCurrentRun(): Promise<SnapshotResult | null> {
193-
if (!this.snapshotState) {
194-
return null
195-
}
196-
const result = await this.snapshotState.pack()
197-
198-
this.snapshotState = undefined
199-
return result
200-
}
201-
202202
clear(): void {
203203
this.snapshotStateMap.clear()
204204
}

packages/snapshot/src/port/inlineSnapshot.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99

1010
export interface InlineSnapshot {
1111
snapshot: string
12+
testId: string
1213
file: string
1314
line: number
1415
column: number

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy