v11.4.0
Highlights
✨ webinspector cdp drives a device from Playwright and Puppeteer
A Chrome-protocol client can now attach to a page on the device and actually drive it. Everything below is a method or event that Chrome's protocol requires and WebKit's Web Inspector does not implement at all, so each one affected any CDP client rather than a particular app — and each is now synthesized from what WebKit does expose.
pymobiledevice3 webinspector cdp --port 9223
# then, in Node:
# const browser = await chromium.connectOverCDP('http://127.0.0.1:9223');
# const page = browser.contexts()[0].pages()[0];
# await page.goto('https://example.com/');
# await page.locator('#search').fill('hello');
# await page.screenshot({ path: 'shot.png' });What works now that did not before:
- Attaching to a page that was already open. The execution context was never announced for it, so the client waited forever for a page it could already see (#1900).
- Navigation.
page.goto(),page.reload()andwaitForNavigation()hung until they timed out: the modernPage.lifecycleEventwas never emitted, andPage.navigatedid not report the document it started, so a client waited for an in-page navigation that a real page load never sends (#1902). - Clicking and hovering. Every interaction spun in its actionability check until timeout, because the two calls a client makes before acting on an element —
DOM.scrollIntoViewIfNeededandDOM.getContentQuads— did not exist (#1903). - Screenshots.
page.screenshot()died before any capture was attempted.Page.getLayoutMetricsandPage.captureScreenshotare now answered, the capture built on WebKit's ownPage.snapshotRect(#1904). - Typing.
fill(),pressSequentially(),type(),press()andkeyboard.insertText()all left fields empty — silently, with every call reporting success, so a test could assert a filled field and be wrong. Text is written through the prototype's native value setter, so a framework that tracks its inputs actually sees the change (#1907). - Child frames. Frames were never announced, so a client never learned they existed; a connection attaching after a frame already existed could not see it at all. Frame discovery, reads and re-attachment now work, including cross-origin frames nested several levels deep (#1908).
🐛 Fixed a crash that took down the whole debugger connection
Attaching to a page that was already attached handed back the existing session id rather than opening a second session. Two sessions numbering their requests independently then received each other's answers, which trips an assertion inside the client and drops the entire connection — not just the extra session. page.context().newCDPSession() hits this, which is exactly the escape hatch people reach for.
📝 Known limitations
Update: the first two were fixed in v11.4.2. Both turned out to be defects in the bridge rather than limits of the platform — the second in particular was a parameter-name mismatch (Chrome's
userGesturevs WebKit'semulateUserGesture), not the focus restriction described below. Upgrade rather than working around them.
Interacting with a node inside a child frame through a locator (Fixed in v11.4.2.click(),evaluate()) is not supported yet; it needs Chrome's node identity model, which WebKit does not expose. Tracked in #1908.Fixed in v11.4.2.fill()into a cross-origin frame reports success and leaves the field empty. An element inside a cross-origin frame cannot be given focus from an evaluated script on this platform, andfill()selects, focuses, then types. Setting the value directly inside that frame works.- The first
frameLocator()call into a newly created frame takes several seconds while the client bootstraps its injected script in that frame over USB. It is not a hang.
What's Changed
- f17495c web_protocol: Support Playwright connectOverCDP against a WKWebView (#1901) (@doronz88)
- c11088a tests: answer the CDP server's websocket keepalive pings (#1906) (@doronz88)
- f16d7cf web_protocol: Report the navigation lifecycle to CDP clients (#1906) (@doronz88)
- 6e1df23 web_protocol: Implement the CDP screenshot methods (#1906) (@doronz88)
- 87f469e web_protocol: Implement the CDP interaction methods (#1906) (@doronz88)
- a2b5911 web_protocol: Keep each frame in its own execution context (#1906) (@doronz88)
- 7ca4a15 web_protocol: Tag remote objects with the subtype Chrome reports (#1906) (@doronz88)
- a0293b4 web_protocol: Type text a CDP client sends into the page (#1906) (@doronz88)
- 6434aa9 web_protocol: Refuse an isolated world for a frame we cannot reach (#1906) (@doronz88)
- 7432218 web_protocol: Make child frames reachable by CDP clients (#1906) (@doronz88)
- 63db993 web_protocol: Reach into child frames the way a CDP client does (#1906) (@doronz88)
- daf7231 web_protocol: Type into the document that truly holds the focus (#1906) (@doronz88)
- b18faa2 web_protocol: Give every attachment to a page its own CDP session (#1906) (@doronz88)
Full Changelog: v11.3.1...v11.4.0