@enekesabel/playwright-lite 0.3.0 → 0.5.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 CHANGED
@@ -18,13 +18,17 @@ await page.getByRole("textbox", { name: "Name" }).fill("Ada");
18
18
  await page.getByRole("button", { name: "Save" }).click();
19
19
  ```
20
20
 
21
- ## Runtime boundaries
21
+ ## Assertions
22
22
 
23
- - **Current document only.** No iframe traversal, `Frame`, or `FrameLocator` support.
24
- - **Navigation ends execution.** `goto()` can start navigation, but replacing the document destroys the JavaScript context running your script. Automation cannot continue across a full-page navigation or reload.
25
- - **Synthetic input.** Input events are not browser-trusted. Native keyboard behavior such as cursor movement, deletion, and focus traversal is not simulated.
26
- - **No browser control.** No browser launch, browser contexts, or browser-level control over network traffic, downloads, or other tabs.
27
- - **Content Security Policy still applies.** Evaluation callbacks need dynamic JavaScript evaluation to be allowed by the page's policy; the library does not bypass it.
23
+ ```ts
24
+ import { createPage, expect } from "@enekesabel/playwright-lite";
25
+
26
+ const page = createPage();
27
+ await expect(page.getByRole("button", { name: "Save" })).toBeEnabled();
28
+ await expect(page.locator(".notice")).toContainText("Saved");
29
+ ```
30
+
31
+ See [Expect](#expect) for the supported matchers and how a failed assertion surfaces.
28
32
 
29
33
  ## Use cases
30
34
 
@@ -41,6 +45,41 @@ playwright-lite is pre-1.0; APIs may change.
41
45
  npm add @enekesabel/playwright-lite
42
46
  ```
43
47
 
48
+ ## Runtime boundaries
49
+
50
+ - **Current document only.** No iframe traversal, `Frame`, or `FrameLocator` support.
51
+ - **Navigation ends execution.** `goto()` can start navigation, but replacing the document destroys the JavaScript context running your script, so automation cannot continue across a full-page navigation or reload.
52
+ - **Synthetic input.** Input events are not browser-trusted; native keyboard behavior such as cursor movement, deletion and focus traversal is not simulated.
53
+ - **No browser control.** No browser launch, browser contexts, or browser-level control over network traffic, downloads, or other tabs.
54
+ - **Content Security Policy applies.** Evaluation callbacks need the page's policy to allow dynamic JavaScript evaluation; the library does not bypass it.
55
+
56
+ ### Page functions playwright-lite replaces
57
+
58
+ | Functions | Replaced when you first… | Put back when… |
59
+ | --------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
60
+ | `window.fetch` and `XMLHttpRequest.prototype.open`, `setRequestHeader` and `send` | add a `request`, `response`, `requestfinished` or `requestfailed` listener, call `waitForRequest()`, `waitForResponse()` or `requests()`, or start a `networkidle` wait | the last of those listeners is removed and no `networkidle` wait is running. After a `requests()` call they stay, so its log keeps filling. |
61
+ | Every `console.*` method Playwright's `ConsoleMessage` covers | add a `console` listener or call `consoleMessages()` | the last `console` listener is removed. After a `consoleMessages()` call they stay, so its log keeps filling. |
62
+ | `window.alert`, `window.confirm` and `window.prompt` | add a `dialog` listener | the last `dialog` listener is removed. |
63
+
64
+ Nothing is replaced until you subscribe, and a function the page replaced itself is never put back. The network and console replacements forward every call unchanged. The dialog replacements pass each dialog to your listeners instead of showing it; see [Dialog](#dialog).
65
+
66
+ ### Network idle
67
+
68
+ `waitForLoadState("networkidle")` and `waitUntil: "networkidle"` resolve once no `fetch()` or `XMLHttpRequest` call of the current document has been in flight for 500 ms.
69
+
70
+ - Only `fetch()` and `XMLHttpRequest` calls count as in flight. An image, script, stylesheet or other resource that finishes loading restarts the 500 ms, but one still loading never holds it.
71
+ - `/favicon.ico` requests are excluded, as in Playwright.
72
+ - A call started before you subscribed is not seen, so a wait started while such a call is in flight can resolve before it ends.
73
+ - Calls from iframes, workers and other realms are not seen.
74
+ - Playwright documents `networkidle` as "**DISCOURAGED** consider operation to be finished when there are no network connections for at least `500` ms. Don't use this method for testing, rely on web assertions to assess readiness instead."
75
+
76
+ <details>
77
+ <summary>Edge cases</summary>
78
+
79
+ - The end of each call and resource is noticed a few milliseconds late, so a wait can resolve slightly more than 500 ms after it.
80
+
81
+ </details>
82
+
44
83
  ## Compatibility
45
84
 
46
85
  Targets Playwright **1.62.1**. Statuses describe API compatibility within the runtime boundaries above. API links open Playwright's current documentation.
@@ -49,124 +88,124 @@ Targets Playwright **1.62.1**. Statuses describe API compatibility within the ru
49
88
 
50
89
  ### Page
51
90
 
52
- | API | Status | Notes |
53
- | --------------------------------------------------------------------------------------------------------------- | :----: | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
54
- | [`$`](https://playwright.dev/docs/api/class-page#page-query-selector) | ⚠️ | Returned `ElementHandle` methods and options differ; see [ElementHandle compatibility](#elementhandle-compatibility). |
55
- | [`$$`](https://playwright.dev/docs/api/class-page#page-query-selector-all) | ⚠️ | Returned `ElementHandle` methods and options differ; see [ElementHandle compatibility](#elementhandle-compatibility). |
56
- | [`$$eval`](https://playwright.dev/docs/api/class-page#page-eval-on-selector-all) | ✅ | |
57
- | [`$eval`](https://playwright.dev/docs/api/class-page#page-eval-on-selector) | ✅ | |
58
- | [`[Symbol.asyncDispose]()`](https://playwright.dev/docs/release-notes#version-160) | ❌ | |
59
- | [`addInitScript`](https://playwright.dev/docs/api/class-page#page-add-init-script) | ❌ | |
60
- | [`addListener`](https://playwright.dev/docs/events) | ❌ | |
61
- | [`addLocatorHandler`](https://playwright.dev/docs/api/class-page#page-add-locator-handler) | ❌ | |
62
- | [`addScriptTag`](https://playwright.dev/docs/api/class-page#page-add-script-tag) | ⚠️ | Rejects `path`, which reads the script from disk. Returned `ElementHandle` methods and options differ; see [ElementHandle compatibility](#elementhandle-compatibility). |
63
- | [`addStyleTag`](https://playwright.dev/docs/api/class-page#page-add-style-tag) | ⚠️ | Rejects `path`, which reads the stylesheet from disk. Returned `ElementHandle` methods and options differ; see [ElementHandle compatibility](#elementhandle-compatibility). |
64
- | [`ariaSnapshot`](https://playwright.dev/docs/api/class-page#page-aria-snapshot) | ✅ | |
65
- | [`bringToFront`](https://playwright.dev/docs/api/class-page#page-bring-to-front) | ❌ | |
66
- | [`cancelPickLocator`](https://playwright.dev/docs/api/class-page#page-cancel-pick-locator) | ❌ | |
67
- | [`check`](https://playwright.dev/docs/api/class-page#page-check) | ✅ | |
68
- | [`clearConsoleMessages`](https://playwright.dev/docs/api/class-page#page-clear-console-messages) | ❌ | |
69
- | [`clearPageErrors`](https://playwright.dev/docs/api/class-page#page-clear-page-errors) | ❌ | |
70
- | [`click`](https://playwright.dev/docs/api/class-page#page-click) | ⚠️ | The action does not wait for navigation. |
71
- | [`clock`](https://playwright.dev/docs/api/class-page#page-clock) | ❌ | |
72
- | [`close`](https://playwright.dev/docs/api/class-page#page-close) | ❌ | |
73
- | [`consoleMessages`](https://playwright.dev/docs/api/class-page#page-console-messages) | ❌ | |
74
- | [`content`](https://playwright.dev/docs/api/class-page#page-content) | ✅ | |
75
- | [`context`](https://playwright.dev/docs/api/class-page#page-context) | ❌ | |
76
- | [`coverage`](https://playwright.dev/docs/api/class-page#page-coverage) | ❌ | |
77
- | [`dblclick`](https://playwright.dev/docs/api/class-page#page-dblclick) | ✅ | |
78
- | [`dispatchEvent`](https://playwright.dev/docs/api/class-page#page-dispatch-event) | ✅ | |
79
- | [`dragAndDrop`](https://playwright.dev/docs/api/class-page#page-drag-and-drop) | ❌ | |
80
- | [`emulateMedia`](https://playwright.dev/docs/api/class-page#page-emulate-media) | ❌ | |
81
- | [`evaluate`](https://playwright.dev/docs/api/class-page#page-evaluate) | ⚠️ | Rejects `exposeFunctions: true`. |
82
- | [`evaluateHandle`](https://playwright.dev/docs/api/class-page#page-evaluate-handle) | ⚠️ | Rejects `exposeFunctions: true`. The returned handle previews differently; see [ElementHandle compatibility](#elementhandle-compatibility). |
83
- | [`exposeBinding`](https://playwright.dev/docs/api/class-page#page-expose-binding) | ❌ | |
84
- | [`exposeFunction`](https://playwright.dev/docs/api/class-page#page-expose-function) | ❌ | |
85
- | [`fill`](https://playwright.dev/docs/api/class-page#page-fill) | ✅ | |
86
- | [`focus`](https://playwright.dev/docs/api/class-page#page-focus) | ✅ | |
87
- | [`frame`](https://playwright.dev/docs/api/class-page#page-frame) | 🚫 | Iframe realms are outside the single-document boundary. |
88
- | [`frameLocator`](https://playwright.dev/docs/api/class-page#page-frame-locator) | 🚫 | Iframe realms are outside the single-document boundary. |
89
- | [`frames`](https://playwright.dev/docs/api/class-page#page-frames) | 🚫 | Iframe realms are outside the single-document boundary. |
90
- | [`getAttribute`](https://playwright.dev/docs/api/class-page#page-get-attribute) | ✅ | |
91
- | [`getByAltText`](https://playwright.dev/docs/api/class-page#page-get-by-alt-text) | ✅ | |
92
- | [`getByLabel`](https://playwright.dev/docs/api/class-page#page-get-by-label) | ✅ | |
93
- | [`getByPlaceholder`](https://playwright.dev/docs/api/class-page#page-get-by-placeholder) | ✅ | |
94
- | [`getByRole`](https://playwright.dev/docs/api/class-page#page-get-by-role) | ✅ | |
95
- | [`getByTestId`](https://playwright.dev/docs/api/class-page#page-get-by-test-id) | ✅ | |
96
- | [`getByText`](https://playwright.dev/docs/api/class-page#page-get-by-text) | ✅ | |
97
- | [`getByTitle`](https://playwright.dev/docs/api/class-page#page-get-by-title) | ✅ | |
98
- | [`goBack`](https://playwright.dev/docs/api/class-page#page-go-back) | ❌ | |
99
- | [`goForward`](https://playwright.dev/docs/api/class-page#page-go-forward) | ❌ | |
100
- | [`goto`](https://playwright.dev/docs/api/class-page#page-goto) | ⚠️ | Does not return a `Response`; resolves to `null` only for same-document hash navigation. Relative URLs use `document.baseURI`, not a configured Playwright `baseURL`. Rejects `referer`, `signal`, and `waitUntil: "networkidle"`. |
101
- | [`hideHighlight`](https://playwright.dev/docs/api/class-page#page-hide-highlight) | ✅ | |
102
- | [`hover`](https://playwright.dev/docs/api/class-page#page-hover) | ✅ | |
103
- | [`innerHTML`](https://playwright.dev/docs/api/class-page#page-inner-html) | ✅ | |
104
- | [`innerText`](https://playwright.dev/docs/api/class-page#page-inner-text) | ✅ | |
105
- | [`inputValue`](https://playwright.dev/docs/api/class-page#page-input-value) | ✅ | |
106
- | [`isChecked`](https://playwright.dev/docs/api/class-page#page-is-checked) | ✅ | |
107
- | [`isClosed`](https://playwright.dev/docs/api/class-page#page-is-closed) | ❌ | |
108
- | [`isDisabled`](https://playwright.dev/docs/api/class-page#page-is-disabled) | ✅ | |
109
- | [`isEditable`](https://playwright.dev/docs/api/class-page#page-is-editable) | ✅ | |
110
- | [`isEnabled`](https://playwright.dev/docs/api/class-page#page-is-enabled) | ✅ | |
111
- | [`isHidden`](https://playwright.dev/docs/api/class-page#page-is-hidden) | ✅ | |
112
- | [`isVisible`](https://playwright.dev/docs/api/class-page#page-is-visible) | ✅ | |
113
- | [`keyboard`](https://playwright.dev/docs/api/class-page#page-keyboard) | ✅ | |
114
- | [`localStorage`](https://playwright.dev/docs/api/class-page#page-local-storage) | ✅ | |
115
- | [`locator`](https://playwright.dev/docs/api/class-page#page-locator) | ✅ | |
116
- | [`mainFrame`](https://playwright.dev/docs/api/class-page#page-main-frame) | ⚠️ | Returns the same `Page` object, not a `Frame`. |
117
- | [`mouse`](https://playwright.dev/docs/api/class-page#page-mouse) | ❌ | |
118
- | [`off`](https://playwright.dev/docs/events) | ❌ | |
119
- | [`on`](https://playwright.dev/docs/events) | ❌ | |
120
- | [`once`](https://playwright.dev/docs/events) | ❌ | |
121
- | [`opener`](https://playwright.dev/docs/api/class-page#page-opener) | ❌ | |
122
- | [`pageErrors`](https://playwright.dev/docs/api/class-page#page-page-errors) | ❌ | |
123
- | [`pause`](https://playwright.dev/docs/api/class-page#page-pause) | ❌ | |
124
- | [`pdf`](https://playwright.dev/docs/api/class-page#page-pdf) | ❌ | |
125
- | [`pickLocator`](https://playwright.dev/docs/api/class-page#page-pick-locator) | ❌ | |
126
- | [`prependListener`](https://playwright.dev/docs/events) | ❌ | |
127
- | [`press`](https://playwright.dev/docs/api/class-page#page-press) | ✅ | |
128
- | [`reload`](https://playwright.dev/docs/api/class-page#page-reload) | ❌ | |
129
- | [`removeAllListeners`](https://playwright.dev/docs/api/class-page#page-remove-all-listeners) | ❌ | |
130
- | [`removeListener`](https://playwright.dev/docs/events) | ❌ | |
131
- | [`removeLocatorHandler`](https://playwright.dev/docs/api/class-page#page-remove-locator-handler) | ❌ | |
132
- | [`request`](https://playwright.dev/docs/api/class-page#page-request) | ❌ | |
133
- | [`requestGC`](https://playwright.dev/docs/api/class-page#page-request-gc) | ❌ | |
134
- | [`requests`](https://playwright.dev/docs/api/class-page#page-requests) | ❌ | |
135
- | [`route`](https://playwright.dev/docs/api/class-page#page-route) | ❌ | |
136
- | [`routeFromHAR`](https://playwright.dev/docs/api/class-page#page-route-from-har) | ❌ | |
137
- | [`routeWebSocket`](https://playwright.dev/docs/api/class-page#page-route-web-socket) | ❌ | |
138
- | [`screencast`](https://playwright.dev/docs/api/class-page#page-screencast) | ❌ | |
139
- | [`screenshot`](https://playwright.dev/docs/api/class-page#page-screenshot) | ❌ | |
140
- | [`selectOption`](https://playwright.dev/docs/api/class-page#page-select-option) | ✅ | |
141
- | [`sessionStorage`](https://playwright.dev/docs/api/class-page#page-session-storage) | ✅ | |
142
- | [`setChecked`](https://playwright.dev/docs/api/class-page#page-set-checked) | ✅ | |
143
- | [`setContent`](https://playwright.dev/docs/api/class-page#page-set-content) | 🚫 | Document replacement is excluded. |
144
- | [`setDefaultNavigationTimeout`](https://playwright.dev/docs/api/class-page#page-set-default-navigation-timeout) | ✅ | |
145
- | [`setDefaultTimeout`](https://playwright.dev/docs/api/class-page#page-set-default-timeout) | ✅ | |
146
- | [`setExtraHTTPHeaders`](https://playwright.dev/docs/api/class-page#page-set-extra-http-headers) | ❌ | |
147
- | [`setInputFiles`](https://playwright.dev/docs/api/class-page#page-set-input-files) | ⚠️ | Accepts only in-memory `{ name, mimeType, buffer }` objects; file paths and directory uploads are unsupported. Empty `mimeType` throws instead of inferring a MIME type. |
148
- | [`setViewportSize`](https://playwright.dev/docs/api/class-page#page-set-viewport-size) | 🚫 | Browser viewport resizing is excluded. |
149
- | [`tap`](https://playwright.dev/docs/api/class-page#page-tap) | ❌ | |
150
- | [`textContent`](https://playwright.dev/docs/api/class-page#page-text-content) | ✅ | |
151
- | [`title`](https://playwright.dev/docs/api/class-page#page-title) | ✅ | |
152
- | [`touchscreen`](https://playwright.dev/docs/api/class-page#page-touchscreen) | ❌ | |
153
- | [`type`](https://playwright.dev/docs/api/class-page#page-type) | ✅ | |
154
- | [`uncheck`](https://playwright.dev/docs/api/class-page#page-uncheck) | ✅ | |
155
- | [`unroute`](https://playwright.dev/docs/api/class-page#page-unroute) | ❌ | |
156
- | [`unrouteAll`](https://playwright.dev/docs/api/class-page#page-unroute-all) | ❌ | |
157
- | [`url`](https://playwright.dev/docs/api/class-page#page-url) | ✅ | |
158
- | [`video`](https://playwright.dev/docs/api/class-page#page-video) | ❌ | |
159
- | [`viewportSize`](https://playwright.dev/docs/api/class-page#page-viewport-size) | ❌ | |
160
- | [`waitForEvent`](https://playwright.dev/docs/api/class-page#page-wait-for-event) | ❌ | |
161
- | [`waitForFunction`](https://playwright.dev/docs/api/class-page#page-wait-for-function) | ⚠️ | The returned handle previews differently; see [ElementHandle compatibility](#elementhandle-compatibility). |
162
- | [`waitForLoadState`](https://playwright.dev/docs/api/class-page#page-wait-for-load-state) | ❌ | |
163
- | [`waitForNavigation`](https://playwright.dev/docs/api/class-page#page-wait-for-navigation) | ❌ | |
164
- | [`waitForRequest`](https://playwright.dev/docs/api/class-page#page-wait-for-request) | ❌ | |
165
- | [`waitForResponse`](https://playwright.dev/docs/api/class-page#page-wait-for-response) | ❌ | |
166
- | [`waitForSelector`](https://playwright.dev/docs/api/class-page#page-wait-for-selector) | ⚠️ | Returned `ElementHandle` methods and options differ; see [ElementHandle compatibility](#elementhandle-compatibility). |
167
- | [`waitForTimeout`](https://playwright.dev/docs/api/class-page#page-wait-for-timeout) | ✅ | |
168
- | [`waitForURL`](https://playwright.dev/docs/api/class-page#page-wait-for-url) | ❌ | |
169
- | [`workers`](https://playwright.dev/docs/api/class-page#page-workers) | ❌ | |
91
+ | API | Status | Notes |
92
+ | --------------------------------------------------------------------------------------------------------------- | :----: | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
93
+ | [`$`](https://playwright.dev/docs/api/class-page#page-query-selector) | ⚠️ | Returned `ElementHandle` methods and options differ; see [ElementHandle and JSHandle](#elementhandle-and-jshandle). |
94
+ | [`$$`](https://playwright.dev/docs/api/class-page#page-query-selector-all) | ⚠️ | Returned `ElementHandle` methods and options differ; see [ElementHandle and JSHandle](#elementhandle-and-jshandle). |
95
+ | [`$$eval`](https://playwright.dev/docs/api/class-page#page-eval-on-selector-all) | ✅ | |
96
+ | [`$eval`](https://playwright.dev/docs/api/class-page#page-eval-on-selector) | ✅ | |
97
+ | [`[Symbol.asyncDispose]()`](https://playwright.dev/docs/release-notes#version-160) | ❌ | |
98
+ | [`addInitScript`](https://playwright.dev/docs/api/class-page#page-add-init-script) | 🚫 | Registers a script to run before the document's own scripts, which have already run by the time this adapter attaches. |
99
+ | [`addListener`](https://playwright.dev/docs/events) | ⚠️ | Fires only the [supported events](#events); other names never fire. |
100
+ | [`addLocatorHandler`](https://playwright.dev/docs/api/class-page#page-add-locator-handler) | ❌ | |
101
+ | [`addScriptTag`](https://playwright.dev/docs/api/class-page#page-add-script-tag) | ⚠️ | Rejects `path`, which reads the script from disk. Returned `ElementHandle` methods and options differ; see [ElementHandle and JSHandle](#elementhandle-and-jshandle). |
102
+ | [`addStyleTag`](https://playwright.dev/docs/api/class-page#page-add-style-tag) | ⚠️ | Rejects `path`, which reads the stylesheet from disk. Returned `ElementHandle` methods and options differ; see [ElementHandle and JSHandle](#elementhandle-and-jshandle). |
103
+ | [`ariaSnapshot`](https://playwright.dev/docs/api/class-page#page-aria-snapshot) | ✅ | |
104
+ | [`bringToFront`](https://playwright.dev/docs/api/class-page#page-bring-to-front) | 🚫 | Browser tab focus control is excluded. |
105
+ | [`cancelPickLocator`](https://playwright.dev/docs/api/class-page#page-cancel-pick-locator) | ❌ | |
106
+ | [`check`](https://playwright.dev/docs/api/class-page#page-check) | ✅ | |
107
+ | [`clearConsoleMessages`](https://playwright.dev/docs/api/class-page#page-clear-console-messages) | ✅ | |
108
+ | [`clearPageErrors`](https://playwright.dev/docs/api/class-page#page-clear-page-errors) | ✅ | |
109
+ | [`click`](https://playwright.dev/docs/api/class-page#page-click) | ⚠️ | The action does not wait for navigation. |
110
+ | [`clock`](https://playwright.dev/docs/api/class-page#page-clock) | ❌ | |
111
+ | [`close`](https://playwright.dev/docs/api/class-page#page-close) | ❌ | |
112
+ | [`consoleMessages`](https://playwright.dev/docs/api/class-page#page-console-messages) | ⚠️ | `filter: "all"` and the default `"since-navigation"` return the same messages; see [ConsoleMessage](#consolemessage). |
113
+ | [`content`](https://playwright.dev/docs/api/class-page#page-content) | ✅ | |
114
+ | [`context`](https://playwright.dev/docs/api/class-page#page-context) | 🚫 | Refers to the owning browser context, which does not exist in this adapter. |
115
+ | [`coverage`](https://playwright.dev/docs/api/class-page#page-coverage) | 🚫 | Collecting code coverage requires the browser process. |
116
+ | [`dblclick`](https://playwright.dev/docs/api/class-page#page-dblclick) | ✅ | |
117
+ | [`dispatchEvent`](https://playwright.dev/docs/api/class-page#page-dispatch-event) | ✅ | |
118
+ | [`dragAndDrop`](https://playwright.dev/docs/api/class-page#page-drag-and-drop) | ❌ | |
119
+ | [`emulateMedia`](https://playwright.dev/docs/api/class-page#page-emulate-media) | ❌ | |
120
+ | [`evaluate`](https://playwright.dev/docs/api/class-page#page-evaluate) | ✅ | |
121
+ | [`evaluateHandle`](https://playwright.dev/docs/api/class-page#page-evaluate-handle) | ⚠️ | The returned handle previews differently; see [ElementHandle and JSHandle](#elementhandle-and-jshandle). |
122
+ | [`exposeBinding`](https://playwright.dev/docs/api/class-page#page-expose-binding) | ⚠️ | Differs as `exposeFunction` does. The callback's `source` is `{ page, frame: page }`, with no `context`, since this package has no `BrowserContext`. |
123
+ | [`exposeFunction`](https://playwright.dev/docs/api/class-page#page-expose-function) | ⚠️ | `dispose()` leaves a value the page itself assigned to the property on `window`, where Playwright deletes it. Arguments and the result skip `JSON.stringify()`, so a page overriding `Array.prototype.toJSON()` does not make the call reject, as it does in Playwright. |
124
+ | [`fill`](https://playwright.dev/docs/api/class-page#page-fill) | ✅ | |
125
+ | [`focus`](https://playwright.dev/docs/api/class-page#page-focus) | ✅ | |
126
+ | [`frame`](https://playwright.dev/docs/api/class-page#page-frame) | 🚫 | Iframe realms are outside the single-document boundary. |
127
+ | [`frameLocator`](https://playwright.dev/docs/api/class-page#page-frame-locator) | 🚫 | Iframe realms are outside the single-document boundary. |
128
+ | [`frames`](https://playwright.dev/docs/api/class-page#page-frames) | 🚫 | Iframe realms are outside the single-document boundary. |
129
+ | [`getAttribute`](https://playwright.dev/docs/api/class-page#page-get-attribute) | ✅ | |
130
+ | [`getByAltText`](https://playwright.dev/docs/api/class-page#page-get-by-alt-text) | ✅ | |
131
+ | [`getByLabel`](https://playwright.dev/docs/api/class-page#page-get-by-label) | ✅ | |
132
+ | [`getByPlaceholder`](https://playwright.dev/docs/api/class-page#page-get-by-placeholder) | ✅ | |
133
+ | [`getByRole`](https://playwright.dev/docs/api/class-page#page-get-by-role) | ✅ | |
134
+ | [`getByTestId`](https://playwright.dev/docs/api/class-page#page-get-by-test-id) | ✅ | |
135
+ | [`getByText`](https://playwright.dev/docs/api/class-page#page-get-by-text) | ✅ | |
136
+ | [`getByTitle`](https://playwright.dev/docs/api/class-page#page-get-by-title) | ✅ | |
137
+ | [`goBack`](https://playwright.dev/docs/api/class-page#page-go-back) | ❌ | |
138
+ | [`goForward`](https://playwright.dev/docs/api/class-page#page-go-forward) | ❌ | |
139
+ | [`goto`](https://playwright.dev/docs/api/class-page#page-goto) | ⚠️ | Returns no `Response` (`null` only for same-document hash navigation); relative URLs resolve against `document.baseURI`, with no `baseURL`; rejects `referer` and `signal`; [`networkidle`](#network-idle) resolves no sooner than 500 ms after the call, even when already idle. |
140
+ | [`hideHighlight`](https://playwright.dev/docs/api/class-page#page-hide-highlight) | ✅ | |
141
+ | [`hover`](https://playwright.dev/docs/api/class-page#page-hover) | ✅ | |
142
+ | [`innerHTML`](https://playwright.dev/docs/api/class-page#page-inner-html) | ✅ | |
143
+ | [`innerText`](https://playwright.dev/docs/api/class-page#page-inner-text) | ✅ | |
144
+ | [`inputValue`](https://playwright.dev/docs/api/class-page#page-input-value) | ✅ | |
145
+ | [`isChecked`](https://playwright.dev/docs/api/class-page#page-is-checked) | ✅ | |
146
+ | [`isClosed`](https://playwright.dev/docs/api/class-page#page-is-closed) | ❌ | |
147
+ | [`isDisabled`](https://playwright.dev/docs/api/class-page#page-is-disabled) | ✅ | |
148
+ | [`isEditable`](https://playwright.dev/docs/api/class-page#page-is-editable) | ✅ | |
149
+ | [`isEnabled`](https://playwright.dev/docs/api/class-page#page-is-enabled) | ✅ | |
150
+ | [`isHidden`](https://playwright.dev/docs/api/class-page#page-is-hidden) | ✅ | |
151
+ | [`isVisible`](https://playwright.dev/docs/api/class-page#page-is-visible) | ✅ | |
152
+ | [`keyboard`](https://playwright.dev/docs/api/class-page#page-keyboard) | ✅ | |
153
+ | [`localStorage`](https://playwright.dev/docs/api/class-page#page-local-storage) | ✅ | |
154
+ | [`locator`](https://playwright.dev/docs/api/class-page#page-locator) | ✅ | |
155
+ | [`mainFrame`](https://playwright.dev/docs/api/class-page#page-main-frame) | ⚠️ | Returns the same `Page` object, not a `Frame`. |
156
+ | [`mouse`](https://playwright.dev/docs/api/class-page#page-mouse) | ❌ | |
157
+ | [`off`](https://playwright.dev/docs/events) | ⚠️ | Only the [supported events](#events) ever fire; other names are accepted. |
158
+ | [`on`](https://playwright.dev/docs/events) | ⚠️ | Fires only the [supported events](#events); other names never fire. |
159
+ | [`once`](https://playwright.dev/docs/events) | ⚠️ | Fires only the [supported events](#events); other names never fire. |
160
+ | [`opener`](https://playwright.dev/docs/api/class-page#page-opener) | 🚫 | Refers to another page, outside the single-document boundary. |
161
+ | [`pageErrors`](https://playwright.dev/docs/api/class-page#page-page-errors) | ⚠️ | `filter: "all"` and the default `"since-navigation"` return the same errors: this single-document adapter never crosses documents within one page's lifetime, so nothing ever marks the buffer at a navigation. |
162
+ | [`pause`](https://playwright.dev/docs/api/class-page#page-pause) | 🚫 | Pausing for the Playwright Inspector requires the browser process. |
163
+ | [`pdf`](https://playwright.dev/docs/api/class-page#page-pdf) | 🚫 | Generating a PDF requires the browser process. |
164
+ | [`pickLocator`](https://playwright.dev/docs/api/class-page#page-pick-locator) | ❌ | |
165
+ | [`prependListener`](https://playwright.dev/docs/events) | ⚠️ | Fires only the [supported events](#events); other names never fire. |
166
+ | [`press`](https://playwright.dev/docs/api/class-page#page-press) | ✅ | |
167
+ | [`reload`](https://playwright.dev/docs/api/class-page#page-reload) | ❌ | |
168
+ | [`removeAllListeners`](https://playwright.dev/docs/api/class-page#page-remove-all-listeners) | ⚠️ | Only the [supported events](#events) ever fire; other names are accepted. |
169
+ | [`removeListener`](https://playwright.dev/docs/events) | ⚠️ | Only the [supported events](#events) ever fire; other names are accepted. |
170
+ | [`removeLocatorHandler`](https://playwright.dev/docs/api/class-page#page-remove-locator-handler) | ❌ | |
171
+ | [`request`](https://playwright.dev/docs/api/class-page#page-request) | 🚫 | Returns Playwright's Node-side API request context, which has no in-document counterpart. |
172
+ | [`requestGC`](https://playwright.dev/docs/api/class-page#page-request-gc) | 🚫 | Forcing garbage collection requires the browser process. |
173
+ | [`requests`](https://playwright.dev/docs/api/class-page#page-requests) | ⚠️ | `fetch()` and `XMLHttpRequest` calls of the current document only; see [Request and Response](#request-and-response). |
174
+ | [`route`](https://playwright.dev/docs/api/class-page#page-route) | 🚫 | Browser-level network interception is excluded. |
175
+ | [`routeFromHAR`](https://playwright.dev/docs/api/class-page#page-route-from-har) | 🚫 | Browser-level network interception is excluded. |
176
+ | [`routeWebSocket`](https://playwright.dev/docs/api/class-page#page-route-web-socket) | 🚫 | Browser-level network interception is excluded. |
177
+ | [`screencast`](https://playwright.dev/docs/api/class-page#page-screencast) | 🚫 | Capturing a screencast requires the browser process. |
178
+ | [`screenshot`](https://playwright.dev/docs/api/class-page#page-screenshot) | ❌ | |
179
+ | [`selectOption`](https://playwright.dev/docs/api/class-page#page-select-option) | ✅ | |
180
+ | [`sessionStorage`](https://playwright.dev/docs/api/class-page#page-session-storage) | ✅ | |
181
+ | [`setChecked`](https://playwright.dev/docs/api/class-page#page-set-checked) | ✅ | |
182
+ | [`setContent`](https://playwright.dev/docs/api/class-page#page-set-content) | 🚫 | Document replacement is excluded. |
183
+ | [`setDefaultNavigationTimeout`](https://playwright.dev/docs/api/class-page#page-set-default-navigation-timeout) | ✅ | |
184
+ | [`setDefaultTimeout`](https://playwright.dev/docs/api/class-page#page-set-default-timeout) | ✅ | |
185
+ | [`setExtraHTTPHeaders`](https://playwright.dev/docs/api/class-page#page-set-extra-http-headers) | 🚫 | Browser-level request header configuration is excluded. |
186
+ | [`setInputFiles`](https://playwright.dev/docs/api/class-page#page-set-input-files) | ⚠️ | Accepts only in-memory `{ name, mimeType, buffer }` objects; file paths and directory uploads are unsupported. Empty `mimeType` throws instead of inferring a MIME type. |
187
+ | [`setViewportSize`](https://playwright.dev/docs/api/class-page#page-set-viewport-size) | 🚫 | Browser viewport resizing is excluded. |
188
+ | [`tap`](https://playwright.dev/docs/api/class-page#page-tap) | ❌ | |
189
+ | [`textContent`](https://playwright.dev/docs/api/class-page#page-text-content) | ✅ | |
190
+ | [`title`](https://playwright.dev/docs/api/class-page#page-title) | ✅ | |
191
+ | [`touchscreen`](https://playwright.dev/docs/api/class-page#page-touchscreen) | ❌ | |
192
+ | [`type`](https://playwright.dev/docs/api/class-page#page-type) | ✅ | |
193
+ | [`uncheck`](https://playwright.dev/docs/api/class-page#page-uncheck) | ✅ | |
194
+ | [`unroute`](https://playwright.dev/docs/api/class-page#page-unroute) | 🚫 | Removes handlers registered by `route()`, which is excluded. |
195
+ | [`unrouteAll`](https://playwright.dev/docs/api/class-page#page-unroute-all) | 🚫 | Removes handlers registered by `route()`, which is excluded. |
196
+ | [`url`](https://playwright.dev/docs/api/class-page#page-url) | ✅ | |
197
+ | [`video`](https://playwright.dev/docs/api/class-page#page-video) | 🚫 | Recording video requires the browser process. |
198
+ | [`viewportSize`](https://playwright.dev/docs/api/class-page#page-viewport-size) | ❌ | |
199
+ | [`waitForEvent`](https://playwright.dev/docs/api/class-page#page-wait-for-event) | ⚠️ | Resolves only for the [supported events](#events); other names time out. |
200
+ | [`waitForFunction`](https://playwright.dev/docs/api/class-page#page-wait-for-function) | ⚠️ | The returned handle previews differently; see [ElementHandle and JSHandle](#elementhandle-and-jshandle). |
201
+ | [`waitForLoadState`](https://playwright.dev/docs/api/class-page#page-wait-for-load-state) | ⚠️ | `"networkidle"` resolves no sooner than 500 ms after the call, even when the document is already idle; see [Network idle](#network-idle). |
202
+ | [`waitForNavigation`](https://playwright.dev/docs/api/class-page#page-wait-for-navigation) | ❌ | |
203
+ | [`waitForRequest`](https://playwright.dev/docs/api/class-page#page-wait-for-request) | ⚠️ | `fetch()` and `XMLHttpRequest` calls of the current document only; see [Request and Response](#request-and-response). |
204
+ | [`waitForResponse`](https://playwright.dev/docs/api/class-page#page-wait-for-response) | ⚠️ | `fetch()` and `XMLHttpRequest` calls of the current document only; see [Request and Response](#request-and-response). |
205
+ | [`waitForSelector`](https://playwright.dev/docs/api/class-page#page-wait-for-selector) | ⚠️ | Returned `ElementHandle` methods and options differ; see [ElementHandle and JSHandle](#elementhandle-and-jshandle). |
206
+ | [`waitForTimeout`](https://playwright.dev/docs/api/class-page#page-wait-for-timeout) | ✅ | |
207
+ | [`waitForURL`](https://playwright.dev/docs/api/class-page#page-wait-for-url) | ⚠️ | `"networkidle"` resolves no sooner than 500 ms after the call, even when the document is already idle; see [Network idle](#network-idle). |
208
+ | [`workers`](https://playwright.dev/docs/api/class-page#page-workers) | 🚫 | Worker realms are outside the single-document boundary. |
170
209
 
171
210
  ### Locator
172
211
 
@@ -190,11 +229,11 @@ Targets Playwright **1.62.1**. Statuses describe API compatibility within the ru
190
229
  | [`dispatchEvent`](https://playwright.dev/docs/api/class-locator#locator-dispatch-event) | ✅ | |
191
230
  | [`dragTo`](https://playwright.dev/docs/api/class-locator#locator-drag-to) | ❌ | |
192
231
  | [`drop`](https://playwright.dev/docs/api/class-locator#locator-drop) | ⚠️ | Accepts only in-memory `{ name, mimeType, buffer }` file payloads; file paths are unsupported. Empty `mimeType` throws instead of inferring a MIME type. |
193
- | [`elementHandle`](https://playwright.dev/docs/api/class-locator#locator-element-handle) | ⚠️ | Returned `ElementHandle` methods and options differ; see [ElementHandle compatibility](#elementhandle-compatibility). |
194
- | [`elementHandles`](https://playwright.dev/docs/api/class-locator#locator-element-handles) | ⚠️ | Returned `ElementHandle` methods and options differ; see [ElementHandle compatibility](#elementhandle-compatibility). |
195
- | [`evaluate`](https://playwright.dev/docs/api/class-locator#locator-evaluate) | ⚠️ | Rejects `exposeFunctions: true`. |
232
+ | [`elementHandle`](https://playwright.dev/docs/api/class-locator#locator-element-handle) | ⚠️ | Returned `ElementHandle` methods and options differ; see [ElementHandle and JSHandle](#elementhandle-and-jshandle). |
233
+ | [`elementHandles`](https://playwright.dev/docs/api/class-locator#locator-element-handles) | ⚠️ | Returned `ElementHandle` methods and options differ; see [ElementHandle and JSHandle](#elementhandle-and-jshandle). |
234
+ | [`evaluate`](https://playwright.dev/docs/api/class-locator#locator-evaluate) | ✅ | |
196
235
  | [`evaluateAll`](https://playwright.dev/docs/api/class-locator#locator-evaluate-all) | ✅ | |
197
- | [`evaluateHandle`](https://playwright.dev/docs/api/class-locator#locator-evaluate-handle) | ⚠️ | Rejects `exposeFunctions: true`. The returned handle previews differently; see [ElementHandle compatibility](#elementhandle-compatibility). |
236
+ | [`evaluateHandle`](https://playwright.dev/docs/api/class-locator#locator-evaluate-handle) | ⚠️ | The returned handle previews differently; see [ElementHandle and JSHandle](#elementhandle-and-jshandle). |
198
237
  | [`fill`](https://playwright.dev/docs/api/class-locator#locator-fill) | ✅ | |
199
238
  | [`filter`](https://playwright.dev/docs/api/class-locator#locator-filter) | ✅ | |
200
239
  | [`first`](https://playwright.dev/docs/api/class-locator#locator-first) | ✅ | |
@@ -242,9 +281,177 @@ Targets Playwright **1.62.1**. Statuses describe API compatibility within the ru
242
281
  | [`waitFor`](https://playwright.dev/docs/api/class-locator#locator-wait-for) | ✅ | |
243
282
  | [`waitForFunction`](https://playwright.dev/docs/api/class-locator#locator-wait-for-function) | ⚠️ | A promise returned by the page function is awaited before its value is judged; Playwright treats the returned promise object itself as truthy and stops waiting. |
244
283
 
245
- ### ElementHandle compatibility
284
+ ### Events
285
+
286
+ Listeners added with `on()`, `once()`, `addListener()` or `prependListener()`, and `waitForEvent()`, receive only these events.
287
+
288
+ | Event | Fires for | Differences from Playwright |
289
+ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
290
+ | [`dialog`](https://playwright.dev/docs/api/class-page#page-event-dialog) | `window.alert()`, `window.confirm()` and `window.prompt()` calls the document makes while a listener is registered. | A listener settles the dialog only synchronously; see [Dialog](#dialog). |
291
+ | [`framenavigated`](https://playwright.dev/docs/api/class-page#page-event-frame-navigated) | Same-document URL changes while a listener is registered. | Fires with the `Page` itself, the object `mainFrame()` returns, up to 20 ms after the change. The URL is sampled every 20 ms: several changes within one interval fire once, and a URL that changes and changes back within one interval fires nothing. |
292
+ | [`pageerror`](https://playwright.dev/docs/api/class-page#page-event-page-error) | Uncaught errors and unhandled promise rejections of the current document. | |
293
+ | [`request`](https://playwright.dev/docs/api/class-page#page-event-request), [`response`](https://playwright.dev/docs/api/class-page#page-event-response), [`requestfinished`](https://playwright.dev/docs/api/class-page#page-event-request-finished), [`requestfailed`](https://playwright.dev/docs/api/class-page#page-event-request-failed) | `fetch()` and `XMLHttpRequest` calls the document makes while a listener is registered. | See [Request and Response](#request-and-response). |
294
+ | [`console`](https://playwright.dev/docs/api/class-page#page-event-console) | The document's own `console.*` calls made while a listener is registered. | See [ConsoleMessage](#consolemessage). |
295
+
296
+ ### Expect
297
+
298
+ A failed assertion throws an error whose `matcherResult` describes the failure: generic matchers throw synchronously, and locator and page assertions reject after retrying until their timeout, 5 s by default. Nothing reports the failure for you, so catch it; otherwise it surfaces as an uncaught error or an unhandled rejection.
299
+
300
+ #### Locator assertions
301
+
302
+ | `expect(locator)` | Status | Notes |
303
+ | --------------------------------------------------------------------------------------------------------------------------------------------- | :----: | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
304
+ | [`toBeAttached`](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-be-attached) | ✅ | |
305
+ | [`toBeChecked`](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-be-checked) | ✅ | |
306
+ | [`toBeDisabled`](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-be-disabled) | ✅ | |
307
+ | [`toBeEditable`](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-be-editable) | ✅ | |
308
+ | [`toBeEmpty`](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-be-empty) | ✅ | |
309
+ | [`toBeEnabled`](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-be-enabled) | ✅ | |
310
+ | [`toBeFocused`](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-be-focused) | ✅ | |
311
+ | [`toBeHidden`](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-be-hidden) | ✅ | |
312
+ | [`toBeInViewport`](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-be-in-viewport) | ✅ | |
313
+ | [`toBeVisible`](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-be-visible) | ✅ | |
314
+ | [`toContainClass`](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-contain-class) | ⚠️ | A RegExp `expected` rejects the returned promise, where Playwright throws synchronously. |
315
+ | [`toContainText`](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-contain-text) | ✅ | |
316
+ | [`toHaveAccessibleDescription`](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-have-accessible-description) | ✅ | |
317
+ | [`toHaveAccessibleErrorMessage`](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-have-accessible-error-message) | ✅ | |
318
+ | [`toHaveAccessibleName`](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-have-accessible-name) | ✅ | |
319
+ | [`toHaveAttribute`](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-have-attribute) | ✅ | |
320
+ | [`toHaveCSS`](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-have-css) | ✅ | |
321
+ | [`toHaveClass`](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-have-class) | ✅ | |
322
+ | [`toHaveCount`](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-have-count) | ✅ | |
323
+ | [`toHaveId`](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-have-id) | ✅ | |
324
+ | [`toHaveJSProperty`](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-have-js-property) | ✅ | |
325
+ | [`toHaveRole`](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-have-role) | ⚠️ | A non-string role rejects the returned promise, where Playwright throws synchronously. |
326
+ | [`toHaveScreenshot`](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-have-screenshot-1) | 🚫 | Comparing against a stored screenshot requires the filesystem and the test runner. |
327
+ | [`toHaveText`](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-have-text) | ✅ | |
328
+ | [`toHaveValue`](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-have-value) | ✅ | |
329
+ | [`toHaveValues`](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-have-values) | ✅ | |
330
+ | [`toMatchAriaSnapshot`](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-match-aria-snapshot) | ⚠️ | Inline string form only. The options-only form, which reads a snapshot file, rejects; snapshot updates and a configured `children` default do not apply. |
331
+
332
+ #### Page assertions
333
+
334
+ | `expect(page)` | Status | Notes |
335
+ | -------------------------------------------------------------------------------------------------------------------- | :----: | ------------------------------------------------------------------------------------------- |
336
+ | [`toHaveScreenshot`](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot-1) | 🚫 | Comparing against a stored screenshot requires the filesystem and the test runner. |
337
+ | [`toHaveTitle`](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-title) | ✅ | Also accepts `ignoreCase`, which Playwright's `toHaveTitle` does not. |
338
+ | [`toHaveURL`](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-url) | ⚠️ | String expectations are not resolved against a configured `baseURL`; this runtime has none. |
339
+ | [`toMatchAriaSnapshot`](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-match-aria-snapshot) | ❌ | |
340
+
341
+ #### Generic expect
342
+
343
+ | API | Status | Notes |
344
+ | ------------------------------------------------------------------------------------------------------- | :----: | -------------------------------------------------------------------------------------------------------------- |
345
+ | [`expect(value)`](https://playwright.dev/docs/api/class-genericassertions) | ✅ | Generic value matchers, asymmetric matchers, `.not`, `.resolves`, `.rejects` and custom messages. |
346
+ | [`expect.configure()`](https://playwright.dev/docs/test-assertions#expectconfigure) | ⚠️ | Supports `timeout` and `message`; `soft: true` throws because there is no test runner to report soft failures. |
347
+ | [`expect.extend()`](https://playwright.dev/docs/test-assertions#add-custom-matchers-using-expectextend) | ✅ | |
348
+ | [`expect.poll()`](https://playwright.dev/docs/test-assertions#expectpoll) | ✅ | |
349
+ | [`expect.soft()`](https://playwright.dev/docs/test-assertions#soft-assertions) | 🚫 | Throws because there is no test runner to report soft failures. |
350
+ | [`toPass()`](https://playwright.dev/docs/test-assertions#expecttopass) | ✅ | |
351
+ | API response assertions | 🚫 | `toBeOK()` operates on Playwright's Node-side API response objects, which have no in-document counterpart. |
352
+ | Filesystem-backed snapshot assertions | 🚫 | `toMatchSnapshot()` requires filesystem and test-runner state that is unavailable in the browser document. |
353
+
354
+ ### ElementHandle and JSHandle
355
+
356
+ The `ElementHandle` and `JSHandle` objects this package returns, for example from `$()`, `waitForSelector()`, `evaluateHandle()` or `locator.elementHandle()`.
357
+
358
+ **Not available:** `ElementHandle.contentFrame()`, `ownerFrame()`, `screenshot()` and `tap()`.
359
+
360
+ **Differences from Playwright:**
361
+
362
+ | Member | playwright-lite | Playwright |
363
+ | --------------------------------- | ----------------------------- | ---------------------------------------- |
364
+ | `ElementHandle.click()` | Does not wait for navigation. | Waits for a navigation the click starts. |
365
+ | `ElementHandle.waitForSelector()` | Rejects `strict`. | Accepts `strict`. |
366
+
367
+ <details>
368
+ <summary>Edge cases</summary>
369
+
370
+ - `toString()` describes the value as it was when the handle was first converted to a string.
371
+ - `toString()` of a handle to a `Proxy` prints the target's class name, such as `Object`, where Playwright prints `Proxy(Object)`.
372
+
373
+ </details>
374
+
375
+ ### Request and Response
376
+
377
+ **Reported:** The `fetch()` and `XMLHttpRequest` calls the current document makes while you are subscribed, through `page.on("request" | "response" | "requestfinished" | "requestfailed")`, `page.waitForRequest()`, `page.waitForResponse()` and `page.requests()`.
378
+
379
+ **Not reported:** Images, scripts, stylesheets, `navigator.sendBeacon`, `WebSocket`, `EventSource`, form submissions and navigations; calls made by another realm, an iframe or a service worker; a `fetch()` started or an `XMLHttpRequest` opened before the first subscription.
380
+
381
+ The package exports `Request` and `Response` types listing exactly the available members. Annotating with them is optional: `createPage()` returns Playwright's own `Page`, so code written against Playwright keeps type-checking.
382
+
383
+ **Not available:** `Request.allHeaders()`, `existingResponse()`, `frame()`, `headersArray()`, `redirectedFrom()`, `redirectedTo()`, `serviceWorker()`, `sizes()` and `timing()`; `Response.allHeaders()`, `frame()`, `fromServiceWorker()`, `headersArray()`, `headerValues()`, `httpVersion()`, `securityDetails()` and `serverAddr()`. Calling one throws a `TypeError`.
384
+
385
+ **Differences from Playwright:**
386
+
387
+ | Member | playwright-lite | Playwright |
388
+ | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------- |
389
+ | `resourceType()` | `"fetch"` or `"xhr"`. | The browser's resource type. |
390
+ | `isNavigationRequest()` | Always `false`. | `true` for navigation requests. |
391
+ | `Request.headers()`, `Request.headerValue()` | The headers the call set: the `Request` headers of a `fetch()`, the `setRequestHeader()` values of an `XMLHttpRequest`. `Cookie`, `Origin`, `User-Agent`, other browser-added headers and the `Content-Type` an `XMLHttpRequest` derives from its body are missing. | `headerValue()` reads the headers that went on the wire. |
392
+ | `Response.headers()`, `Response.headerValue()` | The headers the browser exposes to the document: never `Set-Cookie`, and for a cross-origin response only the CORS-safelisted names plus those its `Access-Control-Expose-Headers` lists. | `headerValue()` reads the headers received on the wire. |
393
+ | `postData()`, `postDataBuffer()`, `postDataJSON()` | Read a string, `URLSearchParams`, `ArrayBuffer` or typed-array body passed as the `fetch()` `body` option or the `send()` argument. A `Blob`, `FormData` or `ReadableStream` body, or one carried by a `Request` argument to `fetch()`, reports `null`. | Read the body the browser sent. |
394
+ | `postDataBuffer()`, `Response.body()` | `Uint8Array`. | Node.js `Buffer`. |
395
+ | `failure().errorText` | The name and message of the error `fetch()` rejected with, or its `AbortSignal`'s reason; for an `XMLHttpRequest`, `XMLHttpRequest:` plus the event that ended it: `error`, `timeout` or `abort`. | The browser's `net::ERR_*` code. |
396
+
397
+ - A redirect chain is one request and one response: the request reports the URL the document asked for, the response the final URL, and no event fires per hop.
398
+
399
+ <details>
400
+ <summary>Edge cases</summary>
401
+
402
+ - An `XMLHttpRequest` opened again while in flight reports `failure().errorText` as `XMLHttpRequest: abort`.
403
+ - `body()`, `text()` and `json()` of an `XMLHttpRequest` with the default `responseType` return the body re-encoded as UTF-8, so a binary or non-UTF-8 body does not come back byte for byte; Playwright returns the bytes received.
404
+ - `body()`, `text()` and `json()` of an `XMLHttpRequest` reject when it set `responseType` to `"json"` or `"document"`.
405
+ - `Response.finished()` resolves once the response body has ended. A `fetch()` response's `body()`, `text()` and `json()` still answer after the page consumed the body.
406
+
407
+ </details>
408
+
409
+ ### Dialog
410
+
411
+ `page.on("dialog")` reports the `window.alert()`, `window.confirm()` and `window.prompt()` calls the current document makes, wrapped as Playwright's `Dialog`. The package exports a `Dialog` type listing exactly its members.
412
+
413
+ **Differences from Playwright:**
414
+
415
+ | Member | playwright-lite | Playwright |
416
+ | ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- |
417
+ | `accept()`, `dismiss()` | Decide the result only when called synchronously in a `dialog` listener, because `alert()`, `confirm()` and `prompt()` block the page's script until they return. | Settle the dialog whenever they are called. |
418
+
419
+ - A dialog no listener settles synchronously is dismissed once every listener has run: `alert()` returns `undefined`, `confirm()` `false`, `prompt()` `null`. Playwright auto-dismisses only when the page has no `dialog` listener.
420
+ - With no `dialog` listener, the browser shows its own dialog and the page waits for a person, where Playwright dismisses it.
421
+ - A dialog from `waitForEvent("dialog")` is already dismissed when the promise resolves, so `(await page.waitForEvent("dialog")).accept()` rejects.
422
+ - `beforeunload` dialogs are never reported.
423
+
424
+ <details>
425
+ <summary>Edge cases</summary>
426
+
427
+ - Pages sharing one window share one dialog settlement: the first `accept()` or `dismiss()` call from any of them wins, and a later one rejects.
428
+
429
+ </details>
430
+
431
+ ### ConsoleMessage
432
+
433
+ `page.on("console")` and `page.consoleMessages()` report the document's own `console.log()`, `debug()`, `info()`, `error()`, `warn()`, `dir()`, `dirxml()`, `table()`, `trace()`, `clear()`, `group()`, `groupCollapsed()`, `groupEnd()`, `assert()`, `profile()`, `profileEnd()`, `count()`, `timeEnd()` and `timeLog()` calls, wrapped as Playwright's `ConsoleMessage`.
434
+
435
+ **Differences from Playwright:**
436
+
437
+ | Member | playwright-lite | Playwright |
438
+ | ----------------------------------------------- | ----------------------------------------------------------------------------------- | --------------------------------------------------------------------- |
439
+ | `text()` of `count()`, `timeEnd()`, `timeLog()` | The label the call passed. | Includes the count or elapsed time the browser computes. |
440
+ | `page.consoleMessages()` | Returns the same messages for `filter: "all"` and the default `"since-navigation"`. | `"since-navigation"` returns only messages since the last navigation. |
441
+
442
+ - Only `console.*` calls made after you first subscribe with `page.on("console")` or call `page.consoleMessages()` are reported. `consoleMessages()` keeps collecting from then on, as `requests()` does.
443
+ - Browser-generated entries, such as a failed resource load or a Content-Security-Policy violation report, are never reported, because they never call a `console.*` method.
444
+
445
+ <details>
446
+ <summary>Edge cases</summary>
447
+
448
+ - `text()` previews objects and arrays one level deep, each entry rendered like a `JSHandle` preview, with no truncation and no sparse-array markers. A class instance passed directly lists its own members (`{a: 1}`) where Playwright prints its constructor name (`Foo`).
449
+ - Building a `text()` preview never calls the page's getters, but it runs a `Proxy` argument's traps, which the browser's own preview never does. A trap that throws previews that argument as `Object`; a revoked `Proxy` argument stops the message from being reported, while the `console.*` call itself behaves as it does unobserved.
450
+ - `location()` is best-effort and can be off by a frame.
451
+ - While a `console.*` method is wrapped, stacks the browser captures gain a frame inside this package, including DevTools' call-site link for a logged message and the stack `console.trace()` prints.
452
+ - A `console.*` call made inside a `console` listener is forwarded to the console but fires no further `console` event, so a listener that logs cannot trigger itself.
246
453
 
247
- Returned `ElementHandle` objects do not implement `contentFrame()`, `ownerFrame()`, `screenshot()`, or `tap()`. Their `$()` ignores `strict`; `click()` does not wait for navigation; `waitForSelector()` rejects `strict`; `evaluate()` rejects `exposeFunctions: true`. A returned `JSHandle` or `ElementHandle` builds its `toString()` preview from the referenced value inside the document instead of reading a browser-process object description: the preview describes the value as it is when the handle is first converted to a string, and a handle to a `Proxy` prints the target's class name, such as `Object`, where Playwright prints `Proxy(Object)`.
454
+ </details>
248
455
 
249
456
  ## License
250
457