diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
commit | 43a97878ce14b72f0981164f87f2e35e14151312 (patch) | |
tree | 620249daf56c0258faa40cbdcf9cfba06de2a846 /testing/web-platform/mozilla/tests/webdriver/bidi | |
parent | Initial commit. (diff) | |
download | firefox-43a97878ce14b72f0981164f87f2e35e14151312.tar.xz firefox-43a97878ce14b72f0981164f87f2e35e14151312.zip |
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/mozilla/tests/webdriver/bidi')
13 files changed, 430 insertions, 0 deletions
diff --git a/testing/web-platform/mozilla/tests/webdriver/bidi/__init__.py b/testing/web-platform/mozilla/tests/webdriver/bidi/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/testing/web-platform/mozilla/tests/webdriver/bidi/__init__.py diff --git a/testing/web-platform/mozilla/tests/webdriver/bidi/browsing_context/__init__.py b/testing/web-platform/mozilla/tests/webdriver/bidi/browsing_context/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/testing/web-platform/mozilla/tests/webdriver/bidi/browsing_context/__init__.py diff --git a/testing/web-platform/mozilla/tests/webdriver/bidi/browsing_context/create/__init__.py b/testing/web-platform/mozilla/tests/webdriver/bidi/browsing_context/create/__init__.py new file mode 100644 index 0000000000..910b202075 --- /dev/null +++ b/testing/web-platform/mozilla/tests/webdriver/bidi/browsing_context/create/__init__.py @@ -0,0 +1,20 @@ +import contextlib + + +def set_context(session, context): + session.send_session_command("POST", "moz/context", {"context": context}) + + +@contextlib.contextmanager +def using_context(session, context): + orig_context = session.send_session_command("GET", "moz/context") + needs_change = context != orig_context + + if needs_change: + set_context(session, context) + + try: + yield + finally: + if needs_change: + set_context(session, orig_context) diff --git a/testing/web-platform/mozilla/tests/webdriver/bidi/browsing_context/create/reference_context.py b/testing/web-platform/mozilla/tests/webdriver/bidi/browsing_context/create/reference_context.py new file mode 100644 index 0000000000..1a5906339b --- /dev/null +++ b/testing/web-platform/mozilla/tests/webdriver/bidi/browsing_context/create/reference_context.py @@ -0,0 +1,72 @@ +import pytest + +from . import using_context + +pytestmark = pytest.mark.asyncio + + +# Helper to assert the order of top level browsing contexts. +# The window used for the assertion is inferred from the first context id of +# expected_context_ids. +def assert_tab_order(session, expected_context_ids): + with using_context(session, "chrome"): + context_ids = session.execute_script( + """ + const contextId = arguments[0]; + const { TabManager } = + ChromeUtils.importESModule("chrome://remote/content/shared/TabManager.sys.mjs"); + const browsingContext = TabManager.getBrowsingContextById(contextId); + const chromeWindow = browsingContext.embedderElement.ownerGlobal; + const tabBrowser = TabManager.getTabBrowser(chromeWindow); + return tabBrowser.browsers.map(browser => TabManager.getIdForBrowser(browser)); + """, + args=(expected_context_ids[0],), + ) + + assert context_ids == expected_context_ids + + +async def test_reference_context(bidi_session, current_session): + # Create a new window with a tab tab1 + result = await bidi_session.browsing_context.create(type_hint="window") + tab1_context_id = result["context"] + + # Create a second window with a tab tab2 + result = await bidi_session.browsing_context.create(type_hint="window") + tab2_context_id = result["context"] + + # Create a new tab tab3 next to tab1 + result = await bidi_session.browsing_context.create( + type_hint="tab", reference_context=tab1_context_id + ) + tab3_context_id = result["context"] + + # Create a new tab tab4 next to tab2 + result = await bidi_session.browsing_context.create( + type_hint="tab", reference_context=tab2_context_id + ) + tab4_context_id = result["context"] + + # Create a new tab tab5 also next to tab2 (should consequently be between + # tab2 and tab4) + result = await bidi_session.browsing_context.create( + type_hint="tab", reference_context=tab2_context_id + ) + tab5_context_id = result["context"] + + # Create a new window, but pass a reference_context from an existing window. + # The reference context is expected to be ignored here. + result = await bidi_session.browsing_context.create( + type_hint="window", reference_context=tab2_context_id + ) + tab6_context_id = result["context"] + + # We expect 3 windows in total, with a specific tab order: + # - the first window should contain tab1, tab3 + assert_tab_order(current_session, [tab1_context_id, tab3_context_id]) + # - the second window should contain tab2, tab5, tab4 + assert_tab_order( + current_session, [tab2_context_id, tab5_context_id, tab4_context_id] + ) + # - the third window should contain tab6 + assert_tab_order(current_session, [tab6_context_id]) diff --git a/testing/web-platform/mozilla/tests/webdriver/bidi/browsing_context/create/type_hint.py b/testing/web-platform/mozilla/tests/webdriver/bidi/browsing_context/create/type_hint.py new file mode 100644 index 0000000000..337a03b3dd --- /dev/null +++ b/testing/web-platform/mozilla/tests/webdriver/bidi/browsing_context/create/type_hint.py @@ -0,0 +1,31 @@ +import pytest +from tests.support.asserts import assert_success + +from . import using_context + +pytestmark = pytest.mark.asyncio + + +def count_window_handles(session): + with using_context(session, "chrome"): + response = session.transport.send( + "GET", "session/{session_id}/window/handles".format(**vars(session)) + ) + chrome_handles = assert_success(response) + return len(chrome_handles) + + +@pytest.mark.parametrize("type_hint", ["tab", "window"]) +async def test_type_hint(bidi_session, current_session, type_hint): + assert len(await bidi_session.browsing_context.get_tree()) == 1 + assert count_window_handles(current_session) == 1 + + await bidi_session.browsing_context.create(type_hint=type_hint) + + if type_hint == "window": + expected_window_count = 2 + else: + expected_window_count = 1 + + assert len(await bidi_session.browsing_context.get_tree()) == 2 + assert count_window_handles(current_session) == expected_window_count diff --git a/testing/web-platform/mozilla/tests/webdriver/bidi/browsing_context/navigate/__init__.py b/testing/web-platform/mozilla/tests/webdriver/bidi/browsing_context/navigate/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/testing/web-platform/mozilla/tests/webdriver/bidi/browsing_context/navigate/__init__.py diff --git a/testing/web-platform/mozilla/tests/webdriver/bidi/browsing_context/navigate/error.py b/testing/web-platform/mozilla/tests/webdriver/bidi/browsing_context/navigate/error.py new file mode 100644 index 0000000000..374359d1ae --- /dev/null +++ b/testing/web-platform/mozilla/tests/webdriver/bidi/browsing_context/navigate/error.py @@ -0,0 +1,48 @@ +import os +from copy import deepcopy + +import pytest +from tests.bidi.browsing_context.navigate import navigate_and_assert + +pytestmark = pytest.mark.asyncio + + +async def test_insecure_certificate(configuration, url, custom_profile, geckodriver): + try: + # Create a new profile and remove the certificate storage so that + # loading a HTTPS page will cause an insecure certificate error + os.remove(os.path.join(custom_profile.profile, "cert9.db")) + except Exception: + pass + + config = deepcopy(configuration) + config["capabilities"]["moz:firefoxOptions"]["args"] = [ + "--profile", + custom_profile.profile, + ] + # Capability matching not implemented yet for WebDriver BiDi (bug 1713784) + config["capabilities"]["acceptInsecureCerts"] = False + config["capabilities"]["webSocketUrl"] = True + + driver = geckodriver(config=config) + driver.new_session() + + bidi_session = driver.session.bidi_session + await bidi_session.start() + + contexts = await bidi_session.browsing_context.get_tree(max_depth=0) + await navigate_and_assert( + bidi_session, + contexts[0], + url("/common/blank.html", protocol="https"), + expected_error=True, + ) + + +async def test_invalid_content_encoding(bidi_session, new_tab, inline): + await navigate_and_assert( + bidi_session, + new_tab, + f"{inline('<div>foo')}&pipe=header(Content-Encoding,gzip)", + expected_error=True, + ) diff --git a/testing/web-platform/mozilla/tests/webdriver/bidi/errors/__init__.py b/testing/web-platform/mozilla/tests/webdriver/bidi/errors/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/testing/web-platform/mozilla/tests/webdriver/bidi/errors/__init__.py diff --git a/testing/web-platform/mozilla/tests/webdriver/bidi/errors/errors.py b/testing/web-platform/mozilla/tests/webdriver/bidi/errors/errors.py new file mode 100644 index 0000000000..69b1f2fb7a --- /dev/null +++ b/testing/web-platform/mozilla/tests/webdriver/bidi/errors/errors.py @@ -0,0 +1,8 @@ +import pytest +from webdriver.bidi.error import UnknownCommandException + + +@pytest.mark.asyncio +async def test_internal_method(bidi_session, send_blocking_command): + with pytest.raises(UnknownCommandException): + await send_blocking_command("log._applySessionData", {}) diff --git a/testing/web-platform/mozilla/tests/webdriver/bidi/interface/__init__.py b/testing/web-platform/mozilla/tests/webdriver/bidi/interface/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/testing/web-platform/mozilla/tests/webdriver/bidi/interface/__init__.py diff --git a/testing/web-platform/mozilla/tests/webdriver/bidi/interface/interface.py b/testing/web-platform/mozilla/tests/webdriver/bidi/interface/interface.py new file mode 100644 index 0000000000..561b80d120 --- /dev/null +++ b/testing/web-platform/mozilla/tests/webdriver/bidi/interface/interface.py @@ -0,0 +1,26 @@ +import pytest +from webdriver.bidi.client import BidiSession +from webdriver.bidi.modules.script import ContextTarget + +pytestmark = pytest.mark.asyncio + + +async def test_navigator_webdriver_enabled(inline, browser): + # Request a new browser with only WebDriver BiDi and not Marionette/CDP enabled. + current_browser = browser(use_bidi=True, extra_prefs={"remote.active-protocols": 1}) + server_host = current_browser.remote_agent_host + server_port = current_browser.remote_agent_port + + async with BidiSession.bidi_only( + f"ws://{server_host}:{server_port}" + ) as bidi_session: + contexts = await bidi_session.browsing_context.get_tree(max_depth=0) + assert len(contexts) > 0 + + result = await bidi_session.script.evaluate( + expression="navigator.webdriver", + target=ContextTarget(contexts[0]["context"]), + await_promise=False, + ) + + assert result == {"type": "boolean", "value": True} diff --git a/testing/web-platform/mozilla/tests/webdriver/bidi/script/exception_details.py b/testing/web-platform/mozilla/tests/webdriver/bidi/script/exception_details.py new file mode 100644 index 0000000000..43bccdb845 --- /dev/null +++ b/testing/web-platform/mozilla/tests/webdriver/bidi/script/exception_details.py @@ -0,0 +1,69 @@ +import pytest +from webdriver.bidi.modules.script import ContextTarget, ScriptEvaluateResultException + + +@pytest.mark.asyncio +@pytest.mark.parametrize("await_promise", [True, False]) +@pytest.mark.parametrize( + "expression", + [ + "null", + "{ toString: 'not a function' }", + "{ toString: () => {{ throw 'toString not allowed'; }} }", + "{ toString: () => true }", + ], +) +@pytest.mark.asyncio +async def test_call_function_without_to_string_interface( + bidi_session, top_context, await_promise, expression +): + function_declaration = "()=>{throw { toString: 'not a function' } }" + if await_promise: + function_declaration = "async" + function_declaration + + with pytest.raises(ScriptEvaluateResultException) as exception: + await bidi_session.script.call_function( + function_declaration=function_declaration, + await_promise=await_promise, + target=ContextTarget(top_context["context"]), + ) + + assert "exceptionDetails" in exception.value.result + exceptionDetails = exception.value.result["exceptionDetails"] + + assert "text" in exceptionDetails + assert isinstance(exceptionDetails["text"], str) + + +@pytest.mark.asyncio +@pytest.mark.parametrize("await_promise", [True, False]) +@pytest.mark.parametrize( + "expression", + [ + "null", + "{ toString: 'not a function' }", + "{ toString: () => {{ throw 'toString not allowed'; }} }", + "{ toString: () => true }", + ], +) +@pytest.mark.asyncio +async def test_evaluate_without_to_string_interface( + bidi_session, top_context, await_promise, expression +): + if await_promise: + expression = f"Promise.reject({expression})" + else: + expression = f"throw {expression}" + + with pytest.raises(ScriptEvaluateResultException) as exception: + await bidi_session.script.evaluate( + expression=expression, + await_promise=await_promise, + target=ContextTarget(top_context["context"]), + ) + + assert "exceptionDetails" in exception.value.result + exceptionDetails = exception.value.result["exceptionDetails"] + + assert "text" in exceptionDetails + assert isinstance(exceptionDetails["text"], str) diff --git a/testing/web-platform/mozilla/tests/webdriver/bidi/websocket_upgrade.py b/testing/web-platform/mozilla/tests/webdriver/bidi/websocket_upgrade.py new file mode 100644 index 0000000000..e5ebfa1eb0 --- /dev/null +++ b/testing/web-platform/mozilla/tests/webdriver/bidi/websocket_upgrade.py @@ -0,0 +1,156 @@ +import pytest +from support.network import get_host, websocket_request + + +@pytest.mark.parametrize( + "hostname, port_type, status", + [ + # Valid hosts + ("localhost", "server_port", 101), + ("localhost", "default_port", 101), + ("127.0.0.1", "server_port", 101), + ("127.0.0.1", "default_port", 101), + ("[::1]", "server_port", 101), + ("[::1]", "default_port", 101), + ("192.168.8.1", "server_port", 101), + ("192.168.8.1", "default_port", 101), + ("[fdf8:f535:82e4::53]", "server_port", 101), + ("[fdf8:f535:82e4::53]", "default_port", 101), + # Invalid hosts + ("mozilla.org", "server_port", 400), + ("mozilla.org", "wrong_port", 400), + ("mozilla.org", "default_port", 400), + ("localhost", "wrong_port", 400), + ("127.0.0.1", "wrong_port", 400), + ("[::1]", "wrong_port", 400), + ("192.168.8.1", "wrong_port", 400), + ("[fdf8:f535:82e4::53]", "wrong_port", 400), + ], + ids=[ + # Valid hosts + "localhost with same port as RemoteAgent", + "localhost with default port", + "127.0.0.1 (loopback) with same port as RemoteAgent", + "127.0.0.1 (loopback) with default port", + "[::1] (ipv6 loopback) with same port as RemoteAgent", + "[::1] (ipv6 loopback) with default port", + "ipv4 address with same port as RemoteAgent", + "ipv4 address with default port", + "ipv6 address with same port as RemoteAgent", + "ipv6 address with default port", + # Invalid hosts + "random hostname with the same port as RemoteAgent", + "random hostname with a different port than RemoteAgent", + "random hostname with default port", + "localhost with a different port than RemoteAgent", + "127.0.0.1 (loopback) with a different port than RemoteAgent", + "[::1] (ipv6 loopback) with a different port than RemoteAgent", + "ipv4 address with a different port than RemoteAgent", + "ipv6 address with a different port than RemoteAgent", + ], +) +def test_host_header(browser, hostname, port_type, status): + # Request a default browser + current_browser = browser(use_bidi=True) + server_host = current_browser.remote_agent_host + server_port = current_browser.remote_agent_port + test_host = get_host(port_type, hostname, server_port) + + response = websocket_request(server_host, server_port, host=test_host) + assert response.status == status + + +@pytest.mark.parametrize( + "hostname, port_type, status", + [ + # Allowed hosts + ("testhost", "server_port", 101), + ("testhost", "default_port", 101), + ("testhost", "wrong_port", 400), + # IP addresses + ("192.168.8.1", "server_port", 101), + ("192.168.8.1", "default_port", 101), + ("[fdf8:f535:82e4::53]", "server_port", 101), + ("[fdf8:f535:82e4::53]", "default_port", 101), + ("127.0.0.1", "server_port", 101), + ("127.0.0.1", "default_port", 101), + ("[::1]", "server_port", 101), + ("[::1]", "default_port", 101), + # Localhost + ("localhost", "server_port", 400), + ("localhost", "default_port", 400), + ], + ids=[ + # Allowed hosts + "allowed host with same port as RemoteAgent", + "allowed host with default port", + "allowed host with wrong port", + # IP addresses + "ipv4 address with same port as RemoteAgent", + "ipv4 address with default port", + "ipv6 address with same port as RemoteAgent", + "ipv6 address with default port", + "127.0.0.1 (loopback) with same port as RemoteAgent", + "127.0.0.1 (loopback) with default port", + "[::1] (ipv6 loopback) with same port as RemoteAgent", + "[::1] (ipv6 loopback) with default port", + # Localhost + "localhost with same port as RemoteAgent", + "localhost with default port", + ], +) +def test_allowed_hosts(browser, hostname, port_type, status): + # Request a browser with custom allowed hosts. + current_browser = browser( + use_bidi=True, + extra_args=["--remote-allow-hosts", "testhost"], + ) + server_host = current_browser.remote_agent_host + server_port = current_browser.remote_agent_port + test_host = get_host(port_type, hostname, server_port) + + response = websocket_request(server_host, server_port, host=test_host) + assert response.status == status + + +@pytest.mark.parametrize( + "origin, status", + [ + (None, 101), + ("", 400), + ("sometext", 400), + ("http://localhost:1234", 400), + ], +) +def test_origin_header(browser, origin, status): + # Request a default browser. + current_browser = browser(use_bidi=True) + server_host = current_browser.remote_agent_host + server_port = current_browser.remote_agent_port + response = websocket_request(server_host, server_port, origin=origin) + assert response.status == status + + +@pytest.mark.parametrize( + "origin, status", + [ + (None, 101), + ("", 400), + ("sometext", 400), + ("http://localhost:1234", 101), + ("https://localhost:1234", 400), + ], +) +def test_allowed_origins(browser, origin, status): + # Request a browser with custom allowed origins. + current_browser = browser( + use_bidi=True, + extra_args=["--remote-allow-origins", "http://localhost:1234"], + ) + server_port = current_browser.remote_agent_port + + # Both `localhost` and `127.0.0.1` have to accept connections. + for target_host in ["127.0.0.1", "localhost"]: + print(f"Connecting to the WebSocket via host {target_host}") + response = websocket_request(target_host, server_port, origin=origin) + assert response.status == status |