You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Network.emulateNetworkConditions is the standard CDP entry point for toggling a target offline (or applying latency / bandwidth throttling). Lightpanda's Network domain doesn't dispatch the method, so every call rejects with -31998 UnknownMethod. Clients that rely on the offline toggle to assert PWA / service-worker / "you are offline" UI behaviour can't drive that branch through Lightpanda — they get neither real offline emulation nor a "best-effort" no-op, just an outright dispatch error that aborts the test.
Today's behavior
Network.emulateNetworkConditions is missing from the action enum in src/cdp/domains/network.zig (processMessage). Any CDP client (chrome-remote-interface, Puppeteer, Playwright, Selenium's execute_cdp, raw websocket) sending the method receives -31998 UnknownMethod and can neither emulate offline conditions nor branch on whether the method exists — the rejection is indistinguishable from any other unknown-method response.
sequenceDiagram
participant Client as CDP Client
participant LP as Lightpanda
participant Net as HttpClient + curl
Client->>LP: Network.emulateNetworkConditions offline=true
LP-->>Client: error -31998 UnknownMethod
Note over LP: action enum has no entry, processMessage rejects
Client->>LP: fetch via Runtime.evaluate
LP->>Net: HTTP GET /api/foo
Net-->>LP: 200 OK
LP-->>Client: response, offline toggle ignored
Loading
Expected behavior
Per the CDP protocol reference, Network.emulateNetworkConditions takes {offline, latency, downloadThroughput, uploadThroughput, connectionType?}. The offline flag is the load-bearing field for tests asserting PWA / offline-fallback UI: when true, subsequent HTTP transfers must fail as if the network were unreachable (Chrome surfaces this through Network.loadingFailed with errorText: "net::ERR_INTERNET_DISCONNECTED"; the in-page fetch / XHR reject with a TypeError).
Latency / bandwidth / connectionType are best-effort hints in Chrome and don't have to be honoured in a headless engine without a layout/timing pipeline — accepting them for protocol compatibility (and logging via .not_implemented) is sufficient. The offline toggle, however, must actually block transfers; otherwise the method is observationally a no-op that lies about success.
sequenceDiagram
participant Client as CDP Client
participant LP as Lightpanda
participant Net as HttpClient + curl
Client->>LP: Network.emulateNetworkConditions offline=true
LP->>Net: set HttpClient.offline = true
LP-->>Client: success
Client->>LP: fetch via Runtime.evaluate
LP->>Net: request()
Net-->>LP: error.InternetDisconnected, curl not called
LP-->>Client: Network.loadingFailed and JS TypeError
Client->>LP: Network.emulateNetworkConditions offline=false
LP->>Net: set HttpClient.offline = false
LP-->>Client: success
Client->>LP: fetch via Runtime.evaluate
LP->>Net: HTTP GET /api/foo, curl path restored
Net-->>LP: 200 OK
LP-->>Client: response
Loading
Reproducer
Self-contained: one HTML fixture, one shell harness, one Node CDP driver. The harness starts lightpanda serve and a Python HTTP server, then drives the browser via raw websocket (ws) to (1) confirm a baseline fetch succeeds, (2) call Network.emulateNetworkConditions {offline: true}, (3) re-attempt the fetch and assert it now rejects, (4) toggle back online and assert recovery.
src/cdp/domains/network.zig — processMessage action enum + a new emulateNetworkConditions handler. The offline toggle itself is a single boolean checked at the top of Client.request in src/browser/HttpClient.zig before the layer chain. Latency / bandwidth / connectionType params can be accepted for protocol compatibility and logged via .not_implemented until a future PR wires them through.
Environment
Lightpanda: nightly 1.0.0-dev.6246+4f33d64c5 (HEAD of main as of filing)
OS: macOS 14 (darwin aarch64)
CDP client: raw ws Node module over the standard CDP websocket
Summary
Network.emulateNetworkConditionsis the standard CDP entry point for toggling a target offline (or applying latency / bandwidth throttling). Lightpanda'sNetworkdomain doesn't dispatch the method, so every call rejects with-31998 UnknownMethod. Clients that rely on the offline toggle to assert PWA / service-worker / "you are offline" UI behaviour can't drive that branch through Lightpanda — they get neither real offline emulation nor a "best-effort" no-op, just an outright dispatch error that aborts the test.Today's behavior
Network.emulateNetworkConditionsis missing from the action enum insrc/cdp/domains/network.zig(processMessage). Any CDP client (chrome-remote-interface, Puppeteer, Playwright, Selenium'sexecute_cdp, raw websocket) sending the method receives-31998 UnknownMethodand can neither emulate offline conditions nor branch on whether the method exists — the rejection is indistinguishable from any other unknown-method response.sequenceDiagram participant Client as CDP Client participant LP as Lightpanda participant Net as HttpClient + curl Client->>LP: Network.emulateNetworkConditions offline=true LP-->>Client: error -31998 UnknownMethod Note over LP: action enum has no entry, processMessage rejects Client->>LP: fetch via Runtime.evaluate LP->>Net: HTTP GET /api/foo Net-->>LP: 200 OK LP-->>Client: response, offline toggle ignoredExpected behavior
Per the CDP protocol reference,
Network.emulateNetworkConditionstakes{offline, latency, downloadThroughput, uploadThroughput, connectionType?}. Theofflineflag is the load-bearing field for tests asserting PWA / offline-fallback UI: when true, subsequent HTTP transfers must fail as if the network were unreachable (Chrome surfaces this throughNetwork.loadingFailedwitherrorText: "net::ERR_INTERNET_DISCONNECTED"; the in-pagefetch/ XHR reject with a TypeError).Latency / bandwidth / connectionType are best-effort hints in Chrome and don't have to be honoured in a headless engine without a layout/timing pipeline — accepting them for protocol compatibility (and logging via
.not_implemented) is sufficient. The offline toggle, however, must actually block transfers; otherwise the method is observationally a no-op that lies about success.sequenceDiagram participant Client as CDP Client participant LP as Lightpanda participant Net as HttpClient + curl Client->>LP: Network.emulateNetworkConditions offline=true LP->>Net: set HttpClient.offline = true LP-->>Client: success Client->>LP: fetch via Runtime.evaluate LP->>Net: request() Net-->>LP: error.InternetDisconnected, curl not called LP-->>Client: Network.loadingFailed and JS TypeError Client->>LP: Network.emulateNetworkConditions offline=false LP->>Net: set HttpClient.offline = false LP-->>Client: success Client->>LP: fetch via Runtime.evaluate LP->>Net: HTTP GET /api/foo, curl path restored Net-->>LP: 200 OK LP-->>Client: responseReproducer
Self-contained: one HTML fixture, one shell harness, one Node CDP driver. The harness starts
lightpanda serveand a Python HTTP server, then drives the browser via raw websocket (ws) to (1) confirm a baselinefetchsucceeds, (2) callNetwork.emulateNetworkConditions {offline: true}, (3) re-attempt the fetch and assert it now rejects, (4) toggle back online and assert recovery.repro.html:probe.js:repro.sh(orchestrator — kills any prior listener on the CDP/HTTP ports, startslightpanda serve+python3 -m http.server, asserts/json/versionreports a Lightpanda listener, then runsnode probe.js):cdp.jsis a ~150-LOC websocket wrapper (CDP create-target + attach-session + auto-sessionIdper call); happy to inline it on request.Run (against a stock build, no fix applied):
Run (against a build with the fix):
Likely fix location
src/cdp/domains/network.zig—processMessageaction enum + a newemulateNetworkConditionshandler. The offline toggle itself is a single boolean checked at the top ofClient.requestinsrc/browser/HttpClient.zigbefore the layer chain. Latency / bandwidth / connectionType params can be accepted for protocol compatibility and logged via.not_implementeduntil a future PR wires them through.Environment
1.0.0-dev.6246+4f33d64c5(HEAD ofmainas of filing)wsNode module over the standard CDP websocket