Skip to content

Cannot await cdp.on() rpc call to resolve #9655

@AriPerkkio

Description

@AriPerkkio

Describe the bug

On client side the cdp.on() is a synchronous function that leaves the underlying rpc call floating. There is no way to wait for the call to resolve. This makes using the API racy on user side.

session.on("Fetch.requestPaused", async (event) => {
  console.log("Fetch.requestPaused", event.request.url);
  await session.send("Fetch.continueRequest", { requestId: event.requestId });
});

// This gets stuck
await session.send("Fetch.enable");

By adding explicit timeout after the event listener, this issue is resolved:

session.on("Fetch.requestPaused", async (event) => {});

+ await new Promise(resolve => setTimeout(resolve, 200))

- // This gets stuck
await session.send("Fetch.enable");

The rpc().trackCdpEvent() returns promise that's left floating:

on(event: string, listener: (payload: any) => void) {
const listenerId = getId(listener)
listeners[event] = listeners[event] || []
listeners[event].push(listener)
rpc().trackCdpEvent(sessionId, 'on', event, listenerId).catch(error)
return cdp
},

Tested quickly by returning the promise from on instead of whole cdp and it works. Though this would be breaking change, unless we make whole cdp a thennable.

- session.on("Fetch.requestPaused", async (event) => {
+ await session.on("Fetch.requestPaused", async (event) => {
  console.log("Fetch.requestPaused", event.request.url);
  await session.send("Fetch.continueRequest", { requestId: event.requestId });
});

// No longer stuck ✅ 
await session.send("Fetch.enable");

Reproduction

Add this in Vitest monorepo tests:

import { beforeAll, test } from "vitest";
import { cdp } from "vitest/browser";

beforeAll(async () => {
  const session = cdp();

  session.on("Fetch.requestPaused", async (event) => {
    console.log("Fetch.requestPaused", event.request.url);
    await session.send("Fetch.continueRequest", { requestId: event.requestId });
  });

  //   await new Promise((r) => setTimeout(r, 200));
  await session.send("Fetch.enable");
});

test("example test", async () => {
  await fetch("https://avatars.githubusercontent.com/u/95747107?s=200&v=4")
    .then((res) => res.blob())
    .then((blob) => console.log(blob.type, blob.size));
});
import { playwright } from "@vitest/browser-playwright";
import { defineConfig } from "vitest/config";

export default defineConfig({
  test: {
    browser: {
      enabled: true,
      headless: true,
      provider: playwright(),
      instances: [{ browser: "chromium" }],
    },
  },
});
 RUN  v4.1.0-beta.3 /Users/ari/Git/examples

   chromium  test/example.test.ts (1 test | 1 failed) 15083ms
   × example test 15079ms

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Failed Tests 1 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯

 FAIL   chromium  test/example.test.ts > example test
Error: Test timed out in 15000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".

Failure screenshot:
  - test/__screenshots__/example.test.ts/example-test-1.png

  test/example.test.ts:16:0
     13|   await session.send("Fetch.enable");
     14| });
     15|
       | ^
     16| test("example test", async () => {
     17|   await fetch("https://avatars.githubusercontent.com/u/95747107?s=200&v=4")

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/1]


 Test Files  1 failed (1)
      Tests  1 failed (1)
   Start at  10:28:46
   Duration  15.87s (transform 0ms, setup 0ms, import 6ms, tests 15.08s, environment 0ms)ELIFECYCLETest failed. See above for more details.

System Info

System:
    OS: macOS 26.2
    CPU: (14) arm64 Apple M4 Pro
    Memory: 1.12 GB / 24.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 22.22.0 - /Users/ari/.nvm/versions/node/v22.22.0/bin/node
    npm: 10.9.4 - /Users/ari/.nvm/versions/node/v22.22.0/bin/npm
    pnpm: 10.29.2 - /Users/ari/.nvm/versions/node/v22.22.0/bin/pnpm
  Browsers:
    Safari: 26.2
  npmPackages:
    @vitest/browser-playwright: * => 4.1.0-beta.3 
    vitest: * => 4.1.0-beta.3

Used Package Manager

pnpm

Validations

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions