From d00f2b5a420e53ace5ef472450a6e724be43bc7b Mon Sep 17 00:00:00 2001 From: Lujeni Date: Mon, 12 Jan 2026 23:17:48 +0100 Subject: [PATCH] test(dev-server): support UI port see #748 --- temporalio/testing/_workflow.py | 12 ++++++++++++ tests/testing/test_workflow.py | 23 +++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/temporalio/testing/_workflow.py b/temporalio/testing/_workflow.py index 62da91b6e..8fedce23f 100644 --- a/temporalio/testing/_workflow.py +++ b/temporalio/testing/_workflow.py @@ -91,6 +91,7 @@ async def start_local( dev_server_download_version: str = "default", dev_server_extra_args: Sequence[str] = [], dev_server_download_ttl: timedelta | None = None, + dev_server_ui_port: str | int | None = None, ) -> WorkflowEnvironment: """Start a full Temporal server locally, downloading if necessary. @@ -149,6 +150,9 @@ async def start_local( dev_server_extra_args: Extra arguments for the CLI binary. dev_server_download_ttl: TTL for the downloaded CLI binary. If unset, it will be cached indefinitely. + dev_server_ui_port: UI port to use if UI is enabled. If not provided, + a free port will be used. Can be specified as a string (e.g., "8080") + or an integer (e.g., 8080). Returns: The started CLI dev server workflow environment. @@ -173,6 +177,14 @@ async def start_local( new_args.append(f"{attr.name}={attr._metadata_type}") new_args += dev_server_extra_args dev_server_extra_args = new_args + if dev_server_ui_port is not None: + ui_port_str = str(dev_server_ui_port) + extra_args_list = list(dev_server_extra_args) + if "--ui-port" not in extra_args_list: + # Prepend to extra_args so user-provided args can override if needed + dev_server_extra_args = ["--ui-port", ui_port_str] + extra_args_list + else: + dev_server_extra_args = extra_args_list # Start CLI dev server runtime = runtime or temporalio.runtime.Runtime.default() download_ttl_ms = None diff --git a/tests/testing/test_workflow.py b/tests/testing/test_workflow.py index b0082d1cd..e7fa6652f 100644 --- a/tests/testing/test_workflow.py +++ b/tests/testing/test_workflow.py @@ -317,6 +317,29 @@ async def test_search_attributes_on_dev_server( assert attrs == desc.typed_search_attributes +@pytest.mark.parametrize( + "ui_port,extra_args,description", + [ + (18080, None, "integer port"), + ("18081", None, "string port"), + (18082, ["--ui-port", "18083"], "extra_args takes precedence"), + ], +) +async def test_dev_server_ui_port(ui_port, extra_args, description): + """Test that dev_server_ui_port parameter works correctly.""" + kwargs = { + "ui": True, + "dev_server_ui_port": ui_port, + "dev_server_download_version": DEV_SERVER_DOWNLOAD_VERSION, + } + if extra_args: + kwargs["dev_server_extra_args"] = extra_args + + async with await WorkflowEnvironment.start_local(**kwargs) as env: + # Just verify it starts without error + assert env.client is not None + + def assert_timestamp_from_now( ts: datetime | float, expected_from_now: float, max_delta: float = 30 ) -> None: