@vitest/browser 3.1.0 → 3.1.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.
@@ -1,241 +0,0 @@
1
- var __defProp = Object.defineProperty;
2
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
- var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
- import { g as getBrowserState, a as getConfig, r as relative } from "./utils-CNTxSNQV.js";
5
- import { client, channel, globalChannel } from "@vitest/browser/client";
6
- function generateHash(str) {
7
- let hash = 0;
8
- if (str.length === 0) {
9
- return `${hash}`;
10
- }
11
- for (let i = 0; i < str.length; i++) {
12
- const char = str.charCodeAt(i);
13
- hash = (hash << 5) - hash + char;
14
- hash = hash & hash;
15
- }
16
- return `${hash}`;
17
- }
18
- function getUiAPI() {
19
- return window.__vitest_ui_api__;
20
- }
21
- const url = new URL(location.href);
22
- const ID_ALL = "__vitest_all__";
23
- class IframeOrchestrator {
24
- constructor() {
25
- __publicField(this, "cancelled", false);
26
- __publicField(this, "runningFiles", /* @__PURE__ */ new Set());
27
- __publicField(this, "iframes", /* @__PURE__ */ new Map());
28
- }
29
- async init(testFiles) {
30
- debug("test files", testFiles.join(", "));
31
- this.runningFiles.clear();
32
- testFiles.forEach((file) => this.runningFiles.add(file));
33
- channel.addEventListener(
34
- "message",
35
- (e) => this.onIframeEvent(e)
36
- );
37
- globalChannel.addEventListener(
38
- "message",
39
- (e) => this.onGlobalChannelEvent(e)
40
- );
41
- }
42
- async createTesters(testFiles) {
43
- this.cancelled = false;
44
- this.runningFiles.clear();
45
- testFiles.forEach((file) => this.runningFiles.add(file));
46
- const config = getConfig();
47
- debug("create testers", testFiles.join(", "));
48
- const container = await getContainer(config);
49
- if (config.browser.ui) {
50
- container.className = "absolute origin-top mt-[8px]";
51
- container.parentElement.setAttribute("data-ready", "true");
52
- container.textContent = "";
53
- }
54
- const { width, height } = config.browser.viewport;
55
- this.iframes.forEach((iframe) => iframe.remove());
56
- this.iframes.clear();
57
- if (config.browser.isolate === false) {
58
- debug("create iframe", ID_ALL);
59
- const iframe = this.createIframe(container, ID_ALL);
60
- await setIframeViewport(iframe, width, height);
61
- return;
62
- }
63
- for (const file of testFiles) {
64
- if (this.cancelled) {
65
- done();
66
- return;
67
- }
68
- debug("create iframe", file);
69
- const iframe = this.createIframe(container, file);
70
- await setIframeViewport(iframe, width, height);
71
- await new Promise((resolve) => {
72
- channel.addEventListener(
73
- "message",
74
- function handler(e) {
75
- if (e.data.type === "done" || e.data.type === "error") {
76
- channel.removeEventListener("message", handler);
77
- resolve();
78
- }
79
- }
80
- );
81
- });
82
- }
83
- }
84
- createIframe(container, file) {
85
- if (this.iframes.has(file)) {
86
- this.iframes.get(file).remove();
87
- this.iframes.delete(file);
88
- }
89
- const iframe = document.createElement("iframe");
90
- iframe.setAttribute("loading", "eager");
91
- iframe.setAttribute(
92
- "src",
93
- `${url.pathname}__vitest_test__/__test__/${getBrowserState().sessionId}/${encodeURIComponent(file)}`
94
- );
95
- iframe.setAttribute("data-vitest", "true");
96
- iframe.style.border = "none";
97
- iframe.style.width = "100%";
98
- iframe.style.height = "100%";
99
- iframe.setAttribute("allowfullscreen", "true");
100
- iframe.setAttribute("allow", "clipboard-write;");
101
- iframe.setAttribute("name", "vitest-iframe");
102
- this.iframes.set(file, iframe);
103
- container.appendChild(iframe);
104
- return iframe;
105
- }
106
- async onGlobalChannelEvent(e) {
107
- debug("global channel event", JSON.stringify(e.data));
108
- switch (e.data.type) {
109
- case "cancel": {
110
- this.cancelled = true;
111
- break;
112
- }
113
- }
114
- }
115
- async onIframeEvent(e) {
116
- var _a;
117
- debug("iframe event", JSON.stringify(e.data));
118
- switch (e.data.type) {
119
- case "viewport": {
120
- const { width, height, id } = e.data;
121
- const iframe = this.iframes.get(id);
122
- if (!iframe) {
123
- const error = new Error(`Cannot find iframe with id ${id}`);
124
- channel.postMessage({
125
- type: "viewport:fail",
126
- id,
127
- error: error.message
128
- });
129
- await client.rpc.onUnhandledError(
130
- {
131
- name: "Teardown Error",
132
- message: error.message
133
- },
134
- "Teardown Error"
135
- );
136
- return;
137
- }
138
- await setIframeViewport(iframe, width, height);
139
- channel.postMessage({ type: "viewport:done", id });
140
- break;
141
- }
142
- case "done": {
143
- const filenames = e.data.filenames;
144
- filenames.forEach((filename) => this.runningFiles.delete(filename));
145
- if (!this.runningFiles.size) {
146
- const ui = getUiAPI();
147
- if (ui && filenames.length > 1) {
148
- const id = generateFileId(filenames[filenames.length - 1]);
149
- ui.setCurrentFileId(id);
150
- }
151
- await done();
152
- } else {
153
- const iframeId = e.data.id;
154
- (_a = this.iframes.get(iframeId)) == null ? void 0 : _a.remove();
155
- this.iframes.delete(iframeId);
156
- }
157
- break;
158
- }
159
- // error happened at the top level, this should never happen in user code, but it can trigger during development
160
- case "error": {
161
- const iframeId = e.data.id;
162
- this.iframes.delete(iframeId);
163
- await client.rpc.onUnhandledError(e.data.error, e.data.errorType);
164
- if (iframeId === ID_ALL) {
165
- this.runningFiles.clear();
166
- } else {
167
- this.runningFiles.delete(iframeId);
168
- }
169
- if (!this.runningFiles.size) {
170
- await done();
171
- }
172
- break;
173
- }
174
- default: {
175
- e.data;
176
- await client.rpc.onUnhandledError(
177
- {
178
- name: "Unexpected Event",
179
- message: `Unexpected event: ${e.data.type}`
180
- },
181
- "Unexpected Event"
182
- );
183
- await done();
184
- }
185
- }
186
- }
187
- }
188
- const orchestrator = new IframeOrchestrator();
189
- let promiseTesters;
190
- getBrowserState().createTesters = async (files) => {
191
- await promiseTesters;
192
- promiseTesters = orchestrator.createTesters(files).finally(() => {
193
- promiseTesters = void 0;
194
- });
195
- await promiseTesters;
196
- };
197
- async function done() {
198
- await client.rpc.finishBrowserTests(getBrowserState().sessionId);
199
- }
200
- async function getContainer(config) {
201
- if (config.browser.ui) {
202
- const element = document.querySelector("#tester-ui");
203
- if (!element) {
204
- return new Promise((resolve) => {
205
- setTimeout(() => {
206
- resolve(getContainer(config));
207
- }, 30);
208
- });
209
- }
210
- return element;
211
- }
212
- return document.querySelector("#vitest-tester");
213
- }
214
- client.waitForConnection().then(async () => {
215
- const testFiles = getBrowserState().files;
216
- await orchestrator.init(testFiles);
217
- if (testFiles.length) {
218
- await orchestrator.createTesters(testFiles);
219
- }
220
- });
221
- function generateFileId(file) {
222
- const config = getConfig();
223
- const project = config.name || "";
224
- const path = relative(config.root, file);
225
- return generateHash(`${path}${project}`);
226
- }
227
- async function setIframeViewport(iframe, width, height) {
228
- const ui = getUiAPI();
229
- if (ui) {
230
- await ui.setIframeViewport(width, height);
231
- } else {
232
- iframe.style.width = `${width}px`;
233
- iframe.style.height = `${height}px`;
234
- }
235
- }
236
- function debug(...args) {
237
- const debug2 = getConfig().env.VITEST_BROWSER_DEBUG;
238
- if (debug2 && debug2 !== "false") {
239
- client.rpc.debug(...args.map(String));
240
- }
241
- }
@@ -1 +0,0 @@
1
- import{server,page}from"@vitest/browser/context";import{I as Ivya,e as getByRoleSelector,c as getByAltTextSelector,f as getByLabelSelector,b as getByPlaceholderSelector,d as getByTestIdSelector,a as getByTextSelector,g as getByTitleSelector,h as getElementError}from"./public-utils-xf4CCUzp.js";function ensureAwaited(e){let b=getWorkerState().current;if(!b||b.type!==`test`)return e();let x=!1,S=Error(`STACK_TRACE_ERROR`);b.onFinished??=[],b.onFinished.push(()=>{if(!x){let e=Error(`The call was not awaited. This method is asynchronous and must be awaited; otherwise, the call will not start to avoid unhandled rejections.`);throw e.stack=S.stack?.replace(S.message,e.message),e}});let C;return{then(b,w){return x=!0,(C||=e(S)).then(b,w)},catch(b){return(C||=e(S)).catch(b)},finally(b){return(C||=e(S)).finally(b)},[Symbol.toStringTag]:`Promise`}}function getBrowserState(){return window.__vitest_browser_runner__}function getWorkerState(){let e=window.__vitest_worker__;if(!e)throw Error(`Worker state is not found. This is an issue with Vitest. Please, open an issue.`);return e}const provider=getBrowserState().provider;function convertElementToCssSelector(e){if(!e||!(e instanceof Element))throw Error(`Expected DOM element to be an instance of Element, received ${typeof e}`);return getUniqueCssSelector(e)}function escapeIdForCSSSelector(e){return e.split(``).map(e=>{let b=e.charCodeAt(0);return e===` `||e===`#`||e===`.`||e===`:`||e===`[`||e===`]`||e===`>`||e===`+`||e===`~`||e===`\\`?`\\${e}`:b>=65536?`\\${b.toString(16).toUpperCase().padStart(6,`0`)} `:b<32||b===127||b>=128?`\\${b.toString(16).toUpperCase().padStart(2,`0`)} `:e}).join(``)}function getUniqueCssSelector(e){let b=[],x,S=!1;for(;x=getParent(e);){x.shadowRoot&&(S=!0);let C=e.tagName;if(e.id)b.push(`#${escapeIdForCSSSelector(e.id)}`);else if(!e.nextElementSibling&&!e.previousElementSibling)b.push(C.toLowerCase());else{let S=0,w=0,T=0;for(let b of x.children)S++,b.tagName===C&&w++,b===e&&(T=S);w>1?b.push(`${C.toLowerCase()}:nth-child(${T})`):b.push(C.toLowerCase())}e=x}return`${getBrowserState().provider===`webdriverio`&&S?`>>>`:``}${b.reverse().join(` > `)}`}function getParent(e){let b=e.parentNode;return b instanceof ShadowRoot?b.host:b}const now=Date.now;function processTimeoutOptions(e){if(e&&e.timeout!=null||provider!==`playwright`||getWorkerState().config.browser.providerOptions.actionTimeout!=null)return e;let b=getBrowserState().runner,x=b._currentTaskStartTime;if(!x)return e;let S=b._currentTaskTimeout;if(S===0||S==null||S===1/0)return e;e||={};let C=now(),w=x+S,T=w-C;return T<=0||(e.timeout=T-100),e}function getIframeScale(){let e=window.parent.document.querySelector(`#tester-ui`);if(!e)throw Error(`Cannot find Tester element. This is a bug in Vitest. Please, open a new issue with reproduction.`);let b=e.getAttribute(`data-scale`),x=Number(b);if(Number.isNaN(x))throw TypeError(`Cannot parse scale value from Tester element (${b}). This is a bug in Vitest. Please, open a new issue with reproduction.`);return x}function escapeRegexForSelector(e){return e.unicode||e.unicodeSets?String(e):String(e).replace(/(^|[^\\])(\\\\)*(["'`])/g,`$1$2\\$3`).replace(/>>/g,`\\>\\>`)}function escapeForTextSelector(e,b){return typeof e==`string`?`${JSON.stringify(e)}i`:escapeRegexForSelector(e)}const selectorEngine=Ivya.create({browser:(e=>{switch(e){case`edge`:case`chrome`:return`chromium`;case`safari`:return`webkit`;default:return e}})(server.config.browser.name),testIdAttribute:server.config.browser.locators.testIdAttribute});class Locator{_parsedSelector;_container;_pwSelector;click(e={}){return this.triggerCommand(`__vitest_click`,this.selector,e)}dblClick(e={}){return this.triggerCommand(`__vitest_dblClick`,this.selector,e)}tripleClick(e={}){return this.triggerCommand(`__vitest_tripleClick`,this.selector,e)}clear(e){return this.triggerCommand(`__vitest_clear`,this.selector,e)}hover(e){return this.triggerCommand(`__vitest_hover`,this.selector,e)}unhover(e){return this.triggerCommand(`__vitest_hover`,`html > body`,e)}fill(e,b){return this.triggerCommand(`__vitest_fill`,this.selector,e,b)}async upload(e,b){let x=(Array.isArray(e)?e:[e]).map(async e=>{if(typeof e==`string`)return e;let b=await new Promise((b,x)=>{let S=new FileReader;S.onload=()=>b(S.result),S.onerror=()=>x(Error(`Failed to read file: ${e.name}`)),S.readAsDataURL(e)});return{name:e.name,mimeType:e.type,base64:b}});return this.triggerCommand(`__vitest_upload`,this.selector,await Promise.all(x),b)}dropTo(e,b={}){return this.triggerCommand(`__vitest_dragAndDrop`,this.selector,e.selector,b)}selectOptions(e,b){let x=(Array.isArray(e)?e:[e]).map(e=>{if(typeof e!=`string`){let b=`element`in e?e.selector:selectorEngine.generateSelectorSimple(e);return{element:b}}return e});return this.triggerCommand(`__vitest_selectOptions`,this.selector,x,b)}screenshot(e){return page.screenshot({...e,element:this})}getByRole(e,b){return this.locator(getByRoleSelector(e,b))}getByAltText(e,b){return this.locator(getByAltTextSelector(e,b))}getByLabelText(e,b){return this.locator(getByLabelSelector(e,b))}getByPlaceholder(e,b){return this.locator(getByPlaceholderSelector(e,b))}getByTestId(b){return this.locator(getByTestIdSelector(server.config.browser.locators.testIdAttribute,b))}getByText(e,b){return this.locator(getByTextSelector(e,b))}getByTitle(e,b){return this.locator(getByTitleSelector(e,b))}filter(e){let b=[];if(e?.hasText&&b.push(`internal:has-text=${escapeForTextSelector(e.hasText)}`),e?.hasNotText&&b.push(`internal:has-not-text=${escapeForTextSelector(e.hasNotText)}`),e?.has){let x=e.has;b.push(`internal:has=${JSON.stringify(x._pwSelector||x.selector)}`)}if(e?.hasNot){let x=e.hasNot;b.push(`internal:has-not=${JSON.stringify(x._pwSelector||x.selector)}`)}if(!b.length)throw Error(`Locator.filter expects at least one filter. None provided.`);return this.locator(b.join(` >> `))}and(e){return this.locator(`internal:and=${JSON.stringify(e._pwSelector||e.selector)}`)}or(e){return this.locator(`internal:or=${JSON.stringify(e._pwSelector||e.selector)}`)}query(){let e=this._parsedSelector||=selectorEngine.parseSelector(this._pwSelector||this.selector);return selectorEngine.querySelector(e,document.documentElement,!0)}element(){let e=this.query();if(!e)throw getElementError(this._pwSelector||this.selector,this._container||document.body);return e}elements(){let e=this._parsedSelector||=selectorEngine.parseSelector(this._pwSelector||this.selector);return selectorEngine.querySelectorAll(e,document.documentElement)}all(){return this.elements().map(e=>this.elementLocator(e))}nth(e){return this.locator(`nth=${e}`)}first(){return this.nth(0)}last(){return this.nth(-1)}toString(){return this.selector}toJSON(){return this.selector}triggerCommand(e,...b){let x=getBrowserState().commands;return ensureAwaited(S=>x.triggerCommand(e,b,S))}}export{Locator as L,getIframeScale as a,convertElementToCssSelector as c,getBrowserState as g,processTimeoutOptions as p,selectorEngine as s};