@quickpickle/vitest-browser 0.0.3 → 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 (44) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/README.md +70 -0
  3. package/dist/VitestBrowserWorld.cjs +36 -17
  4. package/dist/VitestBrowserWorld.cjs.map +1 -1
  5. package/dist/VitestBrowserWorld.d.ts +36 -10
  6. package/dist/VitestBrowserWorld.mjs +36 -17
  7. package/dist/VitestBrowserWorld.mjs.map +1 -1
  8. package/dist/actions.steps.cjs +24 -0
  9. package/dist/actions.steps.cjs.map +1 -1
  10. package/dist/actions.steps.mjs +25 -1
  11. package/dist/actions.steps.mjs.map +1 -1
  12. package/dist/frameworks/ReactBrowserWorld.cjs +17 -6
  13. package/dist/frameworks/ReactBrowserWorld.cjs.map +1 -1
  14. package/dist/frameworks/ReactBrowserWorld.d.ts +9 -0
  15. package/dist/frameworks/ReactBrowserWorld.mjs +17 -7
  16. package/dist/frameworks/ReactBrowserWorld.mjs.map +1 -1
  17. package/dist/frameworks/SvelteBrowserWorld.cjs +11 -2
  18. package/dist/frameworks/SvelteBrowserWorld.cjs.map +1 -1
  19. package/dist/frameworks/SvelteBrowserWorld.d.ts +2 -3
  20. package/dist/frameworks/SvelteBrowserWorld.mjs +11 -2
  21. package/dist/frameworks/SvelteBrowserWorld.mjs.map +1 -1
  22. package/dist/frameworks/VueBrowserWorld.cjs +6 -4
  23. package/dist/frameworks/VueBrowserWorld.cjs.map +1 -1
  24. package/dist/frameworks/VueBrowserWorld.d.ts +1 -3
  25. package/dist/frameworks/VueBrowserWorld.mjs +6 -4
  26. package/dist/frameworks/VueBrowserWorld.mjs.map +1 -1
  27. package/dist/outcomes.steps.cjs +74 -0
  28. package/dist/outcomes.steps.cjs.map +1 -1
  29. package/dist/outcomes.steps.mjs +74 -0
  30. package/dist/outcomes.steps.mjs.map +1 -1
  31. package/package.json +2 -2
  32. package/src/VitestBrowserWorld.ts +60 -26
  33. package/src/actions.steps.ts +26 -0
  34. package/src/frameworks/ReactBrowserWorld.ts +22 -9
  35. package/src/frameworks/SvelteBrowserWorld.ts +11 -3
  36. package/src/frameworks/VueBrowserWorld.ts +6 -5
  37. package/src/outcomes.steps.ts +75 -0
  38. package/tests/generic/browser-actions.feature +193 -0
  39. package/tests/generic/browser-generic.feature +79 -0
  40. package/tests/generic/browser-outcomes.feature +138 -0
  41. package/tests/generic/generic.steps.ts +23 -0
  42. package/tests/svelte/Example.svelte +153 -0
  43. package/vite.config.ts +8 -0
  44. package/vitest.workspace.ts +5 -9
