@e2e-dev/web 0.11.1 → 0.12.0
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/README.md +15 -9
- package/dist/.build.json +1 -1
- package/dist/actions.d.ts +1 -2
- package/dist/actions.js +54 -6
- package/dist/attempt-session.d.ts +1 -2
- package/dist/attempt-session.js +0 -1
- package/dist/bin.d.ts +2 -0
- package/dist/bin.js +3 -0
- package/dist/browser-connection.d.ts +7 -4
- package/dist/browser-connection.js +7 -2
- package/dist/browser.d.ts +43 -7
- package/dist/browser.js +93 -36
- package/dist/capture-scope.d.ts +1 -2
- package/dist/capture-scope.js +0 -1
- package/dist/cdp-recovery.d.ts +1 -2
- package/dist/cdp-recovery.js +0 -1
- package/dist/cdp-selectors.d.ts +1 -2
- package/dist/cdp-selectors.js +0 -1
- package/dist/cli.d.ts +9 -0
- package/dist/cli.js +42 -0
- package/dist/closed-shadow.d.ts +0 -1
- package/dist/closed-shadow.js +0 -1
- package/dist/dialogs.d.ts +1 -2
- package/dist/dialogs.js +0 -1
- package/dist/downloads.d.ts +1 -2
- package/dist/downloads.js +0 -1
- package/dist/engine.d.ts +1 -2
- package/dist/engine.js +74 -17
- package/dist/evaluation.d.ts +2 -1
- package/dist/evaluation.js +3 -2
- package/dist/in-page/read-semantics.d.ts +4 -6
- package/dist/in-page/read-semantics.js +184 -54
- package/dist/index.d.ts +2 -2
- package/dist/index.js +0 -1
- package/dist/init-scripts.d.ts +30 -0
- package/dist/init-scripts.js +105 -0
- package/dist/install.d.ts +8 -2
- package/dist/install.js +35 -9
- package/dist/label-selector.d.ts +0 -1
- package/dist/label-selector.js +0 -1
- package/dist/locators.d.ts +1 -2
- package/dist/locators.js +30 -19
- package/dist/observation-capture.d.ts +1 -2
- package/dist/observation-capture.js +0 -1
- package/dist/observation.d.ts +1 -2
- package/dist/observation.js +3 -4
- package/dist/observe.d.ts +1 -2
- package/dist/observe.js +0 -1
- package/dist/operation-budget.d.ts +0 -1
- package/dist/operation-budget.js +0 -1
- package/dist/protected-app.d.ts +20 -5
- package/dist/protected-app.js +36 -6
- package/dist/provider-video.d.ts +1 -2
- package/dist/provider-video.js +0 -1
- package/dist/provider.d.ts +0 -1
- package/dist/provider.js +0 -1
- package/dist/read-node.d.ts +16 -44
- package/dist/read-node.js +7 -22
- package/dist/read-selector.d.ts +51 -0
- package/dist/read-selector.js +69 -0
- package/dist/refs.d.ts +0 -1
- package/dist/refs.js +0 -1
- package/dist/route-options.d.ts +44 -0
- package/dist/route-options.js +125 -0
- package/dist/route-pattern.d.ts +0 -1
- package/dist/route-pattern.js +0 -1
- package/dist/selector-engines.d.ts +0 -1
- package/dist/selector-engines.js +4 -1
- package/dist/shown-selector.d.ts +20 -0
- package/dist/shown-selector.js +27 -0
- package/dist/support.d.ts +4 -3
- package/dist/support.js +1 -2
- package/dist/surface.d.ts +40 -4
- package/dist/surface.js +62 -28
- package/dist/video.d.ts +1 -2
- package/dist/video.js +0 -1
- package/package.json +9 -5
- package/dist/actions.d.ts.map +0 -1
- package/dist/actions.js.map +0 -1
- package/dist/attempt-session.d.ts.map +0 -1
- package/dist/attempt-session.js.map +0 -1
- package/dist/browser-connection.d.ts.map +0 -1
- package/dist/browser-connection.js.map +0 -1
- package/dist/browser.d.ts.map +0 -1
- package/dist/browser.js.map +0 -1
- package/dist/capture-scope.d.ts.map +0 -1
- package/dist/capture-scope.js.map +0 -1
- package/dist/cdp-recovery.d.ts.map +0 -1
- package/dist/cdp-recovery.js.map +0 -1
- package/dist/cdp-selectors.d.ts.map +0 -1
- package/dist/cdp-selectors.js.map +0 -1
- package/dist/closed-shadow.d.ts.map +0 -1
- package/dist/closed-shadow.js.map +0 -1
- package/dist/dialogs.d.ts.map +0 -1
- package/dist/dialogs.js.map +0 -1
- package/dist/downloads.d.ts.map +0 -1
- package/dist/downloads.js.map +0 -1
- package/dist/engine.d.ts.map +0 -1
- package/dist/engine.js.map +0 -1
- package/dist/evaluation.d.ts.map +0 -1
- package/dist/evaluation.js.map +0 -1
- package/dist/in-page/read-semantics.d.ts.map +0 -1
- package/dist/in-page/read-semantics.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/install.d.ts.map +0 -1
- package/dist/install.js.map +0 -1
- package/dist/label-selector.d.ts.map +0 -1
- package/dist/label-selector.js.map +0 -1
- package/dist/locators.d.ts.map +0 -1
- package/dist/locators.js.map +0 -1
- package/dist/observation-capture.d.ts.map +0 -1
- package/dist/observation-capture.js.map +0 -1
- package/dist/observation.d.ts.map +0 -1
- package/dist/observation.js.map +0 -1
- package/dist/observe.d.ts.map +0 -1
- package/dist/observe.js.map +0 -1
- package/dist/operation-budget.d.ts.map +0 -1
- package/dist/operation-budget.js.map +0 -1
- package/dist/protected-app.d.ts.map +0 -1
- package/dist/protected-app.js.map +0 -1
- package/dist/provider-video.d.ts.map +0 -1
- package/dist/provider-video.js.map +0 -1
- package/dist/provider.d.ts.map +0 -1
- package/dist/provider.js.map +0 -1
- package/dist/read-node.d.ts.map +0 -1
- package/dist/read-node.js.map +0 -1
- package/dist/refs.d.ts.map +0 -1
- package/dist/refs.js.map +0 -1
- package/dist/route-pattern.d.ts.map +0 -1
- package/dist/route-pattern.js.map +0 -1
- package/dist/selector-engines.d.ts.map +0 -1
- package/dist/selector-engines.js.map +0 -1
- package/dist/support.d.ts.map +0 -1
- package/dist/support.js.map +0 -1
- package/dist/surface.d.ts.map +0 -1
- package/dist/surface.js.map +0 -1
- package/dist/video.d.ts.map +0 -1
- package/dist/video.js.map +0 -1
package/dist/cli.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/** The `e2e-web` command: browser installs with the Playwright version this engine pins. */
|
|
2
|
+
import { BROWSER_NAMES, isBrowserName } from './browser-connection.js';
|
|
3
|
+
import { runPlaywrightCli } from './install.js';
|
|
4
|
+
const BROWSER_ARGS = `[${BROWSER_NAMES.join('|')} ...] [--with-deps]`;
|
|
5
|
+
const USAGE = `Usage: npx @e2e-dev/web install ${BROWSER_ARGS}
|
|
6
|
+
bunx @e2e-dev/web install ${BROWSER_ARGS}
|
|
7
|
+
pnpm exec e2e-web install ${BROWSER_ARGS}
|
|
8
|
+
|
|
9
|
+
Installs browsers for the Playwright version @e2e-dev/web runs. Installs
|
|
10
|
+
chromium when no browser is named. --with-deps also installs the system
|
|
11
|
+
libraries the browsers need on Linux.
|
|
12
|
+
`;
|
|
13
|
+
const PROCESS_IO = {
|
|
14
|
+
stdout: (text) => process.stdout.write(text),
|
|
15
|
+
stderr: (text) => process.stderr.write(text),
|
|
16
|
+
run: runPlaywrightCli,
|
|
17
|
+
};
|
|
18
|
+
/** Runs `e2e-web` with the arguments after the command name and resolves to the exit code. */
|
|
19
|
+
export async function main(args, io = PROCESS_IO) {
|
|
20
|
+
const [command, ...rest] = args;
|
|
21
|
+
if (command === 'help' || args.some((arg) => arg === '--help' || arg === '-h')) {
|
|
22
|
+
io.stdout(USAGE);
|
|
23
|
+
return 0;
|
|
24
|
+
}
|
|
25
|
+
if (command !== 'install') {
|
|
26
|
+
io.stderr(`${command === undefined ? 'missing command' : `unknown command "${command}"`}\n\n${USAGE}`);
|
|
27
|
+
return 2;
|
|
28
|
+
}
|
|
29
|
+
const options = rest.filter((arg) => arg.startsWith('-'));
|
|
30
|
+
const names = rest.filter((arg) => !arg.startsWith('-'));
|
|
31
|
+
const unknownOption = options.find((option) => option !== '--with-deps');
|
|
32
|
+
if (unknownOption !== undefined) {
|
|
33
|
+
io.stderr(`unknown option "${unknownOption}"\n\n${USAGE}`);
|
|
34
|
+
return 2;
|
|
35
|
+
}
|
|
36
|
+
const unknownBrowser = names.find((name) => !isBrowserName(name));
|
|
37
|
+
if (unknownBrowser !== undefined) {
|
|
38
|
+
io.stderr(`unknown browser "${unknownBrowser}"; expected one of ${BROWSER_NAMES.join(', ')}\n`);
|
|
39
|
+
return 2;
|
|
40
|
+
}
|
|
41
|
+
return io.run(['install', ...options, ...(names.length > 0 ? names : ['chromium'])]);
|
|
42
|
+
}
|
package/dist/closed-shadow.d.ts
CHANGED
package/dist/closed-shadow.js
CHANGED
|
@@ -139,4 +139,3 @@ export const CLOSED_SHADOW_SELECTOR_ENGINES = [
|
|
|
139
139
|
{ name: CLOSED_SHADOW_SELECTOR_ENGINE, source: CLOSED_SHADOW_SELECTOR_ENGINE_SOURCE },
|
|
140
140
|
{ name: SEARCH_ROOTS_SELECTOR_ENGINE, source: SEARCH_ROOTS_SELECTOR_ENGINE_SOURCE },
|
|
141
141
|
];
|
|
142
|
-
//# sourceMappingURL=closed-shadow.js.map
|
package/dist/dialogs.d.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* fixture; the surface owns the router so a dialog that fires before a test
|
|
4
4
|
* ever touches `web` is still accounted for instead of silently dismissed.
|
|
5
5
|
*/
|
|
6
|
-
import type { Dialog as PwDialog } from 'playwright';
|
|
6
|
+
import type { Dialog as PwDialog } from 'playwright-core';
|
|
7
7
|
import { ErrorLatch } from './support.ts';
|
|
8
8
|
/** A native dialog as a test's handler sees it. */
|
|
9
9
|
export interface Dialog {
|
|
@@ -35,4 +35,3 @@ export declare class DialogRouter {
|
|
|
35
35
|
dispatch(dialog: PwDialog): Promise<void>;
|
|
36
36
|
private route;
|
|
37
37
|
}
|
|
38
|
-
//# sourceMappingURL=dialogs.d.ts.map
|
package/dist/dialogs.js
CHANGED
package/dist/downloads.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* that serves downloads names a directory on the browser's own disk; the
|
|
6
6
|
* browser saves there, and the provider reads each finished file back.
|
|
7
7
|
*/
|
|
8
|
-
import type { Download, Page } from 'playwright';
|
|
8
|
+
import type { Download, Page } from 'playwright-core';
|
|
9
9
|
import type { LeaseDownloads } from './provider.ts';
|
|
10
10
|
/**
|
|
11
11
|
* Has the browser behind `page` save the downloads of the page's context
|
|
@@ -26,4 +26,3 @@ export declare function saveFromBrowser(download: Download, downloads: LeaseDown
|
|
|
26
26
|
* save names it.
|
|
27
27
|
*/
|
|
28
28
|
export declare function saveLocally(download: Download, file: string, unserved: string | undefined): Promise<void>;
|
|
29
|
-
//# sourceMappingURL=downloads.d.ts.map
|
package/dist/downloads.js
CHANGED
package/dist/engine.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* package imports the contract from `e2e/engine` and contributes the `browser`
|
|
6
6
|
* fixture the way a device engine contributes `device`.
|
|
7
7
|
*/
|
|
8
|
-
import type { BrowserContext, Page } from 'playwright';
|
|
8
|
+
import type { BrowserContext, Page } from 'playwright-core';
|
|
9
9
|
import { type EngineHandle } from 'e2e/engine';
|
|
10
10
|
import { type WebOptions } from './surface.ts';
|
|
11
11
|
/**
|
|
@@ -23,4 +23,3 @@ export interface PlaywrightLiveSurface {
|
|
|
23
23
|
/** The live surface of a handle this module created, or undefined for any other engine. */
|
|
24
24
|
export declare function surfaceOf(engine: EngineHandle): PlaywrightLiveSurface | undefined;
|
|
25
25
|
export declare function web(options?: WebOptions): EngineHandle;
|
|
26
|
-
//# sourceMappingURL=engine.d.ts.map
|
package/dist/engine.js
CHANGED
|
@@ -10,6 +10,8 @@ import { createRequire } from 'node:module';
|
|
|
10
10
|
import { asBrowserProvider } from './provider.js';
|
|
11
11
|
import { PlaywrightSurface } from './surface.js';
|
|
12
12
|
import { createBrowserFixture } from './browser.js';
|
|
13
|
+
import { validateInitScripts } from './init-scripts.js';
|
|
14
|
+
import { FIELD_VALUE_CONTROL, headerProblem } from './protected-app.js';
|
|
13
15
|
/** App fields only a device target reads. */
|
|
14
16
|
const NATIVE_APP_KEYS = ['bundleId', 'appPath', 'launchArguments', 'permissions'];
|
|
15
17
|
/** Creates one Playwright engine: one browser per worker, one context per attempt. */
|
|
@@ -46,6 +48,12 @@ export function web(options = {}) {
|
|
|
46
48
|
validateTestIdAttribute(options.testIdAttribute);
|
|
47
49
|
if (options.userAgent !== undefined)
|
|
48
50
|
validateUserAgent(options.userAgent, options.headers);
|
|
51
|
+
if (options.locale !== undefined)
|
|
52
|
+
validateLocale(options.locale, options.headers);
|
|
53
|
+
if (options.timezoneId !== undefined)
|
|
54
|
+
validateTimezoneId(options.timezoneId);
|
|
55
|
+
if (options.initScripts !== undefined)
|
|
56
|
+
validateInitScripts(options.initScripts);
|
|
49
57
|
if (options.screencast !== undefined)
|
|
50
58
|
validateScreencast(options.screencast);
|
|
51
59
|
const reconnecting = options.connect?.reconnectEndpoint !== undefined;
|
|
@@ -55,8 +63,9 @@ export function web(options = {}) {
|
|
|
55
63
|
// A per-attempt lease rides the same persistent context as `reconnectEndpoint`, with the same limits.
|
|
56
64
|
const recoverable = reconnecting || provider?.scope === 'attempt';
|
|
57
65
|
const mode = provider === undefined ? 'connect.reconnectEndpoint' : `browser provider "${provider.name}" with scope "attempt"`;
|
|
58
|
-
|
|
59
|
-
|
|
66
|
+
const creationOptions = CREATION_OPTION_KEYS.filter((key) => options[key] !== undefined);
|
|
67
|
+
if (recoverable && creationOptions.length > 0) {
|
|
68
|
+
throw new ConfigurationError('INVALID_CONFIG', `${mode} uses a persistent context; ${creationOptions.join(', ')} ${creationOptions.length === 1 ? 'requires' : 'require'} a newly created context`);
|
|
60
69
|
}
|
|
61
70
|
const surface = new PlaywrightSurface(options);
|
|
62
71
|
const handle = defineEngine({
|
|
@@ -125,7 +134,12 @@ const WEB_OPTION_KEYS = Object.keys({
|
|
|
125
134
|
basicAuth: true,
|
|
126
135
|
testIdAttribute: true,
|
|
127
136
|
userAgent: true,
|
|
137
|
+
locale: true,
|
|
138
|
+
timezoneId: true,
|
|
139
|
+
initScripts: true,
|
|
128
140
|
});
|
|
141
|
+
/** The options applied when the engine creates a browser context, which a persistent context never is. */
|
|
142
|
+
const CREATION_OPTION_KEYS = ['headers', 'basicAuth', 'userAgent', 'locale', 'timezoneId'];
|
|
129
143
|
/**
|
|
130
144
|
* What a persistent context rules out, named with its cause: `what` replaces
|
|
131
145
|
* the browser context, which `mode` never does. A per-attempt lease starts
|
|
@@ -135,11 +149,6 @@ function persistentContextLimit(what, mode, leased) {
|
|
|
135
149
|
const remedy = leased ? '; every attempt already starts on a fresh browser, and scope "worker" can clear one mid-test' : '';
|
|
136
150
|
return new ConfigurationError('UNSUPPORTED_CAPABILITY', `${what} is unavailable with ${mode}: it replaces the browser context, and the attempt rides one persistent context${remedy}`);
|
|
137
151
|
}
|
|
138
|
-
/** An HTTP header field name: one or more `token` characters (RFC 9110). */
|
|
139
|
-
const HEADER_NAME = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;
|
|
140
|
-
/** A control character no HTTP field value may carry; a horizontal tab is the one the grammar allows. */
|
|
141
|
-
// oxlint-disable-next-line no-control-regex -- the control characters are the point
|
|
142
|
-
const FIELD_VALUE_CONTROL = /[\u0000-\u0008\u000A-\u001F\u007F]/;
|
|
143
152
|
/** True for a plain object; the shape both options take. Config runs as JavaScript, so the types alone are no guard. */
|
|
144
153
|
function isRecord(value) {
|
|
145
154
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
@@ -155,15 +164,9 @@ function validateHeaders(headers) {
|
|
|
155
164
|
throw new ConfigurationError('INVALID_CONFIG', 'web({ headers }) must be an object of header name to value');
|
|
156
165
|
}
|
|
157
166
|
for (const [name, value] of Object.entries(headers)) {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
if (typeof value !== 'string') {
|
|
162
|
-
throw new ConfigurationError('INVALID_CONFIG', `web({ headers }) header "${name}" must be a string, got ${typeof value}`);
|
|
163
|
-
}
|
|
164
|
-
if (FIELD_VALUE_CONTROL.test(value)) {
|
|
165
|
-
throw new ConfigurationError('INVALID_CONFIG', `web({ headers }) header "${name}" must not contain a control character`);
|
|
166
|
-
}
|
|
167
|
+
const problem = headerProblem(name, value);
|
|
168
|
+
if (problem !== undefined)
|
|
169
|
+
throw new ConfigurationError('INVALID_CONFIG', `web({ headers }) ${problem}`);
|
|
167
170
|
}
|
|
168
171
|
}
|
|
169
172
|
/** Refuses credentials the browser could not present: a missing field, or a `:` in the user name (RFC 7617). */
|
|
@@ -199,6 +202,61 @@ function validateUserAgent(userAgent, headers) {
|
|
|
199
202
|
throw new ConfigurationError('INVALID_CONFIG', 'web({ userAgent }) and a user-agent header in web({ headers }) conflict; set userAgent only');
|
|
200
203
|
}
|
|
201
204
|
}
|
|
205
|
+
/**
|
|
206
|
+
* Refuses a locale that is not a BCP 47 tag, and one an `accept-language`
|
|
207
|
+
* header would override on the app's site while `navigator.language` kept
|
|
208
|
+
* reporting it.
|
|
209
|
+
*/
|
|
210
|
+
function validateLocale(locale, headers) {
|
|
211
|
+
if (typeof locale !== 'string' || locale === '' || !isLanguageTag(locale)) {
|
|
212
|
+
throw new ConfigurationError('INVALID_CONFIG', `web({ locale }) must be a BCP 47 language tag such as "de-DE", got ${JSON.stringify(locale)}`);
|
|
213
|
+
}
|
|
214
|
+
if (headers !== undefined && Object.keys(headers).some((name) => name.toLowerCase() === 'accept-language')) {
|
|
215
|
+
throw new ConfigurationError('INVALID_CONFIG', 'web({ locale }) and an accept-language header in web({ headers }) conflict; set locale only');
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* True when `tag` names a language the browser can run in: a Unicode locale
|
|
220
|
+
* `Intl.Locale` parses, other than the undetermined `und`, which Chromium
|
|
221
|
+
* refuses at context creation as it does a private-use-only tag.
|
|
222
|
+
*/
|
|
223
|
+
function isLanguageTag(tag) {
|
|
224
|
+
try {
|
|
225
|
+
const { language } = new Intl.Locale(tag);
|
|
226
|
+
return language !== undefined && language !== 'und';
|
|
227
|
+
}
|
|
228
|
+
catch {
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Refuses, at config load, a time zone the browser would otherwise refuse at
|
|
234
|
+
* the first context. Best effort: Node cannot tell a miscased alias
|
|
235
|
+
* (`us/eastern`) from the real one, so the browser's own `Invalid timezone ID`
|
|
236
|
+
* stays the final word.
|
|
237
|
+
*/
|
|
238
|
+
function validateTimezoneId(timezoneId) {
|
|
239
|
+
if (typeof timezoneId !== 'string' || timezoneId === '' || !isTimeZone(timezoneId)) {
|
|
240
|
+
throw new ConfigurationError('INVALID_CONFIG', `web({ timezoneId }) must be an IANA time zone such as "Europe/Berlin", got ${JSON.stringify(timezoneId)}`);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* True when `timeZone` is an IANA name `Intl` resolves, spelled with its own
|
|
245
|
+
* case. Node also takes an offset (`+01:00`) and any casing (`europe/berlin`),
|
|
246
|
+
* both of which Chromium refuses; an alias resolving to another name
|
|
247
|
+
* (`US/Eastern`) is fine.
|
|
248
|
+
*/
|
|
249
|
+
function isTimeZone(timeZone) {
|
|
250
|
+
if (/^[+-]/.test(timeZone))
|
|
251
|
+
return false;
|
|
252
|
+
try {
|
|
253
|
+
const resolved = new Intl.DateTimeFormat('en-US', { timeZone }).resolvedOptions().timeZone;
|
|
254
|
+
return resolved === timeZone || resolved.toLowerCase() !== timeZone.toLowerCase();
|
|
255
|
+
}
|
|
256
|
+
catch {
|
|
257
|
+
return false;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
202
260
|
/**
|
|
203
261
|
* An attribute name the document grammar accepts (XML `Name`, ASCII): a value
|
|
204
262
|
* outside it could never be on an element, so `getByTestId` would match nothing
|
|
@@ -268,4 +326,3 @@ function ownVersion() {
|
|
|
268
326
|
return 'unknown';
|
|
269
327
|
}
|
|
270
328
|
}
|
|
271
|
-
//# sourceMappingURL=engine.js.map
|
package/dist/evaluation.d.ts
CHANGED
|
@@ -5,6 +5,8 @@ type EvaluationResult = {
|
|
|
5
5
|
ok: false;
|
|
6
6
|
message: string;
|
|
7
7
|
};
|
|
8
|
+
/** The `__name` helper tsx's `keepNames` output calls, declared beside test code serialized into the page. */
|
|
9
|
+
export declare const KEEP_NAMES_HELPER = "const __name = (target, value) => Object.defineProperty(target, 'name', { value, configurable: true });";
|
|
8
10
|
/**
|
|
9
11
|
* Compiles the page-side error boundary without evaluating the caller's source in this process.
|
|
10
12
|
*
|
|
@@ -15,4 +17,3 @@ type EvaluationResult = {
|
|
|
15
17
|
*/
|
|
16
18
|
export declare function compileEvaluation(source: string, hasArgument: boolean): (arg: unknown) => Promise<EvaluationResult>;
|
|
17
19
|
export {};
|
|
18
|
-
//# sourceMappingURL=evaluation.d.ts.map
|
package/dist/evaluation.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/** Separates exceptions thrown by trusted page code from failures of the evaluation transport. */
|
|
2
2
|
import { TestError } from 'e2e/engine';
|
|
3
3
|
import { message } from './support.js';
|
|
4
|
+
/** The `__name` helper tsx's `keepNames` output calls, declared beside test code serialized into the page. */
|
|
5
|
+
export const KEEP_NAMES_HELPER = "const __name = (target, value) => Object.defineProperty(target, 'name', { value, configurable: true });";
|
|
4
6
|
/**
|
|
5
7
|
* Compiles the page-side error boundary without evaluating the caller's source in this process.
|
|
6
8
|
*
|
|
@@ -13,7 +15,7 @@ export function compileEvaluation(source, hasArgument) {
|
|
|
13
15
|
try {
|
|
14
16
|
return new Function('arg', `
|
|
15
17
|
return (async () => {
|
|
16
|
-
|
|
18
|
+
${KEEP_NAMES_HELPER}
|
|
17
19
|
try {
|
|
18
20
|
return { ok: true, value: await (${source}\n)(${hasArgument ? 'arg' : ''}) };
|
|
19
21
|
} catch (cause) {
|
|
@@ -32,4 +34,3 @@ export function compileEvaluation(source, hasArgument) {
|
|
|
32
34
|
throw new TestError('EVALUATE_FAILED', message(cause), { cause });
|
|
33
35
|
}
|
|
34
36
|
}
|
|
35
|
-
//# sourceMappingURL=evaluation.js.map
|
|
@@ -10,11 +10,10 @@ import type { SemanticMode, SemanticResult } from '../read-node.ts';
|
|
|
10
10
|
* Serialized into the page by Playwright. Must stay self-contained: no outer
|
|
11
11
|
* captures beyond its two arguments.
|
|
12
12
|
*
|
|
13
|
-
* `mode.kind === 'node'` reads exactly one element for locator reads
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* nothing on screen.
|
|
13
|
+
* `mode.kind === 'node'` reads exactly one element for locator reads, in
|
|
14
|
+
* the selector engine's task that found it (`read-selector.ts`,
|
|
15
|
+
* `label-selector.ts`), so the element is always in its document.
|
|
16
|
+
* `mode.kind === 'hidden'` answers that one element's `states.hidden` alone.
|
|
18
17
|
* `mode.kind === 'tree'` walks the subtree for one agent observation and
|
|
19
18
|
* returns live element handles aligned with the flattened node list. The two
|
|
20
19
|
* modes also project nodes differently; those differences are data (see
|
|
@@ -25,4 +24,3 @@ export declare const readSemanticsFunction: <Mode extends SemanticMode>(element:
|
|
|
25
24
|
secureFieldSelector: string;
|
|
26
25
|
mode: Mode;
|
|
27
26
|
}) => SemanticResult<Mode>;
|
|
28
|
-
//# sourceMappingURL=read-semantics.d.ts.map
|