diff --git a/packages/pytest-simcore/src/pytest_simcore/helpers/playwright.py b/packages/pytest-simcore/src/pytest_simcore/helpers/playwright.py index bec851c4d33e..6060b2d026f8 100644 --- a/packages/pytest-simcore/src/pytest_simcore/helpers/playwright.py +++ b/packages/pytest-simcore/src/pytest_simcore/helpers/playwright.py @@ -58,6 +58,7 @@ class NodeProgressType(str, Enum): SERVICE_OUTPUTS_PULLING = "SERVICE_OUTPUTS_PULLING" SERVICE_STATE_PULLING = "SERVICE_STATE_PULLING" SERVICE_IMAGES_PULLING = "SERVICE_IMAGES_PULLING" + SERVICE_CONTAINERS_STARTING = "SERVICE_CONTAINERS_STARTING" @classmethod def required_types_for_started_service(cls) -> set["NodeProgressType"]: @@ -67,6 +68,7 @@ def required_types_for_started_service(cls) -> set["NodeProgressType"]: NodeProgressType.SERVICE_OUTPUTS_PULLING, NodeProgressType.SERVICE_STATE_PULLING, NodeProgressType.SERVICE_IMAGES_PULLING, + NodeProgressType.SERVICE_CONTAINERS_STARTING, } diff --git a/packages/pytest-simcore/src/pytest_simcore/helpers/playwright_sim4life.py b/packages/pytest-simcore/src/pytest_simcore/helpers/playwright_sim4life.py index 9cafcc8f6e6f..58c00e695975 100644 --- a/packages/pytest-simcore/src/pytest_simcore/helpers/playwright_sim4life.py +++ b/packages/pytest-simcore/src/pytest_simcore/helpers/playwright_sim4life.py @@ -2,15 +2,15 @@ import logging import re from dataclasses import dataclass -from typing import Dict, Final, Union +from typing import Final, TypedDict import arrow from playwright.sync_api import FrameLocator, Page, WebSocket, expect from .logging_tools import log_context from .playwright import ( - SECOND, MINUTE, + SECOND, SOCKETIO_MESSAGE_PREFIX, SocketIOEvent, decode_socketio_42_message, @@ -30,6 +30,7 @@ _S4L_STARTUP_SCREEN_MAX_TIME: Final[int] = 45 * SECOND _S4L_COPY_WORKSPACE_TIME: Final[int] = 60 * SECOND + @dataclass(kw_only=True) class S4LWaitForWebsocket: logger: logging.Logger @@ -84,7 +85,19 @@ def __call__(self, message: str) -> bool: return False -def launch_S4L(page: Page, node_id, log_in_and_out: WebSocket, autoscaled: bool, copy_workspace: bool = False) -> Dict[str, Union[WebSocket, FrameLocator]]: +class WaitForS4LDict(TypedDict): + websocket: WebSocket + iframe: FrameLocator + + +def wait_for_launched_s4l( + page: Page, + node_id, + log_in_and_out: WebSocket, + *, + autoscaled: bool, + copy_workspace: bool, +) -> WaitForS4LDict: with log_context(logging.INFO, "launch S4L") as ctx: predicate = S4LWaitForWebsocket(logger=ctx.logger) with page.expect_websocket( @@ -95,11 +108,7 @@ def launch_S4L(page: Page, node_id, log_in_and_out: WebSocket, autoscaled: bool, if autoscaled else _S4L_MAX_STARTUP_TIME ) - + ( - _S4L_COPY_WORKSPACE_TIME - if copy_workspace - else 0 - ) + + (_S4L_COPY_WORKSPACE_TIME if copy_workspace else 0) + 10 * SECOND, ) as ws_info: s4l_iframe = wait_for_service_running( @@ -111,22 +120,18 @@ def launch_S4L(page: Page, node_id, log_in_and_out: WebSocket, autoscaled: bool, if autoscaled else _S4L_MAX_STARTUP_TIME ) - + ( - _S4L_COPY_WORKSPACE_TIME - if copy_workspace - else 0 - ), + + (_S4L_COPY_WORKSPACE_TIME if copy_workspace else 0), press_start_button=False, ) s4l_websocket = ws_info.value ctx.logger.info("acquired S4L websocket!") return { "websocket": s4l_websocket, - "iframe" : s4l_iframe, + "iframe": s4l_iframe, } -def interact_with_S4L(page: Page, s4l_iframe: FrameLocator) -> None: +def interact_with_s4l(page: Page, s4l_iframe: FrameLocator) -> None: # Wait until grid is shown # NOTE: the startup screen should disappear very fast after the websocket was acquired with log_context(logging.INFO, "Interact with S4l"): @@ -134,7 +139,9 @@ def interact_with_S4L(page: Page, s4l_iframe: FrameLocator) -> None: page.wait_for_timeout(3000) -def check_video_streaming(page: Page, s4l_iframe: FrameLocator, s4l_websocket: WebSocket) -> None: +def check_video_streaming( + page: Page, s4l_iframe: FrameLocator, s4l_websocket: WebSocket +) -> None: with log_context(logging.INFO, "Check videostreaming works") as ctx: waiter = _S4LSocketIOCheckBitRateIncreasesMessagePrinter( observation_time=datetime.timedelta( diff --git a/tests/e2e-playwright/Makefile b/tests/e2e-playwright/Makefile index af4a8d48538e..4c8984e9aa56 100644 --- a/tests/e2e-playwright/Makefile +++ b/tests/e2e-playwright/Makefile @@ -131,17 +131,18 @@ $(SLEEPERS_INPUT_FILE) $(JUPYTER_LAB_INPUT_FILE) $(CLASSIC_TIP_INPUT_FILE) $(S4L read -p "Enter the size of the large file (human readable form e.g. 3Gib): " LARGE_FILE_SIZE; \ echo "--service-key=jupyter-math --large-file-size=$$LARGE_FILE_SIZE" >> $@; \ elif [ "$@" = "$(S4L_INPUT_FILE)" ]; then \ - echo "--plus_button_test_id=startS4LButton" >> $@; \ read -p "Do you want to check the videostreaming ? (requires to run with chrome/msedge) [y/n]: " VIDEOSTREAM; \ if [ "$$VIDEOSTREAM" = "y" ]; then \ echo "--check-videostreaming" >> $@; \ fi; \ read -p "Do you want to use the plus button (NOTE: if yes then pass the osparc-test-ID of the plus button in the service key) ? [y/n]: " PLUS_BUTTON; \ if [ "$$PLUS_BUTTON" = "y" ]; then \ + echo "--service-key=startS4LButton" >> $@; \ echo "--use-plus-button" >> $@; \ + else \ + read -p "Enter the service key: " SERVICE_KEY; \ + echo "--service-key=$$SERVICE_KEY" >> $@; \ fi; \ - read -p "Enter the service key: " SERVICE_KEY; \ - echo "--service-key=$$SERVICE_KEY" >> $@; \ elif [ "$@" = "$(SLEEPERS_INPUT_FILE)" ]; then \ read -p "Enter the number of sleepers: " NUM_SLEEPERS; \ echo "--num-sleepers=$$NUM_SLEEPERS" >> $@; \ diff --git a/tests/e2e-playwright/tests/sim4life/test_sim4life.py b/tests/e2e-playwright/tests/sim4life/test_sim4life.py index 39b62039fbd2..23778f3f3f56 100644 --- a/tests/e2e-playwright/tests/sim4life/test_sim4life.py +++ b/tests/e2e-playwright/tests/sim4life/test_sim4life.py @@ -13,9 +13,9 @@ from playwright.sync_api import Page, WebSocket from pytest_simcore.helpers.playwright import ServiceType from pytest_simcore.helpers.playwright_sim4life import ( - launch_S4L, - interact_with_S4L, check_video_streaming, + interact_with_s4l, + wait_for_launched_s4l, ) @@ -45,10 +45,12 @@ def test_sim4life( node_ids: list[str] = list(project_data["workbench"]) assert len(node_ids) == 1, "Expected 1 node in the workbench!" - resp = launch_S4L(page, node_ids[0], log_in_and_out, autoscaled) + resp = wait_for_launched_s4l( + page, node_ids[0], log_in_and_out, autoscaled=autoscaled, copy_workspace=False + ) s4l_websocket = resp["websocket"] s4l_iframe = resp["iframe"] - interact_with_S4L(page, s4l_iframe) + interact_with_s4l(page, s4l_iframe) if check_videostreaming: check_video_streaming(page, s4l_iframe, s4l_websocket) diff --git a/tests/e2e-playwright/tests/sim4life/test_template.py b/tests/e2e-playwright/tests/sim4life/test_template.py index b770979770c0..9ac5d4ae0655 100644 --- a/tests/e2e-playwright/tests/sim4life/test_template.py +++ b/tests/e2e-playwright/tests/sim4life/test_template.py @@ -12,9 +12,9 @@ from playwright.sync_api import Page, WebSocket from pytest_simcore.helpers.playwright_sim4life import ( - launch_S4L, - interact_with_S4L, check_video_streaming, + interact_with_s4l, + wait_for_launched_s4l, ) @@ -35,10 +35,12 @@ def test_template( node_ids: list[str] = list(project_data["workbench"]) assert len(node_ids) == 1, "Expected 1 node in the workbench!" - resp = launch_S4L(page, node_ids[0], log_in_and_out, autoscaled, copy_workspace=True) + resp = wait_for_launched_s4l( + page, node_ids[0], log_in_and_out, autoscaled=autoscaled, copy_workspace=True + ) s4l_websocket = resp["websocket"] s4l_iframe = resp["iframe"] - interact_with_S4L(page, s4l_iframe) + interact_with_s4l(page, s4l_iframe) if check_videostreaming: check_video_streaming(page, s4l_iframe, s4l_websocket)