diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/conftest.py b/tests/conftest.py index 9bf6f01..7b8b90e 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -14,6 +14,12 @@ import sys import os +import socket +from typing import Generator, Optional, Type +import pytest +import threading +import http.server +import socketserver pytest_plugins = ["pytester"] @@ -29,3 +35,72 @@ playwright_browser_path = f"{user_profile}\\AppData\\Local\\ms-playwright" os.environ["PLAYWRIGHT_BROWSERS_PATH"] = playwright_browser_path + + +class HTTPTestServer: + PREFIX = "" + EMPTY_PAGE = "" + + def __init__(self) -> None: + self._server: Optional[socketserver.TCPServer] = None + self._server_thread: Optional[threading.Thread] = None + self._port: int = 0 + + def start(self) -> None: + """Start the test server.""" + + # Efficiently find an available port using a raw socket + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + s.bind(("localhost", 0)) + self._port = s.getsockname()[1] + + # Create the actual server + self._server = socketserver.TCPServer( + ("localhost", self._port), self._create_handler() + ) + self._server_thread = threading.Thread(target=self._server.serve_forever) + self._server_thread.daemon = True + self._server_thread.start() + + self.PREFIX = f"http://localhost:{self._port}" + self.EMPTY_PAGE = f"{self.PREFIX}/empty.html" + self.CROSS_PROCESS_PREFIX = f"http://127.0.0.1:{self._port}" + + def stop(self) -> None: + """Stop the test server.""" + if self._server: + self._server.shutdown() + self._server.server_close() + + def _create_handler(self) -> Type[http.server.SimpleHTTPRequestHandler]: + """Create a request handler class.""" + + class SimpleHTTPRequestHandler(http.server.SimpleHTTPRequestHandler): + def do_GET(self) -> None: + """Handle GET requests and return simple HTML with the path.""" + self.send_response(200) + self.send_header("Content-type", "text/html") + self.end_headers() + + html_content = f""" + + + Test Server + + +

Test Server Response

+

Path: {self.path}

+ bar + +""" + self.wfile.write(html_content.encode("utf-8")) + + return SimpleHTTPRequestHandler + + +@pytest.fixture(scope="session") +def test_server() -> Generator[HTTPTestServer, None, None]: + server = HTTPTestServer() + server.start() + yield server + server.stop() diff --git a/tests/test_asyncio.py b/tests/test_asyncio.py index 3b61e1e..8303b7d 100644 --- a/tests/test_asyncio.py +++ b/tests/test_asyncio.py @@ -19,6 +19,8 @@ import pytest +from tests.conftest import HTTPTestServer + @pytest.fixture def pytester(pytester: pytest.Pytester) -> pytest.Pytester: @@ -257,37 +259,39 @@ async def test_is_webkit(page, browser_name, is_chromium, is_firefox, is_webkit) result.assert_outcomes(passed=1) -def test_goto(testdir: pytest.Testdir) -> None: +def test_goto(testdir: pytest.Testdir, test_server: HTTPTestServer) -> None: testdir.makepyfile( - """ + f""" import pytest @pytest.mark.asyncio async def test_base_url(page, base_url): - assert base_url == "https://example.com" + assert base_url == "{test_server.PREFIX}" await page.goto("/foobar") - assert page.url == "https://example.com/foobar" - await page.goto("https://example.org") - assert page.url == "https://example.org/" + assert page.url == "{test_server.PREFIX}/foobar" + await page.goto("{test_server.CROSS_PROCESS_PREFIX}") + assert page.url == "{test_server.CROSS_PROCESS_PREFIX}/" """ ) - result = testdir.runpytest("--base-url", "https://example.com") + result = testdir.runpytest("--base-url", test_server.PREFIX) result.assert_outcomes(passed=1) -def test_base_url_via_fixture(testdir: pytest.Testdir) -> None: +def test_base_url_via_fixture( + testdir: pytest.Testdir, test_server: HTTPTestServer +) -> None: testdir.makepyfile( - """ + f""" import pytest @pytest.fixture(scope="session") def base_url(): - return "https://example.com" + return "{test_server.PREFIX}" @pytest.mark.asyncio async def test_base_url(page, base_url): - assert base_url == "https://example.com" + assert base_url == "{test_server.PREFIX}" await page.goto("/foobar") - assert page.url == "https://example.com/foobar" + assert page.url == "{test_server.PREFIX}/foobar" """ ) result = testdir.runpytest() diff --git a/tests/test_sync.py b/tests/test_sync.py index 84ad2dc..d613e1a 100644 --- a/tests/test_sync.py +++ b/tests/test_sync.py @@ -20,6 +20,8 @@ import pytest +from tests.conftest import HTTPTestServer + @pytest.fixture def pytester(pytester: pytest.Pytester) -> pytest.Pytester: @@ -283,34 +285,36 @@ def test_is_webkit(page, browser_name, is_chromium, is_firefox, is_webkit): result.assert_outcomes(passed=1) -def test_goto(testdir: pytest.Testdir) -> None: +def test_goto(testdir: pytest.Testdir, test_server: HTTPTestServer) -> None: testdir.makepyfile( - """ + f""" def test_base_url(page, base_url): - assert base_url == "https://example.com" + assert base_url == "{test_server.PREFIX}" page.goto("/foobar") - assert page.url == "https://example.com/foobar" - page.goto("https://example.org") - assert page.url == "https://example.org/" + assert page.url == "{test_server.PREFIX}/foobar" + page.goto("{test_server.CROSS_PROCESS_PREFIX}") + assert page.url == "{test_server.CROSS_PROCESS_PREFIX}/" """ ) - result = testdir.runpytest("--base-url", "https://example.com") + result = testdir.runpytest("--base-url", test_server.PREFIX) result.assert_outcomes(passed=1) -def test_base_url_via_fixture(testdir: pytest.Testdir) -> None: +def test_base_url_via_fixture( + testdir: pytest.Testdir, test_server: HTTPTestServer +) -> None: testdir.makepyfile( - """ + f""" import pytest @pytest.fixture(scope="session") def base_url(): - return "https://example.com" + return "{test_server.PREFIX}" def test_base_url(page, base_url): - assert base_url == "https://example.com" + assert base_url == "{test_server.PREFIX}" page.goto("/foobar") - assert page.url == "https://example.com/foobar" + assert page.url == "{test_server.PREFIX}/foobar" """ ) result = testdir.runpytest()