@vitest/browser 2.0.5 → 2.1.0-beta.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/aria-role.d.ts +96 -0
- package/context.d.ts +221 -17
- package/dist/client/.vite/manifest.json +2 -2
- package/dist/client/__vitest__/assets/index-JTfsnJeu.css +1 -0
- package/dist/client/__vitest__/assets/index-uh8h5Yzr.js +52 -0
- package/dist/client/__vitest__/favicon.ico +0 -0
- package/dist/client/__vitest__/index.html +4 -3
- package/dist/client/__vitest_browser__/{orchestrator-CNOAigTE.js → orchestrator-BObhEEvc.js} +4 -4
- package/dist/client/__vitest_browser__/{tester-l8kjusoM.js → tester-CRcWWhrn.js} +10 -2
- package/dist/client/error-catcher.js +10 -16
- package/dist/client/orchestrator.html +1 -1
- package/dist/client/tester/tester.html +3 -11
- package/dist/context.js +194 -77
- package/dist/index-DX16doXA.js +5722 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +38 -23
- package/dist/locators/index.d.ts +261 -0
- package/dist/locators/index.js +2 -0
- package/dist/locators/playwright.js +42 -0
- package/dist/locators/preview.js +86 -0
- package/dist/locators/webdriverio.js +83 -0
- package/jest-dom.d.ts +1 -97
- package/matchers.d.ts +2 -1
- package/package.json +16 -11
- package/providers/playwright.d.ts +2 -1
- package/providers/webdriverio.d.ts +10 -1
- package/dist/client/__vitest__/assets/index--EAEh9Ei.js +0 -52
- package/dist/client/__vitest__/assets/index-C0SwoDYm.css +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -105,7 +105,8 @@ declare class BrowserServer implements BrowserServer$1 {
|
|
|
105
105
|
testerHtml: Promise<string> | string;
|
|
106
106
|
orchestratorHtml: Promise<string> | string;
|
|
107
107
|
injectorJs: Promise<string> | string;
|
|
108
|
-
|
|
108
|
+
errorCatcherUrl: string;
|
|
109
|
+
locatorsUrl: string | undefined;
|
|
109
110
|
stateJs: Promise<string> | string;
|
|
110
111
|
state: BrowserServerState;
|
|
111
112
|
provider: BrowserProvider;
|
package/dist/index.js
CHANGED
|
@@ -566,6 +566,10 @@ function setupBrowserRpc(server) {
|
|
|
566
566
|
const rpc = createBirpc(
|
|
567
567
|
{
|
|
568
568
|
async onUnhandledError(error, type) {
|
|
569
|
+
if (error && typeof error === "object") {
|
|
570
|
+
const _error = error;
|
|
571
|
+
_error.stacks = server.parseErrorStacktrace(_error);
|
|
572
|
+
}
|
|
569
573
|
ctx.state.catchError(error, type);
|
|
570
574
|
},
|
|
571
575
|
async onCollected(files) {
|
|
@@ -894,7 +898,12 @@ class BrowserServer {
|
|
|
894
898
|
resolve(distRoot, "client/esm-client-injector.js"),
|
|
895
899
|
"utf8"
|
|
896
900
|
).then((js) => this.injectorJs = js);
|
|
897
|
-
this.
|
|
901
|
+
this.errorCatcherUrl = join("/@fs/", resolve(distRoot, "client/error-catcher.js"));
|
|
902
|
+
const builtinProviders = ["playwright", "webdriverio", "preview"];
|
|
903
|
+
const providerName = project.config.browser.provider || "preview";
|
|
904
|
+
if (builtinProviders.includes(providerName)) {
|
|
905
|
+
this.locatorsUrl = join("/@fs/", distRoot, "locators", `${providerName}.js`);
|
|
906
|
+
}
|
|
898
907
|
this.stateJs = readFile$1(
|
|
899
908
|
resolve(distRoot, "state.js"),
|
|
900
909
|
"utf-8"
|
|
@@ -908,7 +917,8 @@ class BrowserServer {
|
|
|
908
917
|
testerHtml;
|
|
909
918
|
orchestratorHtml;
|
|
910
919
|
injectorJs;
|
|
911
|
-
|
|
920
|
+
errorCatcherUrl;
|
|
921
|
+
locatorsUrl;
|
|
912
922
|
stateJs;
|
|
913
923
|
state;
|
|
914
924
|
provider;
|
|
@@ -1025,7 +1035,7 @@ const click = async (context, selector, options = {}) => {
|
|
|
1025
1035
|
const provider = context.provider;
|
|
1026
1036
|
if (provider instanceof PlaywrightBrowserProvider) {
|
|
1027
1037
|
const tester = context.iframe;
|
|
1028
|
-
await tester.locator(
|
|
1038
|
+
await tester.locator(selector).click({
|
|
1029
1039
|
timeout: 1e3,
|
|
1030
1040
|
...options
|
|
1031
1041
|
});
|
|
@@ -1040,7 +1050,7 @@ const dblClick = async (context, selector, options = {}) => {
|
|
|
1040
1050
|
const provider = context.provider;
|
|
1041
1051
|
if (provider instanceof PlaywrightBrowserProvider) {
|
|
1042
1052
|
const tester = context.iframe;
|
|
1043
|
-
await tester.locator(
|
|
1053
|
+
await tester.locator(selector).dblclick(options);
|
|
1044
1054
|
} else if (provider instanceof WebdriverBrowserProvider) {
|
|
1045
1055
|
const browser = context.browser;
|
|
1046
1056
|
await browser.$(selector).doubleClick();
|
|
@@ -1052,7 +1062,7 @@ const tripleClick = async (context, selector, options = {}) => {
|
|
|
1052
1062
|
const provider = context.provider;
|
|
1053
1063
|
if (provider instanceof PlaywrightBrowserProvider) {
|
|
1054
1064
|
const tester = context.iframe;
|
|
1055
|
-
await tester.locator(
|
|
1065
|
+
await tester.locator(selector).click({
|
|
1056
1066
|
timeout: 1e3,
|
|
1057
1067
|
...options,
|
|
1058
1068
|
clickCount: 3
|
|
@@ -1523,7 +1533,7 @@ const type = async (context, selector, text, options = {}) => {
|
|
|
1523
1533
|
const unreleased = new Set(Reflect.get(options, "unreleased") ?? []);
|
|
1524
1534
|
if (context.provider instanceof PlaywrightBrowserProvider) {
|
|
1525
1535
|
const { iframe } = context;
|
|
1526
|
-
const element = iframe.locator(
|
|
1536
|
+
const element = iframe.locator(selector);
|
|
1527
1537
|
if (!skipClick) {
|
|
1528
1538
|
await element.focus();
|
|
1529
1539
|
}
|
|
@@ -1565,7 +1575,7 @@ const type = async (context, selector, text, options = {}) => {
|
|
|
1565
1575
|
const clear = async (context, selector) => {
|
|
1566
1576
|
if (context.provider instanceof PlaywrightBrowserProvider) {
|
|
1567
1577
|
const { iframe } = context;
|
|
1568
|
-
const element = iframe.locator(
|
|
1578
|
+
const element = iframe.locator(selector);
|
|
1569
1579
|
await element.clear({
|
|
1570
1580
|
timeout: 1e3
|
|
1571
1581
|
});
|
|
@@ -1581,7 +1591,7 @@ const clear = async (context, selector) => {
|
|
|
1581
1591
|
const fill = async (context, selector, text, options = {}) => {
|
|
1582
1592
|
if (context.provider instanceof PlaywrightBrowserProvider) {
|
|
1583
1593
|
const { iframe } = context;
|
|
1584
|
-
const element = iframe.locator(
|
|
1594
|
+
const element = iframe.locator(selector);
|
|
1585
1595
|
await element.fill(text, { timeout: 1e3, ...options });
|
|
1586
1596
|
} else if (context.provider instanceof WebdriverBrowserProvider) {
|
|
1587
1597
|
const browser = context.browser;
|
|
@@ -1595,12 +1605,12 @@ const selectOptions = async (context, selector, userValues, options = {}) => {
|
|
|
1595
1605
|
if (context.provider instanceof PlaywrightBrowserProvider) {
|
|
1596
1606
|
const value = userValues;
|
|
1597
1607
|
const { iframe } = context;
|
|
1598
|
-
const selectElement = iframe.locator(
|
|
1608
|
+
const selectElement = iframe.locator(selector);
|
|
1599
1609
|
const values = await Promise.all(value.map(async (v) => {
|
|
1600
1610
|
if (typeof v === "string") {
|
|
1601
1611
|
return v;
|
|
1602
1612
|
}
|
|
1603
|
-
const elementHandler = await iframe.locator(
|
|
1613
|
+
const elementHandler = await iframe.locator(v.element).elementHandle();
|
|
1604
1614
|
if (!elementHandler) {
|
|
1605
1615
|
throw new Error(`Element not found: ${v.element}`);
|
|
1606
1616
|
}
|
|
@@ -1643,22 +1653,23 @@ const tab = async (context, options = {}) => {
|
|
|
1643
1653
|
throw new Error(`Provider "${provider.name}" doesn't support tab command`);
|
|
1644
1654
|
};
|
|
1645
1655
|
|
|
1646
|
-
const dragAndDrop = async (context, source, target,
|
|
1656
|
+
const dragAndDrop = async (context, source, target, options_) => {
|
|
1647
1657
|
if (context.provider instanceof PlaywrightBrowserProvider) {
|
|
1648
1658
|
const frame = await context.frame();
|
|
1649
1659
|
await frame.dragAndDrop(
|
|
1650
|
-
|
|
1651
|
-
|
|
1660
|
+
source,
|
|
1661
|
+
target,
|
|
1652
1662
|
{
|
|
1653
1663
|
timeout: 1e3,
|
|
1654
|
-
...
|
|
1664
|
+
...options_
|
|
1655
1665
|
}
|
|
1656
1666
|
);
|
|
1657
1667
|
} else if (context.provider instanceof WebdriverBrowserProvider) {
|
|
1658
1668
|
const $source = context.browser.$(source);
|
|
1659
1669
|
const $target = context.browser.$(target);
|
|
1660
|
-
const
|
|
1661
|
-
|
|
1670
|
+
const options = options_ || {};
|
|
1671
|
+
const duration = options.duration ?? 10;
|
|
1672
|
+
await context.browser.action("pointer").move({ duration: 0, origin: $source, x: options.sourceX ?? 0, y: options.sourceY ?? 0 }).down({ button: 0 }).move({ duration: 0, origin: "pointer", x: 0, y: 0 }).pause(duration).move({ duration: 0, origin: $target, x: options.targetX ?? 0, y: options.targetY ?? 0 }).move({ duration: 0, origin: "pointer", x: 1, y: 0 }).move({ duration: 0, origin: "pointer", x: -1, y: 0 }).up({ button: 0 }).perform();
|
|
1662
1673
|
} else {
|
|
1663
1674
|
throw new TypeError(`Provider "${context.provider.name}" does not support dragging elements`);
|
|
1664
1675
|
}
|
|
@@ -1666,7 +1677,7 @@ const dragAndDrop = async (context, source, target, options) => {
|
|
|
1666
1677
|
|
|
1667
1678
|
const hover = async (context, selector, options = {}) => {
|
|
1668
1679
|
if (context.provider instanceof PlaywrightBrowserProvider) {
|
|
1669
|
-
await context.iframe.locator(
|
|
1680
|
+
await context.iframe.locator(selector).hover({
|
|
1670
1681
|
timeout: 1e3,
|
|
1671
1682
|
...options
|
|
1672
1683
|
});
|
|
@@ -1712,7 +1723,7 @@ const screenshot = async (context, name, options = {}) => {
|
|
|
1712
1723
|
if (!context.testPath) {
|
|
1713
1724
|
throw new Error(`Cannot take a screenshot without a test path`);
|
|
1714
1725
|
}
|
|
1715
|
-
const path = resolveScreenshotPath(
|
|
1726
|
+
const path = options.path ? resolve(context.testPath, options.path) : resolveScreenshotPath(
|
|
1716
1727
|
context.testPath,
|
|
1717
1728
|
name,
|
|
1718
1729
|
context.project.config
|
|
@@ -1721,8 +1732,8 @@ const screenshot = async (context, name, options = {}) => {
|
|
|
1721
1732
|
await mkdir(dirname(path), { recursive: true });
|
|
1722
1733
|
if (context.provider instanceof PlaywrightBrowserProvider) {
|
|
1723
1734
|
if (options.element) {
|
|
1724
|
-
const { element:
|
|
1725
|
-
const element = context.iframe.locator(
|
|
1735
|
+
const { element: selector, ...config } = options;
|
|
1736
|
+
const element = context.iframe.locator(`${selector}`);
|
|
1726
1737
|
const buffer2 = await element.screenshot({
|
|
1727
1738
|
timeout: 1e3,
|
|
1728
1739
|
...config,
|
|
@@ -1846,7 +1857,8 @@ export const server = {
|
|
|
1846
1857
|
browser: ${JSON.stringify(server.project.config.browser.name)},
|
|
1847
1858
|
commands: {
|
|
1848
1859
|
${commandsCode}
|
|
1849
|
-
}
|
|
1860
|
+
},
|
|
1861
|
+
config: __vitest_browser_runner__.config,
|
|
1850
1862
|
}
|
|
1851
1863
|
export const commands = server.commands
|
|
1852
1864
|
export const userEvent = ${getUserEvent(provider)}
|
|
@@ -1984,7 +1996,7 @@ async function resolveOrchestrator(server, url, res) {
|
|
|
1984
1996
|
__VITEST_TITLE__: "Vitest Browser Runner",
|
|
1985
1997
|
__VITEST_SCRIPTS__: server.orchestratorScripts,
|
|
1986
1998
|
__VITEST_INJECTOR__: `<script type="module">${injector}<\/script>`,
|
|
1987
|
-
__VITEST_ERROR_CATCHER__: `<script type="module" src="${server.
|
|
1999
|
+
__VITEST_ERROR_CATCHER__: `<script type="module" src="${server.errorCatcherUrl}"><\/script>`,
|
|
1988
2000
|
__VITEST_CONTEXT_ID__: JSON.stringify(contextId)
|
|
1989
2001
|
});
|
|
1990
2002
|
}
|
|
@@ -2034,7 +2046,10 @@ async function resolveTester(server, url, res) {
|
|
|
2034
2046
|
__VITEST_TITLE__: "Vitest Browser Tester",
|
|
2035
2047
|
__VITEST_SCRIPTS__: server.testerScripts,
|
|
2036
2048
|
__VITEST_INJECTOR__: `<script type="module">${injector}<\/script>`,
|
|
2037
|
-
|
|
2049
|
+
__VITEST_INTERNAL_SCRIPTS__: [
|
|
2050
|
+
`<script type="module" src="${server.errorCatcherUrl}"><\/script>`,
|
|
2051
|
+
server.locatorsUrl ? `<script type="module" src="${server.locatorsUrl}"><\/script>` : ""
|
|
2052
|
+
].join("\n"),
|
|
2038
2053
|
__VITEST_APPEND__: `<script type="module">
|
|
2039
2054
|
__vitest_browser_runner__.runningFiles = ${tests}
|
|
2040
2055
|
__vitest_browser_runner__.iframeId = ${iframeId}
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
import { UserEventClickOptions, UserEventHoverOptions, UserEventFillOptions, UserEventDragAndDropOptions, LocatorScreenshotOptions, LocatorByRoleOptions, LocatorOptions } from '@vitest/browser/context';
|
|
2
|
+
|
|
3
|
+
type ClauseCombinator = '' | '>' | '+' | '~' | '>=';
|
|
4
|
+
type CSSFunctionArgument = CSSComplexSelector | number | string;
|
|
5
|
+
interface CSSFunction {
|
|
6
|
+
name: string;
|
|
7
|
+
args: CSSFunctionArgument[];
|
|
8
|
+
}
|
|
9
|
+
interface CSSSimpleSelector {
|
|
10
|
+
css?: string;
|
|
11
|
+
functions: CSSFunction[];
|
|
12
|
+
}
|
|
13
|
+
interface CSSComplexSelector {
|
|
14
|
+
simples: {
|
|
15
|
+
selector: CSSSimpleSelector;
|
|
16
|
+
combinator: ClauseCombinator;
|
|
17
|
+
}[];
|
|
18
|
+
}
|
|
19
|
+
type CSSComplexSelectorList = CSSComplexSelector[];
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Copyright (c) Microsoft Corporation.
|
|
23
|
+
*
|
|
24
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
25
|
+
* you may not use this file except in compliance with the License.
|
|
26
|
+
* You may obtain a copy of the License at
|
|
27
|
+
*
|
|
28
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
29
|
+
*
|
|
30
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
31
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
32
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
33
|
+
* See the License for the specific language governing permissions and
|
|
34
|
+
* limitations under the License.
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
interface NestedSelectorBody {
|
|
38
|
+
parsed: ParsedSelector;
|
|
39
|
+
distance?: number;
|
|
40
|
+
}
|
|
41
|
+
interface ParsedSelectorPart {
|
|
42
|
+
name: string;
|
|
43
|
+
body: string | CSSComplexSelectorList | NestedSelectorBody;
|
|
44
|
+
source: string;
|
|
45
|
+
}
|
|
46
|
+
interface ParsedSelector {
|
|
47
|
+
parts: ParsedSelectorPart[];
|
|
48
|
+
capture?: number;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Copyright (c) Microsoft Corporation.
|
|
53
|
+
*
|
|
54
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
55
|
+
* you may not use this file except in compliance with the License.
|
|
56
|
+
* You may obtain a copy of the License at
|
|
57
|
+
*
|
|
58
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
59
|
+
*
|
|
60
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
61
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
62
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
63
|
+
* See the License for the specific language governing permissions and
|
|
64
|
+
* limitations under the License.
|
|
65
|
+
*/
|
|
66
|
+
|
|
67
|
+
interface GenerateSelectorOptions {
|
|
68
|
+
testIdAttributeName: string;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Copyright (c) Microsoft Corporation.
|
|
73
|
+
*
|
|
74
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
75
|
+
* you may not use this file except in compliance with the License.
|
|
76
|
+
* You may obtain a copy of the License at
|
|
77
|
+
*
|
|
78
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
79
|
+
*
|
|
80
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
81
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
82
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
83
|
+
* See the License for the specific language governing permissions and
|
|
84
|
+
* limitations under the License.
|
|
85
|
+
*/
|
|
86
|
+
|
|
87
|
+
interface ElementText {
|
|
88
|
+
full: string;
|
|
89
|
+
normalized: string;
|
|
90
|
+
immediate: string[];
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Copyright (c) Microsoft Corporation.
|
|
95
|
+
*
|
|
96
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
97
|
+
* you may not use this file except in compliance with the License.
|
|
98
|
+
* You may obtain a copy of the License at
|
|
99
|
+
*
|
|
100
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
101
|
+
*
|
|
102
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
103
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
104
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
105
|
+
* See the License for the specific language governing permissions and
|
|
106
|
+
* limitations under the License.
|
|
107
|
+
*/
|
|
108
|
+
|
|
109
|
+
interface QueryContext {
|
|
110
|
+
scope: Element | Document;
|
|
111
|
+
pierceShadow: boolean;
|
|
112
|
+
originalScope?: Element | Document;
|
|
113
|
+
}
|
|
114
|
+
type Selector = any;
|
|
115
|
+
interface SelectorEvaluator {
|
|
116
|
+
query: (context: QueryContext, selector: Selector) => Element[];
|
|
117
|
+
matches: (element: Element, selector: Selector, context: QueryContext) => boolean;
|
|
118
|
+
}
|
|
119
|
+
interface SelectorEngine$1 {
|
|
120
|
+
matches?: (element: Element, args: (string | number | Selector)[], context: QueryContext, evaluator: SelectorEvaluator) => boolean;
|
|
121
|
+
query?: (context: QueryContext, args: (string | number | Selector)[], evaluator: SelectorEvaluator) => Element[];
|
|
122
|
+
}
|
|
123
|
+
declare class SelectorEvaluatorImpl implements SelectorEvaluator {
|
|
124
|
+
private _engines;
|
|
125
|
+
private _cacheQueryCSS;
|
|
126
|
+
private _cacheMatches;
|
|
127
|
+
private _cacheQuery;
|
|
128
|
+
private _cacheMatchesSimple;
|
|
129
|
+
private _cacheMatchesParents;
|
|
130
|
+
private _cacheCallMatches;
|
|
131
|
+
private _cacheCallQuery;
|
|
132
|
+
private _cacheQuerySimple;
|
|
133
|
+
_cacheText: Map<Element | ShadowRoot, ElementText>;
|
|
134
|
+
private _scoreMap;
|
|
135
|
+
private _retainCacheCounter;
|
|
136
|
+
constructor(extraEngines: Map<string, SelectorEngine$1>);
|
|
137
|
+
begin(): void;
|
|
138
|
+
end(): void;
|
|
139
|
+
private _cached;
|
|
140
|
+
private _checkSelector;
|
|
141
|
+
matches(element: Element, s: Selector, context: QueryContext): boolean;
|
|
142
|
+
query(context: QueryContext, s: any): Element[];
|
|
143
|
+
_markScore(element: Element, score: number): void;
|
|
144
|
+
private _hasScopeClause;
|
|
145
|
+
private _expandContextForScopeMatching;
|
|
146
|
+
private _matchesSimple;
|
|
147
|
+
private _querySimple;
|
|
148
|
+
private _matchesParents;
|
|
149
|
+
private _matchesEngine;
|
|
150
|
+
private _queryEngine;
|
|
151
|
+
private _callMatches;
|
|
152
|
+
private _callQuery;
|
|
153
|
+
private _matchesCSS;
|
|
154
|
+
_queryCSS(context: QueryContext, css: string): Element[];
|
|
155
|
+
private _getEngine;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Copyright (c) Microsoft Corporation.
|
|
160
|
+
*
|
|
161
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
162
|
+
* you may not use this file except in compliance with the License.
|
|
163
|
+
* You may obtain a copy of the License at
|
|
164
|
+
*
|
|
165
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
166
|
+
*
|
|
167
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
168
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
169
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
170
|
+
* See the License for the specific language governing permissions and
|
|
171
|
+
* limitations under the License.
|
|
172
|
+
*/
|
|
173
|
+
|
|
174
|
+
interface IvyaOptions {
|
|
175
|
+
testIdAttribute: string;
|
|
176
|
+
browser: 'webkit' | 'chromium' | 'firefox';
|
|
177
|
+
}
|
|
178
|
+
interface IvyaConfiguration {
|
|
179
|
+
testIdAttribute?: string;
|
|
180
|
+
browser: 'webkit' | 'chromium' | 'firefox';
|
|
181
|
+
}
|
|
182
|
+
declare class Ivya {
|
|
183
|
+
/** @internal */
|
|
184
|
+
_engines: Map<string, SelectorEngine>;
|
|
185
|
+
/** @internal */
|
|
186
|
+
_evaluator: SelectorEvaluatorImpl;
|
|
187
|
+
static options: IvyaOptions;
|
|
188
|
+
private static singleton;
|
|
189
|
+
static create(options: IvyaConfiguration): Ivya;
|
|
190
|
+
private constructor();
|
|
191
|
+
queryLocatorSelector(locator: string, root?: Node, strict?: boolean): Element | null;
|
|
192
|
+
queryLocatorSelectorAll(locator: string, root?: Node): Element[];
|
|
193
|
+
querySelector(selector: ParsedSelector, root: Node, strict?: boolean): Element | null;
|
|
194
|
+
private strictModeViolationError;
|
|
195
|
+
generateSelectorSimple(targetElement: Element, options?: GenerateSelectorOptions): string;
|
|
196
|
+
parseSelector(selector: string): ParsedSelector;
|
|
197
|
+
previewNode(node: Node): string;
|
|
198
|
+
querySelectorAll(selector: ParsedSelector, root: Node): Element[];
|
|
199
|
+
private _queryEngineAll;
|
|
200
|
+
private _queryNth;
|
|
201
|
+
private _queryLayoutSelector;
|
|
202
|
+
private createStacklessError;
|
|
203
|
+
private _createTextEngine;
|
|
204
|
+
private _createAttributeEngine;
|
|
205
|
+
private _createCSSEngine;
|
|
206
|
+
private _createNamedAttributeEngine;
|
|
207
|
+
private _createVisibleEngine;
|
|
208
|
+
private _createHasEngine;
|
|
209
|
+
private _createHasNotEngine;
|
|
210
|
+
private _createInternalChainEngine;
|
|
211
|
+
private _createInternalLabelEngine;
|
|
212
|
+
private _createInternalHasTextEngine;
|
|
213
|
+
private _createInternalHasNotTextEngine;
|
|
214
|
+
}
|
|
215
|
+
type SelectorRoot = Element | ShadowRoot | Document;
|
|
216
|
+
interface SelectorEngine {
|
|
217
|
+
queryAll: (root: SelectorRoot, selector: string | any) => Element[];
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
declare const selectorEngine: Ivya;
|
|
221
|
+
declare abstract class Locator {
|
|
222
|
+
abstract selector: string;
|
|
223
|
+
private _parsedSelector;
|
|
224
|
+
protected _pwSelector?: string | undefined;
|
|
225
|
+
protected _forceElement?: Element | undefined;
|
|
226
|
+
click(options?: UserEventClickOptions): Promise<void>;
|
|
227
|
+
dblClick(options?: UserEventClickOptions): Promise<void>;
|
|
228
|
+
tripleClick(options?: UserEventClickOptions): Promise<void>;
|
|
229
|
+
clear(): Promise<void>;
|
|
230
|
+
hover(options: UserEventHoverOptions): Promise<void>;
|
|
231
|
+
unhover(options: UserEventHoverOptions): Promise<void>;
|
|
232
|
+
fill(text: string, options?: UserEventFillOptions): Promise<void>;
|
|
233
|
+
dropTo(target: Locator, options?: UserEventDragAndDropOptions): Promise<void>;
|
|
234
|
+
selectOptions(value: HTMLElement | HTMLElement[] | Locator | Locator[] | string | string[]): Promise<void>;
|
|
235
|
+
screenshot(options: Omit<LocatorScreenshotOptions, 'base64'> & {
|
|
236
|
+
base64: true;
|
|
237
|
+
}): Promise<{
|
|
238
|
+
path: string;
|
|
239
|
+
base64: string;
|
|
240
|
+
}>;
|
|
241
|
+
screenshot(options?: LocatorScreenshotOptions): Promise<string>;
|
|
242
|
+
protected abstract locator(selector: string): Locator;
|
|
243
|
+
protected abstract elementLocator(element: Element): Locator;
|
|
244
|
+
getByRole(role: string, options?: LocatorByRoleOptions): Locator;
|
|
245
|
+
getByAltText(text: string | RegExp, options?: LocatorOptions): Locator;
|
|
246
|
+
getByLabelText(text: string | RegExp, options?: LocatorOptions): Locator;
|
|
247
|
+
getByPlaceholder(text: string | RegExp, options?: LocatorOptions): Locator;
|
|
248
|
+
getByTestId(testId: string | RegExp): Locator;
|
|
249
|
+
getByText(text: string | RegExp, options?: LocatorOptions): Locator;
|
|
250
|
+
getByTitle(title: string | RegExp, options?: LocatorOptions): Locator;
|
|
251
|
+
query(): Element | null;
|
|
252
|
+
element(): Element;
|
|
253
|
+
elements(): Element[];
|
|
254
|
+
all(): Locator[];
|
|
255
|
+
private get state();
|
|
256
|
+
private get worker();
|
|
257
|
+
private get rpc();
|
|
258
|
+
protected triggerCommand<T>(command: string, ...args: any[]): Promise<T>;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
export { Locator, selectorEngine };
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { page, server } from '@vitest/browser/context';
|
|
2
|
+
import { g as getByLabelSelector, a as getByRoleSelector, b as getByTestIdSelector, c as getByAltTextSelector, d as getByPlaceholderSelector, e as getByTextSelector, f as getByTitleSelector, s as selectorEngine, L as Locator } from '../index-DX16doXA.js';
|
|
3
|
+
|
|
4
|
+
page.extend({
|
|
5
|
+
getByLabelText(text, options) {
|
|
6
|
+
return new PlaywrightLocator(getByLabelSelector(text, options));
|
|
7
|
+
},
|
|
8
|
+
getByRole(role, options) {
|
|
9
|
+
return new PlaywrightLocator(getByRoleSelector(role, options));
|
|
10
|
+
},
|
|
11
|
+
getByTestId(testId) {
|
|
12
|
+
return new PlaywrightLocator(getByTestIdSelector(server.config.browser.locators.testIdAttribute, testId));
|
|
13
|
+
},
|
|
14
|
+
getByAltText(text, options) {
|
|
15
|
+
return new PlaywrightLocator(getByAltTextSelector(text, options));
|
|
16
|
+
},
|
|
17
|
+
getByPlaceholder(text, options) {
|
|
18
|
+
return new PlaywrightLocator(getByPlaceholderSelector(text, options));
|
|
19
|
+
},
|
|
20
|
+
getByText(text, options) {
|
|
21
|
+
return new PlaywrightLocator(getByTextSelector(text, options));
|
|
22
|
+
},
|
|
23
|
+
getByTitle(title, options) {
|
|
24
|
+
return new PlaywrightLocator(getByTitleSelector(title, options));
|
|
25
|
+
},
|
|
26
|
+
elementLocator(element) {
|
|
27
|
+
return new PlaywrightLocator(selectorEngine.generateSelectorSimple(element), element);
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
class PlaywrightLocator extends Locator {
|
|
31
|
+
constructor(selector, _forceElement) {
|
|
32
|
+
super();
|
|
33
|
+
this.selector = selector;
|
|
34
|
+
this._forceElement = _forceElement;
|
|
35
|
+
}
|
|
36
|
+
locator(selector) {
|
|
37
|
+
return new PlaywrightLocator(`${this.selector} >> ${selector}`);
|
|
38
|
+
}
|
|
39
|
+
elementLocator(element) {
|
|
40
|
+
return new PlaywrightLocator(selectorEngine.generateSelectorSimple(element), element);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { page, server } from '@vitest/browser/context';
|
|
2
|
+
import { userEvent } from '@testing-library/user-event';
|
|
3
|
+
import { g as getByLabelSelector, a as getByRoleSelector, b as getByTestIdSelector, c as getByAltTextSelector, d as getByPlaceholderSelector, e as getByTextSelector, f as getByTitleSelector, s as selectorEngine, L as Locator, h as convertElementToCssSelector } from '../index-DX16doXA.js';
|
|
4
|
+
|
|
5
|
+
page.extend({
|
|
6
|
+
getByLabelText(text, options) {
|
|
7
|
+
return new PreviewLocator(getByLabelSelector(text, options));
|
|
8
|
+
},
|
|
9
|
+
getByRole(role, options) {
|
|
10
|
+
return new PreviewLocator(getByRoleSelector(role, options));
|
|
11
|
+
},
|
|
12
|
+
getByTestId(testId) {
|
|
13
|
+
return new PreviewLocator(getByTestIdSelector(server.config.browser.locators.testIdAttribute, testId));
|
|
14
|
+
},
|
|
15
|
+
getByAltText(text, options) {
|
|
16
|
+
return new PreviewLocator(getByAltTextSelector(text, options));
|
|
17
|
+
},
|
|
18
|
+
getByPlaceholder(text, options) {
|
|
19
|
+
return new PreviewLocator(getByPlaceholderSelector(text, options));
|
|
20
|
+
},
|
|
21
|
+
getByText(text, options) {
|
|
22
|
+
return new PreviewLocator(getByTextSelector(text, options));
|
|
23
|
+
},
|
|
24
|
+
getByTitle(title, options) {
|
|
25
|
+
return new PreviewLocator(getByTitleSelector(title, options));
|
|
26
|
+
},
|
|
27
|
+
elementLocator(element) {
|
|
28
|
+
return new PreviewLocator(selectorEngine.generateSelectorSimple(element), element);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
class PreviewLocator extends Locator {
|
|
32
|
+
constructor(_pwSelector, _forceElement) {
|
|
33
|
+
super();
|
|
34
|
+
this._pwSelector = _pwSelector;
|
|
35
|
+
this._forceElement = _forceElement;
|
|
36
|
+
}
|
|
37
|
+
get selector() {
|
|
38
|
+
const selectors = this.elements().map((element) => convertElementToCssSelector(element));
|
|
39
|
+
if (!selectors.length) {
|
|
40
|
+
throw new Error(`element not found: ${this._pwSelector}`);
|
|
41
|
+
}
|
|
42
|
+
return selectors.join(", ");
|
|
43
|
+
}
|
|
44
|
+
click() {
|
|
45
|
+
return userEvent.click(this.element());
|
|
46
|
+
}
|
|
47
|
+
dblClick() {
|
|
48
|
+
return userEvent.dblClick(this.element());
|
|
49
|
+
}
|
|
50
|
+
tripleClick() {
|
|
51
|
+
return userEvent.tripleClick(this.element());
|
|
52
|
+
}
|
|
53
|
+
hover() {
|
|
54
|
+
return userEvent.hover(this.element());
|
|
55
|
+
}
|
|
56
|
+
unhover() {
|
|
57
|
+
return userEvent.unhover(this.element());
|
|
58
|
+
}
|
|
59
|
+
fill(text) {
|
|
60
|
+
return userEvent.type(this.element(), text);
|
|
61
|
+
}
|
|
62
|
+
selectOptions(options_) {
|
|
63
|
+
const options = (Array.isArray(options_) ? options_ : [options_]).map((option) => {
|
|
64
|
+
if (typeof option !== "string" && "element" in option) {
|
|
65
|
+
return option.element();
|
|
66
|
+
}
|
|
67
|
+
return option;
|
|
68
|
+
});
|
|
69
|
+
return userEvent.selectOptions(this.element(), options);
|
|
70
|
+
}
|
|
71
|
+
async dropTo() {
|
|
72
|
+
throw new Error('The "preview" provider doesn\'t support `dropTo` method.');
|
|
73
|
+
}
|
|
74
|
+
clear() {
|
|
75
|
+
return userEvent.clear(this.element());
|
|
76
|
+
}
|
|
77
|
+
async screenshot() {
|
|
78
|
+
throw new Error('The "preview" provider doesn\'t support `screenshot` method.');
|
|
79
|
+
}
|
|
80
|
+
locator(selector) {
|
|
81
|
+
return new PreviewLocator(`${this._pwSelector} >> ${selector}`);
|
|
82
|
+
}
|
|
83
|
+
elementLocator(element) {
|
|
84
|
+
return new PreviewLocator(selectorEngine.generateSelectorSimple(element), element);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { page, server } from '@vitest/browser/context';
|
|
2
|
+
import { g as getByLabelSelector, a as getByRoleSelector, b as getByTestIdSelector, c as getByAltTextSelector, d as getByPlaceholderSelector, e as getByTextSelector, f as getByTitleSelector, s as selectorEngine, L as Locator, h as convertElementToCssSelector } from '../index-DX16doXA.js';
|
|
3
|
+
|
|
4
|
+
page.extend({
|
|
5
|
+
getByLabelText(text, options) {
|
|
6
|
+
return new WebdriverIOLocator(getByLabelSelector(text, options));
|
|
7
|
+
},
|
|
8
|
+
getByRole(role, options) {
|
|
9
|
+
return new WebdriverIOLocator(getByRoleSelector(role, options));
|
|
10
|
+
},
|
|
11
|
+
getByTestId(testId) {
|
|
12
|
+
return new WebdriverIOLocator(getByTestIdSelector(server.config.browser.locators.testIdAttribute, testId));
|
|
13
|
+
},
|
|
14
|
+
getByAltText(text, options) {
|
|
15
|
+
return new WebdriverIOLocator(getByAltTextSelector(text, options));
|
|
16
|
+
},
|
|
17
|
+
getByPlaceholder(text, options) {
|
|
18
|
+
return new WebdriverIOLocator(getByPlaceholderSelector(text, options));
|
|
19
|
+
},
|
|
20
|
+
getByText(text, options) {
|
|
21
|
+
return new WebdriverIOLocator(getByTextSelector(text, options));
|
|
22
|
+
},
|
|
23
|
+
getByTitle(title, options) {
|
|
24
|
+
return new WebdriverIOLocator(getByTitleSelector(title, options));
|
|
25
|
+
},
|
|
26
|
+
elementLocator(element) {
|
|
27
|
+
return new WebdriverIOLocator(selectorEngine.generateSelectorSimple(element), element);
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
class WebdriverIOLocator extends Locator {
|
|
31
|
+
constructor(_pwSelector, _forceElement) {
|
|
32
|
+
super();
|
|
33
|
+
this._pwSelector = _pwSelector;
|
|
34
|
+
this._forceElement = _forceElement;
|
|
35
|
+
}
|
|
36
|
+
get selector() {
|
|
37
|
+
const selectors = this.elements().map((element) => convertElementToCssSelector(element));
|
|
38
|
+
if (!selectors.length) {
|
|
39
|
+
throw new Error(`element not found: ${this._pwSelector}`);
|
|
40
|
+
}
|
|
41
|
+
return selectors.join(", ");
|
|
42
|
+
}
|
|
43
|
+
selectOptions(value) {
|
|
44
|
+
const values = getWebdriverioSelectOptions(this.element(), value);
|
|
45
|
+
return this.triggerCommand("__vitest_selectOptions", this.selector, values);
|
|
46
|
+
}
|
|
47
|
+
locator(selector) {
|
|
48
|
+
return new WebdriverIOLocator(`${this._pwSelector} >> ${selector}`);
|
|
49
|
+
}
|
|
50
|
+
elementLocator(element) {
|
|
51
|
+
return new WebdriverIOLocator(selectorEngine.generateSelectorSimple(element), element);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function getWebdriverioSelectOptions(element, value) {
|
|
55
|
+
const options = [...element.querySelectorAll("option")];
|
|
56
|
+
const arrayValues = Array.isArray(value) ? value : [value];
|
|
57
|
+
if (!arrayValues.length) {
|
|
58
|
+
return [];
|
|
59
|
+
}
|
|
60
|
+
if (arrayValues.length > 1) {
|
|
61
|
+
throw new Error(`Provider "webdriverio" doesn't support selecting multiple values at once`);
|
|
62
|
+
}
|
|
63
|
+
const optionValue = arrayValues[0];
|
|
64
|
+
if (typeof optionValue !== "string") {
|
|
65
|
+
const element2 = "element" in optionValue ? optionValue.element() : optionValue;
|
|
66
|
+
const index = options.indexOf(element2);
|
|
67
|
+
if (index === -1) {
|
|
68
|
+
throw new Error(`The element ${selectorEngine.previewNode(element2)} was not found in the "select" options.`);
|
|
69
|
+
}
|
|
70
|
+
return [{ index }];
|
|
71
|
+
}
|
|
72
|
+
const valueIndex = options.findIndex((option) => option.value === optionValue);
|
|
73
|
+
if (valueIndex !== -1) {
|
|
74
|
+
return [{ index: valueIndex }];
|
|
75
|
+
}
|
|
76
|
+
const labelIndex = options.findIndex(
|
|
77
|
+
(option) => option.textContent?.trim() === optionValue || option.ariaLabel === optionValue
|
|
78
|
+
);
|
|
79
|
+
if (labelIndex === -1) {
|
|
80
|
+
throw new Error(`The option "${optionValue}" was not found in the "select" options.`);
|
|
81
|
+
}
|
|
82
|
+
return [{ index: labelIndex }];
|
|
83
|
+
}
|