@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/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
- errorCatcherPath: Promise<string> | string;
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.errorCatcherPath = resolve(distRoot, "client/error-catcher.js");
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
- errorCatcherPath;
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(`css=${selector}`).click({
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(`css=${selector}`).dblclick(options);
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(`css=${selector}`).click({
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(`css=${selector}`);
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(`css=${selector}`);
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(`css=${selector}`);
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(`css=${selector}`);
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(`css=${v.element}`).elementHandle();
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, options) => {
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
- `css=${source}`,
1651
- `css=${target}`,
1660
+ source,
1661
+ target,
1652
1662
  {
1653
1663
  timeout: 1e3,
1654
- ...options
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 duration = options?.duration ?? 10;
1661
- await context.browser.action("pointer").move({ duration: 0, origin: $source, x: 0, y: 0 }).down({ button: 0 }).move({ duration: 0, origin: "pointer", x: 0, y: 0 }).pause(duration).move({ duration: 0, origin: $target, x: 0, y: 0 }).move({ duration: 0, origin: "pointer", x: 1, y: 0 }).move({ duration: 0, origin: "pointer", x: -1, y: 0 }).up({ button: 0 }).perform();
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(`css=${selector}`).hover({
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: css, ...config } = options;
1725
- const element = context.iframe.locator(`css=${css}`);
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.errorCatcherPath}"><\/script>`,
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
- __VITEST_ERROR_CATCHER__: `<script type="module" src="${server.errorCatcherPath}"><\/script>`,
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,2 @@
1
+ import '@vitest/browser/context';
2
+ export { L as Locator, s as selectorEngine } from '../index-DX16doXA.js';
@@ -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
+ }