@quickpickle/vitest-browser 0.1.0 → 0.2.1
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/CHANGELOG.md +21 -0
- package/README.md +3 -2
- package/dist/VitestBrowserWorld.cjs +66 -16
- package/dist/VitestBrowserWorld.cjs.map +1 -1
- package/dist/VitestBrowserWorld.d.ts +16 -18
- package/dist/VitestBrowserWorld.mjs +67 -17
- package/dist/VitestBrowserWorld.mjs.map +1 -1
- package/dist/actions.steps.cjs +2 -2
- package/dist/actions.steps.cjs.map +1 -1
- package/dist/actions.steps.mjs +2 -2
- package/dist/actions.steps.mjs.map +1 -1
- package/dist/frameworks/ReactBrowserWorld.cjs +2 -0
- package/dist/frameworks/ReactBrowserWorld.cjs.map +1 -1
- package/dist/frameworks/ReactBrowserWorld.mjs +2 -0
- package/dist/frameworks/ReactBrowserWorld.mjs.map +1 -1
- package/dist/frameworks/SvelteBrowserWorld.cjs +2 -0
- package/dist/frameworks/SvelteBrowserWorld.cjs.map +1 -1
- package/dist/frameworks/SvelteBrowserWorld.mjs +2 -0
- package/dist/frameworks/SvelteBrowserWorld.mjs.map +1 -1
- package/dist/frameworks/VueBrowserWorld.cjs +2 -0
- package/dist/frameworks/VueBrowserWorld.cjs.map +1 -1
- package/dist/frameworks/VueBrowserWorld.mjs +2 -0
- package/dist/frameworks/VueBrowserWorld.mjs.map +1 -1
- package/dist/frameworks/react.cjs +2 -0
- package/dist/frameworks/react.cjs.map +1 -1
- package/dist/frameworks/react.mjs +2 -0
- package/dist/frameworks/react.mjs.map +1 -1
- package/dist/frameworks/svelte.cjs +2 -0
- package/dist/frameworks/svelte.cjs.map +1 -1
- package/dist/frameworks/svelte.mjs +2 -0
- package/dist/frameworks/svelte.mjs.map +1 -1
- package/dist/frameworks/vue.cjs +2 -0
- package/dist/frameworks/vue.cjs.map +1 -1
- package/dist/frameworks/vue.mjs +2 -0
- package/dist/frameworks/vue.mjs.map +1 -1
- package/dist/outcomes.steps.cjs +4 -22
- package/dist/outcomes.steps.cjs.map +1 -1
- package/dist/outcomes.steps.mjs +4 -22
- package/dist/outcomes.steps.mjs.map +1 -1
- package/package.json +5 -4
- package/rollup.config.js +1 -1
- package/src/VitestBrowserWorld.ts +85 -26
- package/src/actions.steps.ts +2 -2
- package/src/outcomes.steps.ts +4 -22
- package/tests/generic/browser-actions.feature +5 -5
- package/tests/generic/browser-generic.feature +26 -64
- package/tests/generic/generic.steps.ts +27 -6
- package/vitest.workspace.ts +30 -27
package/src/actions.steps.ts
CHANGED
|
@@ -148,10 +148,10 @@ When('I uncheck (the ){string}( checkbox)( box)', async function (world:VitestBr
|
|
|
148
148
|
// })
|
|
149
149
|
|
|
150
150
|
When('I wait (for ){int}ms', async function (world:VitestBrowserWorld, num) {
|
|
151
|
-
await world.
|
|
151
|
+
await world.wait(num)
|
|
152
152
|
})
|
|
153
153
|
When('I wait (for ){float} second(s)', async function (world:VitestBrowserWorld, num) {
|
|
154
|
-
await world.
|
|
154
|
+
await world.wait(num * 1000)
|
|
155
155
|
})
|
|
156
156
|
|
|
157
157
|
// ================
|
package/src/outcomes.steps.ts
CHANGED
|
@@ -232,34 +232,16 @@ Then('a/an/the (value of )(the ){string} {word} should not/NOT be/equal {int}',
|
|
|
232
232
|
|
|
233
233
|
// Visual regression testing
|
|
234
234
|
Then('(the )screenshot/snapshot should match', async function (world:VitestBrowserWorld) {
|
|
235
|
-
await
|
|
236
|
-
...world.worldConfig.screenshotOptions,
|
|
237
|
-
customSnapshotsDir: world.screenshotDir,
|
|
238
|
-
customSnapshotIdentifier: world.screenshotFilename,
|
|
239
|
-
})
|
|
235
|
+
await world.expectScreenshotMatch(world.page)
|
|
240
236
|
})
|
|
241
237
|
Then('(the )screenshot/snapshot {string} should match', async function (world:VitestBrowserWorld, name:string) {
|
|
242
|
-
|
|
243
|
-
await expect(world.page).toMatchImageSnapshot({
|
|
244
|
-
...world.worldConfig.screenshotOptions,
|
|
245
|
-
customSnapshotsDir: world.screenshotDir,
|
|
246
|
-
customSnapshotIdentifier: `${name}${explodedTags}`,
|
|
247
|
-
})
|
|
238
|
+
await world.expectScreenshotMatch(world.page, name)
|
|
248
239
|
})
|
|
249
240
|
Then('(the )screenshot/snapshot of the {string} {word} should match', async function (world:VitestBrowserWorld, identifier, role) {
|
|
250
241
|
let locator = await world.getLocator(world.page, identifier, role)
|
|
251
|
-
await
|
|
252
|
-
...world.worldConfig.screenshotOptions,
|
|
253
|
-
customSnapshotsDir: world.screenshotDir,
|
|
254
|
-
customSnapshotIdentifier: world.screenshotFilename,
|
|
255
|
-
})
|
|
242
|
+
await world.expectScreenshotMatch(locator)
|
|
256
243
|
})
|
|
257
244
|
Then('(the )screenshot/snapshot {string} of the {string} {word} should match', async function (world:VitestBrowserWorld, name, identifier, role) {
|
|
258
245
|
let locator = await world.getLocator(world.page, identifier, role)
|
|
259
|
-
|
|
260
|
-
await expect(locator).toMatchImageSnapshot({
|
|
261
|
-
...world.worldConfig.screenshotOptions,
|
|
262
|
-
customSnapshotsDir: world.screenshotDir,
|
|
263
|
-
customSnapshotIdentifier: `${name}${explodedTags}`,
|
|
264
|
-
})
|
|
246
|
+
await world.expectScreenshotMatch(locator, name)
|
|
265
247
|
})
|
|
@@ -168,7 +168,7 @@ Feature: Actions step definitions in Vitest Browser
|
|
|
168
168
|
|
|
169
169
|
Scenario: Taking a default screenshot
|
|
170
170
|
When I take a screenshot
|
|
171
|
-
Then the screenshot "Actions step definitions in Vitest Browser_Taking a default screenshot_01.png" should exist--delete it
|
|
171
|
+
Then the screenshot "Feature Actions step definitions in Vitest Browser_Taking a default screenshot_01.png" should exist--delete it
|
|
172
172
|
|
|
173
173
|
Scenario: Taking a named screenshot
|
|
174
174
|
When I take a screenshot named "pickles"
|
|
@@ -184,10 +184,10 @@ Feature: Actions step definitions in Vitest Browser
|
|
|
184
184
|
|
|
185
185
|
@sequential
|
|
186
186
|
Scenario: Cleaning up the screenshots with exploded tags
|
|
187
|
-
Then the screenshot "Actions step definitions in Vitest Browser_Taking a default screenshot with exploded tags (sequential,tag1)_01.png" should exist--delete it
|
|
188
|
-
And the screenshot "Actions step definitions in Vitest Browser_Taking a default screenshot with exploded tags (sequential,tag2)_01.png" should exist--delete it
|
|
187
|
+
Then the screenshot "Feature Actions step definitions in Vitest Browser_Taking a default screenshot with exploded tags (sequential,tag1)_01.png" should exist--delete it
|
|
188
|
+
And the screenshot "Feature Actions step definitions in Vitest Browser_Taking a default screenshot with exploded tags (sequential,tag2)_01.png" should exist--delete it
|
|
189
189
|
|
|
190
190
|
@sequential @skip-ci
|
|
191
191
|
Scenario: Cleaning up the screenshots with exploded tags
|
|
192
|
-
And the screenshot "
|
|
193
|
-
And the screenshot "
|
|
192
|
+
And the screenshot "temp_(sequential,tag1).png" should exist--delete it
|
|
193
|
+
And the screenshot "temp_(sequential,tag2).png" should exist--delete it
|
|
@@ -1,79 +1,41 @@
|
|
|
1
|
-
@todo
|
|
2
1
|
Feature: Basic tests of Vitest Browser Mode and steps
|
|
3
2
|
|
|
4
|
-
|
|
3
|
+
Background:
|
|
4
|
+
Given I render the "Example" component
|
|
5
|
+
|
|
5
6
|
Rule: Visual regression testing must be supported
|
|
6
7
|
|
|
8
|
+
@soft
|
|
9
|
+
Example: New visual regression test
|
|
10
|
+
Given the screenshot "example" does not exist
|
|
11
|
+
When the screenshot "example" should match
|
|
12
|
+
Then the screenshot "example" should exist--delete it
|
|
13
|
+
And there should have been 1 error
|
|
14
|
+
|
|
7
15
|
Example: Passing visual regression test
|
|
8
|
-
|
|
9
|
-
Then the screenshot should match
|
|
16
|
+
Given the screenshot should match
|
|
10
17
|
|
|
11
18
|
Example: Passing named visual regression test
|
|
12
|
-
When I render the "Example" component
|
|
13
19
|
Then the screenshot "visual-regression-example-page" should match
|
|
14
20
|
|
|
15
21
|
Example: Passing visual regression test of an element
|
|
16
|
-
When I render the "Example" component
|
|
17
22
|
Then the screenshot of the "XKCD Comic" img should match
|
|
18
23
|
|
|
24
|
+
@todo
|
|
19
25
|
Example: Passing named visual regression test of an element
|
|
20
|
-
When I render the "Example" component
|
|
21
26
|
Then the screenshot "visual-regression-faq-section" of the "#faq" element should match
|
|
22
27
|
|
|
23
|
-
@
|
|
24
|
-
Example: Failing visual regression test
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
And the screenshot "visual-regression-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
Scenario: Setting a screenshot mask
|
|
38
|
-
Given I render the "Example" component
|
|
39
|
-
And the following world config:
|
|
40
|
-
```yaml
|
|
41
|
-
screenshotOptions:
|
|
42
|
-
mask:
|
|
43
|
-
- form
|
|
44
|
-
```
|
|
45
|
-
Then the screenshot should match
|
|
46
|
-
|
|
47
|
-
Scenario: Setting a clip area
|
|
48
|
-
Given I render the "Example" component
|
|
49
|
-
And the following world config:
|
|
50
|
-
```yaml
|
|
51
|
-
screenshotOptions:
|
|
52
|
-
clip:
|
|
53
|
-
x: 0
|
|
54
|
-
y: 60
|
|
55
|
-
width: 300
|
|
56
|
-
height: 180
|
|
57
|
-
```
|
|
58
|
-
Then the screenshot should match
|
|
59
|
-
|
|
60
|
-
Rule: Screenshots should be placed in the proper directory
|
|
61
|
-
|
|
62
|
-
Scenario: Taking a screenshot
|
|
63
|
-
When I take a screenshot
|
|
64
|
-
Then the screenshot "Feature Basic tests of Vitest Browser Mode and steps_Taking a screenshot_01.png" should exist--delete it
|
|
65
|
-
|
|
66
|
-
Scenario: Taking a named screenshot
|
|
67
|
-
When I take a screenshot named "test"
|
|
68
|
-
Then the screenshot "test.png" should exist--delete it
|
|
69
|
-
|
|
70
|
-
Scenario: Taking a screenshot of an element
|
|
71
|
-
Given I load the file "tests/examples/example.html"
|
|
72
|
-
When I take a screenshot of the "Image" link
|
|
73
|
-
Then the screenshot "Feature Basic tests of Vitest Browser Mode and steps_Taking a screenshot of an element_02.png" should exist--delete it
|
|
74
|
-
|
|
75
|
-
Scenario: Taking a named screenshot of an element
|
|
76
|
-
Given I load the file "tests/examples/example.html"
|
|
77
|
-
When I take a screenshot of the "XKCD Comic" img named "test2"
|
|
78
|
-
Then the screenshot "test2.png" should exist--delete it
|
|
79
|
-
|
|
28
|
+
@soft
|
|
29
|
+
Example: Failing visual regression test (different image content)
|
|
30
|
+
Given the screenshot "visual-regression-example-page" should exist
|
|
31
|
+
When headings have a green background
|
|
32
|
+
And the screenshot "visual-regression-example-page" should match
|
|
33
|
+
Then error 1 should contain "images were too different"
|
|
34
|
+
And there should have been 1 error
|
|
35
|
+
|
|
36
|
+
@soft
|
|
37
|
+
Example: Failing visual regression test (different image size)
|
|
38
|
+
Given the screenshot "visual-regression-example-page" should exist
|
|
39
|
+
When the screenshot "visual-regression-example-page" of the "Image" header should match
|
|
40
|
+
Then error 1 should contain "sizes do not match"
|
|
41
|
+
And there should have been 1 error
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Before, Then } from 'quickpickle'
|
|
1
|
+
import { Before, Then, When } from 'quickpickle'
|
|
2
2
|
import type { VitestBrowserWorld } from '../../src/VitestBrowserWorld'
|
|
3
3
|
import { expect } from 'vitest'
|
|
4
4
|
import { commands } from '@vitest/browser/context'
|
|
@@ -7,17 +7,38 @@ import { commands } from '@vitest/browser/context'
|
|
|
7
7
|
|
|
8
8
|
// Screenshots
|
|
9
9
|
Then('the screenshot {string} should exist(--delete it)', async function (world:VitestBrowserWorld, filepath:string) {
|
|
10
|
-
let fullpath = world.fullPath(`${world.screenshotDir}/${filepath}`)
|
|
10
|
+
let fullpath = world.fullPath(`${world.screenshotDir}/${filepath}.png`)
|
|
11
11
|
await expect(commands.readFile(fullpath)).toBeTruthy();
|
|
12
12
|
if (world.info.step?.match(/--delete it$/)) await commands.removeFile(fullpath)
|
|
13
13
|
})
|
|
14
|
-
Then('the screenshot {string} should not exist', async function (world:VitestBrowserWorld, filepath:string) {
|
|
15
|
-
let fullpath = world.fullPath(`${world.screenshotDir}/${filepath}`)
|
|
14
|
+
Then('the screenshot {string} should/does not exist', async function (world:VitestBrowserWorld, filepath:string) {
|
|
15
|
+
let fullpath = world.fullPath(`${world.screenshotDir}/${filepath}.png`)
|
|
16
16
|
try {
|
|
17
|
-
await
|
|
17
|
+
await commands.readFile(fullpath);
|
|
18
18
|
throw new Error(`Screenshot ${filepath} should not exist`)
|
|
19
19
|
}
|
|
20
20
|
catch(e) {
|
|
21
|
-
if (e.message
|
|
21
|
+
if (!e.message.match(/ENOENT/i)) throw e
|
|
22
22
|
}
|
|
23
23
|
})
|
|
24
|
+
Then('(the )error {int} should contain {string}', async (world, idx, expected) => {
|
|
25
|
+
let error = world.info.errors[idx-1]
|
|
26
|
+
await expect(error.message).toContain(expected)
|
|
27
|
+
})
|
|
28
|
+
Then('(the )error {int} should contain the following text:', async (world, idx, expected) => {
|
|
29
|
+
let error = world.info.errors[idx-1]
|
|
30
|
+
await expect(error.message).toContain(expected.toString())
|
|
31
|
+
})
|
|
32
|
+
Then('the stack for error {int} should contain {string}', async (world, idx, expected) => {
|
|
33
|
+
let stack = world.info.errors[idx-1].stack.split('\n')[0]
|
|
34
|
+
await expect(stack).toContain(expected)
|
|
35
|
+
})
|
|
36
|
+
Then('there should have been {int} error(s)', async (world:VitestBrowserWorld, int:number) => {
|
|
37
|
+
expect(world.info.errors.length).toBe(int)
|
|
38
|
+
world.info.errors = []
|
|
39
|
+
})
|
|
40
|
+
When('headings have a {word} background', async (world:VitestBrowserWorld, color:string) => {
|
|
41
|
+
await world.page.getByRole('heading').all().map(el => {
|
|
42
|
+
el.element().setAttribute('style', `background-color: ${color};`)
|
|
43
|
+
})
|
|
44
|
+
})
|
package/vitest.workspace.ts
CHANGED
|
@@ -17,6 +17,7 @@ export default [
|
|
|
17
17
|
quickpickle: {
|
|
18
18
|
worldConfig: {
|
|
19
19
|
componentDir: 'tests/svelte',
|
|
20
|
+
screenshotDir: 'tests/svelte/screenshots',
|
|
20
21
|
}
|
|
21
22
|
},
|
|
22
23
|
environment: 'browser',
|
|
@@ -33,33 +34,34 @@ export default [
|
|
|
33
34
|
}
|
|
34
35
|
}
|
|
35
36
|
},
|
|
36
|
-
{
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}
|
|
37
|
+
// {
|
|
38
|
+
// name: 'react',
|
|
39
|
+
// extends: 'vite.config.ts',
|
|
40
|
+
// plugins: [react()],
|
|
41
|
+
// test: {
|
|
42
|
+
// name: 'react',
|
|
43
|
+
// include: [ 'tests/react/*.feature' ],
|
|
44
|
+
// setupFiles: [ 'src/frameworks/react.ts', 'src/actions.steps.ts', 'src/outcomes.steps.ts' ],
|
|
45
|
+
// quickpickle: {
|
|
46
|
+
// worldConfig: {
|
|
47
|
+
// componentDir: 'tests/react',
|
|
48
|
+
// screenshotDir: 'tests/react/screenshots',
|
|
49
|
+
// }
|
|
50
|
+
// },
|
|
51
|
+
// environment: 'browser',
|
|
52
|
+
// browser: {
|
|
53
|
+
// enabled: true,
|
|
54
|
+
// screenshotFailures: false,
|
|
55
|
+
// name: 'chromium',
|
|
56
|
+
// provider: 'playwright',
|
|
57
|
+
// ui: showBrowser,
|
|
58
|
+
// headless: !showBrowser,
|
|
59
|
+
// instances: [
|
|
60
|
+
// { browser:'chromium' },
|
|
61
|
+
// ]
|
|
62
|
+
// }
|
|
63
|
+
// }
|
|
64
|
+
// },
|
|
63
65
|
{
|
|
64
66
|
name: 'vue',
|
|
65
67
|
extends: 'vite.config.ts',
|
|
@@ -71,6 +73,7 @@ export default [
|
|
|
71
73
|
quickpickle: {
|
|
72
74
|
worldConfig: {
|
|
73
75
|
componentDir: 'tests/vue',
|
|
76
|
+
screenshotDir: 'tests/vue/screenshots',
|
|
74
77
|
}
|
|
75
78
|
},
|
|
76
79
|
environment: 'browser',
|