@molecule/app-e2e-fixtures-default 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28556 -0
- package/dist/console-guard.d.ts +39 -0
- package/dist/console-guard.d.ts.map +1 -0
- package/dist/console-guard.js +117 -0
- package/dist/console-guard.js.map +1 -0
- package/dist/expect.d.ts +18 -0
- package/dist/expect.d.ts.map +1 -0
- package/dist/expect.js +233 -0
- package/dist/expect.js.map +1 -0
- package/dist/index.d.ts +99 -52
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +100 -140
- package/dist/index.js.map +1 -0
- package/dist/page.d.ts +370 -0
- package/dist/page.d.ts.map +1 -0
- package/dist/page.js +1052 -0
- package/dist/page.js.map +1 -0
- package/dist/playwright.d.ts +10 -0
- package/dist/playwright.d.ts.map +1 -0
- package/dist/playwright.js +9 -0
- package/dist/playwright.js.map +1 -0
- package/dist/runtime.d.ts +94 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +1501 -0
- package/dist/runtime.js.map +1 -0
- package/dist/test.d.ts +23 -0
- package/dist/test.d.ts.map +1 -0
- package/dist/test.js +69 -0
- package/dist/test.js.map +1 -0
- package/package.json +9 -3
package/dist/index.js
CHANGED
|
@@ -1,154 +1,114 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* The `@playwright/test` drop-in for molecule apps: Playwright's `test`,
|
|
3
|
+
* `expect` and `page`, with the browser supplied by the bonded e2e provider
|
|
4
|
+
* and a console-error guard on every test.
|
|
4
5
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* `@
|
|
8
|
-
* `consoleGuard` fixture with `{ auto: true }`, so every test
|
|
9
|
-
* automatically subscribes to the browser's `pageerror` event and
|
|
10
|
-
* `console.error` messages, then asserts the buffer is empty at test
|
|
11
|
-
* teardown.
|
|
6
|
+
* Import `test` and `expect` from here instead of `@playwright/test` and
|
|
7
|
+
* write ordinary Playwright specs. Which browser runs them is the e2e bond
|
|
8
|
+
* (`@molecule/app-e2e`):
|
|
12
9
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
10
|
+
* - **`@molecule/app-e2e-preview`** drives the LIVE PREVIEW the molecule.dev
|
|
11
|
+
* IDE is already showing — the page the person is looking at, in their own
|
|
12
|
+
* browser — over a WebSocket through the dev server. No browser binary in
|
|
13
|
+
* the sandbox, nothing to download. This is what a molecule sandbox uses.
|
|
14
|
+
* - **`@molecule/app-e2e-playwright`** launches real Playwright browsers. This
|
|
15
|
+
* is what your own machine and CI use.
|
|
19
16
|
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* error text with `[`/`(` can be pasted verbatim). An annotation with
|
|
27
|
-
* no description allows every error — always provide one.
|
|
17
|
+
* The same spec file runs unchanged in both. The provider is picked by
|
|
18
|
+
* `resolveE2EProviderName()`: `MOL_E2E_PROVIDER` when set, otherwise `preview`
|
|
19
|
+
* inside a molecule sandbox (the `/etc/mol/app-root` marker exists) and
|
|
20
|
+
* `playwright` everywhere else. The scaffolded `e2e/bonds.ts` bonds the
|
|
21
|
+
* matching provider (and `test` bonds it by name as a fallback); `test` reads
|
|
22
|
+
* the same answer to decide whether to launch a browser.
|
|
28
23
|
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
* against the actual Chrome message text and constrained to `https://` so it
|
|
35
|
-
* can never silence a genuinely broken source map in the app's OWN bundle
|
|
36
|
-
* (served over plain `http://localhost` in dev/preview).
|
|
24
|
+
* Every test also carries the console-error guard: the page's `pageerror`
|
|
25
|
+
* and `console.error` events fail the test at teardown, so a spec that only
|
|
26
|
+
* asserts on `page.request` cannot stay green while the rendered page is
|
|
27
|
+
* blank. Allow a known error with
|
|
28
|
+
* `test.info().annotations.push({ type: 'allow-console-error', description: '<regex>' })`.
|
|
37
29
|
*
|
|
38
30
|
* @example
|
|
39
31
|
* ```ts
|
|
40
|
-
* //
|
|
41
|
-
* import {
|
|
32
|
+
* // e2e/bonds.ts — scaffolded; wires the provider for THIS environment
|
|
33
|
+
* import { resolveE2EProviderName, setProvider } from '@molecule/app-e2e'
|
|
34
|
+
* import { provider as playwright } from '@molecule/app-e2e-playwright'
|
|
35
|
+
* import { provider as preview } from '@molecule/app-e2e-preview'
|
|
42
36
|
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
37
|
+
* setProvider(resolveE2EProviderName() === 'preview' ? preview : playwright)
|
|
38
|
+
*
|
|
39
|
+
* // e2e/post.spec.ts — an ordinary Playwright spec
|
|
40
|
+
* import { expect, test } from '@molecule/app-e2e-fixtures-default'
|
|
41
|
+
*
|
|
42
|
+
* import './bonds.js'
|
|
43
|
+
*
|
|
44
|
+
* test('the phone layout keeps the prose large', async ({ page }) => {
|
|
45
|
+
* await page.setViewportSize({ width: 390, height: 844 })
|
|
46
|
+
* await page.goto('/blog/hello/')
|
|
47
|
+
* const prose = page.locator('article p').first()
|
|
48
|
+
* const size = await prose.evaluate((el) => parseFloat(getComputedStyle(el).fontSize))
|
|
49
|
+
* expect(size).toBeGreaterThanOrEqual(18)
|
|
50
|
+
* await expect(page.getByRole('switch', { name: /summar/i })).toBeVisible()
|
|
47
51
|
* })
|
|
48
52
|
* ```
|
|
49
53
|
*
|
|
54
|
+
* @remarks
|
|
55
|
+
* - **What works over the preview** (the `@molecule/app-e2e-preview` bond):
|
|
56
|
+
* `page.goto/reload/goBack/goForward/url/title/content`,
|
|
57
|
+
* `page.evaluate/$eval/$$eval`, `page.locator` and every `getBy*` (role
|
|
58
|
+
* with name/level/checked/pressed/expanded/selected, text, label,
|
|
59
|
+
* placeholder, title, alt text, test id), `first/last/nth/filter/count/all`,
|
|
60
|
+
* `click/dblclick/hover/tap/fill/clear/type/press/check/uncheck/setChecked/
|
|
61
|
+
* selectOption/focus/blur/dispatchEvent/scrollIntoViewIfNeeded`,
|
|
62
|
+
* `textContent/innerText/innerHTML/inputValue/getAttribute/isVisible/isHidden/
|
|
63
|
+
* isEnabled/isDisabled/isEditable/isChecked/boundingBox/evaluate/evaluateAll/
|
|
64
|
+
* waitFor`, `page.setViewportSize/viewportSize`, `page.mouse.*`,
|
|
65
|
+
* `page.keyboard.*`, `page.request.get/post/put/patch/delete/fetch` (runs
|
|
66
|
+
* `fetch` inside the page, cookies included), `waitForSelector/waitForURL/
|
|
67
|
+
* waitForFunction/waitForLoadState/waitForTimeout`, `page.on('console' |
|
|
68
|
+
* 'pageerror' | 'dialog' | 'close')`, and `expect(locator)` with
|
|
69
|
+
* `toBeVisible/toBeHidden/toBeAttached/toHaveCount/toHaveText/toContainText/
|
|
70
|
+
* toHaveAttribute/toHaveClass/toContainClass/toHaveCSS/toHaveValue/toHaveId/
|
|
71
|
+
* toBeChecked/toBeEnabled/toBeDisabled/toBeEditable/toBeEmpty/toBeFocused/
|
|
72
|
+
* toBeInViewport/toHaveAccessibleName/toHaveRole` (+ `.not`, `expect.soft`,
|
|
73
|
+
* `expect.configure`), `expect(page).toHaveTitle/toHaveURL`.
|
|
74
|
+
* - **The escape hatch is `page.evaluate()`.** Anything the list above does
|
|
75
|
+
* not cover — a computed style, a scroll position, `matchMedia`, a
|
|
76
|
+
* `fetch` — is one `evaluate` away; the function runs inside the real page
|
|
77
|
+
* and returns JSON.
|
|
78
|
+
* - **Not available over the preview**, and the method THROWS naming the
|
|
79
|
+
* alternative: screenshots and `toHaveScreenshot` (assert layout with
|
|
80
|
+
* `boundingBox()` and computed styles instead), `page.route/waitForResponse/
|
|
81
|
+
* waitForRequest` (read the response with `page.request` or `fetch` in
|
|
82
|
+
* `evaluate`), element handles (`$`, `$$`, `elementHandle` — use locators),
|
|
83
|
+
* `setInputFiles`, `dragTo`, iframes inside the preview, `emulateMedia`,
|
|
84
|
+
* `addInitScript/exposeFunction`, `context.cookies/storageState` (read
|
|
85
|
+
* `document.cookie`/`localStorage` in `evaluate`). The playwright bond
|
|
86
|
+
* supports all of them.
|
|
87
|
+
* - **Viewport.** `page.setViewportSize` asks the IDE to resize the preview
|
|
88
|
+
* frame and throws if the host did not (a preview opened in a plain tab
|
|
89
|
+
* keeps the tab's width). Test phone layouts at 390×844 this way.
|
|
90
|
+
* - **Events.** `page.on('response')`/`'request'` never fire over the preview
|
|
91
|
+
* (a one-time warning says so); `'console'` and `'pageerror'` do, so the
|
|
92
|
+
* console-error guard works there too.
|
|
93
|
+
* - **The person's browser is the renderer.** If every tab showing the
|
|
94
|
+
* preview is closed or asleep, actions wait for a page to reconnect and
|
|
95
|
+
* then time out with a message saying so. Keep the IDE tab open (the IDE
|
|
96
|
+
* holds a screen wake lock while a build runs) or open the preview URL in
|
|
97
|
+
* any other tab — any connected viewer will do.
|
|
98
|
+
* - `createEvaluatePage()` is how a bond that can only run code inside a page
|
|
99
|
+
* (an `E2ETransport`) gets the whole Playwright-shaped page; the preview
|
|
100
|
+
* bond uses it, and so can any future one.
|
|
101
|
+
* - `@playwright/test` is a peer dependency: it supplies the runner
|
|
102
|
+
* (`npx playwright test`), `expect` for plain values, and the `Page` types.
|
|
103
|
+
* It never downloads browsers on install; only the playwright bond needs
|
|
104
|
+
* `npx playwright install`.
|
|
105
|
+
*
|
|
50
106
|
* @module
|
|
51
107
|
*/
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
// Service worker registration failures in headless Chrome — VitePWA
|
|
60
|
-
// tries to register at /sw.js but our smoke build emits to /workbox-*
|
|
61
|
-
// and Playwright fixtures the user-agent. Cosmetic.
|
|
62
|
-
/service worker.*404/i,
|
|
63
|
-
// Chrome DevTools' own probe for source maps on third-party CDN bundles
|
|
64
|
-
// we don't ship maps for (Stripe, Google Maps, etc). Two bugs fixed here,
|
|
65
|
-
// both verified against a headless Chromium probe + the real reported
|
|
66
|
-
// message text (not guessed): (1) the verb was wrong — real Chrome output
|
|
67
|
-
// is "DevTools failed to load SourceMap: Could not load content for
|
|
68
|
-
// <url>: ...", not "failed to fetch source map", so the old pattern never
|
|
69
|
-
// matched real Chrome text at all; (2) the host check (`.cdn.`) doesn't
|
|
70
|
-
// match real vendor hosts (js.stripe.com, maps.googleapis.com contain no
|
|
71
|
-
// '.cdn.' substring). Now matches any `https://`-hosted source map
|
|
72
|
-
// (third-party CDN bundles are always TLS; the app's own dev/preview
|
|
73
|
-
// server is plain `http://localhost`, so same-origin source-map issues
|
|
74
|
-
// are never accidentally silenced by this pattern).
|
|
75
|
-
// NOTE (verified, not assumed): a probe with a broken `sourceMappingURL`
|
|
76
|
-
// produced ZERO console messages via `page.on('console')` under plain
|
|
77
|
-
// Playwright automation (with and without tracing) — Chrome only fetches
|
|
78
|
-
// source maps when a DevTools Sources panel is actually attached, which a
|
|
79
|
-
// headless Playwright run never does. So this entry currently matches
|
|
80
|
-
// nothing observed in practice; it is defense-in-depth against a future
|
|
81
|
-
// Chrome/Playwright behavior change, not an active filter today.
|
|
82
|
-
/devtools failed to load source ?map.*https:\/\//i,
|
|
83
|
-
];
|
|
84
|
-
/**
|
|
85
|
-
* Custom Playwright `test` with an auto-attached browser console-error
|
|
86
|
-
* guard. Drop-in replacement for `import { test } from '@playwright/test'`.
|
|
87
|
-
*/
|
|
88
|
-
export const test = base.extend({
|
|
89
|
-
consoleGuard: [
|
|
90
|
-
async ({ page }, use, testInfo) => {
|
|
91
|
-
const buffer = [];
|
|
92
|
-
// Each allow-console-error description is tried as a regex; an invalid
|
|
93
|
-
// pattern (e.g. verbatim error text containing `[` or `(`) falls back to
|
|
94
|
-
// plain substring matching instead of throwing from inside the guard.
|
|
95
|
-
const matchesAllowed = (text, description) => {
|
|
96
|
-
if (description === undefined)
|
|
97
|
-
return true; // no description = allow everything
|
|
98
|
-
try {
|
|
99
|
-
return new RegExp(description).test(text);
|
|
100
|
-
}
|
|
101
|
-
catch (_error) {
|
|
102
|
-
// Invalid regex — treat the description as a literal substring.
|
|
103
|
-
return text.includes(description);
|
|
104
|
-
}
|
|
105
|
-
};
|
|
106
|
-
const shouldIgnore = (text) => {
|
|
107
|
-
if (ALWAYS_IGNORE.some((re) => re.test(text)))
|
|
108
|
-
return true;
|
|
109
|
-
return testInfo.annotations
|
|
110
|
-
.filter((a) => a.type === 'allow-console-error')
|
|
111
|
-
.some((a) => matchesAllowed(text, a.description));
|
|
112
|
-
};
|
|
113
|
-
const onPageError = (err) => {
|
|
114
|
-
const text = err.message || String(err);
|
|
115
|
-
if (shouldIgnore(text))
|
|
116
|
-
return;
|
|
117
|
-
buffer.push({ type: 'pageerror', text });
|
|
118
|
-
};
|
|
119
|
-
const onConsole = (msg) => {
|
|
120
|
-
if (msg.type() !== 'error')
|
|
121
|
-
return;
|
|
122
|
-
const text = msg.text();
|
|
123
|
-
if (shouldIgnore(text))
|
|
124
|
-
return;
|
|
125
|
-
const loc = msg.location();
|
|
126
|
-
buffer.push({
|
|
127
|
-
type: 'console.error',
|
|
128
|
-
text,
|
|
129
|
-
location: loc?.url ? `${loc.url}:${loc.lineNumber}` : undefined,
|
|
130
|
-
});
|
|
131
|
-
};
|
|
132
|
-
page.on('pageerror', onPageError);
|
|
133
|
-
page.on('console', onConsole);
|
|
134
|
-
try {
|
|
135
|
-
await use();
|
|
136
|
-
}
|
|
137
|
-
finally {
|
|
138
|
-
page.off('pageerror', onPageError);
|
|
139
|
-
page.off('console', onConsole);
|
|
140
|
-
}
|
|
141
|
-
if (buffer.length > 0) {
|
|
142
|
-
const lines = buffer
|
|
143
|
-
.map((e) => ` - [${e.type}] ${e.text}${e.location ? ` (${e.location})` : ''}`)
|
|
144
|
-
.join('\n');
|
|
145
|
-
throw new Error(`Browser console error(s) during test (${buffer.length}):\n${lines}\n\n` +
|
|
146
|
-
`If this error is genuinely expected, add\n` +
|
|
147
|
-
` test.info().annotations.push({ type: 'allow-console-error', description: '<regex>' })\n` +
|
|
148
|
-
`to the test body BEFORE the error fires.`);
|
|
149
|
-
}
|
|
150
|
-
},
|
|
151
|
-
{ auto: true },
|
|
152
|
-
],
|
|
153
|
-
});
|
|
154
|
-
export { expect };
|
|
108
|
+
export * from './console-guard.js';
|
|
109
|
+
export * from './expect.js';
|
|
110
|
+
export * from './page.js';
|
|
111
|
+
export * from './playwright.js';
|
|
112
|
+
export * from './runtime.js';
|
|
113
|
+
export * from './test.js';
|
|
114
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0GG;AAEH,cAAc,oBAAoB,CAAA;AAClC,cAAc,aAAa,CAAA;AAC3B,cAAc,WAAW,CAAA;AACzB,cAAc,iBAAiB,CAAA;AAC/B,cAAc,cAAc,CAAA;AAC5B,cAAc,WAAW,CAAA"}
|
package/dist/page.d.ts
ADDED
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A Playwright-shaped `Page` built on an {@link E2ETransport} — the driver
|
|
3
|
+
* half of the runtime in `runtime.ts`. Bonds that can only run code inside a
|
|
4
|
+
* page (the live preview) get the whole documented subset from this file.
|
|
5
|
+
*
|
|
6
|
+
* @module
|
|
7
|
+
*/
|
|
8
|
+
import type { BrowserContext, Frame, Page } from '@playwright/test';
|
|
9
|
+
import type { E2EPageOptions, E2ETransport, E2EViewport } from '@molecule/app-e2e';
|
|
10
|
+
import { type LocatorStep, type TextMatch } from './runtime.js';
|
|
11
|
+
/** Brand on locators created here (the `expect` wrapper routes on it). */
|
|
12
|
+
export declare const E2E_LOCATOR: unique symbol;
|
|
13
|
+
/** Brand on pages created here. */
|
|
14
|
+
export declare const E2E_PAGE: unique symbol;
|
|
15
|
+
type Dict = Record<string, unknown>;
|
|
16
|
+
type Listener = (payload: unknown) => void;
|
|
17
|
+
declare const toMatch: (value: string | RegExp, opts?: {
|
|
18
|
+
exact?: boolean;
|
|
19
|
+
ignoreCase?: boolean;
|
|
20
|
+
}) => TextMatch;
|
|
21
|
+
/** Full-text match (expect's toHaveText): a string must equal the whole text; a RegExp tests it. */
|
|
22
|
+
declare const toFull: (value: string | RegExp, opts?: {
|
|
23
|
+
ignoreCase?: boolean;
|
|
24
|
+
}) => TextMatch;
|
|
25
|
+
/** A Playwright-shaped Locator: a lazy chain of steps resolved inside the page on every action. */
|
|
26
|
+
declare class LocatorImpl {
|
|
27
|
+
private readonly owner;
|
|
28
|
+
readonly steps: LocatorStep[];
|
|
29
|
+
readonly [E2E_LOCATOR] = true;
|
|
30
|
+
constructor(owner: PageImpl, steps: LocatorStep[]);
|
|
31
|
+
/** A new locator with more steps (locators are immutable). */
|
|
32
|
+
private extend;
|
|
33
|
+
/** Steps for a selector string (parsed in the page) or another locator. */
|
|
34
|
+
private stepsOf;
|
|
35
|
+
/** The filter steps a `filter()` / `locator()` options object adds. */
|
|
36
|
+
private filterStep;
|
|
37
|
+
/** Playwright's `locator()`: narrow to descendants matching a selector, with optional `hasText` / `has` filters. */
|
|
38
|
+
locator(sel: string | LocatorImpl, opts?: {
|
|
39
|
+
hasText?: string | RegExp;
|
|
40
|
+
hasNotText?: string | RegExp;
|
|
41
|
+
has?: LocatorImpl;
|
|
42
|
+
hasNot?: LocatorImpl;
|
|
43
|
+
}): LocatorImpl;
|
|
44
|
+
/** Playwright's `getByRole()`: by ARIA role, with accessible-name, heading-level and state options. */
|
|
45
|
+
getByRole(role: string, opts?: Dict): LocatorImpl;
|
|
46
|
+
/** Playwright's `getByText()`: the smallest elements whose text matches. */
|
|
47
|
+
getByText(text: string | RegExp, opts?: {
|
|
48
|
+
exact?: boolean;
|
|
49
|
+
}): LocatorImpl;
|
|
50
|
+
/** Playwright's `getByLabel()`: form controls by their label text (also `aria-label`). */
|
|
51
|
+
getByLabel(text: string | RegExp, opts?: {
|
|
52
|
+
exact?: boolean;
|
|
53
|
+
}): LocatorImpl;
|
|
54
|
+
/** Playwright's `getByPlaceholder()`. */
|
|
55
|
+
getByPlaceholder(text: string | RegExp, opts?: {
|
|
56
|
+
exact?: boolean;
|
|
57
|
+
}): LocatorImpl;
|
|
58
|
+
/** Playwright's `getByTitle()`. */
|
|
59
|
+
getByTitle(text: string | RegExp, opts?: {
|
|
60
|
+
exact?: boolean;
|
|
61
|
+
}): LocatorImpl;
|
|
62
|
+
/** Playwright's `getByAltText()`. */
|
|
63
|
+
getByAltText(text: string | RegExp, opts?: {
|
|
64
|
+
exact?: boolean;
|
|
65
|
+
}): LocatorImpl;
|
|
66
|
+
/** Playwright's `getByTestId()` on the configured test-id attribute (default `data-testid`). */
|
|
67
|
+
getByTestId(id: string | RegExp): LocatorImpl;
|
|
68
|
+
/** Playwright's `locator.filter()`: keep matches by text, by a descendant locator, or by visibility. */
|
|
69
|
+
filter(opts?: {
|
|
70
|
+
hasText?: string | RegExp;
|
|
71
|
+
hasNotText?: string | RegExp;
|
|
72
|
+
has?: LocatorImpl;
|
|
73
|
+
hasNot?: LocatorImpl;
|
|
74
|
+
visible?: boolean;
|
|
75
|
+
}): LocatorImpl;
|
|
76
|
+
/** The first match. */
|
|
77
|
+
first(): LocatorImpl;
|
|
78
|
+
/** The last match. */
|
|
79
|
+
last(): LocatorImpl;
|
|
80
|
+
/** The i-th match (a negative index counts from the end). */
|
|
81
|
+
nth(i: number): LocatorImpl;
|
|
82
|
+
/** The page this belongs to (null for a console message over the preview). */
|
|
83
|
+
page(): Page;
|
|
84
|
+
/** The locator chain, Playwright-style, for error messages. */
|
|
85
|
+
toString(): string;
|
|
86
|
+
/** The locator chain as text. */
|
|
87
|
+
describe(): string;
|
|
88
|
+
/** Run one runtime call for this locator. */
|
|
89
|
+
private call;
|
|
90
|
+
/** Turn a runtime reply into a value, throwing strict-mode, timeout or plain errors. */
|
|
91
|
+
private unwrap;
|
|
92
|
+
/** Run a single-target action with auto-wait and actionability checks. */
|
|
93
|
+
private act;
|
|
94
|
+
/** Read one value from the single strict target. */
|
|
95
|
+
private read;
|
|
96
|
+
/** Playwright's `click()`: waits until the element is visible, enabled and not covered, then clicks its centre (or `position`). */
|
|
97
|
+
click(opts?: Dict): Promise<void>;
|
|
98
|
+
/** Playwright's `dblclick()`. */
|
|
99
|
+
dblclick(opts?: Dict): Promise<void>;
|
|
100
|
+
/** Playwright's `hover()`: moves the pointer over the element. */
|
|
101
|
+
hover(opts?: Dict): Promise<void>;
|
|
102
|
+
/** Playwright's `tap()`: touch events followed by a click. */
|
|
103
|
+
tap(opts?: Dict): Promise<void>;
|
|
104
|
+
/** Playwright's `fill()`: focuses, replaces the value through the native setter and fires `input` / `change`. */
|
|
105
|
+
fill(value: string, opts?: Dict): Promise<void>;
|
|
106
|
+
/** Playwright's `clear()`: fills with an empty string. */
|
|
107
|
+
clear(opts?: Dict): Promise<void>;
|
|
108
|
+
/** Playwright's `type()`: presses each character in turn (or, on a console message, its level). */
|
|
109
|
+
type(text: string, opts?: Dict): Promise<void>;
|
|
110
|
+
/** Playwright's `pressSequentially()`: presses each character in turn. */
|
|
111
|
+
pressSequentially(text: string, opts?: Dict): Promise<void>;
|
|
112
|
+
/** Playwright's `press()`: a key or chord (`Enter`, `Control+a`); Enter submits a form. */
|
|
113
|
+
press(key: string, opts?: Dict): Promise<void>;
|
|
114
|
+
/** Playwright's `check()`: clicks until checked (or, on the page, throws on a failed runtime reply). */
|
|
115
|
+
check(opts?: Dict): Promise<void>;
|
|
116
|
+
/** Playwright's `uncheck()`: clicks until unchecked. */
|
|
117
|
+
uncheck(opts?: Dict): Promise<void>;
|
|
118
|
+
/** Playwright's `setChecked()`. */
|
|
119
|
+
setChecked(checked: boolean, opts?: Dict): Promise<void>;
|
|
120
|
+
/** Playwright's `selectOption()`: by value, label or index; returns the selected values. */
|
|
121
|
+
selectOption(values: unknown, opts?: Dict): Promise<string[]>;
|
|
122
|
+
/** Playwright's `focus()`. */
|
|
123
|
+
focus(opts?: Dict): Promise<void>;
|
|
124
|
+
/** Playwright's `blur()`. */
|
|
125
|
+
blur(opts?: Dict): Promise<void>;
|
|
126
|
+
/** Playwright's `dispatchEvent()`: a synthetic event of the given type. */
|
|
127
|
+
dispatchEvent(type: string, init?: Dict, opts?: Dict): Promise<void>;
|
|
128
|
+
/** Playwright's `scrollIntoViewIfNeeded()`. */
|
|
129
|
+
scrollIntoViewIfNeeded(opts?: Dict): Promise<void>;
|
|
130
|
+
/** No-op over the preview: nothing to paint. */
|
|
131
|
+
highlight(): Promise<void>;
|
|
132
|
+
/** Playwright's `count()`: how many elements match right now. */
|
|
133
|
+
count(): Promise<number>;
|
|
134
|
+
/** Playwright's `all()`: one locator per current match. */
|
|
135
|
+
all(): Promise<LocatorImpl[]>;
|
|
136
|
+
/** Playwright's `allTextContents()`. */
|
|
137
|
+
allTextContents(): Promise<string[]>;
|
|
138
|
+
/** Playwright's `allInnerTexts()`. */
|
|
139
|
+
allInnerTexts(): Promise<string[]>;
|
|
140
|
+
/** Playwright's `textContent()` (strict: exactly one match). */
|
|
141
|
+
textContent(opts?: Dict): Promise<string | null>;
|
|
142
|
+
/** Playwright's `innerText()`. */
|
|
143
|
+
innerText(opts?: Dict): Promise<string>;
|
|
144
|
+
/** Playwright's `innerHTML()`. */
|
|
145
|
+
innerHTML(opts?: Dict): Promise<string>;
|
|
146
|
+
/** Playwright's `inputValue()` for inputs, textareas and selects. */
|
|
147
|
+
inputValue(opts?: Dict): Promise<string>;
|
|
148
|
+
/** Playwright's `getAttribute()`. */
|
|
149
|
+
getAttribute(name: string, opts?: Dict): Promise<string | null>;
|
|
150
|
+
/** Playwright's `isVisible()`: false when nothing matches; no waiting. */
|
|
151
|
+
isVisible(): Promise<boolean>;
|
|
152
|
+
/** Playwright's `isHidden()`: true when nothing matches; no waiting. */
|
|
153
|
+
isHidden(): Promise<boolean>;
|
|
154
|
+
/** Playwright's `isEnabled()`. */
|
|
155
|
+
isEnabled(opts?: Dict): Promise<boolean>;
|
|
156
|
+
/** Playwright's `isDisabled()`. */
|
|
157
|
+
isDisabled(opts?: Dict): Promise<boolean>;
|
|
158
|
+
/** Playwright's `isEditable()`. */
|
|
159
|
+
isEditable(opts?: Dict): Promise<boolean>;
|
|
160
|
+
/** Playwright's `isChecked()` for checkboxes, radios and switches. */
|
|
161
|
+
isChecked(opts?: Dict): Promise<boolean>;
|
|
162
|
+
/** Playwright's `boundingBox()`: the element's rect, or null when it is not visible. */
|
|
163
|
+
boundingBox(opts?: Dict): Promise<{
|
|
164
|
+
x: number;
|
|
165
|
+
y: number;
|
|
166
|
+
width: number;
|
|
167
|
+
height: number;
|
|
168
|
+
} | null>;
|
|
169
|
+
/** Playwright's `evaluate()`: runs the function inside the page and returns JSON. */
|
|
170
|
+
evaluate(fn: unknown, arg?: unknown, opts?: Dict): Promise<unknown>;
|
|
171
|
+
/** Playwright's `locator.evaluateAll()`: runs `fn(elements, arg)` inside the page. */
|
|
172
|
+
evaluateAll(fn: unknown, arg?: unknown): Promise<unknown>;
|
|
173
|
+
/** Playwright's `waitFor()`: until attached, detached, visible or hidden. */
|
|
174
|
+
waitFor(opts?: {
|
|
175
|
+
state?: 'attached' | 'detached' | 'visible' | 'hidden';
|
|
176
|
+
timeout?: number;
|
|
177
|
+
}): Promise<void>;
|
|
178
|
+
/** One probe for the expect matchers; the wrapper polls it. */
|
|
179
|
+
probe(matcher: string, args: Dict): Promise<Dict>;
|
|
180
|
+
}
|
|
181
|
+
interface DialogImpl {
|
|
182
|
+
type(): string;
|
|
183
|
+
message(): string;
|
|
184
|
+
defaultValue(): string;
|
|
185
|
+
accept(text?: string): Promise<void>;
|
|
186
|
+
dismiss(): Promise<void>;
|
|
187
|
+
}
|
|
188
|
+
/** A Playwright-shaped Page over an `E2ETransport`; `createEvaluatePage` wraps it in a Proxy. */
|
|
189
|
+
declare class PageImpl {
|
|
190
|
+
private readonly transport;
|
|
191
|
+
private readonly options;
|
|
192
|
+
readonly [E2E_PAGE] = true;
|
|
193
|
+
defaultTimeout: number;
|
|
194
|
+
navigationTimeout: number;
|
|
195
|
+
readonly testIdAttribute: string;
|
|
196
|
+
private viewport;
|
|
197
|
+
private closed;
|
|
198
|
+
private proxy;
|
|
199
|
+
private readonly listeners;
|
|
200
|
+
private readonly warned;
|
|
201
|
+
private readonly unsubscribe;
|
|
202
|
+
readonly mouse: Dict;
|
|
203
|
+
readonly keyboard: Dict;
|
|
204
|
+
readonly touchscreen: Dict;
|
|
205
|
+
readonly request: Dict;
|
|
206
|
+
constructor(transport: E2ETransport, options: E2EPageOptions);
|
|
207
|
+
/** The bond's name, for error messages. */
|
|
208
|
+
get bondName(): string;
|
|
209
|
+
/** The branded Page proxy. */
|
|
210
|
+
asPage(): Page;
|
|
211
|
+
/** Called once by `createEvaluatePage` with the proxy that wraps this instance. */
|
|
212
|
+
attachProxy(proxy: Page): void;
|
|
213
|
+
/** Fire the listeners of one event. */
|
|
214
|
+
private emit;
|
|
215
|
+
/** Playwright's `check()`: clicks until checked (or, on the page, throws on a failed runtime reply). */
|
|
216
|
+
private check;
|
|
217
|
+
/** Run a runtime call inside the page, installing the runtime on a fresh document. */
|
|
218
|
+
rt(fn: string, args: unknown[], timeout?: number): Promise<Dict>;
|
|
219
|
+
/** Resolve a spec URL against `baseURL` when it is relative. */
|
|
220
|
+
private resolveUrl;
|
|
221
|
+
/** Playwright's `page.goto()`: navigate and wait for the new document to load. */
|
|
222
|
+
goto(url: string, opts?: {
|
|
223
|
+
timeout?: number;
|
|
224
|
+
}): Promise<null>;
|
|
225
|
+
/** Playwright's `page.reload()`. */
|
|
226
|
+
reload(opts?: {
|
|
227
|
+
timeout?: number;
|
|
228
|
+
}): Promise<null>;
|
|
229
|
+
/** Playwright's `page.goBack()`. */
|
|
230
|
+
goBack(opts?: {
|
|
231
|
+
timeout?: number;
|
|
232
|
+
}): Promise<null>;
|
|
233
|
+
/** Playwright's `page.goForward()`. */
|
|
234
|
+
goForward(opts?: {
|
|
235
|
+
timeout?: number;
|
|
236
|
+
}): Promise<null>;
|
|
237
|
+
/** Playwright's `url()`: the last known URL (or, on a response, its final URL). */
|
|
238
|
+
url(): string;
|
|
239
|
+
/** Playwright's `page.title()`. */
|
|
240
|
+
title(): Promise<string>;
|
|
241
|
+
/** Playwright's `page.content()`: the document's HTML. */
|
|
242
|
+
content(): Promise<string>;
|
|
243
|
+
/** Playwright's `waitForLoadState()`: until the document is complete (plus a quiet moment for `networkidle`). */
|
|
244
|
+
waitForLoadState(state?: string, opts?: {
|
|
245
|
+
timeout?: number;
|
|
246
|
+
}): Promise<void>;
|
|
247
|
+
/** Playwright's `waitForURL()`: a string (full URL or path), RegExp or predicate. */
|
|
248
|
+
waitForURL(url: string | RegExp | ((u: URL) => boolean), opts?: {
|
|
249
|
+
timeout?: number;
|
|
250
|
+
}): Promise<void>;
|
|
251
|
+
/** Playwright's `waitForTimeout()`. */
|
|
252
|
+
waitForTimeout(ms: number): Promise<void>;
|
|
253
|
+
/** Playwright's `waitForFunction()`: polls the function inside the page until it returns a truthy value. */
|
|
254
|
+
waitForFunction(fn: unknown, arg?: unknown, opts?: {
|
|
255
|
+
timeout?: number;
|
|
256
|
+
polling?: number | 'raf';
|
|
257
|
+
}): Promise<unknown>;
|
|
258
|
+
/** Playwright's `waitForSelector()`; returns the locator (element handles are not available). */
|
|
259
|
+
waitForSelector(selector: string, opts?: {
|
|
260
|
+
state?: 'attached' | 'detached' | 'visible' | 'hidden';
|
|
261
|
+
timeout?: number;
|
|
262
|
+
}): Promise<LocatorImpl | null>;
|
|
263
|
+
/** Playwright's `evaluate()`: runs the function inside the page and returns JSON. */
|
|
264
|
+
evaluate(fn: unknown, arg?: unknown): Promise<unknown>;
|
|
265
|
+
/** Playwright's `$eval()`. */
|
|
266
|
+
$eval(selector: string, fn: unknown, arg?: unknown): Promise<unknown>;
|
|
267
|
+
/** Playwright's `$$eval()`. */
|
|
268
|
+
$$eval(selector: string, fn: unknown, arg?: unknown): Promise<unknown>;
|
|
269
|
+
/** Playwright's `addStyleTag()` (inline content). */
|
|
270
|
+
addStyleTag(opts: {
|
|
271
|
+
content?: string;
|
|
272
|
+
url?: string;
|
|
273
|
+
}): Promise<null>;
|
|
274
|
+
/** Playwright's `addScriptTag()`. */
|
|
275
|
+
addScriptTag(opts: {
|
|
276
|
+
content?: string;
|
|
277
|
+
url?: string;
|
|
278
|
+
type?: string;
|
|
279
|
+
}): Promise<null>;
|
|
280
|
+
/** Playwright's `locator()`: narrow to descendants matching a selector, with optional `hasText` / `has` filters. */
|
|
281
|
+
locator(sel: string | LocatorImpl, opts?: {
|
|
282
|
+
hasText?: string | RegExp;
|
|
283
|
+
hasNotText?: string | RegExp;
|
|
284
|
+
has?: LocatorImpl;
|
|
285
|
+
hasNot?: LocatorImpl;
|
|
286
|
+
}): LocatorImpl;
|
|
287
|
+
/** Playwright's `getByRole()`: by ARIA role, with accessible-name, heading-level and state options. */
|
|
288
|
+
getByRole(role: string, opts?: Dict): LocatorImpl;
|
|
289
|
+
/** Playwright's `getByText()`: the smallest elements whose text matches. */
|
|
290
|
+
getByText(text: string | RegExp, opts?: {
|
|
291
|
+
exact?: boolean;
|
|
292
|
+
}): LocatorImpl;
|
|
293
|
+
/** Playwright's `getByLabel()`: form controls by their label text (also `aria-label`). */
|
|
294
|
+
getByLabel(text: string | RegExp, opts?: {
|
|
295
|
+
exact?: boolean;
|
|
296
|
+
}): LocatorImpl;
|
|
297
|
+
/** Playwright's `getByPlaceholder()`. */
|
|
298
|
+
getByPlaceholder(text: string | RegExp, opts?: {
|
|
299
|
+
exact?: boolean;
|
|
300
|
+
}): LocatorImpl;
|
|
301
|
+
/** Playwright's `getByTitle()`. */
|
|
302
|
+
getByTitle(text: string | RegExp, opts?: {
|
|
303
|
+
exact?: boolean;
|
|
304
|
+
}): LocatorImpl;
|
|
305
|
+
/** Playwright's `getByAltText()`. */
|
|
306
|
+
getByAltText(text: string | RegExp, opts?: {
|
|
307
|
+
exact?: boolean;
|
|
308
|
+
}): LocatorImpl;
|
|
309
|
+
/** Playwright's `getByTestId()` on the configured test-id attribute (default `data-testid`). */
|
|
310
|
+
getByTestId(id: string | RegExp): LocatorImpl;
|
|
311
|
+
/** Playwright's `setViewportSize()`: asks the host to resize the frame; throws when it did not. */
|
|
312
|
+
setViewportSize(size: E2EViewport): Promise<void>;
|
|
313
|
+
/** Apply the configured viewport without failing the test when the host cannot resize (used once at connect). */
|
|
314
|
+
applyInitialViewport(): Promise<void>;
|
|
315
|
+
/** Playwright's `viewportSize()`. */
|
|
316
|
+
viewportSize(): E2EViewport | null;
|
|
317
|
+
/** Log a warning once per key. */
|
|
318
|
+
private warnOnce;
|
|
319
|
+
/** Playwright's `page.on()`: console, pageerror, dialog, close and load fire over the preview; network events never do (warned once). */
|
|
320
|
+
on(event: string, fn: Listener): Page;
|
|
321
|
+
/** Alias of `on()`. */
|
|
322
|
+
addListener(event: string, fn: Listener): Page;
|
|
323
|
+
/** Playwright's `page.once()`. */
|
|
324
|
+
once(event: string, fn: Listener): Page;
|
|
325
|
+
/** Playwright's `page.off()`. */
|
|
326
|
+
off(event: string, fn: Listener): Page;
|
|
327
|
+
/** Alias of `off()`. */
|
|
328
|
+
removeListener(event: string, fn: Listener): Page;
|
|
329
|
+
/** Playwright's `removeAllListeners()`. */
|
|
330
|
+
removeAllListeners(event?: string): Page;
|
|
331
|
+
/** Called by a transport that forwards dialogs (the preview client auto-accepts them). */
|
|
332
|
+
emitDialog(dialog: DialogImpl): void;
|
|
333
|
+
/** Playwright's `page.close()`: releases the transport. */
|
|
334
|
+
close(): Promise<void>;
|
|
335
|
+
/** Playwright's `isClosed()`. */
|
|
336
|
+
isClosed(): boolean;
|
|
337
|
+
/** No-op over the preview: the page is already in front. */
|
|
338
|
+
bringToFront(): Promise<void>;
|
|
339
|
+
/** Playwright's `setDefaultTimeout()`. */
|
|
340
|
+
setDefaultTimeout(ms: number): void;
|
|
341
|
+
/** Playwright's `setDefaultNavigationTimeout()`. */
|
|
342
|
+
setDefaultNavigationTimeout(ms: number): void;
|
|
343
|
+
/** No-op: there is no inspector to pause in. */
|
|
344
|
+
pause(): Promise<void>;
|
|
345
|
+
/** The page itself, standing in for the main frame. */
|
|
346
|
+
mainFrame(): Frame;
|
|
347
|
+
/** The main frame only. */
|
|
348
|
+
frames(): Frame[];
|
|
349
|
+
/** Always empty over the preview. */
|
|
350
|
+
workers(): unknown[];
|
|
351
|
+
/** Always null over the preview. */
|
|
352
|
+
opener(): null;
|
|
353
|
+
/** Always null: no recording over the preview. */
|
|
354
|
+
video(): null;
|
|
355
|
+
/** A minimal BrowserContext: pages, timeouts and no-op tracing; the rest throws naming the alternative. */
|
|
356
|
+
context(): BrowserContext;
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Build a Playwright-shaped `Page` over a transport. Bonds call this from
|
|
360
|
+
* `connect()`; the returned object carries the documented subset and throws an
|
|
361
|
+
* {@link E2EUnsupportedError} naming the alternative for the rest.
|
|
362
|
+
*/
|
|
363
|
+
export declare const createEvaluatePage: (transport: E2ETransport, options?: E2EPageOptions) => Promise<Page>;
|
|
364
|
+
/** Whether a value is a locator built by {@link createEvaluatePage}. */
|
|
365
|
+
export declare const isE2ELocator: (value: unknown) => value is LocatorImpl;
|
|
366
|
+
/** Whether a value is a page built by {@link createEvaluatePage}. */
|
|
367
|
+
export declare const isE2EPage: (value: unknown) => value is PageImpl;
|
|
368
|
+
export type { LocatorImpl as E2ELocatorImpl, PageImpl as E2EPageImpl };
|
|
369
|
+
export { toMatch as textMatch, toFull as textMatchFull };
|
|
370
|
+
//# sourceMappingURL=page.d.ts.map
|