@lullabot/playwright-testing 0.1.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.
Files changed (82) hide show
  1. package/README.md +61 -0
  2. package/bin/github-a11y-summary +5 -0
  3. package/bin/github-failure-summary +8 -0
  4. package/lib/accessibility-baseline-file.d.ts +47 -0
  5. package/lib/accessibility-baseline-file.js +205 -0
  6. package/lib/accessibility-baseline.d.ts +19 -0
  7. package/lib/accessibility-baseline.js +38 -0
  8. package/lib/accessible-screenshot.d.ts +181 -0
  9. package/lib/accessible-screenshot.js +519 -0
  10. package/lib/focus.d.ts +14 -0
  11. package/lib/focus.js +28 -0
  12. package/lib/fonts.d.ts +18 -0
  13. package/lib/fonts.js +24 -0
  14. package/lib/frames.d.ts +7 -0
  15. package/lib/frames.js +27 -0
  16. package/lib/github/a11y-summary.d.ts +55 -0
  17. package/lib/github/a11y-summary.js +383 -0
  18. package/lib/github/attachments.d.ts +98 -0
  19. package/lib/github/attachments.js +297 -0
  20. package/lib/github/failure-summary.d.ts +144 -0
  21. package/lib/github/failure-summary.js +567 -0
  22. package/lib/github/index.d.ts +6 -0
  23. package/lib/github/index.js +35 -0
  24. package/lib/github/report-paths.d.ts +38 -0
  25. package/lib/github/report-paths.js +200 -0
  26. package/lib/hover.d.ts +13 -0
  27. package/lib/hover.js +61 -0
  28. package/lib/images.d.ts +118 -0
  29. package/lib/images.js +260 -0
  30. package/lib/index.d.ts +13 -0
  31. package/lib/index.js +29 -0
  32. package/lib/interaction-states.d.ts +22 -0
  33. package/lib/interaction-states.js +75 -0
  34. package/lib/mock/index.d.ts +1 -0
  35. package/lib/mock/index.js +5 -0
  36. package/lib/mock/youtube.d.ts +5 -0
  37. package/lib/mock/youtube.js +38 -0
  38. package/lib/pseudo-state.d.ts +17 -0
  39. package/lib/pseudo-state.js +50 -0
  40. package/lib/videos.d.ts +134 -0
  41. package/lib/videos.js +349 -0
  42. package/lib/visualdiff.d.ts +154 -0
  43. package/lib/visualdiff.js +197 -0
  44. package/package.json +47 -0
  45. package/src/accessibility-baseline-file.test.ts +181 -0
  46. package/src/accessibility-baseline-file.ts +208 -0
  47. package/src/accessibility-baseline.test.ts +601 -0
  48. package/src/accessibility-baseline.ts +50 -0
  49. package/src/accessible-screenshot.test.ts +597 -0
  50. package/src/accessible-screenshot.ts +809 -0
  51. package/src/focus.test.ts +34 -0
  52. package/src/focus.ts +27 -0
  53. package/src/fonts.test.ts +17 -0
  54. package/src/fonts.ts +23 -0
  55. package/src/frames.test.ts +75 -0
  56. package/src/frames.ts +26 -0
  57. package/src/github/a11y-summary.test.ts +439 -0
  58. package/src/github/a11y-summary.ts +421 -0
  59. package/src/github/attachments.test.ts +248 -0
  60. package/src/github/attachments.ts +328 -0
  61. package/src/github/failure-summary.test.ts +636 -0
  62. package/src/github/failure-summary.ts +720 -0
  63. package/src/github/index.test.ts +24 -0
  64. package/src/github/index.ts +35 -0
  65. package/src/github/report-paths.test.ts +222 -0
  66. package/src/github/report-paths.ts +208 -0
  67. package/src/hover.test.ts +76 -0
  68. package/src/hover.ts +64 -0
  69. package/src/images.test.ts +355 -0
  70. package/src/images.ts +299 -0
  71. package/src/index.ts +13 -0
  72. package/src/interaction-states.test.ts +48 -0
  73. package/src/interaction-states.ts +94 -0
  74. package/src/mock/index.ts +1 -0
  75. package/src/mock/youtube.test.ts +38 -0
  76. package/src/mock/youtube.ts +39 -0
  77. package/src/pseudo-state.test.ts +83 -0
  78. package/src/pseudo-state.ts +69 -0
  79. package/src/videos.test.ts +637 -0
  80. package/src/videos.ts +389 -0
  81. package/src/visualdiff.test.ts +452 -0
  82. package/src/visualdiff.ts +381 -0
