| 
3 | 3 | import logging  | 
4 | 4 | import re  | 
5 | 5 | from collections import defaultdict  | 
6 |  | -from contextlib import ExitStack  | 
 | 6 | +from collections.abc import Generator, Iterator  | 
7 | 7 | from dataclasses import dataclass, field  | 
8 | 8 | from enum import Enum, unique  | 
9 |  | -from typing import Any, Final, Generator  | 
 | 9 | +from typing import Any, Final  | 
10 | 10 | 
 
  | 
11 | 11 | from playwright.sync_api import FrameLocator, Page, Request, WebSocket  | 
12 | 12 | from pytest_simcore.helpers.logging_tools import log_context  | 
@@ -263,28 +263,37 @@ def wait_for_pipeline_state(  | 
263 | 263 |     return current_state  | 
264 | 264 | 
 
  | 
265 | 265 | 
 
  | 
266 |  | -def on_web_socket_default_handler(ws) -> None:  | 
267 |  | -    """Usage  | 
268 |  | -
  | 
269 |  | -    from pytest_simcore.playwright_utils import on_web_socket_default_handler  | 
270 |  | -
  | 
271 |  | -    page.on("websocket", on_web_socket_default_handler)  | 
 | 266 | +@contextlib.contextmanager  | 
 | 267 | +def web_socket_default_log_handler(web_socket: WebSocket) -> Iterator[None]:  | 
272 | 268 | 
 
  | 
273 |  | -    """  | 
274 |  | -    stack = ExitStack()  | 
275 |  | -    ctx = stack.enter_context(  | 
276 |  | -        log_context(  | 
 | 269 | +    try:  | 
 | 270 | +        with log_context(  | 
277 | 271 |             logging.INFO,  | 
278 |  | -            (  | 
279 |  | -                f"WebSocket opened: {ws.url}",  | 
280 |  | -                "WebSocket closed",  | 
281 |  | -            ),  | 
282 |  | -        )  | 
283 |  | -    )  | 
284 |  | - | 
285 |  | -    ws.on("framesent", lambda payload: ctx.logger.info("⬇️ %s", payload))  | 
286 |  | -    ws.on("framereceived", lambda payload: ctx.logger.info("⬆️ %s", payload))  | 
287 |  | -    ws.on("close", lambda payload: stack.close())  # noqa: ARG005  | 
 | 272 | +            msg="handle websocket message (set to DEBUG level if you wanna see all of them)",  | 
 | 273 | +        ) as ctx:  | 
 | 274 | + | 
 | 275 | +            def on_framesent(payload: str | bytes) -> None:  | 
 | 276 | +                ctx.logger.debug("⬇️ %s", payload)  | 
 | 277 | + | 
 | 278 | +            def on_framereceived(payload: str | bytes) -> None:  | 
 | 279 | +                ctx.logger.debug("⬆️ %s", payload)  | 
 | 280 | + | 
 | 281 | +            def on_close(payload: WebSocket) -> None:  | 
 | 282 | +                ctx.logger.warning("Websocket closed: %s", payload)  | 
 | 283 | + | 
 | 284 | +            def on_socketerror(error_msg: str) -> None:  | 
 | 285 | +                ctx.logger.error("Websocket error: %s", error_msg)  | 
 | 286 | + | 
 | 287 | +            web_socket.on("framesent", on_framesent)  | 
 | 288 | +            web_socket.on("framereceived", on_framereceived)  | 
 | 289 | +            web_socket.on("close", on_close)  | 
 | 290 | +            web_socket.on("socketerror", on_socketerror)  | 
 | 291 | +            yield  | 
 | 292 | +    finally:  | 
 | 293 | +        web_socket.remove_listener("framesent", on_framesent)  | 
 | 294 | +        web_socket.remove_listener("framereceived", on_framereceived)  | 
 | 295 | +        web_socket.remove_listener("close", on_close)  | 
 | 296 | +        web_socket.remove_listener("socketerror", on_socketerror)  | 
288 | 297 | 
 
  | 
289 | 298 | 
 
  | 
290 | 299 | def _node_started_predicate(request: Request) -> bool:  | 
 | 
0 commit comments