@@ -0,0 +1,138 @@
1
+ Feature: Outcome step definitions on a static page
2
+
3
+ As a developer or tester
4
+ I need to be sure that the step definitions work as promised
5
+
6
+ Background: Load the example HTML page
7
+ Given I render the "Example" component
8
+
9
+ Scenario: test if text is visible when a single element matches
10
+ Then I should see "Item 1"
11
+ And the text "Item 1" should be visible
12
+
13
+ Scenario: test if text is visible when multiple elements match
14
+ Then I should see "Image"
15
+ And the text "Image" should be visible
16
+
17
+ Scenario: test that text is not visible
18
+ Then I should not see "FWAH!!!"
19
+ And the text "FWAH!!!" should not be visible
20
+
21
+ Scenario: test that elements are visible with name and role
22
+ Then I should see an "Email:" textbox
23
+ And I should see a "Form" heading
24
+
25
+ Scenario: test that elements are visible with inexact name and role
26
+ Then I should see an "orm" heading
27
+
28
+ Scenario: test that elements are not visible
29
+ Then I should not see a "FWAH!!!" textbox
30
+ And I should not see a "Form" notheading
31
+
32
+ Scenario: test that an element hidden with display:none is not visible
33
+ Then I should not see "Hidden item"
34
+
35
+ Scenario: test that an element hidden with visibility:hidden is not visible
36
+ Then I should not see "Invisible item"
37
+
38
+ @todo
39
+ Scenario: test that elements matching text are visible
40
+ Then I should see an "h1" element with the text "HTML Test Page"
41
+ And I should see an "li" with the text "First item"
42
+
43
+ @todo
44
+ Scenario: test that elements matching text are not visible
45
+ Then I should NOT see an "h1" element with the text "FWAH!!!"
46
+ And I should NOT see a "fwah" element with the text "FWEEE!!!"
47
+
48
+ Rule: All of the ways of addressing an element should be tested
49
+
50
+ @todo
51
+ Example: it works to address an element with css selector
52
+ Then a "textarea#message" element should be visible
53
+ And an 'input[type="submit"]' element should be visible
54
+ And a "ul>li" element should be visible
55
+ And a "li.hidden" element should be hidden
56
+
57
+ @should-fail @todo
58
+ Example: it FAILS to address an element with a css selector AND a role other than "element"
59
+ Then a "ul>li" listitem should be visible
60
+
61
+ @todo
62
+ Example: it works to address an element with name and role
63
+ Then an "XKCD Comic" img should be visible
64
+ And a "message" textbox should be visible
65
+ And a "lists" link should be visible
66
+
67
+ @should-fail @todo
68
+ Example: it FAILS to address an element with name and role IF the element is hidden
69
+ And a "Hidden item" listitem should be hidden
70
+
71
+ @todo
72
+ Example: it works to address an element with css selector and text
73
+ Then the 'a[href="https://xkcd.com/2928"]' element with the text "2928" should be visible
74
+ And the "li.hidden" element with the text "Hidden item" should be hidden
75
+
76
+ Rule: Testing for invisible elements should be possible
77
+
78
+ @todo
79
+ Scenario: "I should not see" does not ensure presence of invisible elements
80
+ Then I should not see an "li.absent" with the text "nothing"
81
+
82
+ @todo
83
+ Scenario: "the {string} should be hidden" passes when elements are present and invisible
84
+ Then the "li.hidden" element should be invisible
85
+
86
+ @should-fail @todo
87
+ Scenario: "the {string} should be hidden" FAILS when elements are not present
88
+ Then the "li.imaginary" element should be invisible
89
+
90
+ Rule: Testing for disabled / enabled state should be possible
91
+
92
+ Scenario: test that elements are disabled
93
+ Then the "From" textbox should be disabled
94
+
95
+ Scenario: test that elements are enabled
96
+ Then the "Email" textbox should be enabled
97
+
98
+ Rule: Testing for checked / unchecked state should be possible
99
+
100
+ Scenario: Checking a checkbox
101
+ Then the "I agree" checkbox should be unchecked
102
+ When I click the "I agree" checkbox
103
+ Then the "I agree" checkbox should be checked
104
+
105
+ Scenario: Checking a radio button
106
+ Then the "now" radio should be checked
107
+ When I click the "later" radio
108
+ Then the "now" radio should be unchecked
109
+ And the "later" radio should be checked
110
+
111
+ Rule: Testing for focused / unfocused state should be possible
112
+
113
+ Scenario: navigating through the form
114
+ When I click the "Name" textbox
115
+ Then the "Name" textbox should be focused
116
+ When I activate the "Email" textbox
117
+ Then the "Name" textbox should be blurred
118
+ And the "Email" textbox should be focused
119
+ When I type the following keys: Tab
120
+ Then the "Email" textbox should be blurred
121
+ And the "Message" textbox should be focused
122
+
123
+ Rule: Testing for form input values should be possible
124
+
125
+ Scenario: default values should be available
126
+ Then the value of the "From" textbox should be "example@example.com"
127
+ And the value of the "From" textbox should contain "example"
128
+ And the value of the "From" textbox should not include "FWAH!"
129
+ And the value of the "From" textbox should NOT be "example"
130
+ And the value of "From" should contain "example"
131
+ And the value of "From" should NOT be "example"
132
+
133
+ Scenario: date values
134
+ Then the value of the "Date" textbox should be "2024-10-19"
135
+ When I focus on the "Date" textbox
136
+ And I type the following keys: ArrowLeft ArrowLeft ArrowLeft ArrowUp
137
+ Then the value of the "Date" textbox should be "2024-11-19"
138
+
@@ -0,0 +1,23 @@
1
+ import { Before, Then } from 'quickpickle'
2
+ import type { VitestBrowserWorld } from '../../src/VitestBrowserWorld'
3
+ import { expect } from 'vitest'
4
+ import { commands } from '@vitest/browser/context'
5
+
6
+
7
+
8
+ // Screenshots
9
+ Then('the screenshot {string} should exist(--delete it)', async function (world:VitestBrowserWorld, filepath:string) {
10
+ let fullpath = world.fullPath(`${world.screenshotDir}/${filepath}`)
11
+ await expect(commands.readFile(fullpath)).toBeTruthy();
12
+ if (world.info.step?.match(/--delete it$/)) await commands.removeFile(fullpath)
13
+ })
14
+ Then('the screenshot {string} should not exist', async function (world:VitestBrowserWorld, filepath:string) {
15
+ let fullpath = world.fullPath(`${world.screenshotDir}/${filepath}`)
16
+ try {
17
+ await expect(commands.readFile(fullpath)).toBeTruthy();
18
+ throw new Error(`Screenshot ${filepath} should not exist`)
19
+ }
20
+ catch(e) {
21
+ if (e.message === `Screenshot ${filepath} should not exist`) throw e
22
+ }
23
+ })
@@ -0,0 +1,153 @@
1
+ <style>
2
+ .hidden { display:none; }
3
+ .invisible { visibility:hidden; }
4
+
5
+ .faq-item:has(input:checked) .faq-answer {
6
+ display: block;
7
+ max-height: 200px; /* Adjust this value based on your content */
8
+ transition: max-height 0.5s ease-in;
9
+ }
10
+ .faq-toggle { cursor: pointer;}
11
+ .faq-answer {
12
+ max-height: 0;
13
+ overflow: hidden;
14
+ transition: max-height 0.3s ease-out;
15
+ }
16
+ .faq-item {
17
+ cursor: pointer;
18
+ }
19
+ .faq-item input[type="checkbox"] {
20
+ display: none;
21
+ }
22
+ </style>
23
+
24
+ <header>
25
+ <h1>HTML Test Page</h1>
26
+ <nav>
27
+ <ul>
28
+ <li><a href="#text">Text</a></li>
29
+ <li><a href="#lists">Lists</a></li>
30
+ <li><a href="#table">Table</a></li>
31
+ <li><a href="#form">Form</a></li>
32
+ <li><a href="#faq">FAQ</a></li>
33
+ <li><a href="#image">Image</a></li>
34
+ </ul>
35
+ </nav>
36
+ </header>
37
+
38
+ <main>
39
+ <section id="text">
40
+ <h2>Text Elements</h2>
41
+ <p>This is a paragraph with <strong>bold</strong> and <em>italic</em> text.</p>
42
+ <p>Here's a <a href="https://www.example.com">link</a> to an example website.</p>
43
+ <blockquote>This is a blockquote.</blockquote>
44
+ </section>
45
+
46
+ <section id="lists">
47
+ <h2>Lists</h2>
48
+ <h3>Unordered List</h3>
49
+ <ul>
50
+ <li>Item 1</li>
51
+ <li>Item 2</li>
52
+ <li>Item 3</li>
53
+ </ul>
54
+ <h3>Ordered List</h3>
55
+ <ol>
56
+ <li>First item</li>
57
+ <li>Second item</li>
58
+ <li>Third item</li>
59
+ <li class="hidden">Hidden item</li>
60
+ <li class="invisible">Invisible item</li>
61
+ </ol>
62
+ </section>
63
+
64
+ <section id="table">
65
+ <h2>Table</h2>
66
+ <table border="1">
67
+ <thead>
68
+ <tr>
69
+ <th>Header 1</th>
70
+ <th>Header 2</th>
71
+ </tr>
72
+ </thead>
73
+ <tbody>
74
+ <tr>
75
+ <td>Row 1, Cell 1</td>
76
+ <td>Row 1, Cell 2</td>
77
+ </tr>
78
+ <tr>
79
+ <td>Row 2, Cell 1</td>
80
+ <td>Row 2, Cell 2</td>
81
+ </tr>
82
+ </tbody>
83
+ </table>
84
+ </section>
85
+
86
+ <section id="form">
87
+ <h2>Form</h2>
88
+ <form action="#" method="post">
89
+ <label for="name">Name:</label>
90
+ <input type="text" id="name" name="name" required><br><br>
91
+
92
+ <label for="email">Email:</label>
93
+ <input type="email" id="email" name="email" required><br><br>
94
+
95
+ <label for="message">Message:</label><br>
96
+ <textarea id="message" name="message" rows="4" cols="50"></textarea><br><br>
97
+
98
+ <label for="from">From:</label>
99
+ <input type="text" id="from" name="from" disabled value="example@example.com"><br><br>
100
+
101
+ <label for="date">Date:</label>
102
+ <input type="date" id="date" name="date" value="2024-10-19"><br><br>
103
+
104
+ <label for="number">Number:</label>
105
+ <input type="number" id="number" name="number"><br><br>
106
+
107
+ <label for="color">Color:</label>
108
+ <select id="color" name="color">
109
+ <option value="">- none -</option>
110
+ <option value="red">Red</option>
111
+ <option value="green">Green</option>
112
+ <option value="blue">Blue</option>
113
+ </select><br><br>
114
+
115
+ <div>Send this message:</div>
116
+ <input type="radio" name="sendtime" id="sendtime-now" value="now" checked>
117
+ <label for="sendtime-now">Now</label>
118
+ <input type="radio" name="sendtime" id="sendtime-later" value="later">
119
+ <label for="sendtime-later">Later</label><br><br>
120
+
121
+ <input type="checkbox" name="tnc" id="tnc">
122
+ <label for="tnc">I agree to the terms and conditions</label><br><br>
123
+
124
+ <input type="submit" value="Submit">
125
+ </form>
126
+ </section>
127
+
128
+ <section id="faq">
129
+ <h2>FAQ</h2>
130
+ <div class="faq-item" id="faq-item-1">
131
+ <label for="faq-1" class="faq-toggle">
132
+ <input type="checkbox" id="faq-1" class="faq-toggle">
133
+ <h3>Do CSS transitions affect Playwright awaits?</h3>
134
+ </label>
135
+ <p class="faq-answer">
136
+ AI says: "CSS transitions can affect Playwright awaits if not handled properly.
137
+ Playwright's default waiting mechanism might not account for CSS transitions,
138
+ potentially leading to flaky tests. It's important to use appropriate waiting
139
+ strategies or disable transitions in test environments to ensure consistency."
140
+ </p>
141
+ </div>
142
+ </section>
143
+
144
+ <section id="image">
145
+ <h2>Image</h2>
146
+ <img src="https://imgs.xkcd.com/comics/software_testing_day.png" alt="XKCD Comic 2928: Software Testing Day" width="320">
147
+ <p>Image source: <a href="https://xkcd.com/2928">xkcd.com/2928</a></p>
148
+ </section>
149
+ </main>
150
+
151
+ <footer>
152
+ <p>© 2023 HTML Test Page. All rights reserved.</p>
153
+ </footer>
package/vite.config.ts CHANGED
@@ -5,4 +5,12 @@ export default {
5
5
  optimizeDeps: {
6
6
  exclude: ['unicorn-magic'],
7
7
  },
8
+ test: {
9
+ quickpickle: {
10
+ failTags: ['@fail', '@fails', '@should-fail'],
11
+ explodeTags: [
12
+ ['@tag1', '@tag2'],
13
+ ],
14
+ }
15
+ }
8
16
  }
