diff --git a/py/conftest.py b/py/conftest.py index 83ad2eebf579d..97bd082831668 100644 --- a/py/conftest.py +++ b/py/conftest.py @@ -15,8 +15,11 @@ # specific language governing permissions and limitations # under the License. +import http.server import os +import socketserver import sys +import threading from dataclasses import dataclass from pathlib import Path @@ -24,6 +27,7 @@ from selenium import webdriver from selenium.common.exceptions import WebDriverException +from selenium.webdriver.common.utils import free_port from selenium.webdriver.remote.server import Server from test.selenium.webdriver.common.network import get_lan_ip from test.selenium.webdriver.common.webserver import SimpleWebServer @@ -544,3 +548,31 @@ def chromium_options(request): options = Driver.clean_options("edge", request) return options + + +@pytest.fixture +def proxy_server(): + """Creates HTTP proxy servers with custom response content, cleans up after the test.""" + servers = [] + + def create_server(response_content=b"test response"): + port = free_port() + + class CustomHandler(http.server.SimpleHTTPRequestHandler): + def do_GET(self): + self.send_response(200) + self.end_headers() + self.wfile.write(response_content) + + server = socketserver.TCPServer(("localhost", port), CustomHandler) + thread = threading.Thread(target=server.serve_forever, daemon=True) + thread.start() + + servers.append(server) + return {"port": port, "server": server} + + yield create_server + + for server in servers: + server.shutdown() + server.server_close() diff --git a/py/test/selenium/webdriver/common/bidi_browser_tests.py b/py/test/selenium/webdriver/common/bidi_browser_tests.py index e89ccd3f0ff59..433403e661173 100644 --- a/py/test/selenium/webdriver/common/bidi_browser_tests.py +++ b/py/test/selenium/webdriver/common/bidi_browser_tests.py @@ -15,10 +15,7 @@ # specific language governing permissions and limitations # under the License. -import http.server import os -import socketserver -import threading import pytest @@ -28,26 +25,10 @@ from selenium.webdriver.common.bidi.session import UserPromptHandler, UserPromptHandlerType from selenium.webdriver.common.by import By from selenium.webdriver.common.proxy import Proxy, ProxyType -from selenium.webdriver.common.utils import free_port from selenium.webdriver.common.window import WindowTypes from selenium.webdriver.support.ui import WebDriverWait -class FakeProxyHandler(http.server.SimpleHTTPRequestHandler): - def do_GET(self): - print(f"[Fake Proxy] Intercepted request to: {self.path}") - self.send_response(200) - self.end_headers() - self.wfile.write(b"proxied response") - - -def start_fake_proxy(port): - server = socketserver.TCPServer(("localhost", port), FakeProxyHandler) - thread = threading.Thread(target=server.serve_forever, daemon=True) - thread.start() - return server - - def test_browser_initialized(driver): """Test that the browser module is initialized properly.""" assert driver.browser is not None @@ -165,21 +146,21 @@ def test_create_user_context_with_direct_proxy(driver): @pytest.mark.xfail_chrome(reason="Chrome auto upgrades HTTP to HTTPS in untrusted networks like CI environments") -@pytest.mark.xfail_firefox(reason="Firefox proxy settings are different") -@pytest.mark.xfail_remote -def test_create_user_context_with_manual_proxy_all_params(driver): +def test_create_user_context_with_manual_proxy_all_params(driver, proxy_server): """Test creating a user context with manual proxy configuration.""" - # Start a fake proxy server - port = free_port() - fake_proxy_server = start_fake_proxy(port=port) + create_proxy_server = proxy_server(response_content=b"proxied response") + no_proxy_server = proxy_server(response_content=b"direct connection - not proxied") + + proxy_port = create_proxy_server["port"] + no_proxy_port = no_proxy_server["port"] proxy = Proxy() proxy.proxy_type = ProxyType.MANUAL - proxy.http_proxy = f"localhost:{port}" - proxy.ssl_proxy = f"localhost:{port}" - proxy.socks_proxy = f"localhost:{port}" + proxy.http_proxy = f"localhost:{proxy_port}" + proxy.ssl_proxy = f"localhost:{proxy_port}" + proxy.socks_proxy = f"localhost:{proxy_port}" proxy.socks_version = 5 - proxy.no_proxy = ["the-internet.herokuapp.com"] + proxy.no_proxy = [f"localhost:{no_proxy_port}"] user_context = driver.browser.create_user_context(proxy=proxy) @@ -189,9 +170,9 @@ def test_create_user_context_with_manual_proxy_all_params(driver): try: # Visit no proxy site, it should bypass proxy - driver.get("http://the-internet.herokuapp.com/") + driver.get(f"http://localhost:{no_proxy_port}/") body_text = driver.find_element(By.TAG_NAME, "body").text.lower() - assert "welcome to the-internet" in body_text + assert "direct connection - not proxied" in body_text # Visit a site that should be proxied driver.get("http://example.com/") @@ -201,18 +182,13 @@ def test_create_user_context_with_manual_proxy_all_params(driver): finally: driver.browser.remove_user_context(user_context) - fake_proxy_server.shutdown() - fake_proxy_server.server_close() @pytest.mark.xfail_chrome(reason="Chrome auto upgrades HTTP to HTTPS in untrusted networks like CI environments") -@pytest.mark.xfail_firefox(reason="Firefox proxy settings are different") -@pytest.mark.xfail_remote -def test_create_user_context_with_proxy_and_accept_insecure_certs(driver): +def test_create_user_context_with_proxy_and_accept_insecure_certs(driver, proxy_server): """Test creating a user context with both acceptInsecureCerts and proxy parameters.""" - # Start fake proxy server - port = free_port() - fake_proxy_server = start_fake_proxy(port=port) + create_proxy_server = proxy_server(response_content=b"proxied response") + port = create_proxy_server["port"] proxy = Proxy() proxy.proxy_type = ProxyType.MANUAL @@ -238,8 +214,6 @@ def test_create_user_context_with_proxy_and_accept_insecure_certs(driver): finally: driver.browser.remove_user_context(user_context) - fake_proxy_server.shutdown() - fake_proxy_server.server_close() def test_create_user_context_with_unhandled_prompt_behavior(driver, pages):