From 01dc91a97b0c44429ae10b240269893d72de7349 Mon Sep 17 00:00:00 2001 From: Pedro Crespo-Valero <32402063+pcrespov@users.noreply.github.com> Date: Tue, 17 Sep 2024 11:38:48 +0200 Subject: [PATCH 01/21] minor --- tests/e2e-playwright/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e-playwright/Makefile b/tests/e2e-playwright/Makefile index 4c8984e9aa5..0162833ce08 100644 --- a/tests/e2e-playwright/Makefile +++ b/tests/e2e-playwright/Makefile @@ -183,4 +183,4 @@ define run_test_on_chrome endef clean: - @rm -rf $(SLEEPERS_INPUT_FILE) $(JUPYTER_LAB_INPUT_FILE) $(CLASSIC_TIP_INPUT_FILE) + -@rm -rf $(SLEEPERS_INPUT_FILE) $(JUPYTER_LAB_INPUT_FILE) $(CLASSIC_TIP_INPUT_FILE) From e91633173d1914eb218d1e3f88f19263cb2eefdd Mon Sep 17 00:00:00 2001 From: Pedro Crespo-Valero <32402063+pcrespov@users.noreply.github.com> Date: Wed, 18 Sep 2024 15:51:54 +0200 Subject: [PATCH 02/21] adds --product-billable --- tests/e2e-playwright/Makefile | 1 - tests/e2e-playwright/tests/conftest.py | 24 ++++++++++++++----- .../tests/sim4life/test_sim4life.py | 8 +++++-- .../tests/sim4life/test_template.py | 4 ++-- .../e2e-playwright/tests/tip/test_ti_plan.py | 12 +++++----- 5 files changed, 32 insertions(+), 17 deletions(-) diff --git a/tests/e2e-playwright/Makefile b/tests/e2e-playwright/Makefile index 0162833ce08..31aeacf2847 100644 --- a/tests/e2e-playwright/Makefile +++ b/tests/e2e-playwright/Makefile @@ -168,7 +168,6 @@ define run_test pytest -s $2 \ --color=yes \ --browser chromium \ - --headed \ $$TEST_ARGS endef diff --git a/tests/e2e-playwright/tests/conftest.py b/tests/e2e-playwright/tests/conftest.py index 997ac6b7138..e5c1a018bdc 100644 --- a/tests/e2e-playwright/tests/conftest.py +++ b/tests/e2e-playwright/tests/conftest.py @@ -79,6 +79,12 @@ def pytest_addoption(parser: pytest.Parser) -> None: default=False, help="Whether product is billable or not", ) + group.addoption( + "--product-lite", + action="store_true", + default=False, + help="Whether product is lite version or not", + ) group.addoption( "--autoscaled", action="store_true", @@ -227,13 +233,19 @@ def user_password( @pytest.fixture(scope="session") -def product_billable(request: pytest.FixtureRequest) -> bool: +def is_product_billable(request: pytest.FixtureRequest) -> bool: billable = request.config.getoption("--product-billable") return TypeAdapter(bool).validate_python(billable) @pytest.fixture(scope="session") -def autoscaled(request: pytest.FixtureRequest) -> bool: +def is_product_lite(request: pytest.FixtureRequest) -> bool: + enabled = request.config.getoption("--product-lite") + return TypeAdapter(bool).validate_python(enabled) + + +@pytest.fixture(scope="session") +def is_autoscaled(request: pytest.FixtureRequest) -> bool: autoscaled = request.config.getoption("--autoscaled") return TypeAdapter(bool).validate_python(autoscaled) @@ -392,7 +404,7 @@ def log_in_and_out( def create_new_project_and_delete( page: Page, log_in_and_out: WebSocket, - product_billable: bool, + is_product_billable: bool, api_request_context: APIRequestContext, product_url: AnyUrl, ) -> Iterator[Callable[[tuple[RunningState], bool], dict[str, Any]]]: @@ -411,7 +423,7 @@ def _( ), "misuse of this fixture! only 1 study can be opened at a time. Otherwise please modify the fixture" with log_context( logging.INFO, - f"Open project in {product_url=} as {product_billable=}", + f"Open project in {product_url=} as {is_product_billable=}", ) as ctx: waiter = SocketIOProjectStateUpdatedWaiter(expected_states=expected_states) timeout = ( @@ -473,7 +485,7 @@ def wait_for_done(response): ... else: open_button.click() - if product_billable: + if is_product_billable: # Open project with default resources page.get_by_test_id("openWithResources").click() project_data = response_info.value.json() @@ -512,7 +524,7 @@ def wait_for_done(response): for project_uuid in created_project_uuids: with log_context( logging.INFO, - f"Delete project with {project_uuid=} in {product_url=} as {product_billable=}", + f"Delete project with {project_uuid=} in {product_url=} as {is_product_billable=}", ): response = api_request_context.delete( f"{product_url}v0/projects/{project_uuid}" diff --git a/tests/e2e-playwright/tests/sim4life/test_sim4life.py b/tests/e2e-playwright/tests/sim4life/test_sim4life.py index b993f262181..96c361bb546 100644 --- a/tests/e2e-playwright/tests/sim4life/test_sim4life.py +++ b/tests/e2e-playwright/tests/sim4life/test_sim4life.py @@ -31,7 +31,7 @@ def test_sim4life( log_in_and_out: WebSocket, service_key: str, use_plus_button: bool, - autoscaled: bool, + is_autoscaled: bool, check_videostreaming: bool, ): if use_plus_button: @@ -49,7 +49,11 @@ def test_sim4life( assert len(node_ids) == 1, "Expected 1 node in the workbench!" resp = wait_for_launched_s4l( - page, node_ids[0], log_in_and_out, autoscaled=autoscaled, copy_workspace=False + page, + node_ids[0], + log_in_and_out, + autoscaled=is_autoscaled, + copy_workspace=False, ) s4l_websocket = resp["websocket"] with web_socket_default_log_handler(s4l_websocket): diff --git a/tests/e2e-playwright/tests/sim4life/test_template.py b/tests/e2e-playwright/tests/sim4life/test_template.py index a4f104a6291..fb9b260c992 100644 --- a/tests/e2e-playwright/tests/sim4life/test_template.py +++ b/tests/e2e-playwright/tests/sim4life/test_template.py @@ -24,7 +24,7 @@ def test_template( create_project_from_template_dashboard: Callable[[str], dict[str, Any]], log_in_and_out: WebSocket, template_id: str, - autoscaled: bool, + is_autoscaled: bool, check_videostreaming: bool, ): project_data = create_project_from_template_dashboard(template_id) @@ -37,7 +37,7 @@ def test_template( assert len(node_ids) == 1, "Expected 1 node in the workbench!" resp = wait_for_launched_s4l( - page, node_ids[0], log_in_and_out, autoscaled=autoscaled, copy_workspace=True + page, node_ids[0], log_in_and_out, autoscaled=is_autoscaled, copy_workspace=True ) s4l_websocket = resp["websocket"] with web_socket_default_log_handler(s4l_websocket): diff --git a/tests/e2e-playwright/tests/tip/test_ti_plan.py b/tests/e2e-playwright/tests/tip/test_ti_plan.py index e721b7f5ab3..6709daac29a 100644 --- a/tests/e2e-playwright/tests/tip/test_ti_plan.py +++ b/tests/e2e-playwright/tests/tip/test_ti_plan.py @@ -86,11 +86,11 @@ def __call__(self, message: str) -> bool: return False -def test_tip( # noqa: PLR0915 +def test_classic_ti_plan( # noqa: PLR0915 page: Page, create_tip_plan_from_dashboard: Callable[[str], dict[str, Any]], log_in_and_out: WebSocket, - autoscaled: bool, + is_autoscaled: bool, ): project_data = create_tip_plan_from_dashboard("newTIPlanButton") assert "workbench" in project_data, "Expected workbench to be in project data!" @@ -108,7 +108,7 @@ def test_tip( # noqa: PLR0915 websocket=log_in_and_out, timeout=( _ELECTRODE_SELECTOR_AUTOSCALED_MAX_STARTUP_TIME - if autoscaled + if is_autoscaled else _ELECTRODE_SELECTOR_MAX_STARTUP_TIME ), press_start_button=False, @@ -155,7 +155,7 @@ def test_tip( # noqa: PLR0915 timeout=_OUTER_EXPECT_TIMEOUT_RATIO * ( _JLAB_AUTOSCALED_MAX_STARTUP_TIME - if autoscaled + if is_autoscaled else _JLAB_MAX_STARTUP_MAX_TIME ), ) as ws_info: @@ -165,7 +165,7 @@ def test_tip( # noqa: PLR0915 websocket=log_in_and_out, timeout=( _JLAB_AUTOSCALED_MAX_STARTUP_TIME - if autoscaled + if is_autoscaled else _JLAB_MAX_STARTUP_MAX_TIME ), press_start_button=False, @@ -218,7 +218,7 @@ def test_tip( # noqa: PLR0915 websocket=log_in_and_out, timeout=( _POST_PRO_AUTOSCALED_MAX_STARTUP_TIME - if autoscaled + if is_autoscaled else _POST_PRO_MAX_STARTUP_TIME ), press_start_button=False, From 11317a7624d06452a5f8382636a50e06e2046ce1 Mon Sep 17 00:00:00 2001 From: Pedro Crespo-Valero <32402063+pcrespov@users.noreply.github.com> Date: Wed, 18 Sep 2024 15:55:05 +0200 Subject: [PATCH 03/21] undo --- tests/e2e-playwright/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/e2e-playwright/Makefile b/tests/e2e-playwright/Makefile index 31aeacf2847..0162833ce08 100644 --- a/tests/e2e-playwright/Makefile +++ b/tests/e2e-playwright/Makefile @@ -168,6 +168,7 @@ define run_test pytest -s $2 \ --color=yes \ --browser chromium \ + --headed \ $$TEST_ARGS endef From 18bfba749be8ad7e4babc53caa484550752fd73b Mon Sep 17 00:00:00 2001 From: Pedro Crespo-Valero <32402063+pcrespov@users.noreply.github.com> Date: Wed, 18 Sep 2024 16:08:38 +0200 Subject: [PATCH 04/21] checks two out of three steps --- .../e2e-playwright/tests/tip/test_ti_plan.py | 27 +++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/tests/e2e-playwright/tests/tip/test_ti_plan.py b/tests/e2e-playwright/tests/tip/test_ti_plan.py index 6709daac29a..fea545ebe4b 100644 --- a/tests/e2e-playwright/tests/tip/test_ti_plan.py +++ b/tests/e2e-playwright/tests/tip/test_ti_plan.py @@ -14,7 +14,7 @@ from typing import Any, Final from playwright.sync_api import Page, WebSocket -from pytest_simcore.helpers.logging_tools import log_context +from pytest_simcore.helpers.logging_tools import log_context, test_logger from pytest_simcore.helpers.playwright import ( MINUTE, SECOND, @@ -91,6 +91,7 @@ def test_classic_ti_plan( # noqa: PLR0915 create_tip_plan_from_dashboard: Callable[[str], dict[str, Any]], log_in_and_out: WebSocket, is_autoscaled: bool, + is_product_lite: bool, ): project_data = create_tip_plan_from_dashboard("newTIPlanButton") assert "workbench" in project_data, "Expected workbench to be in project data!" @@ -98,9 +99,19 @@ def test_classic_ti_plan( # noqa: PLR0915 project_data["workbench"], dict ), "Expected workbench to be a dict!" node_ids: list[str] = list(project_data["workbench"]) - assert len(node_ids) >= 3, "Expected at least 3 nodes in the workbench!" - with log_context(logging.INFO, "Electrode Selector step") as ctx: + if is_product_lite: + expected_number_of_steps = 2 + assert ( + len(node_ids) == expected_number_of_steps + ), f"Expected {expected_number_of_steps=} in the app-mode" + else: + expected_number_of_steps = 3 + assert ( + len(node_ids) >= expected_number_of_steps + ), f"Expected at least {expected_number_of_steps} nodes in the workbench" + + with log_context(logging.INFO, "Electrode Selector step (1)") as ctx: # NOTE: creating the plan auto-triggers the first service to start, which might already triggers socket events electrode_selector_iframe = wait_for_service_running( page=page, @@ -149,7 +160,7 @@ def test_classic_ti_plan( # noqa: PLR0915 response_body = response.json() ctx.logger.info("the following output was generated: %s", response_body) - with log_context(logging.INFO, "Classic TI step") as ctx: + with log_context(logging.INFO, "Classic TI step (2)") as ctx: with page.expect_websocket( _JLabWaitForWebSocket(), timeout=_OUTER_EXPECT_TIMEOUT_RATIO @@ -211,7 +222,13 @@ def test_classic_ti_plan( # noqa: PLR0915 text_on_output_button = f"Outputs ({len(expected_outputs)})" page.get_by_test_id("outputsBtn").get_by_text(text_on_output_button).click() - with log_context(logging.INFO, "Exposure Analysis step"): + if is_product_lite: + test_logger.info( + "Skipping the rest of the test since it is intended for the full version" + ) + return + + with log_context(logging.INFO, "Exposure Analysis step (3)"): with expected_service_running( page=page, node_id=node_ids[2], From 599fa9859d45bab6ae2c28de7bc44e94694fbd4c Mon Sep 17 00:00:00 2001 From: Pedro Crespo-Valero <32402063+pcrespov@users.noreply.github.com> Date: Wed, 18 Sep 2024 16:41:01 +0200 Subject: [PATCH 05/21] updates makefile --- tests/e2e-playwright/Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/e2e-playwright/Makefile b/tests/e2e-playwright/Makefile index 0162833ce08..88a15a845d1 100644 --- a/tests/e2e-playwright/Makefile +++ b/tests/e2e-playwright/Makefile @@ -117,6 +117,7 @@ CLASSIC_TIP_INPUT_FILE := .e2e-playwright-classictip-env.txt $(SLEEPERS_INPUT_FILE) $(JUPYTER_LAB_INPUT_FILE) $(CLASSIC_TIP_INPUT_FILE) $(S4L_INPUT_FILE): @read -p "Enter your product URL: " PRODUCT_URL; \ read -p "Is the product billable [y/n]: " BILLABLE; \ + read -p "Is the product lite [y/n]: " IS_LITE; \ read -p "Is the test running in autoscaled deployment [y/n]: " AUTOSCALED; \ read -p "Enter your username: " USER_NAME; \ read -s -p "Enter your password: " PASSWORD; echo ""; \ @@ -124,6 +125,9 @@ $(SLEEPERS_INPUT_FILE) $(JUPYTER_LAB_INPUT_FILE) $(CLASSIC_TIP_INPUT_FILE) $(S4L if [ "$$BILLABLE" = "y" ]; then \ echo "--product-billable" >> $@; \ fi; \ + if [ "$$IS_LITE" = "y" ]; then \ + echo "--product-lite" >> $@; \ + fi; \ if [ "$$AUTOSCALED" = "y" ]; then \ echo "--autoscaled" >> $@; \ fi; \ From bb7d57dd863404319c84afa7a3651e15489bb5f7 Mon Sep 17 00:00:00 2001 From: pcrespov <32402063+pcrespov@users.noreply.github.com> Date: Wed, 18 Sep 2024 16:55:15 +0200 Subject: [PATCH 06/21] doc --- tests/e2e-playwright/.gitignore | 4 ++-- tests/e2e-playwright/README.md | 28 +++++++++++++++++++++------- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/tests/e2e-playwright/.gitignore b/tests/e2e-playwright/.gitignore index cf83940dd82..23b36998635 100644 --- a/tests/e2e-playwright/.gitignore +++ b/tests/e2e-playwright/.gitignore @@ -1,5 +1,5 @@ -test-results +.e2e-playwright-*.txt assets report.html -.e2e-playwright-*.txt report.xml +test-results diff --git a/tests/e2e-playwright/README.md b/tests/e2e-playwright/README.md index 0caaa6c6adc..9c8e996b84d 100644 --- a/tests/e2e-playwright/README.md +++ b/tests/e2e-playwright/README.md @@ -1,5 +1,11 @@ + + +## Usage + ### Auto generate new test -`playwright codegen sim4life.io` +``` +playwright codegen sim4life.io +``` ### Run test locally with headed mode ``` @@ -7,16 +13,24 @@ pytest -s tests/sim4life.py --headed --browser chromium --product-billable --pr ``` ### Check test results output -`playwright show-trace test-results/tests-sim4life-py-test-billable-sim4life-chromium/trace.zip` +``` +playwright show-trace test-results/tests-sim4life-py-test-billable-sim4life-chromium/trace.zip +``` ### Run debug mode -`PWDEBUG=1 pytest -s tests/sim4life.py` +``` +PWDEBUG=1 pytest -s tests/sim4life.py +``` ### Run test in different browsers -`pytest -s tests/sim4life.py --tracing on --html=report.html --browser chromium --browser firefox` +``` +pytest -s tests/sim4life.py --tracing on --html=report.html --browser chromium --browser firefox +``` -### or in chrome/msedge -`pytest -s tests/sim4life.py --tracing on --html=report.html --browser-channel chrome` +### or in chrome/ms-edge +``` +pytest -s tests/sim4life.py --tracing on --html=report.html --browser-channel chrome +``` -### Runs in CI +## e2e CI - https://git.speag.com/oSparc/e2e-backend From 2a273b1c25a312366915a67a636759aa6d363819 Mon Sep 17 00:00:00 2001 From: pcrespov <32402063+pcrespov@users.noreply.github.com> Date: Wed, 18 Sep 2024 17:09:43 +0200 Subject: [PATCH 07/21] hid pass --- tests/e2e-playwright/tests/conftest.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/tests/e2e-playwright/tests/conftest.py b/tests/e2e-playwright/tests/conftest.py index e5c1a018bdc..751d7fa425e 100644 --- a/tests/e2e-playwright/tests/conftest.py +++ b/tests/e2e-playwright/tests/conftest.py @@ -21,8 +21,9 @@ from faker import Faker from playwright.sync_api import APIRequestContext, BrowserContext, Page, WebSocket from playwright.sync_api._generated import Playwright -from pydantic import AnyUrl, TypeAdapter +from pydantic import AnyUrl, SecretStr, TypeAdapter from pytest import Item +from pytest_simcore.helpers.faker_factories import DEFAULT_TEST_PASSWORD from pytest_simcore.helpers.logging_tools import log_context from pytest_simcore.helpers.playwright import ( MINUTE, @@ -223,13 +224,13 @@ def user_name(request: pytest.FixtureRequest, auto_register: bool, faker: Faker) @pytest.fixture def user_password( request: pytest.FixtureRequest, auto_register: bool, faker: Faker -) -> str: +) -> SecretStr: if auto_register: - return faker.password(length=12) + return SecretStr(DEFAULT_TEST_PASSWORD) if osparc_password := request.config.getoption("--password"): assert isinstance(osparc_password, str) - return osparc_password - return os.environ["USER_PASSWORD"] + return SecretStr(osparc_password) + return SecretStr(os.environ["USER_PASSWORD"]) @pytest.fixture(scope="session") @@ -292,7 +293,7 @@ def register( page: Page, product_url: AnyUrl, user_name: str, - user_password: str, + user_password: SecretStr, ) -> Callable[[], AutoRegisteredUser]: def _do() -> AutoRegisteredUser: with log_context( @@ -309,11 +310,13 @@ def _do() -> AutoRegisteredUser: for pass_id in ["registrationPass1Fld", "registrationPass2Fld"]: user_password_box = page.get_by_test_id(pass_id) user_password_box.click() - user_password_box.fill(user_password) + user_password_box.fill(user_password.get_secret_value()) with page.expect_response(re.compile(r"/auth/register")) as response_info: page.get_by_test_id("registrationSubmitBtn").click() assert response_info.value.ok, response_info.value.json() - return AutoRegisteredUser(user_email=user_name, password=user_password) + return AutoRegisteredUser( + user_email=user_name, password=user_password.get_secret_value() + ) return _do @@ -323,7 +326,7 @@ def log_in_and_out( page: Page, product_url: AnyUrl, user_name: str, - user_password: str, + user_password: SecretStr, auto_register: bool, register: Callable[[], AutoRegisteredUser], ) -> Iterator[WebSocket]: @@ -364,7 +367,7 @@ def log_in_and_out( _user_email_box.fill(user_name) _user_password_box = page.get_by_test_id("loginPasswordFld") _user_password_box.click() - _user_password_box.fill(user_password) + _user_password_box.fill(user_password.get_secret_value()) with page.expect_response(re.compile(r"/login")) as response_info: page.get_by_test_id("loginSubmitBtn").click() assert response_info.value.ok, f"{response_info.value.json()}" From 61b87e2292590eebdd7eefd51b115f773becea34 Mon Sep 17 00:00:00 2001 From: Pedro Crespo-Valero <32402063+pcrespov@users.noreply.github.com> Date: Thu, 19 Sep 2024 16:27:46 +0200 Subject: [PATCH 08/21] minor --- tests/e2e-playwright/tests/conftest.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/tests/e2e-playwright/tests/conftest.py b/tests/e2e-playwright/tests/conftest.py index 751d7fa425e..e056b898842 100644 --- a/tests/e2e-playwright/tests/conftest.py +++ b/tests/e2e-playwright/tests/conftest.py @@ -11,6 +11,7 @@ import os import random import re +import textwrap import urllib.parse from collections.abc import Callable, Iterator from contextlib import ExitStack @@ -123,7 +124,7 @@ def pytest_addoption(parser: pytest.Parser) -> None: # Dictionary to store start times of tests -_test_start_times = {} +_test_start_times: dict[str, datetime.datetime] = {} def pytest_runtest_setup(item): @@ -151,7 +152,7 @@ def _construct_graylog_url( return f"{monitoring_url}/graylog/search?{query}" -def pytest_runtest_makereport(item: Item, call): +def pytest_runtest_makereport(item: pytest.Item, call): """ Hook to add extra information when a test fails. """ @@ -178,12 +179,9 @@ def pytest_runtest_makereport(item: Item, call): ) diagnostics["duration"] = str(end_time - start_time) - # Print the diagnostics report - with log_context( - logging.WARNING, - f"ℹ️ Diagnostics report for {test_name} ---", # noqa: RUF001 - ) as ctx: - ctx.logger.warning(json.dumps(diagnostics, indent=2)) + print(f"\nDiagnostics report for {test_name} ---") # noqa: RUF001 + print(textwrap.indent(json.dumps(diagnostics, indent=2), " ")) + print("---") @pytest.hookimpl(tryfirst=True) From 3c95848c5568d1f37c83e8293218d24c1d2a7194 Mon Sep 17 00:00:00 2001 From: Pedro Crespo-Valero <32402063+pcrespov@users.noreply.github.com> Date: Thu, 19 Sep 2024 16:32:15 +0200 Subject: [PATCH 09/21] updates tests --- .../e2e-playwright/tests/tip/test_ti_plan.py | 107 +++++++++++------- 1 file changed, 65 insertions(+), 42 deletions(-) diff --git a/tests/e2e-playwright/tests/tip/test_ti_plan.py b/tests/e2e-playwright/tests/tip/test_ti_plan.py index fea545ebe4b..61c56cb73c3 100644 --- a/tests/e2e-playwright/tests/tip/test_ti_plan.py +++ b/tests/e2e-playwright/tests/tip/test_ti_plan.py @@ -14,7 +14,7 @@ from typing import Any, Final from playwright.sync_api import Page, WebSocket -from pytest_simcore.helpers.logging_tools import log_context, test_logger +from pytest_simcore.helpers.logging_tools import log_context from pytest_simcore.helpers.playwright import ( MINUTE, SECOND, @@ -93,6 +93,9 @@ def test_classic_ti_plan( # noqa: PLR0915 is_autoscaled: bool, is_product_lite: bool, ): + + # TODO: check TIP upgrade + project_data = create_tip_plan_from_dashboard("newTIPlanButton") assert "workbench" in project_data, "Expected workbench to be in project data!" assert isinstance( @@ -204,49 +207,69 @@ def test_classic_ti_plan( # noqa: PLR0915 ) with log_context(logging.INFO, "Create report"): - ti_iframe.get_by_role("button", name="Load Analysis").click() - page.wait_for_timeout(_JLAB_REPORTING_MAX_TIME) - ti_iframe.get_by_role("button", name="Load").nth(1).click() - page.wait_for_timeout(_JLAB_REPORTING_MAX_TIME) - ti_iframe.get_by_role("button", name="Add to Report (0)").nth(0).click() - page.wait_for_timeout(_JLAB_REPORTING_MAX_TIME) - ti_iframe.get_by_role("button", name="Export to S4L").click() - page.wait_for_timeout(_JLAB_REPORTING_MAX_TIME) - ti_iframe.get_by_role("button", name="Add to Report (1)").nth(1).click() - page.wait_for_timeout(_JLAB_REPORTING_MAX_TIME) - ti_iframe.get_by_role("button", name="Export Report").click() - page.wait_for_timeout(_JLAB_REPORTING_MAX_TIME) + if is_product_lite: + # NOTE: buttons should be disabled + assert not ti_iframe.get_by_role( + "button", name="Load Analysis" + ).is_enabled() + assert ( + not ti_iframe.get_by_role("button", name="Load").nth(1).is_enabled() + ) + assert not ti_iframe.get_by_role( + "button", name="Export to S4L" + ).is_enabled() + assert not ti_iframe.get_by_role( + "button", name="Export Report" + ).is_enabled() + + else: + ti_iframe.get_by_role("button", name="Load Analysis").click() + page.wait_for_timeout(_JLAB_REPORTING_MAX_TIME) + ti_iframe.get_by_role("button", name="Load").nth(1).click() + page.wait_for_timeout(_JLAB_REPORTING_MAX_TIME) + ti_iframe.get_by_role("button", name="Add to Report (0)").nth(0).click() + page.wait_for_timeout(_JLAB_REPORTING_MAX_TIME) + ti_iframe.get_by_role("button", name="Export to S4L").click() + page.wait_for_timeout(_JLAB_REPORTING_MAX_TIME) + ti_iframe.get_by_role("button", name="Add to Report (1)").nth(1).click() + page.wait_for_timeout(_JLAB_REPORTING_MAX_TIME) + ti_iframe.get_by_role("button", name="Export Report").click() + page.wait_for_timeout(_JLAB_REPORTING_MAX_TIME) with log_context(logging.INFO, "Check outputs"): - expected_outputs = ["output_1.zip", "TIP_report.pdf", "results.csv"] - text_on_output_button = f"Outputs ({len(expected_outputs)})" - page.get_by_test_id("outputsBtn").get_by_text(text_on_output_button).click() + if is_product_lite: + pass + else: + expected_outputs = ["output_1.zip", "TIP_report.pdf", "results.csv"] + text_on_output_button = f"Outputs ({len(expected_outputs)})" + page.get_by_test_id("outputsBtn").get_by_text( + text_on_output_button + ).click() if is_product_lite: - test_logger.info( - "Skipping the rest of the test since it is intended for the full version" - ) - return + assert expected_number_of_steps == 2 + else: + with log_context(logging.INFO, "Exposure Analysis step (3)"): + with expected_service_running( + page=page, + node_id=node_ids[2], + websocket=log_in_and_out, + timeout=( + _POST_PRO_AUTOSCALED_MAX_STARTUP_TIME + if is_autoscaled + else _POST_PRO_MAX_STARTUP_TIME + ), + press_start_button=False, + ) as service_running: + app_mode_trigger_next_app(page) + s4l_postpro_iframe = service_running.iframe_locator + assert s4l_postpro_iframe - with log_context(logging.INFO, "Exposure Analysis step (3)"): - with expected_service_running( - page=page, - node_id=node_ids[2], - websocket=log_in_and_out, - timeout=( - _POST_PRO_AUTOSCALED_MAX_STARTUP_TIME - if is_autoscaled - else _POST_PRO_MAX_STARTUP_TIME - ), - press_start_button=False, - ) as service_running: - app_mode_trigger_next_app(page) - s4l_postpro_iframe = service_running.iframe_locator - assert s4l_postpro_iframe - - with log_context(logging.INFO, "Post process"): - # click on the postpro mode button - s4l_postpro_iframe.get_by_test_id("mode-button-postro").click() - # click on the surface viewer - s4l_postpro_iframe.get_by_test_id("tree-item-ti_field.cache").click() - s4l_postpro_iframe.get_by_test_id("tree-item-SurfaceViewer").nth(0).click() + with log_context(logging.INFO, "Post process"): + # click on the postpro mode button + s4l_postpro_iframe.get_by_test_id("mode-button-postro").click() + # click on the surface viewer + s4l_postpro_iframe.get_by_test_id("tree-item-ti_field.cache").click() + s4l_postpro_iframe.get_by_test_id("tree-item-SurfaceViewer").nth( + 0 + ).click() From 8c3ff98df91a01f515cd08a1472dc9a1361bcc57 Mon Sep 17 00:00:00 2001 From: Pedro Crespo-Valero <32402063+pcrespov@users.noreply.github.com> Date: Thu, 19 Sep 2024 17:15:04 +0200 Subject: [PATCH 10/21] wrong import --- tests/e2e-playwright/tests/conftest.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/e2e-playwright/tests/conftest.py b/tests/e2e-playwright/tests/conftest.py index e056b898842..63ffb8d0d72 100644 --- a/tests/e2e-playwright/tests/conftest.py +++ b/tests/e2e-playwright/tests/conftest.py @@ -23,7 +23,6 @@ from playwright.sync_api import APIRequestContext, BrowserContext, Page, WebSocket from playwright.sync_api._generated import Playwright from pydantic import AnyUrl, SecretStr, TypeAdapter -from pytest import Item from pytest_simcore.helpers.faker_factories import DEFAULT_TEST_PASSWORD from pytest_simcore.helpers.logging_tools import log_context from pytest_simcore.helpers.playwright import ( From f06b1a1f5ca6140a7eefcd7677ba9fb541636b9e Mon Sep 17 00:00:00 2001 From: Pedro Crespo-Valero <32402063+pcrespov@users.noreply.github.com> Date: Fri, 20 Sep 2024 14:15:00 +0200 Subject: [PATCH 11/21] WIP --- tests/e2e-playwright/tests/tip/test_ti_plan.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/e2e-playwright/tests/tip/test_ti_plan.py b/tests/e2e-playwright/tests/tip/test_ti_plan.py index 61c56cb73c3..87783f542cc 100644 --- a/tests/e2e-playwright/tests/tip/test_ti_plan.py +++ b/tests/e2e-playwright/tests/tip/test_ti_plan.py @@ -88,12 +88,13 @@ def __call__(self, message: str) -> bool: def test_classic_ti_plan( # noqa: PLR0915 page: Page, - create_tip_plan_from_dashboard: Callable[[str], dict[str, Any]], log_in_and_out: WebSocket, is_autoscaled: bool, is_product_lite: bool, + create_tip_plan_from_dashboard: Callable[[str], dict[str, Any]], ): + assert page.get_by_text("Access TIP").is_enabled() # TODO: check TIP upgrade project_data = create_tip_plan_from_dashboard("newTIPlanButton") From 22de515258d62b726dd0b87642ab23d8aaff669f Mon Sep 17 00:00:00 2001 From: Pedro Crespo-Valero <32402063+pcrespov@users.noreply.github.com> Date: Mon, 23 Sep 2024 17:54:09 +0200 Subject: [PATCH 12/21] checks TIP button --- .../e2e-playwright/tests/tip/test_ti_plan.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/tests/e2e-playwright/tests/tip/test_ti_plan.py b/tests/e2e-playwright/tests/tip/test_ti_plan.py index 87783f542cc..f9a94e1b029 100644 --- a/tests/e2e-playwright/tests/tip/test_ti_plan.py +++ b/tests/e2e-playwright/tests/tip/test_ti_plan.py @@ -93,10 +93,11 @@ def test_classic_ti_plan( # noqa: PLR0915 is_product_lite: bool, create_tip_plan_from_dashboard: Callable[[str], dict[str, Any]], ): + # checks "Access TIP" button + page.get_by_test_id("userMenuBtn").locator("div").click() + assert page.get_by_text("Access Full TIP").is_visible() - assert page.get_by_text("Access TIP").is_enabled() - # TODO: check TIP upgrade - + # press + button project_data = create_tip_plan_from_dashboard("newTIPlanButton") assert "workbench" in project_data, "Expected workbench to be in project data!" assert isinstance( @@ -115,7 +116,9 @@ def test_classic_ti_plan( # noqa: PLR0915 len(node_ids) >= expected_number_of_steps ), f"Expected at least {expected_number_of_steps} nodes in the workbench" - with log_context(logging.INFO, "Electrode Selector step (1)") as ctx: + with log_context( + logging.INFO, "Electrode Selector step (1/%s)", expected_number_of_steps + ) as ctx: # NOTE: creating the plan auto-triggers the first service to start, which might already triggers socket events electrode_selector_iframe = wait_for_service_running( page=page, @@ -164,7 +167,9 @@ def test_classic_ti_plan( # noqa: PLR0915 response_body = response.json() ctx.logger.info("the following output was generated: %s", response_body) - with log_context(logging.INFO, "Classic TI step (2)") as ctx: + with log_context( + logging.INFO, "Classic TI step (2/%s)", expected_number_of_steps + ) as ctx: with page.expect_websocket( _JLabWaitForWebSocket(), timeout=_OUTER_EXPECT_TIMEOUT_RATIO @@ -250,7 +255,9 @@ def test_classic_ti_plan( # noqa: PLR0915 if is_product_lite: assert expected_number_of_steps == 2 else: - with log_context(logging.INFO, "Exposure Analysis step (3)"): + with log_context( + logging.INFO, "Exposure Analysis step (3/%s)", expected_number_of_steps + ): with expected_service_running( page=page, node_id=node_ids[2], From cdbf0b80f8d241c86db2de3784f63e7e9abafad7 Mon Sep 17 00:00:00 2001 From: Pedro Crespo-Valero <32402063+pcrespov@users.noreply.github.com> Date: Tue, 24 Sep 2024 10:01:38 +0200 Subject: [PATCH 13/21] @matusdrobuliak66 review: masked secret --- .../pytest_simcore/helpers/pydantic_ext.py | 28 +++++++++++++++++++ tests/e2e-playwright/tests/conftest.py | 17 +++++------ 2 files changed, 37 insertions(+), 8 deletions(-) create mode 100644 packages/pytest-simcore/src/pytest_simcore/helpers/pydantic_ext.py diff --git a/packages/pytest-simcore/src/pytest_simcore/helpers/pydantic_ext.py b/packages/pytest-simcore/src/pytest_simcore/helpers/pydantic_ext.py new file mode 100644 index 00000000000..0805b5bd72d --- /dev/null +++ b/packages/pytest-simcore/src/pytest_simcore/helpers/pydantic_ext.py @@ -0,0 +1,28 @@ +from pydantic import SecretStr + + +def _mask(value): + """ + Mask the password, showing only the first and last characters + or *** if very short passwords + """ + if len(value) > 2: + masked_value = value[0] + "*" * (len(value) - 2) + value[-1] + else: + # In case of very short passwords + masked_value = "*" * len(value) + return masked_value + + +class Secret4TestsStr(SecretStr): + """Prints a hint of the secret + TIP: Can be handy for testing + """ + + def __str__(self) -> str: + value = self.get_secret_value() + return _mask(value) if value else "" + + +assert str(Secret4TestsStr("123456890")) == "1*******0" +assert repr(Secret4TestsStr("123456890")) == "SecretStr('1*******0')" diff --git a/tests/e2e-playwright/tests/conftest.py b/tests/e2e-playwright/tests/conftest.py index 63ffb8d0d72..1c8663ca448 100644 --- a/tests/e2e-playwright/tests/conftest.py +++ b/tests/e2e-playwright/tests/conftest.py @@ -22,7 +22,7 @@ from faker import Faker from playwright.sync_api import APIRequestContext, BrowserContext, Page, WebSocket from playwright.sync_api._generated import Playwright -from pydantic import AnyUrl, SecretStr, TypeAdapter +from pydantic import AnyUrl, TypeAdapter from pytest_simcore.helpers.faker_factories import DEFAULT_TEST_PASSWORD from pytest_simcore.helpers.logging_tools import log_context from pytest_simcore.helpers.playwright import ( @@ -37,6 +37,7 @@ decode_socketio_42_message, web_socket_default_log_handler, ) +from pytest_simcore.helpers.pydantic_ext import Secret4TestsStr _PROJECT_CLOSING_TIMEOUT: Final[int] = 10 * MINUTE _OPENING_NEW_EMPTY_PROJECT_MAX_WAIT_TIME: Final[int] = 30 * SECOND @@ -178,7 +179,7 @@ def pytest_runtest_makereport(item: pytest.Item, call): ) diagnostics["duration"] = str(end_time - start_time) - print(f"\nDiagnostics report for {test_name} ---") # noqa: RUF001 + print(f"\nDiagnostics report for {test_name} ---") # noqa: RUF001 print(textwrap.indent(json.dumps(diagnostics, indent=2), " ")) print("---") @@ -221,13 +222,13 @@ def user_name(request: pytest.FixtureRequest, auto_register: bool, faker: Faker) @pytest.fixture def user_password( request: pytest.FixtureRequest, auto_register: bool, faker: Faker -) -> SecretStr: +) -> Secret4TestsStr: if auto_register: - return SecretStr(DEFAULT_TEST_PASSWORD) + return Secret4TestsStr(DEFAULT_TEST_PASSWORD) if osparc_password := request.config.getoption("--password"): assert isinstance(osparc_password, str) - return SecretStr(osparc_password) - return SecretStr(os.environ["USER_PASSWORD"]) + return Secret4TestsStr(osparc_password) + return Secret4TestsStr(os.environ["USER_PASSWORD"]) @pytest.fixture(scope="session") @@ -290,7 +291,7 @@ def register( page: Page, product_url: AnyUrl, user_name: str, - user_password: SecretStr, + user_password: Secret4TestsStr, ) -> Callable[[], AutoRegisteredUser]: def _do() -> AutoRegisteredUser: with log_context( @@ -323,7 +324,7 @@ def log_in_and_out( page: Page, product_url: AnyUrl, user_name: str, - user_password: SecretStr, + user_password: Secret4TestsStr, auto_register: bool, register: Callable[[], AutoRegisteredUser], ) -> Iterator[WebSocket]: From 0aa9460a33025c6dd173b693569a9452b940dd46 Mon Sep 17 00:00:00 2001 From: Pedro Crespo-Valero <32402063+pcrespov@users.noreply.github.com> Date: Tue, 24 Sep 2024 11:07:02 +0200 Subject: [PATCH 14/21] corrected some steps --- .../e2e-playwright/tests/tip/test_ti_plan.py | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/tests/e2e-playwright/tests/tip/test_ti_plan.py b/tests/e2e-playwright/tests/tip/test_ti_plan.py index f9a94e1b029..708af0eafd6 100644 --- a/tests/e2e-playwright/tests/tip/test_ti_plan.py +++ b/tests/e2e-playwright/tests/tip/test_ti_plan.py @@ -213,13 +213,17 @@ def test_classic_ti_plan( # noqa: PLR0915 ) with log_context(logging.INFO, "Create report"): + + ti_iframe.get_by_role("button", name="Load Analysis").click() + page.wait_for_timeout(_JLAB_REPORTING_MAX_TIME) + ti_iframe.get_by_role("button", name="Load").nth(1).click() + page.wait_for_timeout(_JLAB_REPORTING_MAX_TIME) + if is_product_lite: - # NOTE: buttons should be disabled - assert not ti_iframe.get_by_role( - "button", name="Load Analysis" - ).is_enabled() assert ( - not ti_iframe.get_by_role("button", name="Load").nth(1).is_enabled() + not ti_iframe.get_by_role("button", name="Add to Report (0)") + .nth(0) + .is_enabled() ) assert not ti_iframe.get_by_role( "button", name="Export to S4L" @@ -229,10 +233,6 @@ def test_classic_ti_plan( # noqa: PLR0915 ).is_enabled() else: - ti_iframe.get_by_role("button", name="Load Analysis").click() - page.wait_for_timeout(_JLAB_REPORTING_MAX_TIME) - ti_iframe.get_by_role("button", name="Load").nth(1).click() - page.wait_for_timeout(_JLAB_REPORTING_MAX_TIME) ti_iframe.get_by_role("button", name="Add to Report (0)").nth(0).click() page.wait_for_timeout(_JLAB_REPORTING_MAX_TIME) ti_iframe.get_by_role("button", name="Export to S4L").click() @@ -244,7 +244,12 @@ def test_classic_ti_plan( # noqa: PLR0915 with log_context(logging.INFO, "Check outputs"): if is_product_lite: - pass + expected_outputs = ["results.csv"] + text_on_output_button = f"Outputs ({len(expected_outputs)})" + page.get_by_test_id("outputsBtn").get_by_text( + text_on_output_button + ).click() + else: expected_outputs = ["output_1.zip", "TIP_report.pdf", "results.csv"] text_on_output_button = f"Outputs ({len(expected_outputs)})" From f99c34c4a8ede2c94355fe7b2b450069393017b8 Mon Sep 17 00:00:00 2001 From: Pedro Crespo-Valero <32402063+pcrespov@users.noreply.github.com> Date: Tue, 24 Sep 2024 11:35:37 +0200 Subject: [PATCH 15/21] tags tip teaser close button --- .../client/source/class/osparc/product/TIPTeaser.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/services/static-webserver/client/source/class/osparc/product/TIPTeaser.js b/services/static-webserver/client/source/class/osparc/product/TIPTeaser.js index d71ac819f3b..3ae7e364292 100644 --- a/services/static-webserver/client/source/class/osparc/product/TIPTeaser.js +++ b/services/static-webserver/client/source/class/osparc/product/TIPTeaser.js @@ -35,6 +35,9 @@ qx.Class.define("osparc.product.TIPTeaser", { }); this.getChildControl("teaser-text"); + + const closeBtn = this.getChildControl("close-button"); + osparc.utils.Utils.setIdToWidget(closeBtn, "tipTeaserWindowCloseBtn"); }, statics: { From cae3cf10cd613da8390a2224c3a01d15ec0c9ecc Mon Sep 17 00:00:00 2001 From: Pedro Crespo-Valero <32402063+pcrespov@users.noreply.github.com> Date: Tue, 24 Sep 2024 13:17:45 +0200 Subject: [PATCH 16/21] fixes pydyantic_extension --- .../pytest-simcore/src/pytest_simcore/helpers/pydantic_ext.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pytest-simcore/src/pytest_simcore/helpers/pydantic_ext.py b/packages/pytest-simcore/src/pytest_simcore/helpers/pydantic_ext.py index 0805b5bd72d..f589a68069c 100644 --- a/packages/pytest-simcore/src/pytest_simcore/helpers/pydantic_ext.py +++ b/packages/pytest-simcore/src/pytest_simcore/helpers/pydantic_ext.py @@ -25,4 +25,4 @@ def __str__(self) -> str: assert str(Secret4TestsStr("123456890")) == "1*******0" -assert repr(Secret4TestsStr("123456890")) == "SecretStr('1*******0')" +assert "1*******0" in repr(Secret4TestsStr("123456890")) From 5dbf90e58a8d14b0ef2630c48c4a1900af5cef03 Mon Sep 17 00:00:00 2001 From: Pedro Crespo-Valero <32402063+pcrespov@users.noreply.github.com> Date: Tue, 24 Sep 2024 13:18:41 +0200 Subject: [PATCH 17/21] fixes pydyantic_extension --- .../helpers/{pydantic_ext.py => pydantic_extension.py} | 8 +++++++- tests/e2e-playwright/tests/conftest.py | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) rename packages/pytest-simcore/src/pytest_simcore/helpers/{pydantic_ext.py => pydantic_extension.py} (78%) diff --git a/packages/pytest-simcore/src/pytest_simcore/helpers/pydantic_ext.py b/packages/pytest-simcore/src/pytest_simcore/helpers/pydantic_extension.py similarity index 78% rename from packages/pytest-simcore/src/pytest_simcore/helpers/pydantic_ext.py rename to packages/pytest-simcore/src/pytest_simcore/helpers/pydantic_extension.py index f589a68069c..c1252ed8bb4 100644 --- a/packages/pytest-simcore/src/pytest_simcore/helpers/pydantic_ext.py +++ b/packages/pytest-simcore/src/pytest_simcore/helpers/pydantic_extension.py @@ -14,12 +14,18 @@ def _mask(value): return masked_value +def _hash(value): + """Uses hash number to mask the password""" + return f"hash:{hash(value)}" + + class Secret4TestsStr(SecretStr): """Prints a hint of the secret TIP: Can be handy for testing """ - def __str__(self) -> str: + def _display(self) -> str | bytes: + # SEE overrides _SecretBase._display value = self.get_secret_value() return _mask(value) if value else "" diff --git a/tests/e2e-playwright/tests/conftest.py b/tests/e2e-playwright/tests/conftest.py index 1c8663ca448..983bddfaf08 100644 --- a/tests/e2e-playwright/tests/conftest.py +++ b/tests/e2e-playwright/tests/conftest.py @@ -37,7 +37,7 @@ decode_socketio_42_message, web_socket_default_log_handler, ) -from pytest_simcore.helpers.pydantic_ext import Secret4TestsStr +from pytest_simcore.helpers.pydantic_extension import Secret4TestsStr _PROJECT_CLOSING_TIMEOUT: Final[int] = 10 * MINUTE _OPENING_NEW_EMPTY_PROJECT_MAX_WAIT_TIME: Final[int] = 30 * SECOND From f8cb8aff6cde5d842e874afeac5335ac805beea5 Mon Sep 17 00:00:00 2001 From: Pedro Crespo-Valero <32402063+pcrespov@users.noreply.github.com> Date: Tue, 24 Sep 2024 13:29:56 +0200 Subject: [PATCH 18/21] adds test ids --- .../client/source/class/osparc/product/TIPTeaser.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/services/static-webserver/client/source/class/osparc/product/TIPTeaser.js b/services/static-webserver/client/source/class/osparc/product/TIPTeaser.js index 3ae7e364292..f36186e5923 100644 --- a/services/static-webserver/client/source/class/osparc/product/TIPTeaser.js +++ b/services/static-webserver/client/source/class/osparc/product/TIPTeaser.js @@ -36,6 +36,8 @@ qx.Class.define("osparc.product.TIPTeaser", { this.getChildControl("teaser-text"); + osparc.utils.Utils.setIdToWidget(self, "tipTeaserWindow"); + const closeBtn = this.getChildControl("close-button"); osparc.utils.Utils.setIdToWidget(closeBtn, "tipTeaserWindowCloseBtn"); }, From 66847cbbaecdb30046550af085dfe1716b770d0f Mon Sep 17 00:00:00 2001 From: Pedro Crespo-Valero <32402063+pcrespov@users.noreply.github.com> Date: Tue, 24 Sep 2024 13:30:44 +0200 Subject: [PATCH 19/21] updates access tip teaser --- tests/e2e-playwright/tests/tip/test_ti_plan.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/e2e-playwright/tests/tip/test_ti_plan.py b/tests/e2e-playwright/tests/tip/test_ti_plan.py index 708af0eafd6..cac6bb5b56d 100644 --- a/tests/e2e-playwright/tests/tip/test_ti_plan.py +++ b/tests/e2e-playwright/tests/tip/test_ti_plan.py @@ -93,9 +93,11 @@ def test_classic_ti_plan( # noqa: PLR0915 is_product_lite: bool, create_tip_plan_from_dashboard: Callable[[str], dict[str, Any]], ): - # checks "Access TIP" button - page.get_by_test_id("userMenuBtn").locator("div").click() - assert page.get_by_text("Access Full TIP").is_visible() + with log_context(logging.INFO, "Checking 'Access TIP' teaser"): + page.get_by_test_id("userMenuBtn").click() + page.get_by_test_id("userMenuAccessTIPBtn").click() + assert page.get_by_test_id("tipTeaserWindow").is_visible() + page.get_by_test_id("tipTeaserWindowCloseBtn").click() # press + button project_data = create_tip_plan_from_dashboard("newTIPlanButton") From 26752c6cc7a109d5a4d81e85463cbcc479742565 Mon Sep 17 00:00:00 2001 From: Pedro Crespo-Valero <32402063+pcrespov@users.noreply.github.com> Date: Tue, 24 Sep 2024 15:04:50 +0200 Subject: [PATCH 20/21] bad ref --- .../client/source/class/osparc/product/TIPTeaser.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/static-webserver/client/source/class/osparc/product/TIPTeaser.js b/services/static-webserver/client/source/class/osparc/product/TIPTeaser.js index f36186e5923..524d5795c7e 100644 --- a/services/static-webserver/client/source/class/osparc/product/TIPTeaser.js +++ b/services/static-webserver/client/source/class/osparc/product/TIPTeaser.js @@ -36,7 +36,7 @@ qx.Class.define("osparc.product.TIPTeaser", { this.getChildControl("teaser-text"); - osparc.utils.Utils.setIdToWidget(self, "tipTeaserWindow"); + osparc.utils.Utils.setIdToWidget(this, "tipTeaserWindow"); const closeBtn = this.getChildControl("close-button"); osparc.utils.Utils.setIdToWidget(closeBtn, "tipTeaserWindowCloseBtn"); From 3d65081354e3e13f6f213694c88019d37c6896c9 Mon Sep 17 00:00:00 2001 From: Pedro Crespo-Valero <32402063+pcrespov@users.noreply.github.com> Date: Tue, 24 Sep 2024 15:19:55 +0200 Subject: [PATCH 21/21] bad merge --- tests/e2e-playwright/tests/conftest.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/e2e-playwright/tests/conftest.py b/tests/e2e-playwright/tests/conftest.py index 983bddfaf08..1136e4035cb 100644 --- a/tests/e2e-playwright/tests/conftest.py +++ b/tests/e2e-playwright/tests/conftest.py @@ -11,7 +11,6 @@ import os import random import re -import textwrap import urllib.parse from collections.abc import Callable, Iterator from contextlib import ExitStack @@ -179,9 +178,11 @@ def pytest_runtest_makereport(item: pytest.Item, call): ) diagnostics["duration"] = str(end_time - start_time) - print(f"\nDiagnostics report for {test_name} ---") # noqa: RUF001 - print(textwrap.indent(json.dumps(diagnostics, indent=2), " ")) - print("---") + with log_context( + logging.WARNING, + f"ℹ️ Diagnostics report for {test_name} ---", # noqa: RUF001 + ) as ctx: + ctx.logger.warning(json.dumps(diagnostics, indent=2)) @pytest.hookimpl(tryfirst=True)