summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/mozilla/tests/webdriver/bidi
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
commit43a97878ce14b72f0981164f87f2e35e14151312 (patch)
tree620249daf56c0258faa40cbdcf9cfba06de2a846 /testing/web-platform/mozilla/tests/webdriver/bidi
parentInitial commit. (diff)
downloadfirefox-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')
-rw-r--r--testing/web-platform/mozilla/tests/webdriver/bidi/__init__.py0
-rw-r--r--testing/web-platform/mozilla/tests/webdriver/bidi/browsing_context/__init__.py0
-rw-r--r--testing/web-platform/mozilla/tests/webdriver/bidi/browsing_context/create/__init__.py20
-rw-r--r--testing/web-platform/mozilla/tests/webdriver/bidi/browsing_context/create/reference_context.py72
-rw-r--r--testing/web-platform/mozilla/tests/webdriver/bidi/browsing_context/create/type_hint.py31
-rw-r--r--testing/web-platform/mozilla/tests/webdriver/bidi/browsing_context/navigate/__init__.py0
-rw-r--r--testing/web-platform/mozilla/tests/webdriver/bidi/browsing_context/navigate/error.py48
-rw-r--r--testing/web-platform/mozilla/tests/webdriver/bidi/errors/__init__.py0
-rw-r--r--testing/web-platform/mozilla/tests/webdriver/bidi/errors/errors.py8
-rw-r--r--testing/web-platform/mozilla/tests/webdriver/bidi/interface/__init__.py0
-rw-r--r--testing/web-platform/mozilla/tests/webdriver/bidi/interface/interface.py26
-rw-r--r--testing/web-platform/mozilla/tests/webdriver/bidi/script/exception_details.py69
-rw-r--r--testing/web-platform/mozilla/tests/webdriver/bidi/websocket_upgrade.py156
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