@quickpickle/vitest-browser 0.0.2
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 +15 -0
- package/LICENSE +21 -0
- package/README.md +4 -0
- package/dist/VitestBrowserWorld.cjs +179 -0
- package/dist/VitestBrowserWorld.cjs.map +1 -0
- package/dist/VitestBrowserWorld.d.ts +103 -0
- package/dist/VitestBrowserWorld.mjs +176 -0
- package/dist/VitestBrowserWorld.mjs.map +1 -0
- package/dist/actions.steps.cjs +157 -0
- package/dist/actions.steps.cjs.map +1 -0
- package/dist/actions.steps.d.ts +1 -0
- package/dist/actions.steps.mjs +155 -0
- package/dist/actions.steps.mjs.map +1 -0
- package/dist/frameworks/ReactBrowserWorld.cjs +38 -0
- package/dist/frameworks/ReactBrowserWorld.cjs.map +1 -0
- package/dist/frameworks/ReactBrowserWorld.d.ts +10 -0
- package/dist/frameworks/ReactBrowserWorld.mjs +36 -0
- package/dist/frameworks/ReactBrowserWorld.mjs.map +1 -0
- package/dist/frameworks/SvelteBrowserWorld.cjs +17 -0
- package/dist/frameworks/SvelteBrowserWorld.cjs.map +1 -0
- package/dist/frameworks/SvelteBrowserWorld.d.ts +9 -0
- package/dist/frameworks/SvelteBrowserWorld.mjs +15 -0
- package/dist/frameworks/SvelteBrowserWorld.mjs.map +1 -0
- package/dist/frameworks/VueBrowserWorld.cjs +25 -0
- package/dist/frameworks/VueBrowserWorld.cjs.map +1 -0
- package/dist/frameworks/VueBrowserWorld.d.ts +10 -0
- package/dist/frameworks/VueBrowserWorld.mjs +23 -0
- package/dist/frameworks/VueBrowserWorld.mjs.map +1 -0
- package/dist/frameworks/react.cjs +11 -0
- package/dist/frameworks/react.cjs.map +1 -0
- package/dist/frameworks/react.d.ts +1 -0
- package/dist/frameworks/react.mjs +9 -0
- package/dist/frameworks/react.mjs.map +1 -0
- package/dist/frameworks/svelte.cjs +10 -0
- package/dist/frameworks/svelte.cjs.map +1 -0
- package/dist/frameworks/svelte.d.ts +1 -0
- package/dist/frameworks/svelte.mjs +8 -0
- package/dist/frameworks/svelte.mjs.map +1 -0
- package/dist/frameworks/vue.cjs +10 -0
- package/dist/frameworks/vue.cjs.map +1 -0
- package/dist/frameworks/vue.d.ts +1 -0
- package/dist/frameworks/vue.mjs +8 -0
- package/dist/frameworks/vue.mjs.map +1 -0
- package/dist/outcomes.steps.cjs +186 -0
- package/dist/outcomes.steps.cjs.map +1 -0
- package/dist/outcomes.steps.d.ts +1 -0
- package/dist/outcomes.steps.mjs +184 -0
- package/dist/outcomes.steps.mjs.map +1 -0
- package/package.json +103 -0
- package/rollup.config.js +58 -0
- package/src/VitestBrowserWorld.ts +205 -0
- package/src/actions.steps.ts +169 -0
- package/src/frameworks/ReactBrowserWorld.ts +41 -0
- package/src/frameworks/SvelteBrowserWorld.ts +15 -0
- package/src/frameworks/VueBrowserWorld.ts +23 -0
- package/src/frameworks/react.ts +4 -0
- package/src/frameworks/svelte.ts +4 -0
- package/src/frameworks/vue.ts +4 -0
- package/src/outcomes.steps.ts +190 -0
- package/tests/react/Hello.tsx +23 -0
- package/tests/react/react.feature +15 -0
- package/tests/svelte/Hello.svelte +31 -0
- package/tests/svelte/svelte.feature +16 -0
- package/tests/vue/Hello.vue +31 -0
- package/tests/vue/vue.feature +16 -0
- package/tsconfig.json +17 -0
- package/vite.config.ts +8 -0
- package/vitest.workspace.ts +95 -0
- package/world.ts +7 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# @quickpickle/vitest-browser
|
|
2
|
+
|
|
3
|
+
## 0.0.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 02bcadf: added react and vue for the browser module
|
|
8
|
+
- b1217d0: Initial functionality is working.
|
|
9
|
+
- Updated dependencies [2e7530d]
|
|
10
|
+
- Updated dependencies [094f7dd]
|
|
11
|
+
- Updated dependencies [7ad035c]
|
|
12
|
+
- Updated dependencies [1cf8cca]
|
|
13
|
+
- Updated dependencies [ab52cf6]
|
|
14
|
+
- Updated dependencies [1162c84]
|
|
15
|
+
- quickpickle@1.7.0
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 David Hunt
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var quickpickle = require('quickpickle');
|
|
4
|
+
var defaultsDeep = require('lodash/defaultsDeep');
|
|
5
|
+
|
|
6
|
+
const defaultVitestWorldConfig = {
|
|
7
|
+
componentDir: '', // directory in which components are kept, relative to project root
|
|
8
|
+
screenshotDir: 'screenshots', // directory in which to save screenshots, relative to project root (default: "screenshots")
|
|
9
|
+
screenshotOptions: {}, // options for the default screenshot comparisons
|
|
10
|
+
};
|
|
11
|
+
class VitestBrowserWorld extends quickpickle.QuickPickleWorld {
|
|
12
|
+
constructor(context, info) {
|
|
13
|
+
info = defaultsDeep(info || {}, { config: { worldConfig: defaultVitestWorldConfig } });
|
|
14
|
+
super(context, info);
|
|
15
|
+
if (!info.config.worldConfig.screenshotDir && info.config.worldConfig?.screenshotOptions?.customSnapshotsDir) {
|
|
16
|
+
this.info.config.worldConfig.screenshotDir = info.config.worldConfig.screenshotOptions.customSnapshotsDir;
|
|
17
|
+
}
|
|
18
|
+
this.renderFn = () => { };
|
|
19
|
+
this.cleanupFn = () => { };
|
|
20
|
+
}
|
|
21
|
+
async init() {
|
|
22
|
+
let browserContext = await import('@vitest/browser/context');
|
|
23
|
+
this.page = browserContext.page;
|
|
24
|
+
this.userEvent = browserContext.userEvent;
|
|
25
|
+
}
|
|
26
|
+
async render(name, props, renderOptions) {
|
|
27
|
+
let component = typeof name === 'string'
|
|
28
|
+
? await import(`${this.projectRoot}/${this.worldConfig.componentDir}/${name}`.replace(/\/+/g, '/') /* @vite-ignore */)
|
|
29
|
+
: name;
|
|
30
|
+
await this.renderFn(component, props, renderOptions);
|
|
31
|
+
}
|
|
32
|
+
;
|
|
33
|
+
async cleanup() {
|
|
34
|
+
await this.cleanupFn();
|
|
35
|
+
}
|
|
36
|
+
sanitizeFilepath(filepath) {
|
|
37
|
+
return filepath.replace(/\/\/+/g, '/').replace(/\/[\.~]+\//g, '/');
|
|
38
|
+
}
|
|
39
|
+
get screenshotDir() {
|
|
40
|
+
return this.sanitizeFilepath(`${this.projectRoot}/${this.worldConfig.screenshotDir}`);
|
|
41
|
+
}
|
|
42
|
+
get screenshotFilename() {
|
|
43
|
+
return `${this.toString().replace(/^.+?Feature: /, '').replace(' ' + this.info.step, '')}.png`;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Gets a locator based on a certain logic
|
|
47
|
+
* @example getLocator(page, 'Cancel', 'button') => page.getByRole('button', { name: 'Cancel' })
|
|
48
|
+
* @example getLocator(page, 'Search', 'input') => page.getByLabel('Search').or(page.getByPlaceholder('Search'))
|
|
49
|
+
* @example getLocator(page, 'ul.fourteen-points li', 'element', 'Open covenants of peace') => page.locator('ul.fourteen-points li').filter({ hasText: 'Open covenants of peace' })
|
|
50
|
+
*
|
|
51
|
+
* @param el The locator or page inside which to get a new locator
|
|
52
|
+
* @param identifier The value, label, placeholder, or css selector, depending on role
|
|
53
|
+
* @param role An ARIA role, "input", or "element"
|
|
54
|
+
* @param text Optional text to match inside the locator
|
|
55
|
+
* @returns Promise<void>
|
|
56
|
+
*/
|
|
57
|
+
getLocator(el, identifier, role, text = null) {
|
|
58
|
+
let locator;
|
|
59
|
+
if (role === 'element')
|
|
60
|
+
throw new Error('Using "element" for CSS selectors is not yet supported; use an aria role or "input" instead.');
|
|
61
|
+
else if (role === 'input')
|
|
62
|
+
locator = el.getByLabelText(identifier).or(el.getByPlaceholder(identifier));
|
|
63
|
+
else
|
|
64
|
+
locator = el.getByRole(role, { name: identifier });
|
|
65
|
+
if (text && role !== 'input')
|
|
66
|
+
return locator.filter({ hasText: text });
|
|
67
|
+
return locator;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Sets a value on a form element based on its type (select, checkbox/radio, or other input)
|
|
71
|
+
* @example setValue(locator, "Option 1, Option 2") => Selects multiple options in a select element
|
|
72
|
+
* @example setValue(locator, "true") => Checks a checkbox/radio button
|
|
73
|
+
* @example setValue(locator, "false") => Unchecks a checkbox/radio button
|
|
74
|
+
* @example setValue(locator, "Some text") => Fills a text input with "Some text"
|
|
75
|
+
*
|
|
76
|
+
* @param locator The Playwright locator for the form element
|
|
77
|
+
* @param value The value to set - can be string or other value type
|
|
78
|
+
* @returns Promise<void>
|
|
79
|
+
*/
|
|
80
|
+
async setValue(locator, value) {
|
|
81
|
+
let el = await locator.element();
|
|
82
|
+
let tag = el.tagName.toLowerCase();
|
|
83
|
+
if (!tag)
|
|
84
|
+
throw new Error(`Could not find element with locator: ${locator.toString()}`);
|
|
85
|
+
if (tag === 'select') {
|
|
86
|
+
let values = value.split(/\s*(?<!\\),\s*/).map((v) => v.replace(/\\,/g, ','));
|
|
87
|
+
await locator.selectOptions(values);
|
|
88
|
+
}
|
|
89
|
+
else if (isCheckboxOrRadio(el)) {
|
|
90
|
+
let check = !(['false', 'no', 'unchecked', '', 'null', 'undefined', '0'].includes(value.toString().toLowerCase()));
|
|
91
|
+
if (check)
|
|
92
|
+
el.checked = true;
|
|
93
|
+
else
|
|
94
|
+
el.checked = false;
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
await locator.fill(value);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Scrolls the mouse wheel in a specified direction by a given number of pixels
|
|
102
|
+
* @example scroll("down", 100) => Scrolls down 100 pixels
|
|
103
|
+
* @example scroll("up", 50) => Scrolls up 50 pixels
|
|
104
|
+
* @example scroll("left", 200) => Scrolls left 200 pixels
|
|
105
|
+
* @example scroll("right") => Scrolls right using default 100 pixels
|
|
106
|
+
*
|
|
107
|
+
* @param direction The direction to scroll: "up", "down", "left", or "right"
|
|
108
|
+
* @param px The number of pixels to scroll (defaults to 100)
|
|
109
|
+
* @returns Promise<void>
|
|
110
|
+
*/
|
|
111
|
+
async scroll(locator, direction, px = 100) {
|
|
112
|
+
let horiz = direction.includes('t');
|
|
113
|
+
let el = await locator.element();
|
|
114
|
+
if (horiz)
|
|
115
|
+
await el.scrollBy(direction === 'right' ? px : -px, 0);
|
|
116
|
+
else
|
|
117
|
+
await el.scrollBy(0, direction === 'down' ? px : -px);
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* A helper function for parsing text on a page or in an element.
|
|
121
|
+
* Can be used to check for the presence OR absence of visible OR hidden text.
|
|
122
|
+
* Examples:
|
|
123
|
+
* @example expectText(locator, 'text', true, true) // expect that a locator with the text is visible (and there may be hidden ones)
|
|
124
|
+
* @example expectText(locator, 'text', false, true) // expect that NO locator with the text is visible (but there may be hidden ones)
|
|
125
|
+
* @example expectText(locator, 'text', true, false) // expect that a HIDDEN locator with the text IS FOUND on the page (but there may be visible ones)
|
|
126
|
+
* @example expectText(locator, 'text', false, false) // expect that NO hidden locator with the text is found on the page (but there may be visible ones)
|
|
127
|
+
*
|
|
128
|
+
* @param locator the locator to check
|
|
129
|
+
* @param text the text to be found
|
|
130
|
+
* @param toBePresent whether a locator with the text should be present
|
|
131
|
+
* @param toBeVisible whether the locator with the text should be visible
|
|
132
|
+
* @returns void
|
|
133
|
+
*/
|
|
134
|
+
async expectText(locator, text, toBePresent = true, toBeVisible = true) {
|
|
135
|
+
try {
|
|
136
|
+
await this.expectElement(locator.getByText(text), toBePresent, toBeVisible);
|
|
137
|
+
}
|
|
138
|
+
catch (e) {
|
|
139
|
+
let message = `The${toBeVisible ? '' : ' hidden'} text "${text}" was unexpectedly ${toBePresent ? 'not present' : 'present'}.`;
|
|
140
|
+
throw new Error(message);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* A helper function for parsing elements on a page or in an element.
|
|
145
|
+
* Can be used to check for the presence OR absence of visible OR hidden elements.
|
|
146
|
+
* Examples:
|
|
147
|
+
* @example expectElement(locator, true) // expect that an element is visible (and there may be hidden ones)
|
|
148
|
+
* @example expectElement(locator, false) // expect that NO element is visible (but there may be hidden ones)
|
|
149
|
+
* @example expectElement(locator, true, false) // expect that a HIDDEN element IS FOUND on the page (but there may be visible ones)
|
|
150
|
+
* @example expectElement(locator, false, false) // expect that NO hidden element is found on the page (but there may be visible ones)
|
|
151
|
+
*
|
|
152
|
+
* @param locator the locator to check
|
|
153
|
+
* @param toBePresent whether an element should be present
|
|
154
|
+
* @param toBeVisible whether the element should be visible
|
|
155
|
+
*/
|
|
156
|
+
async expectElement(locator, toBePresent = true, toBeVisible = true) {
|
|
157
|
+
let allElements = await locator.elements();
|
|
158
|
+
let matchingElements = allElements.filter(el => toBeVisible === el.checkVisibility({ opacityProperty: true, visibilityProperty: true }));
|
|
159
|
+
if (toBePresent === (matchingElements.length === 0))
|
|
160
|
+
throw new Error(`The${toBeVisible ? '' : ' hidden'} element "${locator}" was unexpectedly ${toBePresent ? 'not present' : 'present'}.`);
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Waits for a certain amount of time
|
|
164
|
+
* @param ms number
|
|
165
|
+
*/
|
|
166
|
+
async waitForTimeout(ms) {
|
|
167
|
+
await new Promise(r => setTimeout(r, ms));
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
function isCheckboxOrRadio(el) {
|
|
171
|
+
return el.type === 'checkbox' || el.type === 'radio';
|
|
172
|
+
}
|
|
173
|
+
quickpickle.Before(async (world) => {
|
|
174
|
+
await world.cleanup();
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
exports.VitestBrowserWorld = VitestBrowserWorld;
|
|
178
|
+
exports.defaultVitestWorldConfig = defaultVitestWorldConfig;
|
|
179
|
+
//# sourceMappingURL=VitestBrowserWorld.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VitestBrowserWorld.cjs","sources":["../src/VitestBrowserWorld.ts"],"sourcesContent":[null],"names":["QuickPickleWorld","Before"],"mappings":"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"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { QuickPickleWorld, QuickPickleWorldInterface } from 'quickpickle';
|
|
2
|
+
import type { BrowserPage, Locator, UserEvent, ScreenshotOptions } from '@vitest/browser/context';
|
|
3
|
+
import type { TestContext } from 'vitest';
|
|
4
|
+
import { InfoConstructor } from 'quickpickle/dist/world';
|
|
5
|
+
export type VitestWorldConfig = {
|
|
6
|
+
componentDir?: string;
|
|
7
|
+
screenshotDir?: string;
|
|
8
|
+
screenshotOptions?: Partial<ScreenshotOptions>;
|
|
9
|
+
};
|
|
10
|
+
export declare const defaultVitestWorldConfig: VitestWorldConfig;
|
|
11
|
+
export type VitestBrowserWorldInterface = QuickPickleWorldInterface & {
|
|
12
|
+
render: (name: string | any, props?: any, renderOptions?: any) => Promise<void>;
|
|
13
|
+
renderFn: (component: any, props?: any, renderOptions?: any) => void | Promise<void>;
|
|
14
|
+
cleanup: () => Promise<void>;
|
|
15
|
+
cleanupFn: () => void | Promise<void>;
|
|
16
|
+
page: BrowserPage;
|
|
17
|
+
userEvent: UserEvent;
|
|
18
|
+
};
|
|
19
|
+
export declare class VitestBrowserWorld extends QuickPickleWorld implements VitestBrowserWorldInterface {
|
|
20
|
+
renderFn: (component: any, props: any, renderOptions: any) => void;
|
|
21
|
+
cleanupFn: () => void;
|
|
22
|
+
page: BrowserPage;
|
|
23
|
+
userEvent: UserEvent;
|
|
24
|
+
constructor(context: TestContext, info: InfoConstructor);
|
|
25
|
+
init(): Promise<void>;
|
|
26
|
+
render(name: string | any, props?: any, renderOptions?: any): Promise<void>;
|
|
27
|
+
cleanup(): Promise<void>;
|
|
28
|
+
sanitizeFilepath(filepath: string): string;
|
|
29
|
+
get screenshotDir(): string;
|
|
30
|
+
get screenshotFilename(): string;
|
|
31
|
+
/**
|
|
32
|
+
* Gets a locator based on a certain logic
|
|
33
|
+
* @example getLocator(page, 'Cancel', 'button') => page.getByRole('button', { name: 'Cancel' })
|
|
34
|
+
* @example getLocator(page, 'Search', 'input') => page.getByLabel('Search').or(page.getByPlaceholder('Search'))
|
|
35
|
+
* @example getLocator(page, 'ul.fourteen-points li', 'element', 'Open covenants of peace') => page.locator('ul.fourteen-points li').filter({ hasText: 'Open covenants of peace' })
|
|
36
|
+
*
|
|
37
|
+
* @param el The locator or page inside which to get a new locator
|
|
38
|
+
* @param identifier The value, label, placeholder, or css selector, depending on role
|
|
39
|
+
* @param role An ARIA role, "input", or "element"
|
|
40
|
+
* @param text Optional text to match inside the locator
|
|
41
|
+
* @returns Promise<void>
|
|
42
|
+
*/
|
|
43
|
+
getLocator(el: Locator | BrowserPage, identifier: string, role: string | 'element' | 'input', text?: string | null): Locator;
|
|
44
|
+
/**
|
|
45
|
+
* Sets a value on a form element based on its type (select, checkbox/radio, or other input)
|
|
46
|
+
* @example setValue(locator, "Option 1, Option 2") => Selects multiple options in a select element
|
|
47
|
+
* @example setValue(locator, "true") => Checks a checkbox/radio button
|
|
48
|
+
* @example setValue(locator, "false") => Unchecks a checkbox/radio button
|
|
49
|
+
* @example setValue(locator, "Some text") => Fills a text input with "Some text"
|
|
50
|
+
*
|
|
51
|
+
* @param locator The Playwright locator for the form element
|
|
52
|
+
* @param value The value to set - can be string or other value type
|
|
53
|
+
* @returns Promise<void>
|
|
54
|
+
*/
|
|
55
|
+
setValue(locator: Locator, value: string | any): Promise<void>;
|
|
56
|
+
/**
|
|
57
|
+
* Scrolls the mouse wheel in a specified direction by a given number of pixels
|
|
58
|
+
* @example scroll("down", 100) => Scrolls down 100 pixels
|
|
59
|
+
* @example scroll("up", 50) => Scrolls up 50 pixels
|
|
60
|
+
* @example scroll("left", 200) => Scrolls left 200 pixels
|
|
61
|
+
* @example scroll("right") => Scrolls right using default 100 pixels
|
|
62
|
+
*
|
|
63
|
+
* @param direction The direction to scroll: "up", "down", "left", or "right"
|
|
64
|
+
* @param px The number of pixels to scroll (defaults to 100)
|
|
65
|
+
* @returns Promise<void>
|
|
66
|
+
*/
|
|
67
|
+
scroll(locator: Locator, direction: "up" | "down" | "left" | "right", px?: number): Promise<void>;
|
|
68
|
+
/**
|
|
69
|
+
* A helper function for parsing text on a page or in an element.
|
|
70
|
+
* Can be used to check for the presence OR absence of visible OR hidden text.
|
|
71
|
+
* Examples:
|
|
72
|
+
* @example expectText(locator, 'text', true, true) // expect that a locator with the text is visible (and there may be hidden ones)
|
|
73
|
+
* @example expectText(locator, 'text', false, true) // expect that NO locator with the text is visible (but there may be hidden ones)
|
|
74
|
+
* @example expectText(locator, 'text', true, false) // expect that a HIDDEN locator with the text IS FOUND on the page (but there may be visible ones)
|
|
75
|
+
* @example expectText(locator, 'text', false, false) // expect that NO hidden locator with the text is found on the page (but there may be visible ones)
|
|
76
|
+
*
|
|
77
|
+
* @param locator the locator to check
|
|
78
|
+
* @param text the text to be found
|
|
79
|
+
* @param toBePresent whether a locator with the text should be present
|
|
80
|
+
* @param toBeVisible whether the locator with the text should be visible
|
|
81
|
+
* @returns void
|
|
82
|
+
*/
|
|
83
|
+
expectText(locator: Locator | BrowserPage, text: string, toBePresent?: boolean, toBeVisible?: boolean): Promise<void>;
|
|
84
|
+
/**
|
|
85
|
+
* A helper function for parsing elements on a page or in an element.
|
|
86
|
+
* Can be used to check for the presence OR absence of visible OR hidden elements.
|
|
87
|
+
* Examples:
|
|
88
|
+
* @example expectElement(locator, true) // expect that an element is visible (and there may be hidden ones)
|
|
89
|
+
* @example expectElement(locator, false) // expect that NO element is visible (but there may be hidden ones)
|
|
90
|
+
* @example expectElement(locator, true, false) // expect that a HIDDEN element IS FOUND on the page (but there may be visible ones)
|
|
91
|
+
* @example expectElement(locator, false, false) // expect that NO hidden element is found on the page (but there may be visible ones)
|
|
92
|
+
*
|
|
93
|
+
* @param locator the locator to check
|
|
94
|
+
* @param toBePresent whether an element should be present
|
|
95
|
+
* @param toBeVisible whether the element should be visible
|
|
96
|
+
*/
|
|
97
|
+
expectElement(locator: Locator, toBePresent?: boolean, toBeVisible?: boolean): Promise<void>;
|
|
98
|
+
/**
|
|
99
|
+
* Waits for a certain amount of time
|
|
100
|
+
* @param ms number
|
|
101
|
+
*/
|
|
102
|
+
waitForTimeout(ms: number): Promise<void>;
|
|
103
|
+
}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { Before, QuickPickleWorld } from 'quickpickle';
|
|
2
|
+
import { defaultsDeep } from 'lodash-es';
|
|
3
|
+
|
|
4
|
+
const defaultVitestWorldConfig = {
|
|
5
|
+
componentDir: '', // directory in which components are kept, relative to project root
|
|
6
|
+
screenshotDir: 'screenshots', // directory in which to save screenshots, relative to project root (default: "screenshots")
|
|
7
|
+
screenshotOptions: {}, // options for the default screenshot comparisons
|
|
8
|
+
};
|
|
9
|
+
class VitestBrowserWorld extends QuickPickleWorld {
|
|
10
|
+
constructor(context, info) {
|
|
11
|
+
info = defaultsDeep(info || {}, { config: { worldConfig: defaultVitestWorldConfig } });
|
|
12
|
+
super(context, info);
|
|
13
|
+
if (!info.config.worldConfig.screenshotDir && info.config.worldConfig?.screenshotOptions?.customSnapshotsDir) {
|
|
14
|
+
this.info.config.worldConfig.screenshotDir = info.config.worldConfig.screenshotOptions.customSnapshotsDir;
|
|
15
|
+
}
|
|
16
|
+
this.renderFn = () => { };
|
|
17
|
+
this.cleanupFn = () => { };
|
|
18
|
+
}
|
|
19
|
+
async init() {
|
|
20
|
+
let browserContext = await import('@vitest/browser/context');
|
|
21
|
+
this.page = browserContext.page;
|
|
22
|
+
this.userEvent = browserContext.userEvent;
|
|
23
|
+
}
|
|
24
|
+
async render(name, props, renderOptions) {
|
|
25
|
+
let component = typeof name === 'string'
|
|
26
|
+
? await import(`${this.projectRoot}/${this.worldConfig.componentDir}/${name}`.replace(/\/+/g, '/') /* @vite-ignore */)
|
|
27
|
+
: name;
|
|
28
|
+
await this.renderFn(component, props, renderOptions);
|
|
29
|
+
}
|
|
30
|
+
;
|
|
31
|
+
async cleanup() {
|
|
32
|
+
await this.cleanupFn();
|
|
33
|
+
}
|
|
34
|
+
sanitizeFilepath(filepath) {
|
|
35
|
+
return filepath.replace(/\/\/+/g, '/').replace(/\/[\.~]+\//g, '/');
|
|
36
|
+
}
|
|
37
|
+
get screenshotDir() {
|
|
38
|
+
return this.sanitizeFilepath(`${this.projectRoot}/${this.worldConfig.screenshotDir}`);
|
|
39
|
+
}
|
|
40
|
+
get screenshotFilename() {
|
|
41
|
+
return `${this.toString().replace(/^.+?Feature: /, '').replace(' ' + this.info.step, '')}.png`;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Gets a locator based on a certain logic
|
|
45
|
+
* @example getLocator(page, 'Cancel', 'button') => page.getByRole('button', { name: 'Cancel' })
|
|
46
|
+
* @example getLocator(page, 'Search', 'input') => page.getByLabel('Search').or(page.getByPlaceholder('Search'))
|
|
47
|
+
* @example getLocator(page, 'ul.fourteen-points li', 'element', 'Open covenants of peace') => page.locator('ul.fourteen-points li').filter({ hasText: 'Open covenants of peace' })
|
|
48
|
+
*
|
|
49
|
+
* @param el The locator or page inside which to get a new locator
|
|
50
|
+
* @param identifier The value, label, placeholder, or css selector, depending on role
|
|
51
|
+
* @param role An ARIA role, "input", or "element"
|
|
52
|
+
* @param text Optional text to match inside the locator
|
|
53
|
+
* @returns Promise<void>
|
|
54
|
+
*/
|
|
55
|
+
getLocator(el, identifier, role, text = null) {
|
|
56
|
+
let locator;
|
|
57
|
+
if (role === 'element')
|
|
58
|
+
throw new Error('Using "element" for CSS selectors is not yet supported; use an aria role or "input" instead.');
|
|
59
|
+
else if (role === 'input')
|
|
60
|
+
locator = el.getByLabelText(identifier).or(el.getByPlaceholder(identifier));
|
|
61
|
+
else
|
|
62
|
+
locator = el.getByRole(role, { name: identifier });
|
|
63
|
+
if (text && role !== 'input')
|
|
64
|
+
return locator.filter({ hasText: text });
|
|
65
|
+
return locator;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Sets a value on a form element based on its type (select, checkbox/radio, or other input)
|
|
69
|
+
* @example setValue(locator, "Option 1, Option 2") => Selects multiple options in a select element
|
|
70
|
+
* @example setValue(locator, "true") => Checks a checkbox/radio button
|
|
71
|
+
* @example setValue(locator, "false") => Unchecks a checkbox/radio button
|
|
72
|
+
* @example setValue(locator, "Some text") => Fills a text input with "Some text"
|
|
73
|
+
*
|
|
74
|
+
* @param locator The Playwright locator for the form element
|
|
75
|
+
* @param value The value to set - can be string or other value type
|
|
76
|
+
* @returns Promise<void>
|
|
77
|
+
*/
|
|
78
|
+
async setValue(locator, value) {
|
|
79
|
+
let el = await locator.element();
|
|
80
|
+
let tag = el.tagName.toLowerCase();
|
|
81
|
+
if (!tag)
|
|
82
|
+
throw new Error(`Could not find element with locator: ${locator.toString()}`);
|
|
83
|
+
if (tag === 'select') {
|
|
84
|
+
let values = value.split(/\s*(?<!\\),\s*/).map((v) => v.replace(/\\,/g, ','));
|
|
85
|
+
await locator.selectOptions(values);
|
|
86
|
+
}
|
|
87
|
+
else if (isCheckboxOrRadio(el)) {
|
|
88
|
+
let check = !(['false', 'no', 'unchecked', '', 'null', 'undefined', '0'].includes(value.toString().toLowerCase()));
|
|
89
|
+
if (check)
|
|
90
|
+
el.checked = true;
|
|
91
|
+
else
|
|
92
|
+
el.checked = false;
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
await locator.fill(value);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Scrolls the mouse wheel in a specified direction by a given number of pixels
|
|
100
|
+
* @example scroll("down", 100) => Scrolls down 100 pixels
|
|
101
|
+
* @example scroll("up", 50) => Scrolls up 50 pixels
|
|
102
|
+
* @example scroll("left", 200) => Scrolls left 200 pixels
|
|
103
|
+
* @example scroll("right") => Scrolls right using default 100 pixels
|
|
104
|
+
*
|
|
105
|
+
* @param direction The direction to scroll: "up", "down", "left", or "right"
|
|
106
|
+
* @param px The number of pixels to scroll (defaults to 100)
|
|
107
|
+
* @returns Promise<void>
|
|
108
|
+
*/
|
|
109
|
+
async scroll(locator, direction, px = 100) {
|
|
110
|
+
let horiz = direction.includes('t');
|
|
111
|
+
let el = await locator.element();
|
|
112
|
+
if (horiz)
|
|
113
|
+
await el.scrollBy(direction === 'right' ? px : -px, 0);
|
|
114
|
+
else
|
|
115
|
+
await el.scrollBy(0, direction === 'down' ? px : -px);
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* A helper function for parsing text on a page or in an element.
|
|
119
|
+
* Can be used to check for the presence OR absence of visible OR hidden text.
|
|
120
|
+
* Examples:
|
|
121
|
+
* @example expectText(locator, 'text', true, true) // expect that a locator with the text is visible (and there may be hidden ones)
|
|
122
|
+
* @example expectText(locator, 'text', false, true) // expect that NO locator with the text is visible (but there may be hidden ones)
|
|
123
|
+
* @example expectText(locator, 'text', true, false) // expect that a HIDDEN locator with the text IS FOUND on the page (but there may be visible ones)
|
|
124
|
+
* @example expectText(locator, 'text', false, false) // expect that NO hidden locator with the text is found on the page (but there may be visible ones)
|
|
125
|
+
*
|
|
126
|
+
* @param locator the locator to check
|
|
127
|
+
* @param text the text to be found
|
|
128
|
+
* @param toBePresent whether a locator with the text should be present
|
|
129
|
+
* @param toBeVisible whether the locator with the text should be visible
|
|
130
|
+
* @returns void
|
|
131
|
+
*/
|
|
132
|
+
async expectText(locator, text, toBePresent = true, toBeVisible = true) {
|
|
133
|
+
try {
|
|
134
|
+
await this.expectElement(locator.getByText(text), toBePresent, toBeVisible);
|
|
135
|
+
}
|
|
136
|
+
catch (e) {
|
|
137
|
+
let message = `The${toBeVisible ? '' : ' hidden'} text "${text}" was unexpectedly ${toBePresent ? 'not present' : 'present'}.`;
|
|
138
|
+
throw new Error(message);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* A helper function for parsing elements on a page or in an element.
|
|
143
|
+
* Can be used to check for the presence OR absence of visible OR hidden elements.
|
|
144
|
+
* Examples:
|
|
145
|
+
* @example expectElement(locator, true) // expect that an element is visible (and there may be hidden ones)
|
|
146
|
+
* @example expectElement(locator, false) // expect that NO element is visible (but there may be hidden ones)
|
|
147
|
+
* @example expectElement(locator, true, false) // expect that a HIDDEN element IS FOUND on the page (but there may be visible ones)
|
|
148
|
+
* @example expectElement(locator, false, false) // expect that NO hidden element is found on the page (but there may be visible ones)
|
|
149
|
+
*
|
|
150
|
+
* @param locator the locator to check
|
|
151
|
+
* @param toBePresent whether an element should be present
|
|
152
|
+
* @param toBeVisible whether the element should be visible
|
|
153
|
+
*/
|
|
154
|
+
async expectElement(locator, toBePresent = true, toBeVisible = true) {
|
|
155
|
+
let allElements = await locator.elements();
|
|
156
|
+
let matchingElements = allElements.filter(el => toBeVisible === el.checkVisibility({ opacityProperty: true, visibilityProperty: true }));
|
|
157
|
+
if (toBePresent === (matchingElements.length === 0))
|
|
158
|
+
throw new Error(`The${toBeVisible ? '' : ' hidden'} element "${locator}" was unexpectedly ${toBePresent ? 'not present' : 'present'}.`);
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Waits for a certain amount of time
|
|
162
|
+
* @param ms number
|
|
163
|
+
*/
|
|
164
|
+
async waitForTimeout(ms) {
|
|
165
|
+
await new Promise(r => setTimeout(r, ms));
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
function isCheckboxOrRadio(el) {
|
|
169
|
+
return el.type === 'checkbox' || el.type === 'radio';
|
|
170
|
+
}
|
|
171
|
+
Before(async (world) => {
|
|
172
|
+
await world.cleanup();
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
export { VitestBrowserWorld, defaultVitestWorldConfig };
|
|
176
|
+
//# sourceMappingURL=VitestBrowserWorld.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VitestBrowserWorld.mjs","sources":["../src/VitestBrowserWorld.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|