Skip to content

[Feature]: Access requested subprotocols when mocking websocket requests #40376

@rohitpaulk

Description

@rohitpaulk

🚀 Feature Request

When mocking websockets, it isn't possible to access the requested sub-protocols (specified via the Sec-WebSocket-Protocol header).

The feature request here is to expose this information using a method like ws.protocols() or ws.requestedProtocols().

Example

This could be used to implement mocks that behave differently based on the requested protocol:

await page.routeWebSocket('wss://example.com/ws', ws => {
  const protocols = ws.protocols();

  if (protocols.includes('chat.v2')) {
    ws.onMessage(message => {
      ws.send(JSON.stringify({ version: 2, echo: message }));
    });
  } else if (protocols.includes('chat.v1')) {
    ws.onMessage(message => ws.send(`v1:${message}`));
  } else {
    ws.close({ code: 1002, reason: 'Unsupported protocol' });
  }
});

Motivation

An example use of the Sec-WebSocket-Protocol header is in GraphQL clients, where the header is set to strings like graphql-ws (legacy) or graphql-transport-ws (modern standard).

Another example use in Zero, where initial query information is included in the Sec-WebSocket-Protocol header as an optimization to avoid an extra round trip.

When mocking APIs like this, it's necessary to have access to the value of this header to mock appropriately.

This is related to #7494, which was closed due to inactivity. The feature request there was to expose all headers, but that isn't feasible given that JS code can only set Sec-WebSocket-Protocol (the rest is automatically set by browser), and Playwright's mock affects the JS entry point.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions