@vitest/browser 5.0.0-beta.1 → 5.0.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/context.d.ts +32 -1
- package/dist/client/.vite/manifest.json +6 -6
- package/dist/client/__vitest__/assets/{index-BmuVn2L3.js → index-Cd6On2Pm.js} +58 -58
- package/dist/client/__vitest__/assets/{index-CxYquQyv.css → index-Dw9P28Qt.css} +1 -1
- package/dist/client/__vitest__/index.html +2 -2
- package/dist/client/__vitest_browser__/{orchestrator-pTEf6o0n.js → orchestrator-BfoS0x4w.js} +31 -3
- package/dist/client/__vitest_browser__/{utils-BYUpz6v6.js → tester-BJtW9QqZ.js} +2551 -342
- package/dist/client/__vitest_browser__/utils-Nd8hqrhP.js +189 -0
- package/dist/client/orchestrator.html +2 -2
- package/dist/client/tester/locators.d.ts +69 -0
- package/dist/client/tester/tester.html +2 -2
- package/dist/client/tester/trace.d.ts +2 -1
- package/dist/context.js +21 -22
- package/dist/expect-element.js +30 -30
- package/dist/index.d.ts +6 -22
- package/dist/index.js +8 -4551
- package/dist/locators-CesZ2RSY.js +5 -0
- package/dist/locators.d.ts +9 -1
- package/dist/locators.js +1 -1
- package/dist/shared/screenshotMatcher/types.d.ts +3 -3
- package/package.json +10 -7
- package/dist/client/__vitest__/bg.png +0 -0
- package/dist/client/__vitest_browser__/tester-CIKiUsoz.js +0 -2431
- package/dist/index-BlWsE3ij.js +0 -5
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
(function polyfill() {
|
|
2
|
+
const relList = document.createElement("link").relList;
|
|
3
|
+
if (relList && relList.supports && relList.supports("modulepreload")) return;
|
|
4
|
+
for (const link of document.querySelectorAll('link[rel="modulepreload"]')) processPreload(link);
|
|
5
|
+
new MutationObserver((mutations) => {
|
|
6
|
+
for (const mutation of mutations) {
|
|
7
|
+
if (mutation.type !== "childList") continue;
|
|
8
|
+
for (const node of mutation.addedNodes) if (node.tagName === "LINK" && node.rel === "modulepreload") processPreload(node);
|
|
9
|
+
}
|
|
10
|
+
}).observe(document, {
|
|
11
|
+
childList: true,
|
|
12
|
+
subtree: true
|
|
13
|
+
});
|
|
14
|
+
function getFetchOpts(link) {
|
|
15
|
+
const fetchOpts = {};
|
|
16
|
+
if (link.integrity) fetchOpts.integrity = link.integrity;
|
|
17
|
+
if (link.referrerPolicy) fetchOpts.referrerPolicy = link.referrerPolicy;
|
|
18
|
+
if (link.crossOrigin === "use-credentials") fetchOpts.credentials = "include";
|
|
19
|
+
else if (link.crossOrigin === "anonymous") fetchOpts.credentials = "omit";
|
|
20
|
+
else fetchOpts.credentials = "same-origin";
|
|
21
|
+
return fetchOpts;
|
|
22
|
+
}
|
|
23
|
+
function processPreload(link) {
|
|
24
|
+
if (link.ep) return;
|
|
25
|
+
link.ep = true;
|
|
26
|
+
const fetchOpts = getFetchOpts(link);
|
|
27
|
+
fetch(link.href, fetchOpts);
|
|
28
|
+
}
|
|
29
|
+
})();
|
|
30
|
+
const _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//;
|
|
31
|
+
function normalizeWindowsPath(input = "") {
|
|
32
|
+
if (!input) {
|
|
33
|
+
return input;
|
|
34
|
+
}
|
|
35
|
+
return input.replace(/\\/g, "/").replace(_DRIVE_LETTER_START_RE, (r) => r.toUpperCase());
|
|
36
|
+
}
|
|
37
|
+
const _IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Za-z]:[/\\]/;
|
|
38
|
+
const _ROOT_FOLDER_RE = /^\/([A-Za-z]:)?$/;
|
|
39
|
+
function cwd() {
|
|
40
|
+
if (typeof process !== "undefined" && typeof process.cwd === "function") {
|
|
41
|
+
return process.cwd().replace(/\\/g, "/");
|
|
42
|
+
}
|
|
43
|
+
return "/";
|
|
44
|
+
}
|
|
45
|
+
const resolve = function(...arguments_) {
|
|
46
|
+
arguments_ = arguments_.map((argument) => normalizeWindowsPath(argument));
|
|
47
|
+
let resolvedPath = "";
|
|
48
|
+
let resolvedAbsolute = false;
|
|
49
|
+
for (let index = arguments_.length - 1; index >= -1 && !resolvedAbsolute; index--) {
|
|
50
|
+
const path = index >= 0 ? arguments_[index] : cwd();
|
|
51
|
+
if (!path || path.length === 0) {
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
resolvedPath = `${path}/${resolvedPath}`;
|
|
55
|
+
resolvedAbsolute = isAbsolute(path);
|
|
56
|
+
}
|
|
57
|
+
resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute);
|
|
58
|
+
if (resolvedAbsolute && !isAbsolute(resolvedPath)) {
|
|
59
|
+
return `/${resolvedPath}`;
|
|
60
|
+
}
|
|
61
|
+
return resolvedPath.length > 0 ? resolvedPath : ".";
|
|
62
|
+
};
|
|
63
|
+
function normalizeString(path, allowAboveRoot) {
|
|
64
|
+
let res = "";
|
|
65
|
+
let lastSegmentLength = 0;
|
|
66
|
+
let lastSlash = -1;
|
|
67
|
+
let dots = 0;
|
|
68
|
+
let char = null;
|
|
69
|
+
for (let index = 0; index <= path.length; ++index) {
|
|
70
|
+
if (index < path.length) {
|
|
71
|
+
char = path[index];
|
|
72
|
+
} else if (char === "/") {
|
|
73
|
+
break;
|
|
74
|
+
} else {
|
|
75
|
+
char = "/";
|
|
76
|
+
}
|
|
77
|
+
if (char === "/") {
|
|
78
|
+
if (lastSlash === index - 1 || dots === 1) ;
|
|
79
|
+
else if (dots === 2) {
|
|
80
|
+
if (res.length < 2 || lastSegmentLength !== 2 || res[res.length - 1] !== "." || res[res.length - 2] !== ".") {
|
|
81
|
+
if (res.length > 2) {
|
|
82
|
+
const lastSlashIndex = res.lastIndexOf("/");
|
|
83
|
+
if (lastSlashIndex === -1) {
|
|
84
|
+
res = "";
|
|
85
|
+
lastSegmentLength = 0;
|
|
86
|
+
} else {
|
|
87
|
+
res = res.slice(0, lastSlashIndex);
|
|
88
|
+
lastSegmentLength = res.length - 1 - res.lastIndexOf("/");
|
|
89
|
+
}
|
|
90
|
+
lastSlash = index;
|
|
91
|
+
dots = 0;
|
|
92
|
+
continue;
|
|
93
|
+
} else if (res.length > 0) {
|
|
94
|
+
res = "";
|
|
95
|
+
lastSegmentLength = 0;
|
|
96
|
+
lastSlash = index;
|
|
97
|
+
dots = 0;
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
if (allowAboveRoot) {
|
|
102
|
+
res += res.length > 0 ? "/.." : "..";
|
|
103
|
+
lastSegmentLength = 2;
|
|
104
|
+
}
|
|
105
|
+
} else {
|
|
106
|
+
if (res.length > 0) {
|
|
107
|
+
res += `/${path.slice(lastSlash + 1, index)}`;
|
|
108
|
+
} else {
|
|
109
|
+
res = path.slice(lastSlash + 1, index);
|
|
110
|
+
}
|
|
111
|
+
lastSegmentLength = index - lastSlash - 1;
|
|
112
|
+
}
|
|
113
|
+
lastSlash = index;
|
|
114
|
+
dots = 0;
|
|
115
|
+
} else if (char === "." && dots !== -1) {
|
|
116
|
+
++dots;
|
|
117
|
+
} else {
|
|
118
|
+
dots = -1;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return res;
|
|
122
|
+
}
|
|
123
|
+
const isAbsolute = function(p) {
|
|
124
|
+
return _IS_ABSOLUTE_RE.test(p);
|
|
125
|
+
};
|
|
126
|
+
const relative = function(from, to) {
|
|
127
|
+
const _from = resolve(from).replace(_ROOT_FOLDER_RE, "$1").split("/");
|
|
128
|
+
const _to = resolve(to).replace(_ROOT_FOLDER_RE, "$1").split("/");
|
|
129
|
+
if (_to[0][1] === ":" && _from[0][1] === ":" && _from[0] !== _to[0]) {
|
|
130
|
+
return _to.join("/");
|
|
131
|
+
}
|
|
132
|
+
const _fromCopy = [..._from];
|
|
133
|
+
for (const segment of _fromCopy) {
|
|
134
|
+
if (_to[0] !== segment) {
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
137
|
+
_from.shift();
|
|
138
|
+
_to.shift();
|
|
139
|
+
}
|
|
140
|
+
return [..._from.map(() => ".."), ..._to].join("/");
|
|
141
|
+
};
|
|
142
|
+
async function importId(id) {
|
|
143
|
+
const name = `/@id/${id}`.replace(/\\/g, "/");
|
|
144
|
+
return (/* @__PURE__ */ getBrowserState()).wrapModule(() => import(
|
|
145
|
+
/* @vite-ignore */
|
|
146
|
+
name
|
|
147
|
+
));
|
|
148
|
+
}
|
|
149
|
+
async function importFs(id) {
|
|
150
|
+
const name = `/@fs/${id}`.replace(/\\/g, "/");
|
|
151
|
+
return (/* @__PURE__ */ getBrowserState()).wrapModule(() => import(
|
|
152
|
+
/* @vite-ignore */
|
|
153
|
+
name
|
|
154
|
+
));
|
|
155
|
+
}
|
|
156
|
+
const moduleRunner = {
|
|
157
|
+
isBrowser: true,
|
|
158
|
+
import: (id) => {
|
|
159
|
+
if (id[0] === "/" || id[1] === ":") {
|
|
160
|
+
return importFs(id);
|
|
161
|
+
}
|
|
162
|
+
return importId(id);
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
const now = globalThis.performance ? globalThis.performance.now.bind(globalThis.performance) : Date.now;
|
|
166
|
+
function getConfig() {
|
|
167
|
+
return (/* @__PURE__ */ getBrowserState()).config;
|
|
168
|
+
}
|
|
169
|
+
// @__NO_SIDE_EFFECTS__
|
|
170
|
+
function getBrowserState() {
|
|
171
|
+
return window.__vitest_browser_runner__;
|
|
172
|
+
}
|
|
173
|
+
// @__NO_SIDE_EFFECTS__
|
|
174
|
+
function getWorkerState() {
|
|
175
|
+
const state = window.__vitest_worker__;
|
|
176
|
+
if (!state) {
|
|
177
|
+
throw new Error("Worker state is not found. This is an issue with Vitest. Please, open an issue.");
|
|
178
|
+
}
|
|
179
|
+
return state;
|
|
180
|
+
}
|
|
181
|
+
export {
|
|
182
|
+
getConfig as a,
|
|
183
|
+
resolve as b,
|
|
184
|
+
getWorkerState as c,
|
|
185
|
+
getBrowserState as g,
|
|
186
|
+
moduleRunner as m,
|
|
187
|
+
now as n,
|
|
188
|
+
relative as r
|
|
189
|
+
};
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
{__VITEST_INJECTOR__}
|
|
27
27
|
{__VITEST_ERROR_CATCHER__}
|
|
28
28
|
{__VITEST_SCRIPTS__}
|
|
29
|
-
<script type="module" crossorigin src="/__vitest_browser__/orchestrator-
|
|
30
|
-
<link rel="modulepreload" crossorigin href="/__vitest_browser__/utils-
|
|
29
|
+
<script type="module" crossorigin src="/__vitest_browser__/orchestrator-BfoS0x4w.js"></script>
|
|
30
|
+
<link rel="modulepreload" crossorigin href="/__vitest_browser__/utils-Nd8hqrhP.js">
|
|
31
31
|
</head>
|
|
32
32
|
<body>
|
|
33
33
|
<div id="vitest-tester"></div>
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { LocatorByRoleOptions, LocatorOptions, LocatorScreenshotOptions, MarkOptions, SelectorOptions, UserEventClearOptions, UserEventClickOptions, UserEventDragAndDropOptions, UserEventFillOptions, UserEventHoverOptions, UserEventSelectOptions, UserEventUploadOptions, UserEventWheelOptions } from "vitest/browser";
|
|
2
|
+
import { Ivya } from "ivya";
|
|
3
|
+
export { ensureAwaited } from "../utils.js";
|
|
4
|
+
export { convertElementToCssSelector, getIframeScale, processTimeoutOptions } from "./tester-utils.js";
|
|
5
|
+
export { getByAltTextSelector, getByLabelSelector, getByPlaceholderSelector, getByRoleSelector, getByTestIdSelector, getByTextSelector, getByTitleSelector } from "ivya";
|
|
6
|
+
export declare const selectorEngine: Ivya;
|
|
7
|
+
export declare abstract class Locator {
|
|
8
|
+
abstract selector: string;
|
|
9
|
+
private _parsedSelector;
|
|
10
|
+
protected _container?: Element | undefined;
|
|
11
|
+
protected _pwSelector?: string | undefined;
|
|
12
|
+
protected _pwLocator?: string | undefined;
|
|
13
|
+
protected _errorSource?: Error;
|
|
14
|
+
constructor();
|
|
15
|
+
click(options?: UserEventClickOptions): Promise<void>;
|
|
16
|
+
dblClick(options?: UserEventClickOptions): Promise<void>;
|
|
17
|
+
tripleClick(options?: UserEventClickOptions): Promise<void>;
|
|
18
|
+
wheel(options: UserEventWheelOptions): Promise<void>;
|
|
19
|
+
clear(options?: UserEventClearOptions): Promise<void>;
|
|
20
|
+
hover(options?: UserEventHoverOptions): Promise<void>;
|
|
21
|
+
unhover(options?: UserEventHoverOptions): Promise<void>;
|
|
22
|
+
fill(text: string, options?: UserEventFillOptions): Promise<void>;
|
|
23
|
+
upload(files: string | string[] | File | File[], options?: UserEventUploadOptions): Promise<void>;
|
|
24
|
+
dropTo(target: Locator, options?: UserEventDragAndDropOptions): Promise<void>;
|
|
25
|
+
selectOptions(value: HTMLElement | HTMLElement[] | Locator | Locator[] | string | string[], options?: UserEventSelectOptions): Promise<void>;
|
|
26
|
+
screenshot(options: Omit<LocatorScreenshotOptions, "base64"> & {
|
|
27
|
+
base64: true;
|
|
28
|
+
}): Promise<{
|
|
29
|
+
path: string;
|
|
30
|
+
base64: string;
|
|
31
|
+
}>;
|
|
32
|
+
screenshot(options?: LocatorScreenshotOptions): Promise<string>;
|
|
33
|
+
mark(name: string, options?: MarkOptions): Promise<void>;
|
|
34
|
+
protected abstract locator(selector: string): Locator;
|
|
35
|
+
protected abstract elementLocator(element: Element): Locator;
|
|
36
|
+
getByRole(role: string, options?: LocatorByRoleOptions): Locator;
|
|
37
|
+
getByAltText(text: string | RegExp, options?: LocatorOptions): Locator;
|
|
38
|
+
getByLabelText(text: string | RegExp, options?: LocatorOptions): Locator;
|
|
39
|
+
getByPlaceholder(text: string | RegExp, options?: LocatorOptions): Locator;
|
|
40
|
+
getByTestId(testId: string | RegExp): Locator;
|
|
41
|
+
getByText(text: string | RegExp, options?: LocatorOptions): Locator;
|
|
42
|
+
getByTitle(title: string | RegExp, options?: LocatorOptions): Locator;
|
|
43
|
+
filter(filter: LocatorOptions): Locator;
|
|
44
|
+
and(locator: Locator): Locator;
|
|
45
|
+
or(locator: Locator): Locator;
|
|
46
|
+
query(): HTMLElement | SVGElement | null;
|
|
47
|
+
element(): HTMLElement | SVGElement;
|
|
48
|
+
elements(): (HTMLElement | SVGElement)[];
|
|
49
|
+
get length(): number;
|
|
50
|
+
all(): Locator[];
|
|
51
|
+
nth(index: number): Locator;
|
|
52
|
+
first(): Locator;
|
|
53
|
+
last(): Locator;
|
|
54
|
+
toString(): string;
|
|
55
|
+
serialize(): SerializedLocator;
|
|
56
|
+
asLocator(): string;
|
|
57
|
+
toJSON(): SerializedLocator;
|
|
58
|
+
findElement(options_?: SelectorOptions): Promise<HTMLElement | SVGElement>;
|
|
59
|
+
protected triggerCommand<T>(command: string, ...args: any[]): Promise<T>;
|
|
60
|
+
}
|
|
61
|
+
export declare function triggerCommandWithTrace<T>(options: {
|
|
62
|
+
name: string;
|
|
63
|
+
arguments: unknown[];
|
|
64
|
+
errorSource?: Error | undefined;
|
|
65
|
+
}): Promise<T>;
|
|
66
|
+
export interface SerializedLocator {
|
|
67
|
+
selector: string;
|
|
68
|
+
locator: string;
|
|
69
|
+
}
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
<link rel="icon" href="{__VITEST_FAVICON__}" type="image/svg+xml">
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
7
|
<title>Vitest Browser Tester</title>
|
|
8
|
-
<script type="module" crossorigin src="/__vitest_browser__/tester-
|
|
9
|
-
<link rel="modulepreload" crossorigin href="/__vitest_browser__/utils-
|
|
8
|
+
<script type="module" crossorigin src="/__vitest_browser__/tester-BJtW9QqZ.js"></script>
|
|
9
|
+
<link rel="modulepreload" crossorigin href="/__vitest_browser__/utils-Nd8hqrhP.js">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
|
12
12
|
</body>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Task } from "@vitest/runner";
|
|
2
|
+
import type { SerializedLocator } from "./locators.js";
|
|
2
3
|
export interface BrowserTraceData {
|
|
3
4
|
retry: number;
|
|
4
5
|
repeats: number;
|
|
@@ -20,7 +21,7 @@ export interface BrowserTraceEntry {
|
|
|
20
21
|
line: number;
|
|
21
22
|
column: number;
|
|
22
23
|
};
|
|
23
|
-
|
|
24
|
+
element?: SerializedLocator;
|
|
24
25
|
snapshot: TraceSnapshot;
|
|
25
26
|
}
|
|
26
27
|
interface TraceSnapshot {
|
package/dist/context.js
CHANGED
|
@@ -74,19 +74,9 @@ function getTraceStateKey(testId, repeats, retry) {
|
|
|
74
74
|
}
|
|
75
75
|
// TODO: should we avoid accumulating? send and immediately clear each entry to save memory?
|
|
76
76
|
function recordBrowserTraceEntry(task, options) {
|
|
77
|
-
// TODO: trace-view currently receives selectors after locator/action resolution,
|
|
78
|
-
// so provider-specific lowered selectors can leak into snapshot lookup. Preserve
|
|
79
|
-
// the original locator selector, or record the target node id before lowering.
|
|
80
|
-
// for example, this causes shadow dom selectors to fail with `>>>` marker.
|
|
81
|
-
// For now, remove trivial `html >` prefix generated by convertElementToCssSelector.
|
|
82
|
-
// this is also necessary to `engine.querySelector + document.documentElement`
|
|
83
|
-
// to find an element on webdriverio
|
|
84
|
-
if (options.selector?.startsWith("html >")) {
|
|
85
|
-
options.selector = options.selector.slice(6);
|
|
86
|
-
}
|
|
87
77
|
const attemptInfo = getBrowserState().browserTraceAttempts.get(task.id);
|
|
88
78
|
const relativeStartTime = (options.startTime ?? now()) - attemptInfo.startTime;
|
|
89
|
-
const snapshot = takeSnapshot(options.
|
|
79
|
+
const snapshot = takeSnapshot(options.element);
|
|
90
80
|
const entry = {
|
|
91
81
|
...options,
|
|
92
82
|
startTime: relativeStartTime,
|
|
@@ -110,7 +100,7 @@ function recordBrowserTraceEntry(task, options) {
|
|
|
110
100
|
// selector engine inside the snapshot iframe at view time via injected script.
|
|
111
101
|
// Our approach resolves at collection time (same moment as snapshot) — simpler but
|
|
112
102
|
// requires Mirror plumbing. nodeId-based lookup also works across shadow DOM, unlike querySelector.
|
|
113
|
-
function takeSnapshot(
|
|
103
|
+
function takeSnapshot(serializedLocator) {
|
|
114
104
|
const { snapshot, createMirror } = getBrowserState().browserTraceDomSnapshot;
|
|
115
105
|
const traceView = getBrowserState().config.browser.traceView;
|
|
116
106
|
const engine = getBrowserState().selectorEngine;
|
|
@@ -137,9 +127,9 @@ function takeSnapshot(selector) {
|
|
|
137
127
|
const ids = Array.from(elements, (el) => mirror.getId(el)).filter((id) => id !== -1);
|
|
138
128
|
result.pseudoClassIds[className] = ids;
|
|
139
129
|
}
|
|
140
|
-
if (
|
|
130
|
+
if (serializedLocator) {
|
|
141
131
|
try {
|
|
142
|
-
const el = engine.querySelector(engine.parseSelector(selector), document.documentElement, false);
|
|
132
|
+
const el = engine.querySelector(engine.parseSelector(serializedLocator._pwSelector ?? serializedLocator.selector), document.documentElement, false);
|
|
143
133
|
if (!el) {
|
|
144
134
|
result.selectorResolution = "missing";
|
|
145
135
|
} else {
|
|
@@ -262,19 +252,28 @@ function processTimeoutOptions(options_) {
|
|
|
262
252
|
}
|
|
263
253
|
const provider$1 = getBrowserState().provider;
|
|
264
254
|
const kElementLocator = Symbol.for("$$vitest:locator-resolved");
|
|
265
|
-
async function
|
|
255
|
+
async function serializeElement(elementOrLocator, options) {
|
|
266
256
|
if (!elementOrLocator) {
|
|
267
257
|
throw new Error("Expected element or locator to be defined.");
|
|
268
258
|
}
|
|
269
259
|
if (elementOrLocator instanceof Element) {
|
|
270
|
-
|
|
260
|
+
const selector = convertElementToCssSelector(elementOrLocator);
|
|
261
|
+
return {
|
|
262
|
+
selector,
|
|
263
|
+
locator: __INTERNAL._asLocator("javascript", selector)
|
|
264
|
+
};
|
|
271
265
|
}
|
|
272
266
|
if (isLocator(elementOrLocator)) {
|
|
273
267
|
if (provider$1 === "playwright" || kElementLocator in elementOrLocator) {
|
|
274
|
-
return elementOrLocator.
|
|
268
|
+
return elementOrLocator.serialize();
|
|
275
269
|
}
|
|
276
270
|
const element = await elementOrLocator.findElement(options);
|
|
277
|
-
|
|
271
|
+
const selector = convertElementToCssSelector(element);
|
|
272
|
+
const locator = __INTERNAL._asLocator("javascript", selector);
|
|
273
|
+
return {
|
|
274
|
+
selector,
|
|
275
|
+
locator
|
|
276
|
+
};
|
|
278
277
|
}
|
|
279
278
|
throw new Error("Expected element or locator to be an instance of Element or Locator.");
|
|
280
279
|
}
|
|
@@ -380,9 +379,9 @@ function createUserEvent(__tl_user_event_base__, options) {
|
|
|
380
379
|
},
|
|
381
380
|
type(element, text, options) {
|
|
382
381
|
return ensureAwaited(async (error) => {
|
|
383
|
-
const
|
|
382
|
+
const serializedElement = await serializeElement(element, options);
|
|
384
383
|
const { unreleased } = await triggerCommand("__vitest_type", [
|
|
385
|
-
|
|
384
|
+
serializedElement,
|
|
386
385
|
text,
|
|
387
386
|
{
|
|
388
387
|
...options,
|
|
@@ -566,7 +565,7 @@ const page = {
|
|
|
566
565
|
screenshotIds[repeatCount] ??= {};
|
|
567
566
|
screenshotIds[repeatCount][taskName] = number + 1;
|
|
568
567
|
const name = options.path || `${taskName.replace(/[^a-z0-9]/gi, "-")}-${number}.png`;
|
|
569
|
-
const [element, ...mask] = await Promise.all([options.element ?
|
|
568
|
+
const [element, ...mask] = await Promise.all([options.element ? serializeElement(options.element, options) : undefined, ..."mask" in options ? options.mask.map((el) => serializeElement(el, options)) : []]);
|
|
570
569
|
const normalizedOptions = "mask" in options ? {
|
|
571
570
|
...options,
|
|
572
571
|
mask
|
|
@@ -754,7 +753,7 @@ function prettyDOM(dom, maxLength = Number(defaultOptions?.maxLength ?? import.m
|
|
|
754
753
|
return dom.outerHTML.length > maxLength ? `${pretty.slice(0, maxLength)}...` : pretty;
|
|
755
754
|
}
|
|
756
755
|
function getElementError(selector, container) {
|
|
757
|
-
const error = new Error(`Cannot find element with locator: ${__INTERNAL._asLocator("javascript", selector)}\n\n${prettyDOM(container)}`);
|
|
756
|
+
const error = new Error(`Cannot find element with locator: ${typeof selector === "string" ? __INTERNAL._asLocator("javascript", selector) : selector.asLocator()}\n\n${prettyDOM(container)}`);
|
|
758
757
|
error.name = "VitestBrowserElementError";
|
|
759
758
|
return error;
|
|
760
759
|
}
|