diff --git a/test/openjd/expr/test_strings.py b/test/openjd/expr/test_strings.py index 1a6abd82..f50d69f5 100644 --- a/test/openjd/expr/test_strings.py +++ b/test/openjd/expr/test_strings.py @@ -650,10 +650,21 @@ def test_pwsh_range_expr_as_list(self) -> None: @pytest.mark.skipif(os.name != "nt", reason="PowerShell validation only on Windows") +# pytest-timeout counts the class-scoped warm-up below against the first test. +@pytest.mark.timeout(180) class TestReprPwshWindowsValidation: """Validate repr_pwsh output by running PowerShell subprocess on Windows.""" - def _pwsh_eval(self, expr: str) -> str: + @staticmethod + @pytest.fixture(scope="class", autouse=True) + def _warm_powershell() -> None: + # The first PowerShell launch on a fresh Windows runner can exceed the + # per-call timeout. Pay that once here, with a deadline sized for it. + ready = TestReprPwshWindowsValidation._pwsh_eval("Write-Output ready", timeout=120) + assert ready == "ready" + + @staticmethod + def _pwsh_eval(expr: str, *, timeout: float = 10) -> str: """Write expr to a temporary .ps1 file and execute it, so PowerShell interprets the repr_pwsh output exactly once (no argument-layer parsing).""" import subprocess @@ -667,7 +678,7 @@ def _pwsh_eval(self, expr: str) -> str: ["powershell", "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", ps1_path], capture_output=True, text=True, - timeout=10, + timeout=timeout, ) return result.stdout.strip() finally: