diff --git a/nicegui/testing/screen.py b/nicegui/testing/screen.py index e22634f610..f8b02d2bdd 100644 --- a/nicegui/testing/screen.py +++ b/nicegui/testing/screen.py @@ -19,7 +19,7 @@ from selenium.webdriver.common.by import By from selenium.webdriver.remote.webelement import WebElement -from nicegui import app, core, ui +from nicegui import app, core, helpers, ui from nicegui.server import Server from .general import prepare_simulation @@ -43,8 +43,8 @@ def __init__(self, selenium: webdriver.Chrome, caplog: pytest.LogCaptureFixture, self.url = f'http://localhost:{self.PORT}' self.allowed_js_errors: list[str] = [] - def start_server(self) -> None: - """Start the webserver in a separate thread.""" + def start_server(self, timeout: float = 10.0) -> None: + """Start the webserver in a separate thread and wait until it accepts connections.""" main_path = get_path_to_main_file(self.pytest_request) if self.pytest_request else None if main_path is None: prepare_simulation() @@ -52,6 +52,13 @@ def start_server(self) -> None: else: self.server_thread = threading.Thread(target=lambda: runpy.run_path(str(main_path), run_name='__main__')) self.server_thread.start() + deadline = time.time() + timeout + while not helpers.is_port_open('localhost', self.PORT): + if not self.server_thread.is_alive(): + raise RuntimeError('The NiceGUI server has stopped running') + if time.time() > deadline: + raise RuntimeError(f'The NiceGUI server did not start listening on port {self.PORT} within {timeout} s') + time.sleep(0.01) @property def is_open(self) -> bool: diff --git a/tests/test_screen.py b/tests/test_screen.py new file mode 100644 index 0000000000..bf1a0126c4 --- /dev/null +++ b/tests/test_screen.py @@ -0,0 +1,14 @@ +import httpx + +from nicegui import helpers, ui +from nicegui.testing import Screen + + +def test_start_server_waits_until_the_port_is_open(screen: Screen): + @ui.page('/') + def page(): + ui.label('Hello') + + screen.start_server() + assert helpers.is_port_open('localhost', Screen.PORT) + assert httpx.get(f'http://localhost:{Screen.PORT}/').status_code == 200