docs: improve docs for WebSocketRoute (#33097)

This commit is contained in:
Dmitry Gozman 2024-10-15 02:07:03 -07:00 коммит произвёл GitHub
Родитель 2c05d294a8
Коммит 8a275e5a5b
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
4 изменённых файлов: 204 добавлений и 8 удалений

Просмотреть файл

@ -8,7 +8,7 @@ Whenever a [`WebSocket`](https://developer.mozilla.org/en-US/docs/Web/API/WebSoc
By default, the routed WebSocket will not connect to the server. This way, you can mock entire communcation over the WebSocket. Here is an example that responds to a `"request"` with a `"response"`.
```js
await page.routeWebSocket('/ws', ws => {
await page.routeWebSocket('wss://example.com/ws', ws => {
ws.onMessage(message => {
if (message === 'request')
ws.send('response');
@ -17,7 +17,7 @@ await page.routeWebSocket('/ws', ws => {
```
```java
page.routeWebSocket("/ws", ws -> {
page.routeWebSocket("wss://example.com/ws", ws -> {
ws.onMessage(message -> {
if ("request".equals(message))
ws.send("response");
@ -30,7 +30,7 @@ def message_handler(ws: WebSocketRoute, message: Union[str, bytes]):
if message == "request":
ws.send("response")
await page.route_web_socket("/ws", lambda ws: ws.on_message(
await page.route_web_socket("wss://example.com/ws", lambda ws: ws.on_message(
lambda message: message_handler(ws, message)
))
```
@ -40,13 +40,13 @@ def message_handler(ws: WebSocketRoute, message: Union[str, bytes]):
if message == "request":
ws.send("response")
page.route_web_socket("/ws", lambda ws: ws.on_message(
page.route_web_socket("wss://example.com/ws", lambda ws: ws.on_message(
lambda message: message_handler(ws, message)
))
```
```csharp
await page.RouteWebSocketAsync("/ws", ws => {
await page.RouteWebSocketAsync("wss://example.com/ws", ws => {
ws.OnMessage(message => {
if (message == "request")
ws.Send("response");
@ -56,6 +56,69 @@ await page.RouteWebSocketAsync("/ws", ws => {
Since we do not call [`method: WebSocketRoute.connectToServer`] inside the WebSocket route handler, Playwright assumes that WebSocket will be mocked, and opens the WebSocket inside the page automatically.
Here is another example that handles JSON messages:
```js
await page.routeWebSocket('wss://example.com/ws', ws => {
ws.onMessage(message => {
const json = JSON.parse(message);
if (json.request === 'question')
ws.send(JSON.stringify({ response: 'answer' }));
});
});
```
```java
page.routeWebSocket("wss://example.com/ws", ws -> {
ws.onMessage(message -> {
JsonObject json = new JsonParser().parse(message).getAsJsonObject();
if ("question".equals(json.get("request").getAsString())) {
Map<String, String> result = new HashMap();
result.put("response", "answer");
ws.send(gson.toJson(result));
}
});
});
```
```python async
def message_handler(ws: WebSocketRoute, message: Union[str, bytes]):
json_message = json.loads(message)
if json_message["request"] == "question":
ws.send(json.dumps({ "response": "answer" }))
await page.route_web_socket("wss://example.com/ws", lambda ws: ws.on_message(
lambda message: message_handler(ws, message)
))
```
```python sync
def message_handler(ws: WebSocketRoute, message: Union[str, bytes]):
json_message = json.loads(message)
if json_message["request"] == "question":
ws.send(json.dumps({ "response": "answer" }))
page.route_web_socket("wss://example.com/ws", lambda ws: ws.on_message(
lambda message: message_handler(ws, message)
))
```
```csharp
await page.RouteWebSocketAsync("wss://example.com/ws", ws => {
ws.OnMessage(message => {
using var jsonDoc = JsonDocument.Parse(message);
JsonElement root = jsonDoc.RootElement;
if (root.TryGetProperty("request", out JsonElement requestElement) && requestElement.GetString() == "question")
{
var response = new Dictionary<string, string> { ["response"] = "answer" };
string jsonResponse = JsonSerializer.Serialize(response);
ws.Send(jsonResponse);
}
});
});
```
**Intercepting**
Alternatively, you may want to connect to the actual server, but intercept messages in-between and modify or block them. Calling [`method: WebSocketRoute.connectToServer`] returns a server-side `WebSocketRoute` instance that you can send messages to, or handle incoming messages.

Просмотреть файл

@ -435,3 +435,122 @@ pwsh bin/Debug/netX/playwright.ps1 open --save-har=example.har --save-har-glob="
```
Read more about [advanced networking](./network.md).
## Mock WebSockets
The following code will intercept WebSocket connections and mock entire communcation over the WebSocket, instead of connecting to the server. This example responds to a `"request"` with a `"response"`.
```js
await page.routeWebSocket('wss://example.com/ws', ws => {
ws.onMessage(message => {
if (message === 'request')
ws.send('response');
});
});
```
```java
page.routeWebSocket("wss://example.com/ws", ws -> {
ws.onMessage(message -> {
if ("request".equals(message))
ws.send("response");
});
});
```
```python async
def message_handler(ws: WebSocketRoute, message: Union[str, bytes]):
if message == "request":
ws.send("response")
await page.route_web_socket("wss://example.com/ws", lambda ws: ws.on_message(
lambda message: message_handler(ws, message)
))
```
```python sync
def message_handler(ws: WebSocketRoute, message: Union[str, bytes]):
if message == "request":
ws.send("response")
page.route_web_socket("wss://example.com/ws", lambda ws: ws.on_message(
lambda message: message_handler(ws, message)
))
```
```csharp
await page.RouteWebSocketAsync("wss://example.com/ws", ws => {
ws.OnMessage(message => {
if (message == "request")
ws.Send("response");
});
});
```
Alternatively, you may want to connect to the actual server, but intercept messages in-between and modify or block them. Here is an example that modifies some of the messages sent by the page to the server, and leaves the rest unmodified.
```js
await page.routeWebSocket('wss://example.com/ws', ws => {
const server = ws.connectToServer();
ws.onMessage(message => {
if (message === 'request')
server.send('request2');
else
server.send(message);
});
});
```
```java
page.routeWebSocket("wss://example.com/ws", ws -> {
WebSocketRoute server = ws.connectToServer();
ws.onMessage(message -> {
if ("request".equals(message))
server.send("request2");
else
server.send(message);
});
});
```
```python async
def message_handler(server: WebSocketRoute, message: Union[str, bytes]):
if message == "request":
server.send("request2")
else:
server.send(message)
def handler(ws: WebSocketRoute):
server = ws.connect_to_server()
ws.on_message(lambda message: message_handler(server, message))
await page.route_web_socket("wss://example.com/ws", handler)
```
```python sync
def message_handler(server: WebSocketRoute, message: Union[str, bytes]):
if message == "request":
server.send("request2")
else:
server.send(message)
def handler(ws: WebSocketRoute):
server = ws.connect_to_server()
ws.on_message(lambda message: message_handler(server, message))
page.route_web_socket("wss://example.com/ws", handler)
```
```csharp
await page.RouteWebSocketAsync("wss://example.com/ws", ws => {
var server = ws.ConnectToServer();
ws.OnMessage(message => {
if (message == "request")
server.Send("request2");
else
server.Send(message);
});
});
```
For more details, see [WebSocketRoute].

Просмотреть файл

@ -10,7 +10,7 @@ Playwright provides APIs to **monitor** and **modify** browser network traffic,
## Mock APIs
Check out our [API mocking guide](./mock.md) to learn more on how to
Check out our [API mocking guide](./mock.md) to learn more on how to
- mock API requests and never hit the API
- perform the API request and modify the response
- use HAR files to mock network requests.
@ -723,7 +723,9 @@ Important notes:
## WebSockets
Playwright supports [WebSockets](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API) inspection out of the box. Every time a WebSocket is created, the [`event: Page.webSocket`] event is fired. This event contains the [WebSocket] instance for further web socket frames inspection:
Playwright supports [WebSockets](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API) inspection, mocking and modifying out of the box. See our [API mocking guide](./mock.md#mock-websockets) to learn how to mock WebSockets.
Every time a WebSocket is created, the [`event: Page.webSocket`] event is fired. This event contains the [WebSocket] instance for further web socket frames inspection:
```js
page.on('websocket', ws => {

14
packages/playwright-core/types/types.d.ts поставляемый
Просмотреть файл

@ -15356,7 +15356,7 @@ export interface CDPSession {
* the WebSocket. Here is an example that responds to a `"request"` with a `"response"`.
*
* ```js
* await page.routeWebSocket('/ws', ws => {
* await page.routeWebSocket('wss://example.com/ws', ws => {
* ws.onMessage(message => {
* if (message === 'request')
* ws.send('response');
@ -15369,6 +15369,18 @@ export interface CDPSession {
* inside the WebSocket route handler, Playwright assumes that WebSocket will be mocked, and opens the WebSocket
* inside the page automatically.
*
* Here is another example that handles JSON messages:
*
* ```js
* await page.routeWebSocket('wss://example.com/ws', ws => {
* ws.onMessage(message => {
* const json = JSON.parse(message);
* if (json.request === 'question')
* ws.send(JSON.stringify({ response: 'answer' }));
* });
* });
* ```
*
* **Intercepting**
*
* Alternatively, you may want to connect to the actual server, but intercept messages in-between and modify or block