ohos-playwright 0.3.3 → 0.3.4

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
@@ -69,9 +69,9 @@ The following Playwright APIs have been validated on ArkWeb / HarmonyOS 6.1 (Chr
69
69
  | WebSocket | `page.routeWebSocket()` (requires Playwright ≥ 1.48) — intercepts WebSocket connections |
70
70
  | Accessibility (CDP) | `newCDPSession` + `Accessibility.getFullAXTree` — returns the full AX node tree |
71
71
  | Navigation history | `page.goBack()`, `page.goForward()` — implemented via `history.back/forward()` + CDP polling; returns when the history index changes |
72
- | Hover events | `locator.hover()` — fires `mouseover` / `mouseenter` event listeners; CSS `:hover` pseudo-class is **not** activated (adapter uses JS dispatch, not a real pointer move) |
72
+ | Hover events | `locator.hover()` — fires `mouseover` / `mouseenter` event listeners **and** activates the CSS `:hover` pseudo-class via the real `Input.dispatchMouseEvent` path. Falls back to JS-only dispatch (DOM events without `:hover`) if Playwright's `boundingBox()` hangs for more than 5 s. |
73
73
  | Locale (partial) | `emulateLocale(tag)` fixture — rewrites `navigator.language` / `navigator.languages` via `addInitScript`; does not affect HTTP `Accept-Language` or browser UI locale |
74
- | User-Agent (partial) | `emulateDevice({ userAgent })` — overrides `navigator.userAgent` for page scripts; call before `page.goto()` for the override to take effect. HTTP `User-Agent` request headers are not changed. |
74
+ | User-Agent | `emulateDevice({ userAgent })` — overrides both `navigator.userAgent` and the outgoing HTTP `User-Agent` header; call before `page.goto()` for the override to take effect. (`context.setExtraHTTPHeaders({ 'User-Agent': ... })` does **not** override UA — ArkWeb preserves the browser default there.) |
75
75
  | Service Workers | `navigator.serviceWorker.register()` — works on HTTPS pages; `navigator.serviceWorker` is `undefined` on non-secure origins (`data:`, `about:blank`) as in all browsers |
76
76
  | Clipboard | `navigator.clipboard.writeText()` / `readText()` — works on HTTPS pages after `context.grantPermissions(['clipboard-read', 'clipboard-write'])`; unavailable on non-secure origins |
77
77
 
@@ -99,7 +99,7 @@ test('precise viewport', async ({ page, emulateDevice }) => {
99
99
  > **⚠️ `isMobile: true` does not produce a precise viewport on ArkWeb.**
100
100
  > When `Emulation.setDeviceMetricsOverride` is called with `mobile: true`, ArkWeb enables its mobile layout-viewport compatibility path and renders at the 980px default mobile layout viewport — the passed `width`/`height` are effectively ignored (`window.innerWidth` reads 980 regardless). `deviceScaleFactor` has no effect on this. Use `isMobile: false` when you need an exact pixel viewport.
101
101
  >
102
- > **`userAgent` override is JS-layer only.** Call `await emulateDevice({ userAgent: '...' })` before `page.goto(url)` — `navigator.userAgent` on the destination page will reflect the override. The HTTP `User-Agent` request header is not changed (ArkWeb does not honour CDP UA overrides for outgoing headers).
102
+ > **`userAgent` override applies to both JS and HTTP layers.** Call `await emulateDevice({ userAgent: '...' })` before `page.goto(url)` — `navigator.userAgent` on the destination page will reflect the override, and the outgoing HTTP `User-Agent` header is rewritten as well. Use `emulateDevice` rather than `context.setExtraHTTPHeaders({ 'User-Agent': ... })` — the latter does not override UA on ArkWeb.
103
103
 
104
104
  ### `tap` fixture
105
105
 
@@ -121,10 +121,10 @@ Coordinates are CSS pixels relative to the viewport (same as `touchscreen.tap`).
121
121
  ## Limitations
122
122
 
123
123
  - **Chromium only.** firefox and webkit aren't available on HarmonyOS.
124
- - **`newPage()` after `browser.newContext()` throws.** The raw `browser.newContext()` call succeeds (returns an empty context, 0 pages) but `ctx.newPage()` fails with `Cannot read properties of undefined (reading '_page')`. ArkWeb's CDP `Target.createBrowserContext` / `Target.createTarget` aren't usable in `connectOverCDP` mode. Tests share one context and one page isolate with `localStorage.clear()` + `page.reload()`. For device emulation use the `emulateDevice` fixture instead of `browser.newContext({ ...device })`.
124
+ - **Multi-context / multi-page is opt-in.** By default the adapter intercepts `browser.newContext()` with a friendly error. The root cause: ArkWeb's `Target.createTarget` returns a target with `type: 'other'`, not `'page'`, so Playwright's `crBrowser._onAttachedToTarget` skips it and `ctx.newPage()` throws `Cannot read properties of undefined (reading '_page')`. To opt in, set `process.env.PW_CHROMIUM_ATTACH_TO_OTHER = '1'` **before** importing `@playwright/test` — Playwright's upstream escape hatch then treats `'other'` targets as pages and `browser.newContext()` / `ctx.newPage()` work normally. Trade-off: ArkWeb's internal `'other'` targets (shared workers, etc.) also get treated as pages, which can perturb tests that use `touchscreen.tap()` or `context.recordHar()`. For single-context tests (the common case) leave the env unset and isolate with `localStorage.clear()` + `page.reload()`. For device emulation use the `emulateDevice` fixture instead of `browser.newContext({ ...device })`.
125
125
  - **HTTP `User-Agent` header can be changed via CDP, but not via `setExtraHTTPHeaders`.** `Emulation.setUserAgentOverride` (sent by `emulateDevice({ userAgent })`) rewrites both `navigator.userAgent` and the outgoing HTTP UA header — call it before `page.goto()` so it applies to the destination page. `context.setExtraHTTPHeaders({ 'User-Agent': '...' })` does **not** override UA on ArkWeb (the header is preserved as browser default).
126
126
  - **`locator.hover()` activates CSS `:hover` on typical pages.** The fixture goes through the real `Input.dispatchMouseEvent` path via `page.mouse.move`. On pages where Playwright's `boundingBox()` hangs (e.g. some MutationObserver configurations), it falls back to a JS `mouseover` dispatch after a 5 s timeout — DOM listeners still fire but `:hover` will not activate in that fallback path.
127
- - **`page.mouse.move()` / `page.mouse.down()` / `page.mouse.up()` work normally.** DOM listeners receive `mousemove` / `mousedown` / `mouseup` / `click` in ArkWeb just as they do on stock Chromium. A narrow edge case (data: URL with embedded newlines AND a shared function reference registered for multiple event types on the same element) was previously documented; reaudit could not reproduce it. The `mouseMove` / `mouseDown` / `mouseUp` fixtures remain available as JS-dispatch fallbacks for unusual cases.
127
+ - **`page.mouse.move()` / `page.mouse.down()` / `page.mouse.up()` work normally.** DOM listeners receive `mousemove` / `mousedown` / `mouseup` / `click` in ArkWeb just as they do on stock Chromium. A previously documented narrow edge case (data: URL with embedded newlines AND a shared function reference registered for multiple event types) could not be reproduced in the v0.3.3 reaudit. The `mouseMove` / `mouseDown` / `mouseUp` fixtures remain in the API surface for backward compatibility but are no longer needed for normal use.
128
128
  - **`emulateDevice({ isMobile: true })` does not apply the viewport** — see the note in the `emulateDevice` fixture section above.
129
129
  - **`exposeBinding({ handle: true })` is not supported.** Playwright 1.60's public `exposeBinding` signature is `(name, callback)` — the third `{ handle }` argument is silently ignored. The callback receives a serialized form of the argument (DOM nodes arrive as the string `"ref: <Node>"`), not a JSHandle. Use `exposeFunction` or a plain `exposeBinding` callback that reads element properties directly and returns a by-value object.
130
130
  - **`process.platform` reads `'linux'`** during the run — Playwright's `calculatePlatform()` only branches on linux/darwin/win32 (falls through to `<unknown>` on openharmony), and 20+ other sites in `playwright-core` read `process.platform` directly (UA string assembly, headful window insets, modifier keys, registry). The adapter patches `process.platform` to `'linux'` and pins `PLAYWRIGHT_HOST_PLATFORM_OVERRIDE=ubuntu24.04-arm64` for `calculatePlatform()`. For real platform checks use `process.env.OHOS_PW_HOST`.
package/dist/fixture.mjs CHANGED
@@ -20,24 +20,30 @@ export const test = base.extend({
20
20
  browser: [
21
21
  async ({}, use) => {
22
22
  const browser = await chromium.connectOverCDP(readEndpoint());
23
- // ArkWeb CDP does not implement Target.createBrowserContext — connectOverCDP
24
- // reuses the single existing context. browser.newContext() returns without
25
- // throwing but produces an empty shell (0 pages) that silently fails every
26
- // subsequent operation. Intercept and throw an explicit, actionable error
27
- // so users aren't misled by the false-positive success.
28
- const origNewContext = browser.newContext.bind(browser);
29
- browser.newContext = (() => {
30
- throw new Error('browser.newContext() is not supported in ArkWeb CDP mode (single context only). ' +
31
- 'Tests share one context and one page — isolate with localStorage.clear() + page.reload(). ' +
32
- 'See ohos-playwright README "Limitations" section.');
33
- });
34
- try {
35
- await use(browser);
23
+ // ArkWeb's Target.createTarget returns type='other', so Playwright's
24
+ // crBrowser._onAttachedToTarget skips it and ctx.newPage() throws
25
+ // "Cannot read properties of undefined (reading '_page')". The upstream
26
+ // PW_CHROMIUM_ATTACH_TO_OTHER=1 escape hatch fixes newContext/newPage
27
+ // but also makes Playwright treat internal "other" targets as pages
28
+ // (perturbs touchscreen / recordHar). When the user has not opted in,
29
+ // intercept browser.newContext() with a friendly, actionable error.
30
+ if (!process.env.PW_CHROMIUM_ATTACH_TO_OTHER) {
31
+ const origNewContext = browser.newContext.bind(browser);
32
+ browser.newContext = (() => {
33
+ throw new Error('browser.newContext() is not supported on ArkWeb unless you opt in via ' +
34
+ 'process.env.PW_CHROMIUM_ATTACH_TO_OTHER=\'1\' before importing @playwright/test. ' +
35
+ 'See ohos-playwright README "Limitations" → "Multi-context" for trade-offs.');
36
+ });
37
+ try {
38
+ await use(browser);
39
+ }
40
+ finally {
41
+ ;
42
+ browser.newContext = origNewContext;
43
+ }
36
44
  }
37
- finally {
38
- // Restore in case the browser object is reused across workers.
39
- ;
40
- browser.newContext = origNewContext;
45
+ else {
46
+ await use(browser);
41
47
  }
42
48
  },
43
49
  { scope: 'worker' },
package/dist/register.mjs CHANGED
@@ -21,5 +21,19 @@ if (process.platform === 'openharmony') {
21
21
  // process. Safe because we connect over CDP and never touch Playwright's
22
22
  // bundled browser binaries. Clean fix requires upstream openharmony branch.
23
23
  Object.defineProperty(process, 'platform', { value: 'linux' });
24
+ // ArkWeb's Target.createTarget returns a target with type='other', not
25
+ // 'page'. Playwright's crBrowser._onAttachedToTarget (crBrowser.ts:191)
26
+ // only registers 'page' targets into _crPages — 'other' targets get
27
+ // detached and ctx.newPage() throws "Cannot read properties of undefined
28
+ // (reading '_page')".
29
+ //
30
+ // PW_CHROMIUM_ATTACH_TO_OTHER (crBrowser.ts:181) is playwright's upstream
31
+ // escape hatch: treat type='other' as page so newContext/newPage work.
32
+ // It's opt-in (not set here by default) because it also makes Playwright
33
+ // treat ArkWeb's internal "other" targets (shared workers, etc.) as pages,
34
+ // which perturbs page-list assumptions in tests that use touchscreen /
35
+ // recordHar. Users who need multi-context set it explicitly:
36
+ // process.env.PW_CHROMIUM_ATTACH_TO_OTHER = '1'
37
+ // before importing @playwright/test.
24
38
  register('./loader.mjs', import.meta.url);
25
39
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ohos-playwright",
3
- "version": "0.3.3",
3
+ "version": "0.3.4",
4
4
  "description": "Playwright adapter for OpenHarmony / ArkWeb via hdc + CDP",
5
5
  "license": "MIT",
6
6
  "author": "social4hyq",