@@ -10,17 +10,10 @@ export default [
10
10
  name: 'svelte',
11
11
  extends: `vite.config.ts`,
12
12
  plugins: [svelte()],
13
- optimizeDeps: {
14
- include: [
15
- 'vue',
16
- 'react',
17
- 'svelte',
18
- ],
19
- },
20
13
  test: {
21
14
  name: 'svelte',
22
- include: [ `tests/svelte/*.feature` ],
23
- setupFiles: [ `src/frameworks/svelte.ts`, 'src/actions.steps.ts', 'src/outcomes.steps.ts' ],
15
+ include: [ `tests/svelte/*.feature`, `tests/generic/*.feature` ],
16
+ setupFiles: [ `src/frameworks/svelte.ts`, 'src/actions.steps.ts', 'src/outcomes.steps.ts', 'tests/generic/generic.steps.ts' ],
24
17
  quickpickle: {
25
18
  worldConfig: {
26
19
  componentDir: 'tests/svelte',
@@ -29,6 +22,7 @@ export default [
29
22
  environment: 'browser',
30
23
  browser: {
31
24
  enabled: true,
25
+ screenshotFailures: false,
32
26
  name: 'chromium',
33
27
  provider: 'playwright',
34
28
  ui: showBrowser,
@@ -55,6 +49,7 @@ export default [
55
49
  environment: 'browser',
56
50
  browser: {
57
51
  enabled: true,
52
+ screenshotFailures: false,
58
53
  name: 'chromium',
59
54
  provider: 'playwright',
60
55
  ui: showBrowser,
@@ -81,6 +76,7 @@ export default [
81
76
  environment: 'browser',
82
77
  browser: {
83
78
  enabled: true,
79
+ screenshotFailures: false,
84
80
  name: 'chromium',
85
81
  provider: 'playwright',
86
82
  ui: showBrowser,