@vitest/browser 4.0.0-beta.5 → 4.0.0-beta.7
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/LICENSE +1 -1
- package/dist/client/.vite/manifest.json +2 -2
- package/dist/client/__vitest__/assets/{index-Co-EY0lY.js → index-DalB9Rpk.js} +35 -35
- package/dist/client/__vitest__/index.html +1 -1
- package/dist/client/__vitest_browser__/{orchestrator-CmUsRING.js → orchestrator-C2rrmv36.js} +1 -14
- package/dist/client/__vitest_browser__/{tester-1ooObZUu.js → tester-mSVktQ7a.js} +75 -67
- package/dist/client/error-catcher.js +7 -3
- package/dist/client/esm-client-injector.js +1 -0
- package/dist/client/orchestrator.html +1 -1
- package/dist/client/tester/tester.html +1 -1
- package/dist/context.js +17 -13
- package/dist/expect-element.js +2 -2
- package/dist/index-B7Hfmz-h.js +1 -0
- package/dist/index.js +5 -2
- package/dist/locators/index.js +1 -1
- package/dist/locators/playwright.js +1 -1
- package/dist/locators/preview.js +1 -1
- package/dist/locators/webdriverio.js +1 -1
- package/dist/shared/screenshotMatcher/types.d.ts +3 -0
- package/dist/types.d.ts +0 -1
- package/package.json +10 -10
- package/providers/playwright.d.ts +4 -1
- package/dist/index-D_g_FMM5.js +0 -1
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
})();
|
|
24
24
|
</script>
|
|
25
25
|
<!-- !LOAD_METADATA! -->
|
|
26
|
-
<script type="module" src="./assets/index-
|
|
26
|
+
<script type="module" src="./assets/index-DalB9Rpk.js"></script>
|
|
27
27
|
<link rel="stylesheet" href="./assets/index-KbpJLW--.css">
|
|
28
28
|
</head>
|
|
29
29
|
<body>
|
package/dist/client/__vitest_browser__/{orchestrator-CmUsRING.js → orchestrator-C2rrmv36.js}
RENAMED
|
@@ -425,20 +425,7 @@ function inspectSymbol(value) {
|
|
|
425
425
|
}
|
|
426
426
|
return value.toString();
|
|
427
427
|
}
|
|
428
|
-
|
|
429
|
-
try {
|
|
430
|
-
const { getPromiseDetails, kPending, kRejected } = process.binding("util");
|
|
431
|
-
if (Array.isArray(getPromiseDetails(Promise.resolve()))) {
|
|
432
|
-
getPromiseValue = (value, options) => {
|
|
433
|
-
const [state, innerValue] = getPromiseDetails(value);
|
|
434
|
-
if (state === kPending) {
|
|
435
|
-
return "Promise{<pending>}";
|
|
436
|
-
}
|
|
437
|
-
return `Promise${state === kRejected ? "!" : ""}{${options.inspect(innerValue, options)}}`;
|
|
438
|
-
};
|
|
439
|
-
}
|
|
440
|
-
} catch (notNode) {
|
|
441
|
-
}
|
|
428
|
+
const getPromiseValue = () => "Promise{…}";
|
|
442
429
|
function inspectObject$1(object, options) {
|
|
443
430
|
const properties = Object.getOwnPropertyNames(object);
|
|
444
431
|
const symbols = Object.getOwnPropertySymbols ? Object.getOwnPropertySymbols(object) : [];
|
|
@@ -1749,18 +1749,42 @@ function mockObject(options, object2, mockExports = {}) {
|
|
|
1749
1749
|
return false;
|
|
1750
1750
|
}
|
|
1751
1751
|
};
|
|
1752
|
+
const createMock = (currentValue) => {
|
|
1753
|
+
if (!options.createMockInstance) {
|
|
1754
|
+
throw new Error("[@vitest/mocker] `createMockInstance` is not defined. This is a Vitest error. Please open a new issue with reproduction.");
|
|
1755
|
+
}
|
|
1756
|
+
const createMockInstance = options.createMockInstance;
|
|
1757
|
+
const prototypeMembers = currentValue.prototype ? collectFunctionProperties(currentValue.prototype) : [];
|
|
1758
|
+
return createMockInstance({
|
|
1759
|
+
name: currentValue.name,
|
|
1760
|
+
prototypeMembers,
|
|
1761
|
+
originalImplementation: options.type === "autospy" ? currentValue : void 0,
|
|
1762
|
+
keepMembersImplementation: options.type === "autospy"
|
|
1763
|
+
});
|
|
1764
|
+
};
|
|
1752
1765
|
const mockPropertiesOf = (container, newContainer) => {
|
|
1753
1766
|
const containerType = getType(container);
|
|
1754
1767
|
const isModule = containerType === "Module" || !!container.__esModule;
|
|
1755
1768
|
for (const { key: property, descriptor } of getAllMockableProperties(container, isModule, options.globalConstructors)) {
|
|
1756
1769
|
if (!isModule && descriptor.get) {
|
|
1757
1770
|
try {
|
|
1758
|
-
|
|
1771
|
+
if (options.type === "autospy") {
|
|
1772
|
+
Object.defineProperty(newContainer, property, descriptor);
|
|
1773
|
+
} else {
|
|
1774
|
+
Object.defineProperty(newContainer, property, {
|
|
1775
|
+
configurable: descriptor.configurable,
|
|
1776
|
+
enumerable: descriptor.enumerable,
|
|
1777
|
+
get: () => {
|
|
1778
|
+
},
|
|
1779
|
+
set: descriptor.set ? () => {
|
|
1780
|
+
} : void 0
|
|
1781
|
+
});
|
|
1782
|
+
}
|
|
1759
1783
|
} catch {
|
|
1760
1784
|
}
|
|
1761
1785
|
continue;
|
|
1762
1786
|
}
|
|
1763
|
-
if (
|
|
1787
|
+
if (isReadonlyProp(container[property], property)) {
|
|
1764
1788
|
continue;
|
|
1765
1789
|
}
|
|
1766
1790
|
const value = container[property];
|
|
@@ -1771,7 +1795,22 @@ function mockObject(options, object2, mockExports = {}) {
|
|
|
1771
1795
|
}
|
|
1772
1796
|
const type = getType(value);
|
|
1773
1797
|
if (Array.isArray(value)) {
|
|
1774
|
-
|
|
1798
|
+
if (options.type === "automock") {
|
|
1799
|
+
define(newContainer, property, []);
|
|
1800
|
+
} else {
|
|
1801
|
+
const array = value.map((value2) => {
|
|
1802
|
+
if (value2 && typeof value2 === "object") {
|
|
1803
|
+
const newObject = {};
|
|
1804
|
+
mockPropertiesOf(value2, newObject);
|
|
1805
|
+
return newObject;
|
|
1806
|
+
}
|
|
1807
|
+
if (typeof value2 === "function") {
|
|
1808
|
+
return createMock(value2);
|
|
1809
|
+
}
|
|
1810
|
+
return value2;
|
|
1811
|
+
});
|
|
1812
|
+
define(newContainer, property, array);
|
|
1813
|
+
}
|
|
1775
1814
|
continue;
|
|
1776
1815
|
}
|
|
1777
1816
|
const isFunction = type.includes("Function") && typeof value === "function";
|
|
@@ -1779,47 +1818,12 @@ function mockObject(options, object2, mockExports = {}) {
|
|
|
1779
1818
|
define(newContainer, property, value);
|
|
1780
1819
|
continue;
|
|
1781
1820
|
}
|
|
1782
|
-
if (!define(newContainer, property, isFunction ? value : {})) {
|
|
1821
|
+
if (!define(newContainer, property, isFunction || options.type === "autospy" ? value : {})) {
|
|
1783
1822
|
continue;
|
|
1784
1823
|
}
|
|
1785
1824
|
if (isFunction) {
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
for (const { key, descriptor: descriptor2 } of getAllMockableProperties(this, false, options.globalConstructors)) {
|
|
1789
|
-
if (descriptor2.get) {
|
|
1790
|
-
continue;
|
|
1791
|
-
}
|
|
1792
|
-
const value2 = this[key];
|
|
1793
|
-
const type2 = getType(value2);
|
|
1794
|
-
const isFunction2 = type2.includes("Function") && typeof value2 === "function";
|
|
1795
|
-
if (isFunction2) {
|
|
1796
|
-
const original = this[key];
|
|
1797
|
-
const mock2 = spyOn(this, key).mockImplementation(original);
|
|
1798
|
-
const origMockReset = mock2.mockReset;
|
|
1799
|
-
mock2.mockRestore = mock2.mockReset = () => {
|
|
1800
|
-
origMockReset.call(mock2);
|
|
1801
|
-
mock2.mockImplementation(original);
|
|
1802
|
-
return mock2;
|
|
1803
|
-
};
|
|
1804
|
-
}
|
|
1805
|
-
}
|
|
1806
|
-
}
|
|
1807
|
-
};
|
|
1808
|
-
if (!options.spyOn) {
|
|
1809
|
-
throw new Error("[@vitest/mocker] `spyOn` is not defined. This is a Vitest error. Please open a new issue with reproduction.");
|
|
1810
|
-
}
|
|
1811
|
-
const spyOn = options.spyOn;
|
|
1812
|
-
const mock = spyOn(newContainer, property);
|
|
1813
|
-
if (options.type === "automock") {
|
|
1814
|
-
mock.mockImplementation(mockFunction);
|
|
1815
|
-
const origMockReset = mock.mockReset;
|
|
1816
|
-
mock.mockRestore = mock.mockReset = () => {
|
|
1817
|
-
origMockReset.call(mock);
|
|
1818
|
-
mock.mockImplementation(mockFunction);
|
|
1819
|
-
return mock;
|
|
1820
|
-
};
|
|
1821
|
-
}
|
|
1822
|
-
Object.defineProperty(newContainer[property], "length", { value: 0 });
|
|
1825
|
+
const mock = createMock(newContainer[property]);
|
|
1826
|
+
newContainer[property] = mock;
|
|
1823
1827
|
}
|
|
1824
1828
|
refs.track(value, newContainer[property]);
|
|
1825
1829
|
mockPropertiesOf(value, newContainer[property]);
|
|
@@ -1853,14 +1857,15 @@ class RefTracker {
|
|
|
1853
1857
|
function getType(value) {
|
|
1854
1858
|
return Object.prototype.toString.apply(value).slice(8, -1);
|
|
1855
1859
|
}
|
|
1856
|
-
function
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
"
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
"
|
|
1863
|
-
|
|
1860
|
+
function isReadonlyProp(object2, prop) {
|
|
1861
|
+
if (prop === "arguments" || prop === "caller" || prop === "callee" || prop === "name" || prop === "length") {
|
|
1862
|
+
const typeName = getType(object2);
|
|
1863
|
+
return typeName === "Function" || typeName === "AsyncFunction" || typeName === "GeneratorFunction" || typeName === "AsyncGeneratorFunction";
|
|
1864
|
+
}
|
|
1865
|
+
if (prop === "source" || prop === "global" || prop === "ignoreCase" || prop === "multiline") {
|
|
1866
|
+
return getType(object2) === "RegExp";
|
|
1867
|
+
}
|
|
1868
|
+
return false;
|
|
1864
1869
|
}
|
|
1865
1870
|
function getAllMockableProperties(obj, isModule, constructors) {
|
|
1866
1871
|
const { Map: Map2, Object: Object2, Function: Function2, RegExp: RegExp2, Array: Array2 } = constructors;
|
|
@@ -1896,6 +1901,20 @@ function collectOwnProperties(obj, collector) {
|
|
|
1896
1901
|
Object.getOwnPropertyNames(obj).forEach(collect);
|
|
1897
1902
|
Object.getOwnPropertySymbols(obj).forEach(collect);
|
|
1898
1903
|
}
|
|
1904
|
+
function collectFunctionProperties(prototype) {
|
|
1905
|
+
const properties = /* @__PURE__ */ new Set();
|
|
1906
|
+
collectOwnProperties(prototype, (prop) => {
|
|
1907
|
+
const descriptor = Object.getOwnPropertyDescriptor(prototype, prop);
|
|
1908
|
+
if (!descriptor || descriptor.get) {
|
|
1909
|
+
return;
|
|
1910
|
+
}
|
|
1911
|
+
const type = getType(descriptor.value);
|
|
1912
|
+
if (type.includes("Function") && !isReadonlyProp(descriptor.value, prop)) {
|
|
1913
|
+
properties.add(prop);
|
|
1914
|
+
}
|
|
1915
|
+
});
|
|
1916
|
+
return Array.from(properties);
|
|
1917
|
+
}
|
|
1899
1918
|
const _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//;
|
|
1900
1919
|
function normalizeWindowsPath(input = "") {
|
|
1901
1920
|
if (!input) {
|
|
@@ -2378,20 +2397,6 @@ const reactIsMethods = [
|
|
|
2378
2397
|
"isValidElementType"
|
|
2379
2398
|
];
|
|
2380
2399
|
Object.fromEntries(reactIsMethods.map((m) => [m, (v) => ReactIs18[m](v) || ReactIs19[m](v)]));
|
|
2381
|
-
let getPromiseValue = () => "Promise{…}";
|
|
2382
|
-
try {
|
|
2383
|
-
const { getPromiseDetails, kPending, kRejected } = process.binding("util");
|
|
2384
|
-
if (Array.isArray(getPromiseDetails(Promise.resolve()))) {
|
|
2385
|
-
getPromiseValue = (value, options) => {
|
|
2386
|
-
const [state, innerValue] = getPromiseDetails(value);
|
|
2387
|
-
if (state === kPending) {
|
|
2388
|
-
return "Promise{<pending>}";
|
|
2389
|
-
}
|
|
2390
|
-
return `Promise${state === kRejected ? "!" : ""}{${options.inspect(innerValue, options)}}`;
|
|
2391
|
-
};
|
|
2392
|
-
}
|
|
2393
|
-
} catch (notNode) {
|
|
2394
|
-
}
|
|
2395
2400
|
var jsTokens_1;
|
|
2396
2401
|
var hasRequiredJsTokens;
|
|
2397
2402
|
function requireJsTokens() {
|
|
@@ -2856,13 +2861,13 @@ var UrlType;
|
|
|
2856
2861
|
})(UrlType || (UrlType = {}));
|
|
2857
2862
|
const { now } = Date;
|
|
2858
2863
|
class ModuleMocker {
|
|
2859
|
-
constructor(interceptor, rpc2,
|
|
2864
|
+
constructor(interceptor, rpc2, createMockInstance, config) {
|
|
2860
2865
|
__publicField(this, "registry", new MockerRegistry());
|
|
2861
2866
|
__publicField(this, "queue", /* @__PURE__ */ new Set());
|
|
2862
2867
|
__publicField(this, "mockedIds", /* @__PURE__ */ new Set());
|
|
2863
2868
|
this.interceptor = interceptor;
|
|
2864
2869
|
this.rpc = rpc2;
|
|
2865
|
-
this.
|
|
2870
|
+
this.createMockInstance = createMockInstance;
|
|
2866
2871
|
this.config = config;
|
|
2867
2872
|
}
|
|
2868
2873
|
async prepare() {
|
|
@@ -2960,7 +2965,7 @@ class ModuleMocker {
|
|
|
2960
2965
|
Map,
|
|
2961
2966
|
RegExp
|
|
2962
2967
|
},
|
|
2963
|
-
|
|
2968
|
+
createMockInstance: this.createMockInstance,
|
|
2964
2969
|
type: moduleType
|
|
2965
2970
|
}, object2);
|
|
2966
2971
|
}
|
|
@@ -3161,7 +3166,7 @@ async function prepareTestEnvironment(options) {
|
|
|
3161
3166
|
const mocker = new VitestBrowserClientMocker(
|
|
3162
3167
|
interceptor,
|
|
3163
3168
|
rpc2,
|
|
3164
|
-
SpyModule.
|
|
3169
|
+
SpyModule.createMockInstance,
|
|
3165
3170
|
{
|
|
3166
3171
|
root: getBrowserState().viteConfig.root
|
|
3167
3172
|
}
|
|
@@ -3236,6 +3241,9 @@ async function prepare(options) {
|
|
|
3236
3241
|
});
|
|
3237
3242
|
})()
|
|
3238
3243
|
]);
|
|
3244
|
+
if (!config.browser.trackUnhandledErrors) {
|
|
3245
|
+
getBrowserState().disposeExceptionTracker();
|
|
3246
|
+
}
|
|
3239
3247
|
}
|
|
3240
3248
|
async function cleanup() {
|
|
3241
3249
|
const state = getWorkerState();
|
|
@@ -55,10 +55,14 @@ function catchWindowErrors(errorEvent, prop, cb) {
|
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
function registerUnexpectedErrors() {
|
|
58
|
-
catchWindowErrors('error', 'error', event =>
|
|
58
|
+
const offError = catchWindowErrors('error', 'error', event =>
|
|
59
59
|
reportUnexpectedError('Error', event.error))
|
|
60
|
-
catchWindowErrors('unhandledrejection', 'reason', event =>
|
|
60
|
+
const offRejection = catchWindowErrors('unhandledrejection', 'reason', event =>
|
|
61
61
|
reportUnexpectedError('Unhandled Rejection', event.reason))
|
|
62
|
+
return () => {
|
|
63
|
+
offError()
|
|
64
|
+
offRejection()
|
|
65
|
+
}
|
|
62
66
|
}
|
|
63
67
|
|
|
64
68
|
async function reportUnexpectedError(
|
|
@@ -71,4 +75,4 @@ async function reportUnexpectedError(
|
|
|
71
75
|
}).catch(console.error)
|
|
72
76
|
}
|
|
73
77
|
|
|
74
|
-
registerUnexpectedErrors()
|
|
78
|
+
globalThis.__vitest_browser_runner__.disposeExceptionTracker = registerUnexpectedErrors()
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
{__VITEST_INJECTOR__}
|
|
27
27
|
{__VITEST_ERROR_CATCHER__}
|
|
28
28
|
{__VITEST_SCRIPTS__}
|
|
29
|
-
<script type="module" crossorigin src="/__vitest_browser__/orchestrator-
|
|
29
|
+
<script type="module" crossorigin src="/__vitest_browser__/orchestrator-C2rrmv36.js"></script>
|
|
30
30
|
<link rel="modulepreload" crossorigin href="/__vitest_browser__/utils-FY_Qin7d.js">
|
|
31
31
|
</head>
|
|
32
32
|
<body>
|
|
@@ -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-mSVktQ7a.js"></script>
|
|
9
9
|
<link rel="modulepreload" crossorigin href="/__vitest_browser__/utils-FY_Qin7d.js">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
package/dist/context.js
CHANGED
|
@@ -149,6 +149,18 @@ function processTimeoutOptions(options_) {
|
|
|
149
149
|
options_.timeout = remainingTime - 100;
|
|
150
150
|
return options_;
|
|
151
151
|
}
|
|
152
|
+
function convertToSelector(elementOrLocator) {
|
|
153
|
+
if (!elementOrLocator) {
|
|
154
|
+
throw new Error("Expected element or locator to be defined.");
|
|
155
|
+
}
|
|
156
|
+
if (elementOrLocator instanceof Element) {
|
|
157
|
+
return convertElementToCssSelector(elementOrLocator);
|
|
158
|
+
}
|
|
159
|
+
if ("selector" in elementOrLocator) {
|
|
160
|
+
return elementOrLocator.selector;
|
|
161
|
+
}
|
|
162
|
+
throw new Error("Expected element or locator to be an instance of Element or Locator.");
|
|
163
|
+
}
|
|
152
164
|
|
|
153
165
|
// this file should not import anything directly, only types and utils
|
|
154
166
|
// @ts-expect-error not typed global
|
|
@@ -374,9 +386,13 @@ const page = {
|
|
|
374
386
|
screenshotIds[repeatCount] ??= {};
|
|
375
387
|
screenshotIds[repeatCount][taskName] = number + 1;
|
|
376
388
|
const name = options.path || `${taskName.replace(/[^a-z0-9]/gi, "-")}-${number}.png`;
|
|
389
|
+
const normalizedOptions = "mask" in options ? {
|
|
390
|
+
...options,
|
|
391
|
+
mask: options.mask.map(convertToSelector)
|
|
392
|
+
} : options;
|
|
377
393
|
return ensureAwaited((error) => triggerCommand("__vitest_screenshot", [name, processTimeoutOptions(
|
|
378
394
|
{
|
|
379
|
-
...
|
|
395
|
+
...normalizedOptions,
|
|
380
396
|
element: options.element ? convertToSelector(options.element) : undefined
|
|
381
397
|
}
|
|
382
398
|
/** TODO */
|
|
@@ -422,18 +438,6 @@ function convertToLocator(element) {
|
|
|
422
438
|
}
|
|
423
439
|
return element;
|
|
424
440
|
}
|
|
425
|
-
function convertToSelector(elementOrLocator) {
|
|
426
|
-
if (!elementOrLocator) {
|
|
427
|
-
throw new Error("Expected element or locator to be defined.");
|
|
428
|
-
}
|
|
429
|
-
if (elementOrLocator instanceof Element) {
|
|
430
|
-
return convertElementToCssSelector(elementOrLocator);
|
|
431
|
-
}
|
|
432
|
-
if ("selector" in elementOrLocator) {
|
|
433
|
-
return elementOrLocator.selector;
|
|
434
|
-
}
|
|
435
|
-
throw new Error("Expected element or locator to be an instance of Element or Locator.");
|
|
436
|
-
}
|
|
437
441
|
function getTaskFullName(task) {
|
|
438
442
|
return task.suite ? `${getTaskFullName(task.suite)} ${task.name}` : task.name;
|
|
439
443
|
}
|
package/dist/expect-element.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{expect,chai}from"vitest";import{k as kAriaCheckedRoles,i as getAriaChecked,j as getAriaRole,l as getAriaDisabled,m as beginAriaCaches,n as endAriaCaches,o as isElementVisible$1,p as getElementAccessibleDescription,q as getElementAccessibleErrorMessage,r as getElementAccessibleName,s as cssEscape}from"./public-utils-Kx5DUGWa.js";import{L as Locator,b as getWorkerState,
|
|
1
|
+
import{expect,chai}from"vitest";import{k as kAriaCheckedRoles,i as getAriaChecked,j as getAriaRole,l as getAriaDisabled,m as beginAriaCaches,n as endAriaCaches,o as isElementVisible$1,p as getElementAccessibleDescription,q as getElementAccessibleErrorMessage,r as getElementAccessibleName,s as cssEscape}from"./public-utils-Kx5DUGWa.js";import{L as Locator,b as getWorkerState,d as convertToSelector,a as getBrowserState,p as processTimeoutOptions}from"./index-B7Hfmz-h.js";import{server}from"@vitest/browser/context";import"vitest/internal/browser";function getAriaCheckedRoles(){return[...kAriaCheckedRoles]}function getElementFromUserInput(_,K,q){if(_ instanceof Locator&&(_=_.element()),_ instanceof HTMLElement||_ instanceof SVGElement)return _;throw new UserInputElementTypeError(_,K,q)}function getNodeFromUserInput(_,K,q){if(_ instanceof Locator&&(_=_.element()),_ instanceof Node)return _;throw new UserInputNodeTypeError(_,K,q)}function getMessage(_,K,q,J,Y,X){return[`${K}\n`,`${q}:\n${_.utils.EXPECTED_COLOR(redent(display(_,J),2))}`,`${Y}:\n${_.utils.RECEIVED_COLOR(redent(display(_,X),2))}`].join(`
|
|
2
2
|
`)}function redent(_,K){return indentString(stripIndent(_),K)}function indentString(_,K){let q=/^(?!\s*$)/gm;return _.replace(q,` `.repeat(K))}function minIndent(_){let K=_.match(/^[ \t]*(?=\S)/gm);return K?K.reduce((_,K)=>Math.min(_,K.length),1/0):0}function stripIndent(_){let K=minIndent(_);if(K===0)return _;let q=RegExp(`^[ \\t]{${K}}`,`gm`);return _.replace(q,``)}function display(_,K){return typeof K==`string`?K:_.utils.stringify(K)}function toSentence(_,{wordConnector:K=`, `,lastWordConnector:q=` and `}={}){return[_.slice(0,-1).join(K),_[_.length-1]].join(_.length>1?q:``)}class GenericTypeError extends Error{constructor(_,K,q,J){super(),Error.captureStackTrace&&Error.captureStackTrace(this,q);let Y=``;try{Y=J.utils.printWithType(`Received`,K,J.utils.printReceived)}catch{}this.message=[J.utils.matcherHint(`${J.isNot?`.not`:``}.${q.name}`,`received`,``),``,`${J.utils.RECEIVED_COLOR(`received`)} value must ${_} or a Locator that returns ${_}.`,Y].join(`
|
|
3
3
|
`)}}class UserInputElementTypeError extends GenericTypeError{constructor(_,K,q){super(`an HTMLElement or an SVGElement`,_,K,q)}}class UserInputNodeTypeError extends GenericTypeError{constructor(_,K,q){super(`a Node`,_,K,q)}}function getTag(_){return _ instanceof HTMLFormElement?`FORM`:_.tagName.toUpperCase()}function isInputElement(_){return getTag(_)===`INPUT`}function getSingleElementValue(_){if(_)switch(getTag(_)){case`INPUT`:return getInputValue(_);case`SELECT`:return getSelectValue(_);default:return _.value??getAccessibleValue(_)}}function getSelectValue({multiple:_,options:K}){let q=[...K].filter(_=>_.selected);if(_)return[...q].map(_=>_.value);if(q.length!==0)return q[0].value}function getInputValue(_){switch(_.type){case`number`:return _.value===``?null:Number(_.value);case`checkbox`:return _.checked;default:return _.value}}const rolesSupportingValues=[`meter`,`progressbar`,`slider`,`spinbutton`];function getAccessibleValue(_){if(rolesSupportingValues.includes(_.getAttribute(`role`)||``))return Number(_.getAttribute(`aria-valuenow`))}function normalize(_){return _.replace(/\s+/g,` `).trim()}function matches(_,K){return K instanceof RegExp?K.test(_):_.includes(String(K))}function arrayAsSetComparison(_,K){if(Array.isArray(_)&&Array.isArray(K)){let q=new Set(K);for(let K of new Set(_))if(!q.has(K))return!1;return!0}}const supportedRoles=getAriaCheckedRoles();function toBeChecked(_){let K=getElementFromUserInput(_,toBeChecked,this),q=()=>isInputElement(K)&&[`checkbox`,`radio`].includes(K.type),X=()=>supportedRoles.includes(getAriaRole(K)||``)&&[`true`,`false`].includes(K.getAttribute(`aria-checked`)||``);if(!q()&&!X())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 Z=getAriaChecked(K),Q=Z===!0;return{pass:Q,message:()=>{let _=Q?`is`:`is not`;return[this.utils.matcherHint(`${this.isNot?`.not`:``}.toBeChecked`,`element`,``),``,`Received element ${_} checked:`,` ${this.utils.printReceived(K.cloneNode(!1))}`].join(`
|
|
4
4
|
`)}}}function supportedRolesSentence(){return toSentence(supportedRoles.map(_=>`role="${_}"`),{lastWordConnector:` or `})}function toBeEmptyDOMElement(_){let K=getElementFromUserInput(_,toBeEmptyDOMElement,this);return{pass:isEmptyElement(K),message:()=>[this.utils.matcherHint(`${this.isNot?`.not`:``}.toBeEmptyDOMElement`,`element`,``),``,`Received:`,` ${this.utils.printReceived(K.innerHTML)}`].join(`
|
|
@@ -23,5 +23,5 @@ import{expect,chai}from"vitest";import{k as kAriaCheckedRoles,i as getAriaChecke
|
|
|
23
23
|
`)}}}function getMultiElementValue(_){let K=[...new Set(_.map(_=>_.type))];if(K.length!==1)throw Error(`Multiple form elements with the same name must be of the same type`);switch(K[0]){case`radio`:{let K=_.find(_=>_.checked);return K?K.value:void 0}case`checkbox`:return _.filter(_=>_.checked).map(_=>_.value);default:return _.map(_=>_.value)}}function getFormValue(_,K){let q=[..._.querySelectorAll(`[name="${cssEscape(K)}"]`)];if(q.length!==0)switch(q.length){case 1:return getSingleElementValue(q[0]);default:return getMultiElementValue(q)}}function getPureName(_){return/\[\]$/.test(_)?_.slice(0,-2):_}function getAllFormValues(_){let K={};for(let q of _.elements){if(!(`name`in q))continue;let J=q.name;K[getPureName(J)]=getFormValue(_,J)}return K}function toHaveRole(_,K){let q=getElementFromUserInput(_,toHaveRole,this);beginAriaCaches();let J=getAriaRole(q);return endAriaCaches(),{pass:J===K,message:()=>{let _=this.isNot?`not to`:`to`;return getMessage(this,this.utils.matcherHint(`${this.isNot?`.not`:``}.toHaveRole`,`element`,``),`Expected element ${_} have role`,K,`Received`,J)}}}function toHaveSelection(_,K){let q=getElementFromUserInput(_,toHaveSelection,this),J=K!==void 0;if(J&&typeof K!=`string`)throw Error(`expected selection must be a string or undefined`);let Y=getSelection(q);return{pass:J?this.equals(Y,K,[arrayAsSetComparison,...this.customTesters]):!!Y,message:()=>{let _=this.isNot?`not to`:`to`,q=this.utils.matcherHint(`${this.isNot?`.not`:``}.toHaveSelection`,`element`,K);return getMessage(this,q,`Expected the element ${_} have selection`,J?K:`(any)`,`Received`,Y)}}}function getSelection(_){let K=_.ownerDocument.getSelection();if(!K)return``;if([`INPUT`,`TEXTAREA`].includes(getTag(_))){let K=_;return[`radio`,`checkbox`].includes(K.type)||K.selectionStart==null||K.selectionEnd==null?``:K.value.toString().substring(K.selectionStart,K.selectionEnd)}if(K.anchorNode===null||K.focusNode===null)return``;let q=K.getRangeAt(0),J=_.ownerDocument.createRange();if(K.containsNode(_,!1))J.selectNodeContents(_),K.removeAllRanges(),K.addRange(J);else if(!(_.contains(K.anchorNode)&&_.contains(K.focusNode))){let Y=_===q.startContainer||_.contains(q.startContainer),X=_===q.endContainer||_.contains(q.endContainer);K.removeAllRanges(),(Y||X)&&(J.selectNodeContents(_),Y&&J.setStart(q.startContainer,q.startOffset),X&&J.setEnd(q.endContainer,q.endOffset),K.addRange(J))}let Y=K.toString();return K.removeAllRanges(),K.addRange(q),Y}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(_,K){let q=getElementFromUserInput(_,toHaveStyle,this),{getComputedStyle:J}=q.ownerDocument.defaultView,Y=typeof K==`object`?getStyleFromObjectCSS(K):computeCSSStyleDeclaration(K),X=J(q),Z=new Set(Array.from(q.style));return{pass:isSubset(Y,q,X,Z),message:()=>{let _=`${this.isNot?`.not`:``}.toHaveStyle`,K=new Set(Object.keys(Y)),J=Array.from(X).filter(_=>K.has(_)).reduce((_,K)=>{let J=Z.has(K)&&usedValuesProps.has(K)?q.style:X;return _[K]=J[K],_},{}),Q=printoutObjectStyles(J),$=Q===``?`Expected styles could not be parsed by the browser. Did you make a typo?`:this.utils.diff(printoutObjectStyles(Y),Q);return[this.utils.matcherHint(_,`element`,``),$].join(`
|
|
24
24
|
|
|
25
25
|
`)}}}function getStyleFromObjectCSS(_){let K=browser===`chrome`||browser===`chromium`?document:document.implementation.createHTMLDocument(``),q=K.createElement(`div`);K.body.appendChild(q);let J=Object.keys(_);J.forEach(K=>{q.style[K]=_[K]});let Y={},X=window.getComputedStyle(q);return J.forEach(_=>{let K=usedValuesProps.has(_)?q.style:X,J=K[_];J!=null&&(Y[_]=J)}),q.remove(),Y}function computeCSSStyleDeclaration(_){let K=browser===`chrome`||browser===`chromium`||browser===`webkit`?document:document.implementation.createHTMLDocument(``),q=K.createElement(`div`);q.setAttribute(`style`,_.replace(/\n/g,``)),K.body.appendChild(q);let J=window.getComputedStyle(q),Y=Array.from(q.style).reduce((_,K)=>(_[K]=usedValuesProps.has(K)?q.style.getPropertyValue(K):J.getPropertyValue(K),_),{});return q.remove(),Y}function printoutObjectStyles(_){return Object.keys(_).sort().map(K=>`${K}: ${_[K]};`).join(`
|
|
26
|
-
`)}function isSubset(_,K,q,J){let Y=Object.keys(_);return Y.length?Y.every(Y=>{let X=_[Y],Z=Y.startsWith(`--`),Q=[Y];Z||Q.push(Y.toLowerCase());let $=Q.some(_=>{let Z=J.has(Y)&&usedValuesProps.has(Y)?K.style:q;return Z[_]===X||Z.getPropertyValue(_)===X});return $}):!1}function toHaveTextContent(_,K,q={normalizeWhitespace:!0}){let J=getNodeFromUserInput(_,toHaveTextContent,this),Y=q.normalizeWhitespace?normalize(J.textContent||``):(J.textContent||``).replace(/\u00A0/g,` `),X=Y!==``&&K===``;return{pass:!X&&matches(Y,K),message:()=>{let _=this.isNot?`not to`:`to`;return getMessage(this,this.utils.matcherHint(`${this.isNot?`.not`:``}.toHaveTextContent`,`element`,``),X?`Checking with empty string will always match, use .toBeEmptyDOMElement() instead`:`Expected element ${_} have text content`,K,`Received`,Y)}}}function toHaveValue(_,K){let q=getElementFromUserInput(_,toHaveValue,this);if(isInputElement(q)&&[`checkbox`,`radio`].includes(q.type))throw Error(`input with type=checkbox or type=radio cannot be used with .toHaveValue(). Use .toBeChecked() for type=checkbox or .toHaveFormValues() instead`);let J=getSingleElementValue(q),Y=K!==void 0,X=K,Z=J;return K==J&&K!==J&&(X=`${K} (${typeof K})`,Z=`${J} (${typeof J})`),{pass:Y?this.equals(J,K,[arrayAsSetComparison,...this.customTesters]):!!J,message:()=>{let _=this.isNot?`not to`:`to`,q=this.utils.matcherHint(`${this.isNot?`.not`:``}.toHaveValue`,`element`,K);return getMessage(this,q,`Expected the element ${_} have value`,Y?X:`(any)`,`Received`,Z)}}}const counters=new Map([]);async function toMatchScreenshot(_,K,q=typeof K==`object`?K:{}){if(this.isNot)throw Error(`'toMatchScreenshot' cannot be used with "not"`);let J=getWorkerState().current;if(J===void 0||this.currentTestName===void 0)throw Error(`'toMatchScreenshot' cannot be used without test context`);let Y=`${J.result?.repeatCount??0}${this.testPath}${this.currentTestName}`,X=counters.get(Y);X===void 0&&(X={current:0},counters.set(Y,X)),X.current+=1;let Z=typeof K==`string`?K:`${this.currentTestName} ${X.current}`,Q=await getBrowserState().commands.triggerCommand(`__vitest_screenshotMatcher`,[Z,this.currentTestName,{element:
|
|
26
|
+
`)}function isSubset(_,K,q,J){let Y=Object.keys(_);return Y.length?Y.every(Y=>{let X=_[Y],Z=Y.startsWith(`--`),Q=[Y];Z||Q.push(Y.toLowerCase());let $=Q.some(_=>{let Z=J.has(Y)&&usedValuesProps.has(Y)?K.style:q;return Z[_]===X||Z.getPropertyValue(_)===X});return $}):!1}function toHaveTextContent(_,K,q={normalizeWhitespace:!0}){let J=getNodeFromUserInput(_,toHaveTextContent,this),Y=q.normalizeWhitespace?normalize(J.textContent||``):(J.textContent||``).replace(/\u00A0/g,` `),X=Y!==``&&K===``;return{pass:!X&&matches(Y,K),message:()=>{let _=this.isNot?`not to`:`to`;return getMessage(this,this.utils.matcherHint(`${this.isNot?`.not`:``}.toHaveTextContent`,`element`,``),X?`Checking with empty string will always match, use .toBeEmptyDOMElement() instead`:`Expected element ${_} have text content`,K,`Received`,Y)}}}function toHaveValue(_,K){let q=getElementFromUserInput(_,toHaveValue,this);if(isInputElement(q)&&[`checkbox`,`radio`].includes(q.type))throw Error(`input with type=checkbox or type=radio cannot be used with .toHaveValue(). Use .toBeChecked() for type=checkbox or .toHaveFormValues() instead`);let J=getSingleElementValue(q),Y=K!==void 0,X=K,Z=J;return K==J&&K!==J&&(X=`${K} (${typeof K})`,Z=`${J} (${typeof J})`),{pass:Y?this.equals(J,K,[arrayAsSetComparison,...this.customTesters]):!!J,message:()=>{let _=this.isNot?`not to`:`to`,q=this.utils.matcherHint(`${this.isNot?`.not`:``}.toHaveValue`,`element`,K);return getMessage(this,q,`Expected the element ${_} have value`,Y?X:`(any)`,`Received`,Z)}}}const counters=new Map([]);async function toMatchScreenshot(_,K,q=typeof K==`object`?K:{}){if(this.isNot)throw Error(`'toMatchScreenshot' cannot be used with "not"`);let J=getWorkerState().current;if(J===void 0||this.currentTestName===void 0)throw Error(`'toMatchScreenshot' cannot be used without test context`);let Y=`${J.result?.repeatCount??0}${this.testPath}${this.currentTestName}`,X=counters.get(Y);X===void 0&&(X={current:0},counters.set(Y,X)),X.current+=1;let Z=typeof K==`string`?K:`${this.currentTestName} ${X.current}`,Q=q.screenshotOptions&&`mask`in q.screenshotOptions?{...q,screenshotOptions:{...q.screenshotOptions,mask:q.screenshotOptions.mask.map(convertToSelector)}}:q,$=await getBrowserState().commands.triggerCommand(`__vitest_screenshotMatcher`,[Z,this.currentTestName,{element:convertToSelector(_),...Q}]);if($.pass===!1&&`context`in J){let{annotate:_}=J.context,K=[];$.reference&&K.push(_(`Reference screenshot`,{path:$.reference})),$.actual&&K.push(_(`Actual screenshot`,{path:$.actual})),$.diff&&K.push(_(`Diff`,{path:$.diff})),await Promise.all(K)}return{pass:$.pass,message:()=>$.pass?``:[this.utils.matcherHint(`toMatchScreenshot`,`element`,``),``,$.message,$.reference?`\nReference screenshot:\n ${this.utils.EXPECTED_COLOR($.reference)}`:null,$.actual?`\nActual screenshot:\n ${this.utils.RECEIVED_COLOR($.actual)}`:null,$.diff?this.utils.DIM_COLOR(`\nDiff image:\n ${$.diff}`):null].filter(_=>_!==null).join(`
|
|
27
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};function element(q,J){if(q!=null&&!(q instanceof Element)&&!(`element`in q))throw Error(`Invalid element or locator: ${q}. Expected an instance of Element or Locator, received ${typeof q}`);return expect.poll(function(){if(q instanceof Element||q==null)return q;chai.util.flag(this,`_poll.element`,!0);let _=chai.util.flag(this,`negate`),J=chai.util.flag(this,`_name`),Y=chai.util.flag(this,`_isLastPollAttempt`);if(_&&J===`toBeInTheDocument`)return q.query();if(Y)return q.element();let X=q.query();if(!X)throw Error(`Cannot find element with locator: ${JSON.stringify(q)}`);return X},processTimeoutOptions(J))}expect.extend(matchers),Object.assign(expect,{element});
|
|
@@ -0,0 +1 @@
|
|
|
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-Kx5DUGWa.js";function ensureAwaited(e){let x=getWorkerState().current;if(!x||x.type!==`test`)return e();let S=!1,C=Error(`STACK_TRACE_ERROR`);x.onFinished??=[],x.onFinished.push(()=>{if(!S){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=C.stack?.replace(C.message,e.message),e}});let w;return{then(x,T){return S=!0,(w||=e(C)).then(x,T)},catch(x){return(w||=e(C)).catch(x)},finally(x){return(w||=e(C)).finally(x)},[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 x=e.charCodeAt(0);return e===` `||e===`#`||e===`.`||e===`:`||e===`[`||e===`]`||e===`>`||e===`+`||e===`~`||e===`\\`?`\\${e}`:x>=65536?`\\${x.toString(16).toUpperCase().padStart(6,`0`)} `:x<32||x===127||x>=128?`\\${x.toString(16).toUpperCase().padStart(2,`0`)} `:e}).join(``)}function getUniqueCssSelector(e){let x=[],S,C=!1;for(;S=getParent(e);){S.shadowRoot&&(C=!0);let w=e.tagName;if(e.id)x.push(`#${escapeIdForCSSSelector(e.id)}`);else if(!e.nextElementSibling&&!e.previousElementSibling)x.push(w.toLowerCase());else{let C=0,T=0,E=0;for(let x of S.children)C++,x.tagName===w&&T++,x===e&&(E=C);T>1?x.push(`${w.toLowerCase()}:nth-child(${E})`):x.push(w.toLowerCase())}e=S}return`${getBrowserState().provider===`webdriverio`&&C?`>>>`:``}${x.reverse().join(` > `)}`}function getParent(e){let x=e.parentNode;return x instanceof ShadowRoot?x.host:x}const now=Date.now;function processTimeoutOptions(e){if(e&&e.timeout!=null||provider!==`playwright`||getWorkerState().config.browser.providerOptions.actionTimeout!=null)return e;let x=getBrowserState().runner,S=x._currentTaskStartTime;if(!S)return e;let C=x._currentTaskTimeout;if(C===0||C==null||C===1/0)return e;e||={};let w=now(),T=S+C,E=T-w;return E<=0||(e.timeout=E-100),e}function getIframeScale(){let e=window.parent.document.querySelector(`iframe[data-vitest]`)?.parentElement;if(!e)throw Error(`Cannot find Tester element. This is a bug in Vitest. Please, open a new issue with reproduction.`);let x=e.getAttribute(`data-scale`),S=Number(x);if(Number.isNaN(S))throw TypeError(`Cannot parse scale value from Tester element (${x}). This is a bug in Vitest. Please, open a new issue with reproduction.`);return S}function escapeRegexForSelector(e){return e.unicode||e.unicodeSets?String(e):String(e).replace(/(^|[^\\])(\\\\)*(["'`])/g,`$1$2\\$3`).replace(/>>/g,`\\>\\>`)}function escapeForTextSelector(e,x){return typeof e==`string`?`${JSON.stringify(e)}i`:escapeRegexForSelector(e)}function convertToSelector(e){if(!e)throw Error(`Expected element or locator to be defined.`);if(e instanceof Element)return convertElementToCssSelector(e);if(`selector`in e)return e.selector;throw Error(`Expected element or locator to be an instance of Element or Locator.`)}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,x){return this.triggerCommand(`__vitest_fill`,this.selector,e,x)}async upload(e,x){let S=(Array.isArray(e)?e:[e]).map(async e=>{if(typeof e==`string`)return e;let x=await new Promise((x,S)=>{let C=new FileReader;C.onload=()=>x(C.result),C.onerror=()=>S(Error(`Failed to read file: ${e.name}`)),C.readAsDataURL(e)});return{name:e.name,mimeType:e.type,base64:x}});return this.triggerCommand(`__vitest_upload`,this.selector,await Promise.all(S),x)}dropTo(e,x={}){return this.triggerCommand(`__vitest_dragAndDrop`,this.selector,e.selector,x)}selectOptions(e,x){let S=(Array.isArray(e)?e:[e]).map(e=>{if(typeof e!=`string`){let x=`element`in e?e.selector:selectorEngine.generateSelectorSimple(e);return{element:x}}return e});return this.triggerCommand(`__vitest_selectOptions`,this.selector,S,x)}screenshot(e){return page.screenshot({...e,element:this})}getByRole(e,x){return this.locator(getByRoleSelector(e,x))}getByAltText(e,x){return this.locator(getByAltTextSelector(e,x))}getByLabelText(e,x){return this.locator(getByLabelSelector(e,x))}getByPlaceholder(e,x){return this.locator(getByPlaceholderSelector(e,x))}getByTestId(x){return this.locator(getByTestIdSelector(server.config.browser.locators.testIdAttribute,x))}getByText(e,x){return this.locator(getByTextSelector(e,x))}getByTitle(e,x){return this.locator(getByTitleSelector(e,x))}filter(e){let x=[];if(e?.hasText&&x.push(`internal:has-text=${escapeForTextSelector(e.hasText)}`),e?.hasNotText&&x.push(`internal:has-not-text=${escapeForTextSelector(e.hasNotText)}`),e?.has){let S=e.has;x.push(`internal:has=${JSON.stringify(S._pwSelector||S.selector)}`)}if(e?.hasNot){let S=e.hasNot;x.push(`internal:has-not=${JSON.stringify(S._pwSelector||S.selector)}`)}if(!x.length)throw Error(`Locator.filter expects at least one filter. None provided.`);return this.locator(x.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,...x){let S=getBrowserState().commands;return ensureAwaited(C=>S.triggerCommand(e,x,C))}}export{Locator as L,getBrowserState as a,getWorkerState as b,convertElementToCssSelector as c,convertToSelector as d,getIframeScale as g,processTimeoutOptions as p,selectorEngine as s};
|
package/dist/index.js
CHANGED
|
@@ -22,7 +22,7 @@ import pm from 'pixelmatch';
|
|
|
22
22
|
import { WebSocketServer } from 'ws';
|
|
23
23
|
import { performance } from 'node:perf_hooks';
|
|
24
24
|
|
|
25
|
-
var version = "4.0.0-beta.
|
|
25
|
+
var version = "4.0.0-beta.7";
|
|
26
26
|
|
|
27
27
|
const _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//;
|
|
28
28
|
function normalizeWindowsPath(input = "") {
|
|
@@ -2403,11 +2403,13 @@ async function takeScreenshot(context, name, options) {
|
|
|
2403
2403
|
const savePath = normalize$1(path);
|
|
2404
2404
|
await mkdir(dirname(path), { recursive: true });
|
|
2405
2405
|
if (context.provider instanceof PlaywrightBrowserProvider) {
|
|
2406
|
+
const mask = options.mask?.map((selector) => context.iframe.locator(selector));
|
|
2406
2407
|
if (options.element) {
|
|
2407
2408
|
const { element: selector,...config } = options;
|
|
2408
|
-
const element = context.iframe.locator(
|
|
2409
|
+
const element = context.iframe.locator(selector);
|
|
2409
2410
|
const buffer = await element.screenshot({
|
|
2410
2411
|
...config,
|
|
2412
|
+
mask,
|
|
2411
2413
|
path: options.save ? savePath : undefined
|
|
2412
2414
|
});
|
|
2413
2415
|
return {
|
|
@@ -2417,6 +2419,7 @@ async function takeScreenshot(context, name, options) {
|
|
|
2417
2419
|
}
|
|
2418
2420
|
const buffer = await context.iframe.locator("body").screenshot({
|
|
2419
2421
|
...options,
|
|
2422
|
+
mask,
|
|
2420
2423
|
path: options.save ? savePath : undefined
|
|
2421
2424
|
});
|
|
2422
2425
|
return {
|
package/dist/locators/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"@vitest/browser/context";import"../public-utils-Kx5DUGWa.js";export{L as Locator,s as selectorEngine}from"../index-
|
|
1
|
+
import"@vitest/browser/context";import"../public-utils-Kx5DUGWa.js";export{L as Locator,s as selectorEngine}from"../index-B7Hfmz-h.js";import"vitest/internal/browser";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{page,server}from"@vitest/browser/context";import{g as getByTitleSelector,a as getByTextSelector,b as getByPlaceholderSelector,c as getByAltTextSelector,d as getByTestIdSelector,e as getByRoleSelector,f as getByLabelSelector}from"../public-utils-Kx5DUGWa.js";import{s as selectorEngine,L as Locator,p as processTimeoutOptions,g as getIframeScale}from"../index-
|
|
1
|
+
import{page,server}from"@vitest/browser/context";import{g as getByTitleSelector,a as getByTextSelector,b as getByPlaceholderSelector,c as getByAltTextSelector,d as getByTestIdSelector,e as getByRoleSelector,f as getByLabelSelector}from"../public-utils-Kx5DUGWa.js";import{s as selectorEngine,L as Locator,p as processTimeoutOptions,g as getIframeScale}from"../index-B7Hfmz-h.js";import"vitest/internal/browser";page.extend({getByLabelText(e,_){return new PlaywrightLocator(getByLabelSelector(e,_))},getByRole(e,_){return new PlaywrightLocator(getByRoleSelector(e,_))},getByTestId(e){return new PlaywrightLocator(getByTestIdSelector(server.config.browser.locators.testIdAttribute,e))},getByAltText(e,_){return new PlaywrightLocator(getByAltTextSelector(e,_))},getByPlaceholder(e,_){return new PlaywrightLocator(getByPlaceholderSelector(e,_))},getByText(e,_){return new PlaywrightLocator(getByTextSelector(e,_))},getByTitle(e,_){return new PlaywrightLocator(getByTitleSelector(e,_))},_createLocator(e){return new PlaywrightLocator(e)},elementLocator(e){return new PlaywrightLocator(selectorEngine.generateSelectorSimple(e),e)}});class PlaywrightLocator extends Locator{constructor(e,_){super(),this.selector=e,this._container=_}click(e){return super.click(processTimeoutOptions(processClickOptions(e)))}dblClick(e){return super.dblClick(processTimeoutOptions(processClickOptions(e)))}tripleClick(e){return super.tripleClick(processTimeoutOptions(processClickOptions(e)))}selectOptions(e,_){return super.selectOptions(e,processTimeoutOptions(_))}clear(e){return super.clear(processTimeoutOptions(e))}hover(e){return super.hover(processTimeoutOptions(processHoverOptions(e)))}upload(e,_){return super.upload(e,processTimeoutOptions(_))}fill(e,_){return super.fill(e,processTimeoutOptions(_))}dropTo(e,_){return super.dropTo(e,processTimeoutOptions(processDragAndDropOptions(_)))}locator(e){return new PlaywrightLocator(`${this.selector} >> ${e}`,this._container)}elementLocator(e){return new PlaywrightLocator(selectorEngine.generateSelectorSimple(e),e)}}function processDragAndDropOptions(e){if(!e)return e;let _=e;return _.sourcePosition&&=processPlaywrightPosition(_.sourcePosition),_.targetPosition&&=processPlaywrightPosition(_.targetPosition),e}function processHoverOptions(e){if(!e)return e;let _=e;return _.position&&=processPlaywrightPosition(_.position),e}function processClickOptions(e){if(!e)return e;let _=e;return _.position&&=processPlaywrightPosition(_.position),_}function processPlaywrightPosition(e){let _=getIframeScale();return e.x!=null&&(e.x*=_),e.y!=null&&(e.y*=_),e}
|
package/dist/locators/preview.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{page,server,userEvent}from"@vitest/browser/context";import{g as getByTitleSelector,a as getByTextSelector,b as getByPlaceholderSelector,c as getByAltTextSelector,d as getByTestIdSelector,e as getByRoleSelector,f as getByLabelSelector,h as getElementError}from"../public-utils-Kx5DUGWa.js";import{s as selectorEngine,L as Locator,c as convertElementToCssSelector}from"../index-
|
|
1
|
+
import{page,server,userEvent}from"@vitest/browser/context";import{g as getByTitleSelector,a as getByTextSelector,b as getByPlaceholderSelector,c as getByAltTextSelector,d as getByTestIdSelector,e as getByRoleSelector,f as getByLabelSelector,h as getElementError}from"../public-utils-Kx5DUGWa.js";import{s as selectorEngine,L as Locator,c as convertElementToCssSelector}from"../index-B7Hfmz-h.js";import"vitest/internal/browser";page.extend({getByLabelText(e,m){return new PreviewLocator(getByLabelSelector(e,m))},getByRole(e,m){return new PreviewLocator(getByRoleSelector(e,m))},getByTestId(e){return new PreviewLocator(getByTestIdSelector(server.config.browser.locators.testIdAttribute,e))},getByAltText(e,m){return new PreviewLocator(getByAltTextSelector(e,m))},getByPlaceholder(e,m){return new PreviewLocator(getByPlaceholderSelector(e,m))},getByText(e,m){return new PreviewLocator(getByTextSelector(e,m))},getByTitle(e,m){return new PreviewLocator(getByTitleSelector(e,m))},_createLocator(e){return new PreviewLocator(e)},elementLocator(e){return new PreviewLocator(selectorEngine.generateSelectorSimple(e),e)}});class PreviewLocator extends Locator{constructor(e,m){super(),this._pwSelector=e,this._container=m}get selector(){let e=this.elements().map(e=>convertElementToCssSelector(e));if(!e.length)throw getElementError(this._pwSelector,this._container||document.body);return e.join(`, `)}click(){return userEvent.click(this.element())}dblClick(){return userEvent.dblClick(this.element())}tripleClick(){return userEvent.tripleClick(this.element())}hover(){return userEvent.hover(this.element())}unhover(){return userEvent.unhover(this.element())}async fill(e){return userEvent.fill(this.element(),e)}async upload(e){return userEvent.upload(this.element(),e)}selectOptions(e){return userEvent.selectOptions(this.element(),e)}clear(){return userEvent.clear(this.element())}locator(e){return new PreviewLocator(`${this._pwSelector} >> ${e}`,this._container)}elementLocator(e){return new PreviewLocator(selectorEngine.generateSelectorSimple(e),e)}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{page,server}from"@vitest/browser/context";import{g as getByTitleSelector,a as getByTextSelector,b as getByPlaceholderSelector,c as getByAltTextSelector,d as getByTestIdSelector,e as getByRoleSelector,f as getByLabelSelector,h as getElementError}from"../public-utils-Kx5DUGWa.js";import{s as selectorEngine,L as Locator,c as convertElementToCssSelector,a as getBrowserState,g as getIframeScale}from"../index-
|
|
1
|
+
import{page,server}from"@vitest/browser/context";import{g as getByTitleSelector,a as getByTextSelector,b as getByPlaceholderSelector,c as getByAltTextSelector,d as getByTestIdSelector,e as getByRoleSelector,f as getByLabelSelector,h as getElementError}from"../public-utils-Kx5DUGWa.js";import{s as selectorEngine,L as Locator,c as convertElementToCssSelector,a as getBrowserState,g as getIframeScale}from"../index-B7Hfmz-h.js";import"vitest/internal/browser";page.extend({getByLabelText(e,g){return new WebdriverIOLocator(getByLabelSelector(e,g))},getByRole(e,g){return new WebdriverIOLocator(getByRoleSelector(e,g))},getByTestId(e){return new WebdriverIOLocator(getByTestIdSelector(server.config.browser.locators.testIdAttribute,e))},getByAltText(e,g){return new WebdriverIOLocator(getByAltTextSelector(e,g))},getByPlaceholder(e,g){return new WebdriverIOLocator(getByPlaceholderSelector(e,g))},getByText(e,g){return new WebdriverIOLocator(getByTextSelector(e,g))},getByTitle(e,g){return new WebdriverIOLocator(getByTitleSelector(e,g))},_createLocator(e){return new WebdriverIOLocator(e)},elementLocator(e){return new WebdriverIOLocator(selectorEngine.generateSelectorSimple(e))}});class WebdriverIOLocator extends Locator{constructor(e,g){super(),this._pwSelector=e,this._container=g}get selector(){let e=this.elements().map(e=>convertElementToCssSelector(e));if(!e.length)throw getElementError(this._pwSelector,this._container||document.body);let g=!1,_=e.map(e=>e.startsWith(`>>>`)?(g=!0,e.slice(3)):e);return(g?`>>>`:``)+_.join(`, `)}click(e){return super.click(processClickOptions(e))}dblClick(e){return super.dblClick(processClickOptions(e))}tripleClick(e){return super.tripleClick(processClickOptions(e))}selectOptions(e,g){let _=getWebdriverioSelectOptions(this.element(),e);return this.triggerCommand(`__vitest_selectOptions`,this.selector,_,g)}hover(e){return super.hover(processHoverOptions(e))}dropTo(e,g){return super.dropTo(e,processDragAndDropOptions(g))}locator(e){return new WebdriverIOLocator(`${this._pwSelector} >> ${e}`,this._container)}elementLocator(e){return new WebdriverIOLocator(selectorEngine.generateSelectorSimple(e),e)}}function getWebdriverioSelectOptions(e,g){let _=[...e.querySelectorAll(`option`)],v=Array.isArray(g)?g:[g];if(!v.length)return[];if(v.length>1)throw Error(`Provider "webdriverio" doesn't support selecting multiple values at once`);let y=v[0];if(typeof y!=`string`){let e=`element`in y?y.element():y,g=_.indexOf(e);if(g===-1)throw Error(`The element ${selectorEngine.previewNode(e)} was not found in the "select" options.`);return[{index:g}]}let b=_.findIndex(e=>e.value===y);if(b!==-1)return[{index:b}];let x=_.findIndex(e=>e.textContent?.trim()===y||e.ariaLabel===y);if(x===-1)throw Error(`The option "${y}" was not found in the "select" options.`);return[{index:x}]}function processClickOptions(e){if(!e||!getBrowserState().config.browser.ui)return e;let g=e;if(g.x!=null||g.y!=null){let e={};g.x!=null&&(g.x=scaleCoordinate(g.x,e)),g.y!=null&&(g.y=scaleCoordinate(g.y,e))}return e}function processHoverOptions(e){if(!e||!getBrowserState().config.browser.ui)return e;let g=e,_={};return g.xOffset!=null&&(g.xOffset=scaleCoordinate(g.xOffset,_)),g.yOffset!=null&&(g.yOffset=scaleCoordinate(g.yOffset,_)),e}function processDragAndDropOptions(e){if(!e||!getBrowserState().config.browser.ui)return e;let g={},_=e;return _.sourceX!=null&&(_.sourceX=scaleCoordinate(_.sourceX,g)),_.sourceY!=null&&(_.sourceY=scaleCoordinate(_.sourceY,g)),_.targetX!=null&&(_.targetX=scaleCoordinate(_.targetX,g)),_.targetY!=null&&(_.targetY=scaleCoordinate(_.targetY,g)),e}function scaleCoordinate(e,g){return Math.round(e*getCachedScale(g))}function getCachedScale(e){return e.scale??=getIframeScale()}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type { ScreenshotComparatorRegistry, ScreenshotMatcherOptions } from "../../../context.js";
|
|
2
2
|
export type ScreenshotMatcherArguments<ComparatorName extends keyof ScreenshotComparatorRegistry = keyof ScreenshotComparatorRegistry> = [name: string, testName: string, options: ScreenshotMatcherOptions<ComparatorName> & {
|
|
3
3
|
element: string;
|
|
4
|
+
screenshotOptions?: ScreenshotMatcherOptions<ComparatorName>["screenshotOptions"] & {
|
|
5
|
+
mask?: readonly string[];
|
|
6
|
+
};
|
|
4
7
|
}];
|
|
5
8
|
export type ScreenshotMatcherOutput = Promise<{
|
|
6
9
|
pass: false;
|
package/dist/types.d.ts
CHANGED
|
@@ -39,7 +39,6 @@ export interface WebSocketBrowserHandlers {
|
|
|
39
39
|
export type Awaitable<T> = T | PromiseLike<T>;
|
|
40
40
|
export interface WebSocketEvents {
|
|
41
41
|
onCollected?: (files: RunnerTestFile[]) => Awaitable<void>;
|
|
42
|
-
onFinished?: (files: File[], errors: unknown[], coverage?: unknown) => Awaitable<void>;
|
|
43
42
|
onTaskUpdate?: (packs: TaskResultPack[]) => Awaitable<void>;
|
|
44
43
|
onUserConsoleLog?: (log: UserConsoleLog) => Awaitable<void>;
|
|
45
44
|
onPathsCollected?: (paths?: string[]) => Awaitable<void>;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vitest/browser",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "4.0.0-beta.
|
|
4
|
+
"version": "4.0.0-beta.7",
|
|
5
5
|
"description": "Browser running for Vitest",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"funding": "https://opencollective.com/vitest",
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
"peerDependencies": {
|
|
67
67
|
"playwright": "*",
|
|
68
68
|
"webdriverio": "^7.0.0 || ^8.0.0 || ^9.0.0",
|
|
69
|
-
"vitest": "4.0.0-beta.
|
|
69
|
+
"vitest": "4.0.0-beta.7"
|
|
70
70
|
},
|
|
71
71
|
"peerDependenciesMeta": {
|
|
72
72
|
"playwright": {
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
}
|
|
81
81
|
},
|
|
82
82
|
"dependencies": {
|
|
83
|
-
"@testing-library/dom": "^10.4.
|
|
83
|
+
"@testing-library/dom": "^10.4.1",
|
|
84
84
|
"@testing-library/user-event": "^14.6.1",
|
|
85
85
|
"magic-string": "^0.30.17",
|
|
86
86
|
"pixelmatch": "7.1.0",
|
|
@@ -88,8 +88,8 @@
|
|
|
88
88
|
"sirv": "^3.0.1",
|
|
89
89
|
"tinyrainbow": "^2.0.0",
|
|
90
90
|
"ws": "^8.18.3",
|
|
91
|
-
"@vitest/mocker": "4.0.0-beta.
|
|
92
|
-
"@vitest/utils": "4.0.0-beta.
|
|
91
|
+
"@vitest/mocker": "4.0.0-beta.7",
|
|
92
|
+
"@vitest/utils": "4.0.0-beta.7"
|
|
93
93
|
},
|
|
94
94
|
"devDependencies": {
|
|
95
95
|
"@types/pngjs": "^6.0.5",
|
|
@@ -105,11 +105,11 @@
|
|
|
105
105
|
"playwright": "^1.54.1",
|
|
106
106
|
"playwright-core": "^1.54.1",
|
|
107
107
|
"safaridriver": "^1.0.0",
|
|
108
|
-
"webdriverio": "^9.18.
|
|
109
|
-
"@vitest/runner": "4.0.0-beta.
|
|
110
|
-
"
|
|
111
|
-
"@vitest/ws-client": "4.0.0-beta.
|
|
112
|
-
"vitest": "4.0.0-beta.
|
|
108
|
+
"webdriverio": "^9.18.4",
|
|
109
|
+
"@vitest/runner": "4.0.0-beta.7",
|
|
110
|
+
"vitest": "4.0.0-beta.7",
|
|
111
|
+
"@vitest/ws-client": "4.0.0-beta.7",
|
|
112
|
+
"@vitest/ui": "4.0.0-beta.7"
|
|
113
113
|
},
|
|
114
114
|
"scripts": {
|
|
115
115
|
"typecheck": "tsc -p ./src/client/tsconfig.json --noEmit",
|
|
@@ -12,6 +12,7 @@ import { Protocol } from 'playwright-core/types/protocol'
|
|
|
12
12
|
import '../matchers.js'
|
|
13
13
|
import type {} from "vitest/node"
|
|
14
14
|
import type {
|
|
15
|
+
Locator,
|
|
15
16
|
ScreenshotComparatorRegistry,
|
|
16
17
|
ScreenshotMatcherOptions,
|
|
17
18
|
} from "@vitest/browser/context"
|
|
@@ -71,7 +72,9 @@ declare module '@vitest/browser/context' {
|
|
|
71
72
|
export interface UserEventDragAndDropOptions extends PWDragAndDropOptions {}
|
|
72
73
|
export interface UserEventUploadOptions extends PWSetInputFiles {}
|
|
73
74
|
|
|
74
|
-
export interface ScreenshotOptions extends PWScreenshotOptions {
|
|
75
|
+
export interface ScreenshotOptions extends Omit<PWScreenshotOptions, 'mask'> {
|
|
76
|
+
mask?: ReadonlyArray<Element | Locator> | undefined
|
|
77
|
+
}
|
|
75
78
|
|
|
76
79
|
export interface CDPSession {
|
|
77
80
|
send<T extends keyof Protocol.CommandParameters>(
|
package/dist/index-D_g_FMM5.js
DELETED
|
@@ -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-Kx5DUGWa.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(`iframe[data-vitest]`)?.parentElement;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,getBrowserState as a,getWorkerState as b,convertElementToCssSelector as c,getIframeScale as g,processTimeoutOptions as p,selectorEngine as s};
|