Path: blob/trunk/py/test/selenium/webdriver/common/bidi_browser_tests.py
4020 views
# Licensed to the Software Freedom Conservancy (SFC) under one1# or more contributor license agreements. See the NOTICE file2# distributed with this work for additional information3# regarding copyright ownership. The SFC licenses this file4# to you under the Apache License, Version 2.0 (the5# "License"); you may not use this file except in compliance6# with the License. You may obtain a copy of the License at7#8# http://www.apache.org/licenses/LICENSE-2.09#10# Unless required by applicable law or agreed to in writing,11# software distributed under the License is distributed on an12# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY13# KIND, either express or implied. See the License for the14# specific language governing permissions and limitations15# under the License.1617import os1819import pytest2021from selenium.common.exceptions import TimeoutException22from selenium.webdriver.common.bidi.browser import ClientWindowInfo, ClientWindowState23from selenium.webdriver.common.bidi.browsing_context import ReadinessState24from selenium.webdriver.common.bidi.session import UserPromptHandler, UserPromptHandlerType25from selenium.webdriver.common.by import By26from selenium.webdriver.common.proxy import Proxy, ProxyType27from selenium.webdriver.common.window import WindowTypes28from selenium.webdriver.support.ui import WebDriverWait293031def test_browser_initialized(driver):32"""Test that the browser module is initialized properly."""33assert driver.browser is not None343536def test_create_user_context(driver):37"""Test creating a user context."""38user_context = driver.browser.create_user_context()39assert user_context is not None4041# Clean up42driver.browser.remove_user_context(user_context)434445def test_get_user_contexts(driver):46"""Test getting user contexts."""47user_context1 = driver.browser.create_user_context()48user_context2 = driver.browser.create_user_context()4950user_contexts = driver.browser.get_user_contexts()51# it should be 3 since there is a default user context present, therefore >= 252assert len(user_contexts) >= 25354# Clean up55driver.browser.remove_user_context(user_context1)56driver.browser.remove_user_context(user_context2)575859def test_remove_user_context(driver):60"""Test removing a user context."""61user_context1 = driver.browser.create_user_context()62user_context2 = driver.browser.create_user_context()6364user_contexts = driver.browser.get_user_contexts()65assert len(user_contexts) >= 26667driver.browser.remove_user_context(user_context2)6869updated_user_contexts = driver.browser.get_user_contexts()70assert user_context1 in updated_user_contexts71assert user_context2 not in updated_user_contexts7273# Clean up74driver.browser.remove_user_context(user_context1)757677def test_get_client_windows(driver):78"""Test getting client windows."""79client_windows = driver.browser.get_client_windows()8081assert client_windows is not None82assert len(client_windows) > 08384window_info = client_windows[0]85assert isinstance(window_info, ClientWindowInfo)86assert window_info.get_client_window() is not None87assert window_info.get_state() is not None88assert isinstance(window_info.get_state(), str)89assert window_info.get_width() > 090assert window_info.get_height() > 091assert isinstance(window_info.is_active(), bool)92assert window_info.get_x() >= 093assert window_info.get_y() >= 0949596def test_raises_exception_when_removing_default_user_context(driver):97with pytest.raises(Exception):98driver.browser.remove_user_context("default")99100101def test_client_window_state_constants(driver):102assert ClientWindowState.FULLSCREEN == "fullscreen"103assert ClientWindowState.MAXIMIZED == "maximized"104assert ClientWindowState.MINIMIZED == "minimized"105assert ClientWindowState.NORMAL == "normal"106107108def test_create_user_context_with_accept_insecure_certs(driver):109"""Test creating a user context with accept_insecure_certs parameter."""110INSECURE_TEST_SITE = "https://self-signed.badssl.com/"111user_context = driver.browser.create_user_context(accept_insecure_certs=True)112113bc = driver.browsing_context.create(type=WindowTypes.WINDOW, user_context=user_context)114driver.switch_to.window(bc)115assert user_context is not None116assert bc is not None117118driver.get(INSECURE_TEST_SITE)119120h1 = driver.find_element(By.TAG_NAME, "h1")121assert h1.text.strip() == "self-signed.\nbadssl.com"122123# Clean up124driver.browser.remove_user_context(user_context)125126127def test_create_user_context_with_direct_proxy(driver):128"""Test creating a user context with direct proxy configuration."""129proxy = Proxy()130proxy.proxy_type = ProxyType.DIRECT131132user_context = driver.browser.create_user_context(proxy=proxy)133assert user_context is not None134135bc = driver.browsing_context.create(type=WindowTypes.WINDOW, user_context=user_context)136driver.switch_to.window(bc)137138# Visiting a site should load directly without proxy139driver.get("http://example.com/")140body_text = driver.find_element(By.TAG_NAME, "body").text.lower()141assert "example domain" in body_text142143# Clean up144driver.browser.remove_user_context(user_context)145146147@pytest.mark.xfail_chrome(reason="Chrome auto upgrades HTTP to HTTPS in untrusted networks like CI environments")148def test_create_user_context_with_manual_proxy_all_params(driver, proxy_server):149"""Test creating a user context with manual proxy configuration."""150create_proxy_server = proxy_server(response_content=b"proxied response")151no_proxy_server = proxy_server(response_content=b"direct connection - not proxied")152153proxy_port = create_proxy_server["port"]154no_proxy_port = no_proxy_server["port"]155156proxy = Proxy()157proxy.proxy_type = ProxyType.MANUAL158proxy.http_proxy = f"localhost:{proxy_port}"159proxy.ssl_proxy = f"localhost:{proxy_port}"160proxy.socks_proxy = f"localhost:{proxy_port}"161proxy.socks_version = 5162proxy.no_proxy = [f"localhost:{no_proxy_port}"]163164user_context = driver.browser.create_user_context(proxy=proxy)165166# Create and switch to a new browsing context using this proxy167bc = driver.browsing_context.create(type=WindowTypes.WINDOW, user_context=user_context)168driver.switch_to.window(bc)169170try:171# Visit no proxy site, it should bypass proxy172driver.get(f"http://localhost:{no_proxy_port}/")173body_text = driver.find_element(By.TAG_NAME, "body").text.lower()174assert "direct connection - not proxied" in body_text175176# Visit a site that should be proxied177driver.get("http://example.com/")178179body_text = driver.find_element("tag name", "body").text180assert "proxied response" in body_text.lower()181182finally:183driver.browser.remove_user_context(user_context)184185186@pytest.mark.xfail_chrome(reason="Chrome auto upgrades HTTP to HTTPS in untrusted networks like CI environments")187def test_create_user_context_with_proxy_and_accept_insecure_certs(driver, proxy_server):188"""Test creating a user context with both acceptInsecureCerts and proxy parameters."""189create_proxy_server = proxy_server(response_content=b"proxied response")190port = create_proxy_server["port"]191192proxy = Proxy()193proxy.proxy_type = ProxyType.MANUAL194proxy.http_proxy = f"localhost:{port}"195proxy.ssl_proxy = f"localhost:{port}"196proxy.no_proxy = ["self-signed.badssl.com"]197198user_context = driver.browser.create_user_context(accept_insecure_certs=True, proxy=proxy)199200bc = driver.browsing_context.create(type=WindowTypes.WINDOW, user_context=user_context)201driver.switch_to.window(bc)202203try:204# Visit a site with an invalid certificate205driver.get("https://self-signed.badssl.com/")206h1 = driver.find_element(By.TAG_NAME, "h1")207assert "badssl.com" in h1.text.lower()208209# Visit a site that should go through the fake proxy210driver.get("http://example.com/")211body_text = driver.find_element(By.TAG_NAME, "body").text212assert "proxied response" in body_text.lower()213214finally:215driver.browser.remove_user_context(user_context)216217218def test_create_user_context_with_unhandled_prompt_behavior(driver, pages):219"""Test creating a user context with unhandled prompt behavior configuration."""220prompt_handler = UserPromptHandler(221alert=UserPromptHandlerType.DISMISS, default=UserPromptHandlerType.DISMISS, prompt=UserPromptHandlerType.DISMISS222)223224user_context = driver.browser.create_user_context(unhandled_prompt_behavior=prompt_handler)225assert user_context is not None226227# create a new browsing context with the user context228bc = driver.browsing_context.create(type=WindowTypes.WINDOW, user_context=user_context)229assert bc is not None230231driver.switch_to.window(bc)232pages.load("alerts.html")233234# TODO: trigger an alert and test that it is dismissed automatically, currently not working,235# conftest.py unhandled_prompt_behavior set to IGNORE, see if it is related236# driver.find_element(By.ID, "alert").click()237# # accessing title should be possible since alert is auto handled238# assert driver.title == "Testing Alerts"239240# Clean up241driver.browser.remove_user_context(user_context)242243244@pytest.mark.xfail_firefox245def test_set_download_behavior_allowed(driver, pages, tmp_path):246print(f"Driver info: {driver.capabilities}")247try:248driver.browser.set_download_behavior(allowed=True, destination_folder=tmp_path)249250context_id = driver.current_window_handle251url = pages.url("downloads/download.html")252driver.browsing_context.navigate(context=context_id, url=url, wait=ReadinessState.COMPLETE)253254driver.find_element(By.ID, "file-1").click()255256WebDriverWait(driver, 5).until(lambda d: "file_1.txt" in os.listdir(tmp_path))257258files = os.listdir(tmp_path)259assert "file_1.txt" in files, f"Expected file_1.txt in {tmp_path}, but found: {files}"260finally:261driver.browser.set_download_behavior(allowed=None)262263264@pytest.mark.xfail_firefox265def test_set_download_behavior_denied(driver, pages, tmp_path):266try:267driver.browser.set_download_behavior(allowed=False)268269context_id = driver.current_window_handle270url = pages.url("downloads/download.html")271driver.browsing_context.navigate(context=context_id, url=url, wait=ReadinessState.COMPLETE)272273driver.find_element(By.ID, "file-1").click()274275try:276WebDriverWait(driver, 3, poll_frequency=0.2).until(lambda _: len(os.listdir(tmp_path)) > 0)277files = os.listdir(tmp_path)278pytest.fail(f"A file was downloaded unexpectedly: {files}")279except TimeoutException:280pass # Expected, no file downloaded281finally:282driver.browser.set_download_behavior(allowed=None)283284285@pytest.mark.xfail_firefox286def test_set_download_behavior_user_context(driver, pages, tmp_path):287user_context = driver.browser.create_user_context()288289try:290bc = driver.browsing_context.create(type=WindowTypes.WINDOW, user_context=user_context)291driver.switch_to.window(bc)292293try:294driver.browser.set_download_behavior(295allowed=True, destination_folder=tmp_path, user_contexts=[user_context]296)297298url = pages.url("downloads/download.html")299driver.browsing_context.navigate(context=bc, url=url, wait=ReadinessState.COMPLETE)300301driver.find_element(By.ID, "file-1").click()302303WebDriverWait(driver, 5).until(lambda d: "file_1.txt" in os.listdir(tmp_path))304305files = os.listdir(tmp_path)306assert "file_1.txt" in files, f"Expected file_1.txt in {tmp_path}, but found: {files}"307308initial_file_count = len(files)309310driver.browser.set_download_behavior(allowed=False, user_contexts=[user_context])311312driver.find_element(By.ID, "file-2").click()313314try:315WebDriverWait(driver, 3, poll_frequency=0.2).until(316lambda _: len(os.listdir(tmp_path)) > initial_file_count317)318files_after = os.listdir(tmp_path)319pytest.fail(f"A file was downloaded unexpectedly: {files_after}")320except TimeoutException:321pass # Expected, no file downloaded322finally:323driver.browser.set_download_behavior(allowed=None, user_contexts=[user_context])324finally:325driver.browser.remove_user_context(user_context)326327328@pytest.mark.xfail_firefox329def test_set_download_behavior_validation(driver):330with pytest.raises(ValueError, match="destination_folder is required when allowed=True"):331driver.browser.set_download_behavior(allowed=True)332333with pytest.raises(ValueError, match="destination_folder should not be provided when allowed=False"):334driver.browser.set_download_behavior(allowed=False, destination_folder="/tmp")335336337