@vitest/browser 4.1.0-beta.4 → 4.1.0-beta.5
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 +43 -3
- package/dist/client/.vite/manifest.json +1 -1
- package/dist/client/__vitest__/assets/index-Da0hb3oU.css +1 -0
- package/dist/client/__vitest__/assets/index-vKQ25zpc.js +63 -0
- package/dist/client/__vitest__/index.html +2 -2
- package/dist/client/__vitest_browser__/{tester-CgiVtoKi.js → tester-C0ZOZX6s.js} +24 -4
- package/dist/client/tester/tester.html +1 -1
- package/dist/context.js +23 -17
- package/dist/expect-element.js +23 -23
- package/dist/{index-Dlkb5vw8.js → index-BvKPfXh9.js} +4 -3
- package/dist/index.js +15 -54
- package/dist/locators.d.ts +12 -3
- package/dist/locators.js +1 -1
- package/package.json +7 -7
- package/dist/client/__vitest__/assets/index-C71EXv4T.css +0 -1
- package/dist/client/__vitest__/assets/index-CPanfHPD.js +0 -63
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
})();
|
|
24
24
|
</script>
|
|
25
25
|
<!-- !LOAD_METADATA! -->
|
|
26
|
-
<script type="module" src="./assets/index-
|
|
27
|
-
<link rel="stylesheet" href="./assets/index-
|
|
26
|
+
<script type="module" src="./assets/index-vKQ25zpc.js"></script>
|
|
27
|
+
<link rel="stylesheet" href="./assets/index-Da0hb3oU.css">
|
|
28
28
|
</head>
|
|
29
29
|
<body>
|
|
30
30
|
<div id="app"></div>
|
|
@@ -1515,7 +1515,19 @@ function mockObject(options, object2, mockExports = {}) {
|
|
|
1515
1515
|
define(newContainer, property, value);
|
|
1516
1516
|
continue;
|
|
1517
1517
|
}
|
|
1518
|
-
if (
|
|
1518
|
+
if (options.type === "autospy" && type === "Module") {
|
|
1519
|
+
const exports$1 = /* @__PURE__ */ Object.create(null);
|
|
1520
|
+
Object.defineProperty(exports$1, Symbol.toStringTag, {
|
|
1521
|
+
value: "Module",
|
|
1522
|
+
configurable: true,
|
|
1523
|
+
writable: true
|
|
1524
|
+
});
|
|
1525
|
+
try {
|
|
1526
|
+
newContainer[property] = exports$1;
|
|
1527
|
+
} catch {
|
|
1528
|
+
continue;
|
|
1529
|
+
}
|
|
1530
|
+
} else if (!define(newContainer, property, isFunction || options.type === "autospy" ? value : {})) {
|
|
1519
1531
|
continue;
|
|
1520
1532
|
}
|
|
1521
1533
|
if (isFunction) {
|
|
@@ -1841,14 +1853,22 @@ class ModuleMocker {
|
|
|
1841
1853
|
/* @vite-ignore */
|
|
1842
1854
|
`${url2.pathname}${query}&mock=${mock.type}${url2.hash}`
|
|
1843
1855
|
), true ? [] : void 0);
|
|
1844
|
-
return this.mockObject(moduleObject,
|
|
1856
|
+
return this.mockObject(moduleObject, mock.type);
|
|
1845
1857
|
}
|
|
1846
1858
|
return import(
|
|
1847
1859
|
/* @vite-ignore */
|
|
1848
1860
|
mock.redirect
|
|
1849
1861
|
);
|
|
1850
1862
|
}
|
|
1851
|
-
mockObject(object2,
|
|
1863
|
+
mockObject(object2, mockExportsOrModuleType, moduleType) {
|
|
1864
|
+
let mockExports;
|
|
1865
|
+
if (mockExportsOrModuleType === "automock" || mockExportsOrModuleType === "autospy") {
|
|
1866
|
+
moduleType = mockExportsOrModuleType;
|
|
1867
|
+
mockExports = void 0;
|
|
1868
|
+
} else {
|
|
1869
|
+
mockExports = mockExportsOrModuleType;
|
|
1870
|
+
}
|
|
1871
|
+
moduleType ?? (moduleType = "automock");
|
|
1852
1872
|
const result = mockObject({
|
|
1853
1873
|
globalConstructors: {
|
|
1854
1874
|
Object,
|
|
@@ -1969,7 +1989,6 @@ function createModuleMockerInterceptor() {
|
|
|
1969
1989
|
function rpc() {
|
|
1970
1990
|
return getWorkerState().rpc;
|
|
1971
1991
|
}
|
|
1972
|
-
getBrowserState().provider;
|
|
1973
1992
|
class CommandsManager {
|
|
1974
1993
|
_listeners = [];
|
|
1975
1994
|
onCommand(listener) {
|
|
@@ -2003,6 +2022,7 @@ class CommandsManager {
|
|
|
2003
2022
|
);
|
|
2004
2023
|
}
|
|
2005
2024
|
}
|
|
2025
|
+
getBrowserState().provider;
|
|
2006
2026
|
const debugVar = getConfig().env.VITEST_BROWSER_DEBUG;
|
|
2007
2027
|
const debug = debugVar && debugVar !== "false" ? (...args) => {
|
|
2008
2028
|
var _a, _b;
|
|
@@ -5,7 +5,7 @@
|
|
|
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-
|
|
8
|
+
<script type="module" crossorigin src="/__vitest_browser__/tester-C0ZOZX6s.js"></script>
|
|
9
9
|
<link rel="modulepreload" crossorigin href="/__vitest_browser__/utils-C2ISqq1C.js">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
package/dist/context.js
CHANGED
|
@@ -46,7 +46,6 @@ function getWorkerState() {
|
|
|
46
46
|
return state;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
const provider$1 = getBrowserState().provider;
|
|
50
49
|
/* @__NO_SIDE_EFFECTS__ */
|
|
51
50
|
function convertElementToCssSelector(element) {
|
|
52
51
|
if (!element || !(element instanceof Element)) {
|
|
@@ -121,7 +120,7 @@ function getParent(el) {
|
|
|
121
120
|
}
|
|
122
121
|
const now = Date.now;
|
|
123
122
|
function processTimeoutOptions(options_) {
|
|
124
|
-
if (options_ && options_.timeout != null
|
|
123
|
+
if (options_ && options_.timeout != null) {
|
|
125
124
|
return options_;
|
|
126
125
|
}
|
|
127
126
|
// if there is a default action timeout, use it
|
|
@@ -149,7 +148,9 @@ function processTimeoutOptions(options_) {
|
|
|
149
148
|
options_.timeout = remainingTime - 100;
|
|
150
149
|
return options_;
|
|
151
150
|
}
|
|
152
|
-
|
|
151
|
+
const provider$1 = getBrowserState().provider;
|
|
152
|
+
const kElementLocator = Symbol.for("$$vitest:locator-resolved");
|
|
153
|
+
async function convertToSelector(elementOrLocator, options) {
|
|
153
154
|
if (!elementOrLocator) {
|
|
154
155
|
throw new Error("Expected element or locator to be defined.");
|
|
155
156
|
}
|
|
@@ -157,7 +158,11 @@ function convertToSelector(elementOrLocator) {
|
|
|
157
158
|
return convertElementToCssSelector(elementOrLocator);
|
|
158
159
|
}
|
|
159
160
|
if (isLocator(elementOrLocator)) {
|
|
160
|
-
|
|
161
|
+
if (provider$1 === "playwright" || kElementLocator in elementOrLocator) {
|
|
162
|
+
return elementOrLocator.selector;
|
|
163
|
+
}
|
|
164
|
+
const element = await elementOrLocator.findElement(options);
|
|
165
|
+
return convertElementToCssSelector(element);
|
|
161
166
|
}
|
|
162
167
|
throw new Error("Expected element or locator to be an instance of Element or Locator.");
|
|
163
168
|
}
|
|
@@ -216,10 +221,10 @@ function createUserEvent(__tl_user_event_base__, options) {
|
|
|
216
221
|
setup() {
|
|
217
222
|
return createUserEvent();
|
|
218
223
|
},
|
|
219
|
-
|
|
224
|
+
cleanup() {
|
|
220
225
|
// avoid cleanup rpc call if there is nothing to cleanup
|
|
221
226
|
if (!keyboard.unreleased.length) {
|
|
222
|
-
return;
|
|
227
|
+
return Promise.resolve();
|
|
223
228
|
}
|
|
224
229
|
return ensureAwaited(async (error) => {
|
|
225
230
|
await triggerCommand("__vitest_cleanup", [keyboard], error);
|
|
@@ -261,9 +266,9 @@ function createUserEvent(__tl_user_event_base__, options) {
|
|
|
261
266
|
const targetLocator = convertToLocator(target);
|
|
262
267
|
return sourceLocator.dropTo(targetLocator, options);
|
|
263
268
|
},
|
|
264
|
-
|
|
269
|
+
type(element, text, options) {
|
|
265
270
|
return ensureAwaited(async (error) => {
|
|
266
|
-
const selector = convertToSelector(element);
|
|
271
|
+
const selector = await convertToSelector(element, options);
|
|
267
272
|
const { unreleased } = await triggerCommand("__vitest_type", [
|
|
268
273
|
selector,
|
|
269
274
|
text,
|
|
@@ -278,20 +283,20 @@ function createUserEvent(__tl_user_event_base__, options) {
|
|
|
278
283
|
tab(options = {}) {
|
|
279
284
|
return ensureAwaited((error) => triggerCommand("__vitest_tab", [options], error));
|
|
280
285
|
},
|
|
281
|
-
|
|
286
|
+
keyboard(text) {
|
|
282
287
|
return ensureAwaited(async (error) => {
|
|
283
288
|
const { unreleased } = await triggerCommand("__vitest_keyboard", [text, keyboard], error);
|
|
284
289
|
keyboard.unreleased = unreleased;
|
|
285
290
|
});
|
|
286
291
|
},
|
|
287
|
-
|
|
288
|
-
|
|
292
|
+
copy() {
|
|
293
|
+
return userEvent.keyboard(`{${modifier}>}{c}{/${modifier}}`);
|
|
289
294
|
},
|
|
290
|
-
|
|
291
|
-
|
|
295
|
+
cut() {
|
|
296
|
+
return userEvent.keyboard(`{${modifier}>}{x}{/${modifier}}`);
|
|
292
297
|
},
|
|
293
|
-
|
|
294
|
-
|
|
298
|
+
paste() {
|
|
299
|
+
return userEvent.keyboard(`{${modifier}>}{v}{/${modifier}}`);
|
|
295
300
|
}
|
|
296
301
|
};
|
|
297
302
|
return userEvent;
|
|
@@ -443,14 +448,15 @@ const page = {
|
|
|
443
448
|
screenshotIds[repeatCount] ??= {};
|
|
444
449
|
screenshotIds[repeatCount][taskName] = number + 1;
|
|
445
450
|
const name = options.path || `${taskName.replace(/[^a-z0-9]/gi, "-")}-${number}.png`;
|
|
451
|
+
const [element, ...mask] = await Promise.all([options.element ? convertToSelector(options.element, options) : undefined, ..."mask" in options ? options.mask.map((el) => convertToSelector(el, options)) : []]);
|
|
446
452
|
const normalizedOptions = "mask" in options ? {
|
|
447
453
|
...options,
|
|
448
|
-
mask
|
|
454
|
+
mask
|
|
449
455
|
} : options;
|
|
450
456
|
return ensureAwaited((error) => triggerCommand("__vitest_screenshot", [name, processTimeoutOptions(
|
|
451
457
|
{
|
|
452
458
|
...normalizedOptions,
|
|
453
|
-
element
|
|
459
|
+
element
|
|
454
460
|
}
|
|
455
461
|
/** TODO */
|
|
456
462
|
)], error));
|
package/dist/expect-element.js
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
import{recordArtifact,expect,chai}from"vitest";import{getType}from"vitest/internal/browser";import{k as kAriaCheckedRoles,L as Locator,g as getAriaChecked,a as getAriaRole,b as getAriaDisabled,c as beginAriaCaches,e as endAriaCaches,i as isElementVisible$1,d as getElementAccessibleDescription,f as getElementAccessibleErrorMessage,h as getElementAccessibleName,j as cssEscape,l as convertToSelector,m as getBrowserState,p as processTimeoutOptions}from"./index-
|
|
2
|
-
`)}function redent(
|
|
3
|
-
`)}}class UserInputElementTypeError extends GenericTypeError{constructor(
|
|
4
|
-
`)}}}function supportedRolesSentence(){return toSentence(supportedRoles.map(
|
|
5
|
-
`)}}function isEmptyElement(
|
|
6
|
-
`)}}}function toBeEnabled(
|
|
7
|
-
`)}}}function isElementDisabled(
|
|
8
|
-
`)}}const FORM_TAGS$1=[`FORM`,`INPUT`,`SELECT`,`TEXTAREA`];function isElementHavingAriaInvalid(
|
|
9
|
-
`)}}}function toBeValid(
|
|
10
|
-
`)}}}function toBeInViewport(
|
|
11
|
-
`)}}))}async function getViewportIntersection(
|
|
12
|
-
`)}}}function isAriaMixed(
|
|
13
|
-
`)}}}function toBeVisible(
|
|
14
|
-
`)}}}function isElementVisible(
|
|
1
|
+
import{recordArtifact,expect,chai}from"vitest";import{getType}from"vitest/internal/browser";import{k as kAriaCheckedRoles,L as Locator,g as getAriaChecked,a as getAriaRole,b as getAriaDisabled,c as beginAriaCaches,e as endAriaCaches,i as isElementVisible$1,d as getElementAccessibleDescription,f as getElementAccessibleErrorMessage,h as getElementAccessibleName,j as cssEscape,l as convertToSelector,m as getBrowserState,p as processTimeoutOptions}from"./index-BvKPfXh9.js";import{server}from"vitest/browser";function getAriaCheckedRoles(){return[...kAriaCheckedRoles]}function queryElementFromUserInput(h,W,G){return h instanceof Locator&&(h=h.query()),h==null?null:getElementFromUserInput(h,W,G)}function getElementFromUserInput(h,W,G){h instanceof Locator&&(h=h.element());let K=h?.ownerDocument?.defaultView||window;if(h instanceof K.HTMLElement||h instanceof K.SVGElement)return h;throw new UserInputElementTypeError(h,W,G)}function getNodeFromUserInput(h,W,G){h instanceof Locator&&(h=h.element());let K=h.ownerDocument?.defaultView||window;if(h instanceof K.Node)return h;throw new UserInputNodeTypeError(h,W,G)}function getMessage(h,W,G,K,q,J){return[`${W}\n`,`${G}:\n${h.utils.EXPECTED_COLOR(redent(display(h,K),2))}`,`${q}:\n${h.utils.RECEIVED_COLOR(redent(display(h,J),2))}`].join(`
|
|
2
|
+
`)}function redent(h,W){return indentString(stripIndent(h),W)}function indentString(h,W){return h.replace(/^(?!\s*$)/gm,` `.repeat(W))}function minIndent(h){let W=h.match(/^[ \t]*(?=\S)/gm);return W?W.reduce((h,W)=>Math.min(h,W.length),1/0):0}function stripIndent(h){let W=minIndent(h);if(W===0)return h;let G=RegExp(`^[ \\t]{${W}}`,`gm`);return h.replace(G,``)}function display(h,W){return typeof W==`string`?W:h.utils.stringify(W)}function toSentence(h,{wordConnector:W=`, `,lastWordConnector:G=` and `}={}){return[h.slice(0,-1).join(W),h.at(-1)].join(h.length>1?G:``)}class GenericTypeError extends Error{constructor(h,W,G,K){super(),Error.captureStackTrace&&Error.captureStackTrace(this,G);let q=``;try{q=K.utils.printWithType(`Received`,W,K.utils.printReceived)}catch{}this.message=[K.utils.matcherHint(`${K.isNot?`.not`:``}.${G.name}`,`received`,``),``,`${K.utils.RECEIVED_COLOR(`received`)} value must ${h} or a Locator that returns ${h}.`,q].join(`
|
|
3
|
+
`)}}class UserInputElementTypeError extends GenericTypeError{constructor(h,W,G){super(`an HTMLElement or an SVGElement`,h,W,G)}}class UserInputNodeTypeError extends GenericTypeError{constructor(h,W,G){super(`a Node`,h,W,G)}}function getTag(h){return h instanceof HTMLFormElement?`FORM`:h.tagName.toUpperCase()}function isInputElement(h){return getTag(h)===`INPUT`}function getSingleElementValue(h){if(h)switch(getTag(h)){case`INPUT`:return getInputValue(h);case`SELECT`:return getSelectValue(h);default:return h.value??getAccessibleValue(h)}}function getSelectValue({multiple:h,options:W}){let G=[...W].filter(h=>h.selected);if(h)return[...G].map(h=>h.value);if(G.length!==0)return G[0].value}function getInputValue(h){switch(h.type){case`number`:return h.value===``?null:Number(h.value);case`checkbox`:return h.checked;default:return h.value}}const rolesSupportingValues=[`meter`,`progressbar`,`slider`,`spinbutton`];function getAccessibleValue(h){if(rolesSupportingValues.includes(h.getAttribute(`role`)||``))return Number(h.getAttribute(`aria-valuenow`))}function normalize(h){return h.replace(/\s+/g,` `).trim()}function matches(h,W){return W instanceof RegExp?W.test(h):h.includes(String(W))}function arrayAsSetComparison(h,W){if(Array.isArray(h)&&Array.isArray(W)){let G=new Set(W);for(let W of new Set(h))if(!G.has(W))return!1;return!0}}const supportedRoles=getAriaCheckedRoles();function toBeChecked(h){let W=getElementFromUserInput(h,toBeChecked,this);if(!(isInputElement(W)&&[`checkbox`,`radio`].includes(W.type))&&!(supportedRoles.includes(getAriaRole(W)||``)&&[`true`,`false`].includes(W.getAttribute(`aria-checked`)||``)))return{pass:!1,message:()=>`only inputs with type="checkbox" or type="radio" or elements with ${supportedRolesSentence()} and a valid aria-checked attribute can be used with .toBeChecked(). Use .toHaveValue() instead`};let G=getAriaChecked(W)===!0;return{pass:G,message:()=>{let h=G?`is`:`is not`;return[this.utils.matcherHint(`${this.isNot?`.not`:``}.toBeChecked`,`element`,``),``,`Received element ${h} checked:`,` ${this.utils.printReceived(W.cloneNode(!1))}`].join(`
|
|
4
|
+
`)}}}function supportedRolesSentence(){return toSentence(supportedRoles.map(h=>`role="${h}"`),{lastWordConnector:` or `})}function toBeEmptyDOMElement(h){let W=getElementFromUserInput(h,toBeEmptyDOMElement,this);return{pass:isEmptyElement(W),message:()=>[this.utils.matcherHint(`${this.isNot?`.not`:``}.toBeEmptyDOMElement`,`element`,``),``,`Received:`,` ${this.utils.printReceived(W.innerHTML)}`].join(`
|
|
5
|
+
`)}}function isEmptyElement(h){return[...h.childNodes].filter(h=>h.nodeType!==Node.COMMENT_NODE).length===0}function toBeDisabled(h){let W=getElementFromUserInput(h,toBeDisabled,this),G=isElementDisabled(W);return{pass:G,message:()=>{let h=G?`is`:`is not`;return[this.utils.matcherHint(`${this.isNot?`.not`:``}.toBeDisabled`,`element`,``),``,`Received element ${h} disabled:`,` ${this.utils.printReceived(W.cloneNode(!1))}`].join(`
|
|
6
|
+
`)}}}function toBeEnabled(h){let W=getElementFromUserInput(h,toBeEnabled,this),G=isElementDisabled(W);return{pass:!G,message:()=>{let h=G?`is not`:`is`;return[this.utils.matcherHint(`${this.isNot?`.not`:``}.toBeEnabled`,`element`,``),``,`Received element ${h} enabled:`,` ${this.utils.printReceived(W.cloneNode(!1))}`].join(`
|
|
7
|
+
`)}}}function isElementDisabled(h){return getTag(h).includes(`-`)?h.hasAttribute(`disabled`):getAriaDisabled(h)}function toBeInTheDocument(h){let W=null;(h!==null||!this.isNot)&&(W=queryElementFromUserInput(h,toBeInTheDocument,this));let G=W===null?!1:W.ownerDocument===W.getRootNode({composed:!0}),K=()=>`expected document not to contain element, found ${this.utils.stringify(W?.cloneNode(!0))} instead`,q=()=>`element could not be found in the document`;return{pass:G,message:()=>[this.utils.matcherHint(`${this.isNot?`.not`:``}.toBeInTheDocument`,`element`,``),``,this.utils.RECEIVED_COLOR(this.isNot?K():q())].join(`
|
|
8
|
+
`)}}const FORM_TAGS$1=[`FORM`,`INPUT`,`SELECT`,`TEXTAREA`];function isElementHavingAriaInvalid(h){return h.hasAttribute(`aria-invalid`)&&h.getAttribute(`aria-invalid`)!==`false`}function isSupportsValidityMethod(h){return FORM_TAGS$1.includes(getTag(h))}function isElementInvalid(h){let W=isElementHavingAriaInvalid(h);return isSupportsValidityMethod(h)?W||!h.checkValidity():W}function toBeInvalid(h){let W=getElementFromUserInput(h,toBeInvalid,this),G=isElementInvalid(W);return{pass:G,message:()=>{let h=G?`is`:`is not`;return[this.utils.matcherHint(`${this.isNot?`.not`:``}.toBeInvalid`,`element`,``),``,`Received element ${h} currently invalid:`,` ${this.utils.printReceived(W.cloneNode(!1))}`].join(`
|
|
9
|
+
`)}}}function toBeValid(h){let W=getElementFromUserInput(h,toBeInvalid,this),G=!isElementInvalid(W);return{pass:G,message:()=>{let h=G?`is`:`is not`;return[this.utils.matcherHint(`${this.isNot?`.not`:``}.toBeValid`,`element`,``),``,`Received element ${h} currently valid:`,` ${this.utils.printReceived(W.cloneNode(!1))}`].join(`
|
|
10
|
+
`)}}}function toBeInViewport(h,W){let G=getElementFromUserInput(h,toBeInViewport,this),K=W?.ratio??0;return getViewportIntersection(G,K).then(({pass:h,ratio:W})=>({pass:h,message:()=>{let q=h?`is`:`is not`,J=K>0?` with ratio ${K}`:``,Y=W===void 0?``:` (actual ratio: ${W.toFixed(3)})`;return[this.utils.matcherHint(`${this.isNot?`.not`:``}.toBeInViewport`,`element`,``),``,`Received element ${q} in viewport${J}${Y}:`,` ${this.utils.printReceived(G.cloneNode(!1))}`].join(`
|
|
11
|
+
`)}}))}async function getViewportIntersection(h,W){let G=await new Promise(W=>{let G=new IntersectionObserver(h=>{h.length>0?W(h[0].intersectionRatio):W(0),G.disconnect()});G.observe(h),requestAnimationFrame(()=>{})});return{pass:G>0&&G>W-1e-9,ratio:G}}function toBePartiallyChecked(h){let W=getElementFromUserInput(h,toBePartiallyChecked,this);if(!(isInputElement(W)&&W.type===`checkbox`)&&W.getAttribute(`role`)!==`checkbox`)return{pass:!1,message:()=>`only inputs with type="checkbox" or elements with role="checkbox" and a valid aria-checked attribute can be used with .toBePartiallyChecked(). Use .toHaveValue() instead`};let G=isAriaMixed(W);return{pass:G,message:()=>{let h=G?`is`:`is not`;return[this.utils.matcherHint(`${this.isNot?`.not`:``}.toBePartiallyChecked`,`element`,``),``,`Received element ${h} partially checked:`,` ${this.utils.printReceived(W.cloneNode(!1))}`].join(`
|
|
12
|
+
`)}}}function isAriaMixed(h){let W=getAriaChecked(h)===`mixed`;return!W&&isInputElement(h)&&[`checkbox`,`radio`].includes(h.type)&&h.getAttribute(`aria-checked`)===`mixed`?!0:W}const FORM_TAGS=[`SELECT`,`TEXTAREA`],ARIA_FORM_TAGS=[`INPUT`,`SELECT`,`TEXTAREA`],UNSUPPORTED_INPUT_TYPES=[`color`,`hidden`,`range`,`submit`,`image`,`reset`],SUPPORTED_ARIA_ROLES=[`checkbox`,`combobox`,`gridcell`,`listbox`,`radiogroup`,`spinbutton`,`textbox`,`tree`];function isRequiredOnFormTagsExceptInput(h){return FORM_TAGS.includes(getTag(h))&&h.hasAttribute(`required`)}function isRequiredOnSupportedInput(h){return getTag(h)===`INPUT`&&h.hasAttribute(`required`)&&(h.hasAttribute(`type`)&&!UNSUPPORTED_INPUT_TYPES.includes(h.getAttribute(`type`)||``)||!h.hasAttribute(`type`))}function isElementRequiredByARIA(h){return h.hasAttribute(`aria-required`)&&h.getAttribute(`aria-required`)===`true`&&(ARIA_FORM_TAGS.includes(getTag(h))||h.hasAttribute(`role`)&&SUPPORTED_ARIA_ROLES.includes(h.getAttribute(`role`)||``))}function toBeRequired(h){let W=getElementFromUserInput(h,toBeRequired,this),G=isRequiredOnFormTagsExceptInput(W)||isRequiredOnSupportedInput(W)||isElementRequiredByARIA(W);return{pass:G,message:()=>{let h=G?`is`:`is not`;return[this.utils.matcherHint(`${this.isNot?`.not`:``}.toBeRequired`,`element`,``),``,`Received element ${h} required:`,` ${this.utils.printReceived(W.cloneNode(!1))}`].join(`
|
|
13
|
+
`)}}}function toBeVisible(h){let W=getElementFromUserInput(h,toBeVisible,this),G=W.ownerDocument===W.getRootNode({composed:!0});beginAriaCaches();let K=G&&isElementVisible(W);return endAriaCaches(),{pass:K,message:()=>{let h=K?`is`:`is not`;return[this.utils.matcherHint(`${this.isNot?`.not`:``}.toBeVisible`,`element`,``),``,`Received element ${h} visible${G?``:` (element is not in the document)`}:`,` ${this.utils.printReceived(W.cloneNode(!1))}`].join(`
|
|
14
|
+
`)}}}function isElementVisible(h){let W=isElementVisible$1(h);if(server.browser!==`webkit`)return W;let G=h.closest(`details`);return!G||h===G?W:isElementVisibleInDetails(h)}function isElementVisibleInDetails(h){let W=h;for(;W;){if(W.tagName===`DETAILS`){let G=W.querySelector(`summary`)===h;if(!W.open&&!G)return!1}W=W.parentElement}return h.offsetParent!==null}function toContainElement(h,W){let G=getElementFromUserInput(h,toContainElement,this),K=W===null?null:getElementFromUserInput(W,toContainElement,this);return{pass:G.contains(K),message:()=>[this.utils.matcherHint(`${this.isNot?`.not`:``}.toContainElement`,`element`,`element`),``,this.utils.RECEIVED_COLOR(`${this.utils.stringify(G.cloneNode(!1))} ${this.isNot?`contains:`:`does not contain:`} ${this.utils.stringify(K?K.cloneNode(!1):null)}
|
|
15
15
|
`)].join(`
|
|
16
|
-
`)}}function getNormalizedHtml(
|
|
17
|
-
`)}}function toHaveAccessibleDescription(
|
|
16
|
+
`)}}function getNormalizedHtml(h,W){let G=h.ownerDocument.createElement(`div`);return G.innerHTML=W,G.innerHTML}function toContainHTML(h,W){let G=getElementFromUserInput(h,toContainHTML,this);if(typeof W!=`string`)throw TypeError(`.toContainHTML() expects a string value, got ${W}`);return{pass:G.outerHTML.includes(getNormalizedHtml(G,W)),message:()=>[this.utils.matcherHint(`${this.isNot?`.not`:``}.toContainHTML`,`element`,``),`Expected:`,` ${this.utils.EXPECTED_COLOR(W)}`,`Received:`,` ${this.utils.printReceived(G.cloneNode(!0))}`].join(`
|
|
17
|
+
`)}}function toHaveAccessibleDescription(h,W){let G=getElementFromUserInput(h,toHaveAccessibleDescription,this),K=getElementAccessibleDescription(G,!1),q=G.ownerDocument.defaultView||window,J=arguments.length===1,Y=!1;return Y=J?K!==``:W instanceof q.RegExp?W.test(K):this.equals(K,W,this.customTesters),{pass:Y,message:()=>{let h=this.isNot?`not to`:`to`;return getMessage(this,this.utils.matcherHint(`${this.isNot?`.not`:``}.toHaveAccessibleDescription`,`element`,``),`Expected element ${h} have accessible description`,W,`Received`,K)}}}function toHaveAccessibleErrorMessage(h,W){let G=getElementFromUserInput(h,toHaveAccessibleErrorMessage,this),K=getElementAccessibleErrorMessage(G)??``,q=G.ownerDocument.defaultView||window,J=arguments.length===1,Y=!1;return Y=J?K!==``:W instanceof q.RegExp?W.test(K):this.equals(K,W,this.customTesters),{pass:Y,message:()=>{let h=this.isNot?`not to`:`to`;return W==null?[this.utils.matcherHint(`${this.isNot?`.not`:``}.toHaveAccessibleErrorMessage`,`element`,``),`Expected element ${h} have accessible error message, but got${this.isNot?``:` nothing`}`,this.isNot?this.utils.RECEIVED_COLOR(redent(K,2)):``].filter(Boolean).join(`
|
|
18
18
|
|
|
19
|
-
`):getMessage(this,this.utils.matcherHint(`${this.isNot?`.not`:``}.toHaveAccessibleErrorMessage`,`element`,``),`Expected element ${
|
|
20
|
-
`)}}function getExpectedClassNamesAndOptions(
|
|
21
|
-
`)}}function toHaveFormValues(
|
|
19
|
+
`):getMessage(this,this.utils.matcherHint(`${this.isNot?`.not`:``}.toHaveAccessibleErrorMessage`,`element`,``),`Expected element ${h} have accessible error message`,W,`Received`,K)}}}function toHaveAccessibleName(h,W){let G=getElementFromUserInput(h,toHaveAccessibleName,this),K=getElementAccessibleName(G,!1),q=arguments.length===1,J=G.ownerDocument.defaultView||window,Y=!1;return Y=q?K!==``:W instanceof J.RegExp?W.test(K):this.equals(K,W,this.customTesters),{pass:Y,message:()=>{let h=this.isNot?`not to`:`to`;return getMessage(this,this.utils.matcherHint(`${this.isNot?`.not`:``}.${toHaveAccessibleName.name}`,`element`,``),`Expected element ${h} have accessible name`,W,`Received`,K)}}}function toHaveAttribute(h,W,G){let K=getElementFromUserInput(h,toHaveAttribute,this),q=G!==void 0,J=K.hasAttribute(W),Y=K.getAttribute(W);return{pass:q?J&&this.equals(Y,G,this.customTesters):J,message:()=>{let h=this.isNot?`not to`:`to`,K=J?printAttribute(this.utils.stringify,W,Y):null,X=this.utils.matcherHint(`${this.isNot?`.not`:``}.toHaveAttribute`,`element`,this.utils.printExpected(W),{secondArgument:q?this.utils.printExpected(G):void 0,comment:getAttributeComment(this.utils.stringify,W,G)});return getMessage(this,X,`Expected the element ${h} have attribute`,printAttribute(this.utils.stringify,W,G),`Received`,K)}}}function printAttribute(h,W,G){return G===void 0?W:`${W}=${h(G)}`}function getAttributeComment(h,W,G){return G===void 0?`element.hasAttribute(${h(W)})`:`element.getAttribute(${h(W)}) === ${h(G)}`}function toHaveClass(h,...W){let G=getElementFromUserInput(h,toHaveClass,this),{expectedClassNames:K,options:q}=getExpectedClassNamesAndOptions(W),J=splitClassNames(G.getAttribute(`class`)),Y=K.reduce((h,W)=>h.concat(typeof W==`string`||!W?splitClassNames(W):W),[]),X=Y.some(h=>h instanceof RegExp);if(q.exact&&X)throw Error(`Exact option does not support RegExp expected class names`);return q.exact?{pass:isSubset$1(Y,J)&&Y.length===J.length,message:()=>{let h=this.isNot?`not to`:`to`;return getMessage(this,this.utils.matcherHint(`${this.isNot?`.not`:``}.toHaveClass`,`element`,this.utils.printExpected(Y.join(` `))),`Expected the element ${h} have EXACTLY defined classes`,Y.join(` `),`Received`,J.join(` `))}}:Y.length>0?{pass:isSubset$1(Y,J),message:()=>{let h=this.isNot?`not to`:`to`;return getMessage(this,this.utils.matcherHint(`${this.isNot?`.not`:``}.toHaveClass`,`element`,this.utils.printExpected(Y.join(` `))),`Expected the element ${h} have class`,Y.join(` `),`Received`,J.join(` `))}}:{pass:this.isNot?J.length>0:!1,message:()=>this.isNot?getMessage(this,this.utils.matcherHint(`.not.toHaveClass`,`element`,``),`Expected the element to have classes`,`(none)`,`Received`,J.join(` `)):[this.utils.matcherHint(`.toHaveClass`,`element`),`At least one expected class must be provided.`].join(`
|
|
20
|
+
`)}}function getExpectedClassNamesAndOptions(h){let W=h.pop(),G,K;return typeof W==`object`&&!(W instanceof RegExp)?(G=h,K=W):(G=h.concat(W),K={exact:!1}),{expectedClassNames:G,options:K}}function splitClassNames(h){return h?h.split(/\s+/).filter(h=>h.length>0):[]}function isSubset$1(h,W){return h.every(h=>typeof h==`string`?W.includes(h):W.some(W=>h.test(W)))}function toHaveDisplayValue(h,W){let G=getElementFromUserInput(h,toHaveDisplayValue,this),K=getTag(G);if(![`SELECT`,`INPUT`,`TEXTAREA`].includes(K))throw Error(`.toHaveDisplayValue() currently supports only input, textarea or select elements, try with another matcher instead.`);if(isInputElement(G)&&[`radio`,`checkbox`].includes(G.type))throw Error(`.toHaveDisplayValue() currently does not support input[type="${G.type}"], try with another matcher instead.`);let q=getValues(K,G),J=getExpectedValues(W),Y=J.filter(h=>q.some(W=>h instanceof RegExp?h.test(W):this.equals(W,String(h),this.customTesters))).length,X=Y===q.length,Z=Y===J.length;return{pass:X&&Z,message:()=>getMessage(this,this.utils.matcherHint(`${this.isNot?`.not`:``}.toHaveDisplayValue`,`element`,``),`Expected element ${this.isNot?`not `:``}to have display value`,W,`Received`,q)}}function getValues(h,W){return h===`SELECT`?Array.from(W).filter(h=>h.selected).map(h=>h.textContent||``):[W.value]}function getExpectedValues(h){return Array.isArray(h)?h:[h]}function toHaveFocus(h){let W=getElementFromUserInput(h,toHaveFocus,this);return{pass:W.ownerDocument.activeElement===W,message:()=>[this.utils.matcherHint(`${this.isNot?`.not`:``}.toHaveFocus`,`element`,``),``,...this.isNot?[`Received element is focused:`,` ${this.utils.printReceived(W)}`]:[`Expected element with focus:`,` ${this.utils.printExpected(W)}`,`Received element with focus:`,` ${this.utils.printReceived(W.ownerDocument.activeElement)}`]].join(`
|
|
21
|
+
`)}}function toHaveFormValues(h,W){let G=getElementFromUserInput(h,toHaveFormValues,this),K=G.ownerDocument.defaultView||window;if(!(G instanceof K.HTMLFieldSetElement)&&!(G instanceof K.HTMLFormElement))throw TypeError(`toHaveFormValues must be called on a form or a fieldset, instead got ${getTag(G)}`);if(!W||typeof W!=`object`)throw TypeError(`toHaveFormValues must be called with an object of expected form values. Got ${W}`);let q=getAllFormValues(G);return{pass:Object.entries(W).every(([h,W])=>this.equals(q[h],W,[arrayAsSetComparison,...this.customTesters])),message:()=>{let h=this.isNot?`not to`:`to`,G=`${this.isNot?`.not`:``}.toHaveFormValues`,K={};for(let h in q)Object.hasOwn(W,h)&&(K[h]=q[h]);return[this.utils.matcherHint(G,`element`,``),`Expected the element ${h} have form values`,this.utils.diff(W,K)].join(`
|
|
22
22
|
|
|
23
|
-
`)}}}function getMultiElementValue(
|
|
23
|
+
`)}}}function getMultiElementValue(h){let W=``;for(let G of h){if(W&&W!==G.type)throw Error(`Multiple form elements with the same name must be of the same type`);W=G.type}switch(W){case`radio`:{let W=h.find(h=>h.checked);return W?W.value:void 0}case`checkbox`:return h.filter(h=>h.checked).map(h=>h.value);default:return h.map(h=>h.value)}}function getFormValue(h,W){let G=[...h.querySelectorAll(`[name="${cssEscape(W)}"]`)];if(G.length!==0)switch(G.length){case 1:return getSingleElementValue(G[0]);default:return getMultiElementValue(G)}}function getPureName(h){return/\[\]$/.test(h)?h.slice(0,-2):h}function getAllFormValues(h){let W={};for(let G of h.elements){if(!(`name`in G))continue;let K=G.name;W[getPureName(K)]=getFormValue(h,K)}return W}function toHaveRole(h,W){let G=getElementFromUserInput(h,toHaveRole,this);beginAriaCaches();let K=getAriaRole(G);return endAriaCaches(),{pass:K===W,message:()=>{let h=this.isNot?`not to`:`to`;return getMessage(this,this.utils.matcherHint(`${this.isNot?`.not`:``}.toHaveRole`,`element`,``),`Expected element ${h} have role`,W,`Received`,K)}}}function toHaveSelection(h,W){let G=getElementFromUserInput(h,toHaveSelection,this),K=W!==void 0;if(K&&typeof W!=`string`)throw Error(`expected selection must be a string or undefined`);let q=getSelection(G);return{pass:K?this.equals(q,W,[arrayAsSetComparison,...this.customTesters]):!!q,message:()=>{let h=this.isNot?`not to`:`to`,G=this.utils.matcherHint(`${this.isNot?`.not`:``}.toHaveSelection`,`element`,W);return getMessage(this,G,`Expected the element ${h} have selection`,K?W:`(any)`,`Received`,q)}}}function getSelection(h){let W=h.ownerDocument.getSelection();if(!W)return``;if([`INPUT`,`TEXTAREA`].includes(getTag(h))){let W=h;return[`radio`,`checkbox`].includes(W.type)||W.selectionStart==null||W.selectionEnd==null?``:W.value.toString().substring(W.selectionStart,W.selectionEnd)}if(W.anchorNode===null||W.focusNode===null)return``;let G=W.getRangeAt(0),K=h.ownerDocument.createRange();if(W.containsNode(h,!1))K.selectNodeContents(h),W.removeAllRanges(),W.addRange(K);else if(!(h.contains(W.anchorNode)&&h.contains(W.focusNode))){let q=h===G.startContainer||h.contains(G.startContainer),J=h===G.endContainer||h.contains(G.endContainer);W.removeAllRanges(),(q||J)&&(K.selectNodeContents(h),q&&K.setStart(G.startContainer,G.startOffset),J&&K.setEnd(G.endContainer,G.endOffset),W.addRange(K))}let q=W.toString();return W.removeAllRanges(),W.addRange(G),q}const browser=server.config.browser.name,usedValuesProps=new Set(`backgroundPosition.background-position.bottom.left.right.top.height.width.margin-bottom.marginBottom.margin-left.marginLeft.margin-right.marginRight.margin-top.marginTop.min-height.minHeight.min-width.minWidth.padding-bottom.padding-left.padding-right.padding-top.text-indent.paddingBottom.paddingLeft.paddingRight.paddingTop.textIndent`.split(`.`));function toHaveStyle(h,W){let G=getElementFromUserInput(h,toHaveStyle,this),{getComputedStyle:K}=G.ownerDocument.defaultView,q=typeof W==`object`?getStyleFromObjectCSS(W):computeCSSStyleDeclaration(W),J=K(G),Y=new Set(Array.from(G.style));return{pass:isSubset(q,G,J,Y),message:()=>{let h=`${this.isNot?`.not`:``}.toHaveStyle`,W=new Set(Object.keys(q)),K=printoutObjectStyles(Array.from(J).filter(h=>W.has(h)).reduce((h,W)=>(h[W]=(Y.has(W)&&usedValuesProps.has(W)?G.style:J)[W],h),{})),X=K===``?`Expected styles could not be parsed by the browser. Did you make a typo?`:this.utils.diff(printoutObjectStyles(q),K);return[this.utils.matcherHint(h,`element`,``),X].join(`
|
|
24
24
|
|
|
25
|
-
`)}}}function getStyleFromObjectCSS(
|
|
26
|
-
`)}function isSubset(
|
|
27
|
-
`)}}const matchers={toBeDisabled,toBeEnabled,toBeEmptyDOMElement,toBeInTheDocument,toBeInViewport,toBeInvalid,toBeRequired,toBeValid,toBeVisible,toContainElement,toContainHTML,toHaveAccessibleDescription,toHaveAccessibleErrorMessage,toHaveAccessibleName,toHaveAttribute,toHaveClass,toHaveFocus,toHaveFormValues,toHaveStyle,toHaveTextContent,toHaveValue,toHaveDisplayValue,toBeChecked,toBePartiallyChecked,toHaveRole,toHaveSelection,toMatchScreenshot},kLocator=Symbol.for(`$$vitest:locator`);function element(
|
|
25
|
+
`)}}}function getStyleFromObjectCSS(h){let W=browser===`chrome`||browser===`chromium`?document:document.implementation.createHTMLDocument(``),G=W.createElement(`div`);W.body.appendChild(G);let K=Object.keys(h);K.forEach(W=>{G.style[W]=h[W]});let q={},J=window.getComputedStyle(G);return K.forEach(h=>{let W=(usedValuesProps.has(h)?G.style:J)[h];W!=null&&(q[h]=W)}),G.remove(),q}function computeCSSStyleDeclaration(h){let W=browser===`chrome`||browser===`chromium`||browser===`webkit`?document:document.implementation.createHTMLDocument(``),G=W.createElement(`div`);G.setAttribute(`style`,h.replace(/\n/g,``)),W.body.appendChild(G);let K=window.getComputedStyle(G),q=Array.from(G.style).reduce((h,W)=>(h[W]=usedValuesProps.has(W)?G.style.getPropertyValue(W):K.getPropertyValue(W),h),{});return G.remove(),q}function printoutObjectStyles(h){return Object.keys(h).sort().map(W=>`${W}: ${h[W]};`).join(`
|
|
26
|
+
`)}function isSubset(h,W,G,K){let q=Object.keys(h);return q.length?q.every(q=>{let J=h[q],Y=q.startsWith(`--`),X=[q];return Y||X.push(q.toLowerCase()),X.some(h=>{let Y=K.has(q)&&usedValuesProps.has(q)?W.style:G;return Y[h]===J||Y.getPropertyValue(h)===J})}):!1}function toHaveTextContent(h,W,G={normalizeWhitespace:!0}){let K=getNodeFromUserInput(h,toHaveTextContent,this),q=G.normalizeWhitespace?normalize(K.textContent||``):(K.textContent||``).replace(/\u00A0/g,` `),J=q!==``&&W===``;return{pass:!J&&matches(q,W),message:()=>{let h=this.isNot?`not to`:`to`;return getMessage(this,this.utils.matcherHint(`${this.isNot?`.not`:``}.toHaveTextContent`,`element`,``),J?`Checking with empty string will always match, use .toBeEmptyDOMElement() instead`:`Expected element ${h} have text content`,W,`Received`,q)}}}function toHaveValue(h,W){let G=getElementFromUserInput(h,toHaveValue,this);if(isInputElement(G)&&[`checkbox`,`radio`].includes(G.type))throw Error(`input with type=checkbox or type=radio cannot be used with .toHaveValue(). Use .toBeChecked() for type=checkbox or .toHaveFormValues() instead`);let K=getSingleElementValue(G),q=W!==void 0,J=W,Y=K;return W==K&&W!==K&&(J=`${W} (${typeof W})`,Y=`${K} (${typeof K})`),{pass:q?this.equals(K,W,[arrayAsSetComparison,...this.customTesters]):!!K,message:()=>{let h=this.isNot?`not to`:`to`,G=this.utils.matcherHint(`${this.isNot?`.not`:``}.toHaveValue`,`element`,W);return getMessage(this,G,`Expected the element ${h} have value`,q?J:`(any)`,`Received`,Y)}}}const counters=new Map([]);async function toMatchScreenshot(W,G,K=typeof G==`object`?G:{}){if(this.isNot)throw Error(`'toMatchScreenshot' cannot be used with "not"`);if(this.task===void 0||this.currentTestName===void 0)throw Error(`'toMatchScreenshot' cannot be used without test context`);let q=`${this.task.result?.repeatCount??0}${this.testPath}${this.currentTestName}`,J=counters.get(q);J===void 0&&(J={current:0},counters.set(q,J)),J.current+=1;let Y=typeof G==`string`?G:`${this.currentTestName} ${J.current}`,[X,...Z]=await Promise.all([convertToSelector(W,K),...K.screenshotOptions&&`mask`in K.screenshotOptions?K.screenshotOptions.mask.map(h=>convertToSelector(h,K)):[]]),Q=K.screenshotOptions&&`mask`in K.screenshotOptions?{...K,screenshotOptions:{...K.screenshotOptions,mask:Z}}:K,$=await getBrowserState().commands.triggerCommand(`__vitest_screenshotMatcher`,[Y,this.currentTestName,{element:X,...Q}]);if($.pass===!1){let W=[];$.reference&&W.push({name:`reference`,...$.reference}),$.actual&&W.push({name:`actual`,...$.actual}),$.diff&&W.push({name:`diff`,...$.diff}),W.length>0&&await recordArtifact(this.task,{type:`internal:toMatchScreenshot`,kind:`visual-regression`,message:$.message,attachments:W})}return{pass:$.pass,message:()=>$.pass?``:[this.utils.matcherHint(`toMatchScreenshot`,`element`,``),``,$.message,$.reference?`\nReference screenshot:\n ${this.utils.EXPECTED_COLOR($.reference.path)}`:null,$.actual?`\nActual screenshot:\n ${this.utils.RECEIVED_COLOR($.actual.path)}`:null,$.diff?this.utils.DIM_COLOR(`\nDiff image:\n ${$.diff.path}`):null,``].filter(h=>h!==null).join(`
|
|
27
|
+
`)}}const matchers={toBeDisabled,toBeEnabled,toBeEmptyDOMElement,toBeInTheDocument,toBeInViewport,toBeInvalid,toBeRequired,toBeValid,toBeVisible,toContainElement,toContainHTML,toHaveAccessibleDescription,toHaveAccessibleErrorMessage,toHaveAccessibleName,toHaveAttribute,toHaveClass,toHaveFocus,toHaveFormValues,toHaveStyle,toHaveTextContent,toHaveValue,toHaveDisplayValue,toBeChecked,toBePartiallyChecked,toHaveRole,toHaveSelection,toMatchScreenshot},kLocator=Symbol.for(`$$vitest:locator`);function element(h,q){if(h!=null&&!(h instanceof HTMLElement)&&!(h instanceof SVGElement)&&!(kLocator in h))throw Error(`Invalid element or locator: ${h}. Expected an instance of HTMLElement, SVGElement or Locator, received ${getType(h)}`);let J=expect.poll(function(){if(h instanceof Element||h==null)return h;let W=chai.util.flag(this,`negate`),K=chai.util.flag(this,`_name`);if(W&&K===`toBeInTheDocument`)return h.query();if(K===`toHaveLength`)return h.elements();if(K===`toMatchScreenshot`&&!chai.util.flag(this,`_poll.assert_once`)&&chai.util.flag(this,`_poll.assert_once`,!0),chai.util.flag(this,`_isLastPollAttempt`))return h.element();let q=h.query();if(!q)throw Error(`Cannot find element with locator: ${JSON.stringify(h)}`);return q},processTimeoutOptions(q));return chai.util.flag(J,`_poll.element`,!0),J}expect.extend(matchers),expect.element=element;
|