@@ -0,0 +1,452 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest'
2
+ import {
3
+ defaultTestFunction,
4
+ defineVisualDiffConfig,
5
+ VisualDiff,
6
+ VisualDiffGroup,
7
+ VisualDiffTestCases,
8
+ VisualDiffUrlConfig,
9
+ } from './visualdiff'
10
+
11
+ const {mockTest, mockDescribe, mockSkip} = vi.hoisted(() => {
12
+ const mockTest = vi.fn()
13
+ const mockDescribe = vi.fn((_name: string, callback: () => void) => callback())
14
+ const mockSkip = vi.fn()
15
+ return {mockTest, mockDescribe, mockSkip}
16
+ })
17
+
18
+ vi.mock('@playwright/test', () => ({
19
+ test: Object.assign(mockTest, {describe: mockDescribe, skip: mockSkip}),
20
+ }))
21
+
22
+ // Mock takeAccessibleScreenshot to capture the options passed to it.
23
+ const mockTakeAccessibleScreenshot = vi.fn()
24
+ const mockForcePseudoState = vi.fn()
25
+ vi.mock('./accessible-screenshot', () => ({
26
+ takeAccessibleScreenshot: (...args: any[]) => mockTakeAccessibleScreenshot(...args),
27
+ }))
28
+ vi.mock('./pseudo-state', () => ({
29
+ forcePseudoState: (...args: any[]) => mockForcePseudoState(...args),
30
+ }))
31
+
32
+ function makeTestCase(overrides?: Partial<VisualDiff>): VisualDiff {
33
+ return {
34
+ name: 'Test',
35
+ path: '/test',
36
+ ...overrides,
37
+ }
38
+ }
39
+
40
+ function makeGroup(overrides?: Partial<VisualDiffGroup>): VisualDiffGroup {
41
+ return {
42
+ name: 'Group',
43
+ testCases: [],
44
+ ...overrides,
45
+ }
46
+ }
47
+
48
+ function makeConfig(overrides?: Partial<VisualDiffUrlConfig>): VisualDiffUrlConfig {
49
+ return {
50
+ name: 'Config',
51
+ groups: [],
52
+ ...overrides,
53
+ }
54
+ }
55
+
56
+ /**
57
+ * Execute the function returned by defaultTestFunction with mock page/context/testInfo.
58
+ */
59
+ async function runDefaultTestFunction(
60
+ testCase: VisualDiff,
61
+ group: VisualDiffGroup,
62
+ config?: VisualDiffUrlConfig,
63
+ preset?: Parameters<typeof defaultTestFunction>[3],
64
+ ) {
65
+ const fn = defaultTestFunction(testCase, group, config, preset)
66
+ const mockLocator = vi.fn((selector: string) => ({ _selector: selector }))
67
+ const mockPage = {
68
+ goto: vi.fn(),
69
+ locator: mockLocator,
70
+ }
71
+ const mockContext = {
72
+ on: vi.fn(),
73
+ }
74
+ const mockTestInfo = {
75
+ annotations: [],
76
+ }
77
+ await fn({ page: mockPage, context: mockContext }, mockTestInfo)
78
+ return { mockPage, mockTestInfo }
79
+ }
80
+
81
+ describe('defaultTestFunction mask merging', () => {
82
+ beforeEach(() => {
83
+ mockTakeAccessibleScreenshot.mockReset()
84
+ mockForcePseudoState.mockReset()
85
+ })
86
+
87
+ it('merges masks from all three levels', async () => {
88
+ const config = makeConfig({ mask: ['.config-mask'] })
89
+ const group = makeGroup({ mask: ['.group-mask'] })
90
+ const testCase = makeTestCase({ mask: ['.test-mask'] })
91
+
92
+ await runDefaultTestFunction(testCase, group, config)
93
+
94
+ const options = mockTakeAccessibleScreenshot.mock.calls[0][2]
95
+ expect(options.mask).toHaveLength(3)
96
+ expect(options.mask[0]).toEqual({ _selector: '.config-mask' })
97
+ expect(options.mask[1]).toEqual({ _selector: '.group-mask' })
98
+ expect(options.mask[2]).toEqual({ _selector: '.test-mask' })
99
+ })
100
+
101
+ it('works with masks from a single level', async () => {
102
+ const group = makeGroup({ mask: ['.only-group'] })
103
+ const testCase = makeTestCase()
104
+
105
+ await runDefaultTestFunction(testCase, group)
106
+
107
+ const options = mockTakeAccessibleScreenshot.mock.calls[0][2]
108
+ expect(options.mask).toHaveLength(1)
109
+ expect(options.mask[0]).toEqual({ _selector: '.only-group' })
110
+ })
111
+
112
+ it('handles empty/undefined masks at some levels', async () => {
113
+ const config = makeConfig({ mask: ['.config-a', '.config-b'] })
114
+ const group = makeGroup() // no mask
115
+ const testCase = makeTestCase({ mask: ['.test-only'] })
116
+
117
+ await runDefaultTestFunction(testCase, group, config)
118
+
119
+ const options = mockTakeAccessibleScreenshot.mock.calls[0][2]
120
+ expect(options.mask).toHaveLength(3)
121
+ expect(options.mask[0]).toEqual({ _selector: '.config-a' })
122
+ expect(options.mask[1]).toEqual({ _selector: '.config-b' })
123
+ expect(options.mask[2]).toEqual({ _selector: '.test-only' })
124
+ })
125
+
126
+ it('does not include mask property when no masks are defined', async () => {
127
+ const testCase = makeTestCase()
128
+ const group = makeGroup()
129
+
130
+ await runDefaultTestFunction(testCase, group)
131
+
132
+ const options = mockTakeAccessibleScreenshot.mock.calls[0][2]
133
+ expect(options.mask).toBeUndefined()
134
+ expect(options.fullPage).toBe(true)
135
+ })
136
+
137
+ it('resolves maskColor with most-specific-wins: testCase > group > config', async () => {
138
+ const config = makeConfig({ maskColor: '#111' })
139
+ const group = makeGroup({ maskColor: '#222' })
140
+ const testCase = makeTestCase({ maskColor: '#333' })
141
+
142
+ await runDefaultTestFunction(testCase, group, config)
143
+
144
+ const options = mockTakeAccessibleScreenshot.mock.calls[0][2]
145
+ expect(options.maskColor).toBe('#333')
146
+ })
147
+
148
+ it('falls back maskColor to group when testCase is undefined', async () => {
149
+ const config = makeConfig({ maskColor: '#111' })
150
+ const group = makeGroup({ maskColor: '#222' })
151
+ const testCase = makeTestCase()
152
+
153
+ await runDefaultTestFunction(testCase, group, config)
154
+
155
+ const options = mockTakeAccessibleScreenshot.mock.calls[0][2]
156
+ expect(options.maskColor).toBe('#222')
157
+ })
158
+
159
+ it('falls back maskColor to config when testCase and group are undefined', async () => {
160
+ const config = makeConfig({ maskColor: '#111' })
161
+ const group = makeGroup()
162
+ const testCase = makeTestCase()
163
+
164
+ await runDefaultTestFunction(testCase, group, config)
165
+
166
+ const options = mockTakeAccessibleScreenshot.mock.calls[0][2]
167
+ expect(options.maskColor).toBe('#111')
168
+ })
169
+
170
+ it('does not include maskColor when none are defined', async () => {
171
+ const testCase = makeTestCase()
172
+ const group = makeGroup()
173
+
174
+ await runDefaultTestFunction(testCase, group)
175
+
176
+ const options = mockTakeAccessibleScreenshot.mock.calls[0][2]
177
+ expect(options.maskColor).toBeUndefined()
178
+ })
179
+ })
180
+
181
+ describe('defaultTestFunction pseudo-state handling', () => {
182
+ beforeEach(() => {
183
+ vi.clearAllMocks()
184
+ mockForcePseudoState.mockImplementation(async () => vi.fn())
185
+ })
186
+
187
+ it('merges pseudo-states from all three levels and keeps them through the scan', async () => {
188
+ const clearConfigState = vi.fn()
189
+ const clearGroupState = vi.fn()
190
+ const clearTestState = vi.fn()
191
+ mockForcePseudoState
192
+ .mockResolvedValueOnce(clearConfigState)
193
+ .mockResolvedValueOnce(clearGroupState)
194
+ .mockResolvedValueOnce(clearTestState)
195
+ const config = makeConfig({
196
+ pseudoStates: [{selector: '.nav', pseudoClasses: ['hover']}],
197
+ })
198
+ const group = makeGroup({
199
+ pseudoStates: [{selector: '.menu', pseudoClasses: ['focus-within']}],
200
+ })
201
+ const testCase = makeTestCase({
202
+ pseudoStates: [{selector: '.link', pseudoClasses: ['focus-visible']}],
203
+ })
204
+
205
+ const {mockPage} = await runDefaultTestFunction(testCase, group, config)
206
+
207
+ expect(mockForcePseudoState.mock.calls).toEqual([
208
+ [mockPage, '.nav', ['hover']],
209
+ [mockPage, '.menu', ['focus-within']],
210
+ [mockPage, '.link', ['focus-visible']],
211
+ ])
212
+ expect(mockTakeAccessibleScreenshot).toHaveBeenCalledOnce()
213
+ expect(clearTestState.mock.invocationCallOrder[0])
214
+ .toBeGreaterThan(mockTakeAccessibleScreenshot.mock.invocationCallOrder[0])
215
+ expect(clearTestState.mock.invocationCallOrder[0])
216
+ .toBeLessThan(clearGroupState.mock.invocationCallOrder[0])
217
+ expect(clearGroupState.mock.invocationCallOrder[0])
218
+ .toBeLessThan(clearConfigState.mock.invocationCallOrder[0])
219
+ })
220
+
221
+ it('clears forced states when the screenshot or accessibility scan fails', async () => {
222
+ const clearState = vi.fn()
223
+ mockForcePseudoState.mockResolvedValueOnce(clearState)
224
+ mockTakeAccessibleScreenshot.mockRejectedValueOnce(new Error('scan failed'))
225
+ const testCase = makeTestCase({
226
+ pseudoStates: [{selector: 'button', pseudoClasses: ['focus']}],
227
+ })
228
+
229
+ await expect(runDefaultTestFunction(testCase, makeGroup())).rejects.toThrow('scan failed')
230
+
231
+ expect(clearState).toHaveBeenCalledOnce()
232
+ })
233
+
234
+ it('attempts every cleanup in reverse order when one cleanup fails', async () => {
235
+ const events: string[] = []
236
+ const clearConfigState = vi.fn(async () => { events.push('config') })
237
+ const clearGroupState = vi.fn(async () => {
238
+ events.push('group')
239
+ throw new Error('group cleanup failed')
240
+ })
241
+ const clearTestState = vi.fn(async () => { events.push('test') })
242
+ mockForcePseudoState
243
+ .mockResolvedValueOnce(clearConfigState)
244
+ .mockResolvedValueOnce(clearGroupState)
245
+ .mockResolvedValueOnce(clearTestState)
246
+
247
+ await expect(runDefaultTestFunction(
248
+ makeTestCase({pseudoStates: [{selector: '.test', pseudoClasses: ['hover']}]}),
249
+ makeGroup({pseudoStates: [{selector: '.group', pseudoClasses: ['focus']}]}),
250
+ makeConfig({pseudoStates: [{selector: '.config', pseudoClasses: ['active']}]}),
251
+ )).rejects.toThrow('group cleanup failed')
252
+
253
+ expect(events).toEqual(['test', 'group', 'config'])
254
+ })
255
+ })
256
+
257
+ describe('defaultTestFunction precedence and preset injection', () => {
258
+ beforeEach(() => {
259
+ vi.clearAllMocks()
260
+ mockForcePseudoState.mockImplementation(async () => vi.fn())
261
+ })
262
+
263
+ it('combines config and group path prefixes and uses the most specific representative URL', async () => {
264
+ const config = makeConfig({pathPrefix: '/site', representativeUrl: 'https://example.com/config'} as any)
265
+ const group = makeGroup({pathPrefix: '/section', representativeUrl: 'https://example.com/group'})
266
+ const testCase = makeTestCase({path: '/page', representativeUrl: 'https://example.com/case'})
267
+
268
+ const {mockPage, mockTestInfo} = await runDefaultTestFunction(testCase, group, config)
269
+
270
+ expect(mockPage.goto).toHaveBeenCalledWith('/site/section/page')
271
+ expect(mockTestInfo.annotations).toContainEqual({
272
+ type: 'Representative URL',
273
+ description: 'https://example.com/case',
274
+ })
275
+ })
276
+
277
+ it('uses the most specific accessibility baseline and merges it with preset options', async () => {
278
+ const configBaseline = [{rule: 'config', targets: ['#config'], reason: 'Known', willBeFixedIn: 'PROJ-1'}]
279
+ const groupBaseline = [{rule: 'group', targets: ['#group'], reason: 'Known', willBeFixedIn: 'PROJ-2'}]
280
+ const caseBaseline = [{rule: 'case', targets: ['#case'], reason: 'Known', willBeFixedIn: 'PROJ-3'}]
281
+ const preset = {
282
+ screenshotOptions: vi.fn().mockResolvedValue({
283
+ threshold: 0.4,
284
+ accessibility: {wcagExclude: ['.adapter-owned']},
285
+ }),
286
+ }
287
+
288
+ await runDefaultTestFunction(
289
+ makeTestCase({a11yBaseline: caseBaseline} as any),
290
+ makeGroup({a11yBaseline: groupBaseline} as any),
291
+ makeConfig({a11yBaseline: configBaseline}),
292
+ preset,
293
+ )
294
+
295
+ const options = mockTakeAccessibleScreenshot.mock.calls[0][2]
296
+ expect(options.threshold).toBe(0.4)
297
+ expect(options.accessibility).toEqual({
298
+ wcagExclude: ['.adapter-owned'],
299
+ baseline: caseBaseline,
300
+ })
301
+ })
302
+
303
+ it('falls back to group-level representative URL and accessibility baseline', async () => {
304
+ const configBaseline = [{rule: 'config', targets: ['#config'], reason: 'Known', willBeFixedIn: 'PROJ-1'}]
305
+ const groupBaseline = [{rule: 'group', targets: ['#group'], reason: 'Known', willBeFixedIn: 'PROJ-2'}]
306
+
307
+ const {mockTestInfo} = await runDefaultTestFunction(
308
+ makeTestCase(),
309
+ makeGroup({
310
+ representativeUrl: 'https://example.com/group',
311
+ a11yBaseline: groupBaseline,
312
+ }),
313
+ makeConfig({
314
+ representativeUrl: 'https://example.com/config',
315
+ a11yBaseline: configBaseline,
316
+ }),
317
+ )
318
+
319
+ expect(mockTestInfo.annotations).toContainEqual({
320
+ type: 'Representative URL',
321
+ description: 'https://example.com/group',
322
+ })
323
+ expect(mockTakeAccessibleScreenshot.mock.calls[0][2].accessibility.baseline)
324
+ .toBe(groupBaseline)
325
+ })
326
+
327
+ it('installs a case mock before navigation', async () => {
328
+ const mock = vi.fn().mockResolvedValue(undefined)
329
+ class CaseMock { mock = mock }
330
+
331
+ const {mockPage} = await runDefaultTestFunction(
332
+ makeTestCase({mockClass: CaseMock}),
333
+ makeGroup(),
334
+ )
335
+
336
+ expect(mock).toHaveBeenCalledWith(mockPage)
337
+ expect(mock.mock.invocationCallOrder[0]).toBeLessThan(mockPage.goto.mock.invocationCallOrder[0])
338
+ })
339
+
340
+ it('falls back to a group mock when a case does not define one', async () => {
341
+ const mock = vi.fn().mockResolvedValue(undefined)
342
+ class GroupMock { mock = mock }
343
+
344
+ const {mockPage} = await runDefaultTestFunction(
345
+ makeTestCase(),
346
+ makeGroup({mockClass: GroupMock}),
347
+ )
348
+
349
+ expect(mock).toHaveBeenCalledWith(mockPage)
350
+ })
351
+
352
+ it('forwards defineVisualDiffConfig preset options into generated tests', async () => {
353
+ const preset = {screenshotOptions: {threshold: 0.25}}
354
+ const visualTests = defineVisualDiffConfig(makeConfig({
355
+ groups: [makeGroup({testCases: [makeTestCase()]})],
356
+ }), preset)
357
+ visualTests.describe()
358
+
359
+ const generatedTest = mockTest.mock.calls[0][1]
360
+ const page = {goto: vi.fn(), locator: vi.fn()}
361
+ const context = {on: vi.fn()}
362
+ const testInfo = {annotations: []}
363
+ await generatedTest({page, context}, testInfo)
364
+
365
+ expect(mockTakeAccessibleScreenshot.mock.calls[0][2]).toMatchObject({
366
+ fullPage: true,
367
+ threshold: 0.25,
368
+ })
369
+ })
370
+ })
371
+
372
+ describe('VisualDiffTestCases.describe skip semantics', () => {
373
+ beforeEach(() => vi.clearAllMocks())
374
+
375
+ it('registers skipped groups and cases with their reason and tracking reference', () => {
376
+ const config = makeConfig({groups: [
377
+ makeGroup({
378
+ name: 'Skipped group',
379
+ skip: {reason: 'Unavailable', willBeFixedIn: 'PROJ-10'},
380
+ }),
381
+ makeGroup({
382
+ name: 'Active group',
383
+ testCases: [makeTestCase({
384
+ name: 'Skipped case',
385
+ skip: {reason: 'Flaky', willBeFixedIn: 'PROJ-11'},
386
+ })],
387
+ }),
388
+ ]})
389
+
390
+ const visualTests = new VisualDiffTestCases(config)
391
+ visualTests.describe()
392
+
393
+ expect(mockSkip).toHaveBeenCalledWith(
394
+ 'Skipped group: Unavailable <PROJ-10>',
395
+ expect.any(Function),
396
+ )
397
+ expect(mockSkip).toHaveBeenCalledWith(
398
+ 'Skipped case: Flaky <PROJ-11>',
399
+ expect.any(Function),
400
+ )
401
+ })
402
+
403
+ it('defines a test when a conditional skip callback returns false', () => {
404
+ const config = makeConfig({groups: [makeGroup({
405
+ name: 'Conditional group',
406
+ skip: {reason: 'Conditional', willBeFixedIn: 'PROJ-12', callback: () => false},
407
+ testCases: [makeTestCase()],
408
+ })]})
409
+
410
+ const visualTests = new VisualDiffTestCases(config)
411
+ visualTests.describe()
412
+
413
+ expect(mockSkip).not.toHaveBeenCalled()
414
+ expect(mockDescribe).toHaveBeenCalledWith('Conditional group', expect.any(Function))
415
+ expect(mockTest).toHaveBeenCalledWith('Test: /test', expect.any(Function))
416
+ })
417
+ })
418
+
419
+ describe('defaultTestFunction interaction-state handling', () => {
420
+ beforeEach(() => {
421
+ vi.clearAllMocks()
422
+ })
423
+
424
+ it('merges cross-browser interaction states from all three levels', async () => {
425
+ const config = makeConfig({
426
+ interactionStates: [{selector: '.nav', states: ['hover']}],
427
+ })
428
+ const group = makeGroup({
429
+ interactionStates: [{selector: '.menu-item', states: ['focus']}],
430
+ })
431
+ const testCase = makeTestCase({
432
+ interactionStates: [{selector: '.trigger', states: ['hover', 'focus']}],
433
+ })
434
+
435
+ const {mockPage} = await runDefaultTestFunction(testCase, group, config)
436
+
437
+ expect(mockTakeAccessibleScreenshot.mock.calls[0][2].interactionStates).toEqual([
438
+ {locator: {_selector: '.nav'}, states: ['hover']},
439
+ {locator: {_selector: '.menu-item'}, states: ['focus']},
440
+ {locator: {_selector: '.trigger'}, states: ['hover', 'focus']},
441
+ ])
442
+ expect(mockPage.locator).toHaveBeenCalledWith('.nav')
443
+ expect(mockPage.locator).toHaveBeenCalledWith('.menu-item')
444
+ expect(mockPage.locator).toHaveBeenCalledWith('.trigger')
445
+ })
446
+
447
+ it('omits interactionStates when none are configured', async () => {
448
+ await runDefaultTestFunction(makeTestCase(), makeGroup())
449
+
450
+ expect(mockTakeAccessibleScreenshot.mock.calls[0][2].interactionStates).toBeUndefined()
451
+ })
452
+ })