From 6a613b1e86d1e3152ad943fb2c0e2d49784c4ae9 Mon Sep 17 00:00:00 2001 From: Elijah Sawyers Date: Wed, 18 Dec 2024 17:00:59 -0800 Subject: [PATCH] Add web platform tests for WebExtensions API in WebDriver Classic This patch adds web platform tests for the new WebExtensions API to be introduced in WebDriver classic. These tests cover both loading and unloading web extensions, including success and error cases. WebKit Bugzilla Bug: https://bugs.webkit.org/show_bug.cgi?id=284922 --- lint.ignore | 1 + .../tests/classic/web_extensions/__init__.py | 0 .../tests/classic/web_extensions/load.py | 143 ++++++++++++++++++ .../resources/extension/background.js | 1 + .../resources/extension/manifest.json | 9 ++ .../resources/invalid_extension.zip | Bin 0 -> 1183 bytes .../tests/classic/web_extensions/unload.py | 38 +++++ webdriver/tests/support/asserts.py | 4 +- 8 files changed, 195 insertions(+), 1 deletion(-) create mode 100644 webdriver/tests/classic/web_extensions/__init__.py create mode 100644 webdriver/tests/classic/web_extensions/load.py create mode 100644 webdriver/tests/classic/web_extensions/resources/extension/background.js create mode 100644 webdriver/tests/classic/web_extensions/resources/extension/manifest.json create mode 100644 webdriver/tests/classic/web_extensions/resources/invalid_extension.zip create mode 100644 webdriver/tests/classic/web_extensions/unload.py diff --git a/lint.ignore b/lint.ignore index 4bf325500491b2..4de021ed7476bc 100644 --- a/lint.ignore +++ b/lint.ignore @@ -120,6 +120,7 @@ CONSOLE: service-workers/service-worker/navigation-redirect.https.html CONSOLE: service-workers/service-worker/resources/clients-get-other-origin.html CONSOLE: webrtc/tools/* CONSOLE: webaudio/resources/audit.js:41 +CONSOLE: webdriver/tests/classic/web_extensions/resources/extension/background.js # Intentional use of console.* CONSOLE: infrastructure/webdriver/bidi/subscription.html diff --git a/webdriver/tests/classic/web_extensions/__init__.py b/webdriver/tests/classic/web_extensions/__init__.py new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/webdriver/tests/classic/web_extensions/load.py b/webdriver/tests/classic/web_extensions/load.py new file mode 100644 index 00000000000000..acff6879a5906b --- /dev/null +++ b/webdriver/tests/classic/web_extensions/load.py @@ -0,0 +1,143 @@ +import os +import pytest + +from base64 import b64encode +from shutil import copyfileobj +from tempfile import mkdtemp +from tests.support.asserts import assert_error, assert_success +from zipfile import ZipFile + +def load_extension(session, parameters): + return session.transport.send( + "POST", "session/%s/webextension" % session.session_id, + {"type": parameters.get("type"), "value": parameters.get("value")}) + + +def copy_dir_into_zip(source, dest): + with ZipFile(dest, "w") as zf: + for root, _, files in os.walk(source): + for f in files: + path = os.path.join(root, f) + with open(path, "rb") as fd: + with zf.open(os.path.relpath(path, source), "w") as fd2: + copyfileobj(fd, fd2) + + +@pytest.fixture(params=[ + ("path", os.path.join(os.path.dirname(__file__), "resources/extension/")), + ("archivePath", os.path.join(os.path.dirname(__file__), "resources/extension/")), + ("base64", os.path.join(os.path.dirname(__file__), "resources/extension/")) +]) +def extension(request): + if request.param[0] == "path": + return { + "type": request.param[0], + "value": request.param[1], + } + + elif request.param[0] == "archivePath": + zip_path = os.path.join(mkdtemp(), "extension.zip") + copy_dir_into_zip(request.param[1], zip_path) + return { + "type": request.param[0], + "value": zip_path, + } + + elif request.param[0] == "base64": + zip_path = os.path.join(mkdtemp(), "extension.zip") + copy_dir_into_zip(request.param[1], zip_path) + with open(zip_path, "rb") as f: + encoded = b64encode(f.read()).decode("utf-8") + + return { + "type": request.param[0], + "value": encoded, + } + + else: + raise NotImplementedError( + "Unexpected param, unable to return requested extension" + ) + + +def test_no_top_browsing_context(session, closed_window): + extension = { + "type": "path", + "value": "/" + } + + response = load_extension(session, extension) + assert_error(response, "no such window") + + +def test_null_type_parameter(session): + extension = { + "value": "/" + } + + response = load_extension(session, extension) + assert_error(response, "invalid argument") + + +def test_invalid_type_parameter(session): + extension = { + "type": "invalid", + "value": "/" + } + + response = load_extension(session, extension) + assert_error(response, "invalid argument") + + +def test_null_value_parameter(session): + extension = { + "type": "path" + } + + response = load_extension(session, extension) + assert_error(response, "invalid argument") + + +def test_invalid_zip(session): + extension = { + "type": "archivePath", + "value": os.path.join(os.path.dirname(__file__), "resources/invalid_extension.zip") + } + + response = load_extension(session, extension) + assert_error(response, "unable to load extension") + + +def test_invalid_base64(session): + extension = { + "type": "base64", + "value": "invalid base64" + } + + response = load_extension(session, extension) + assert_error(response, "unable to load extension") + + +@pytest.mark.parametrize("hint,value", [ + ("path", "/invalid/path/"), + ("archivePath", "/invalid/path/extension.zip") +]) +def test_invalid_path(session, hint, value): + extension = { + "type": hint, + "value": value + } + + response = load_extension(session, extension) + assert_error(response, "unable to load extension") + + +def test_load_extension(session, extension): + response = load_extension(session, extension) + assert_success(response) + + assert "value" in response.body + assert isinstance(response.body["value"], dict) + assert "extensionId" in response.body["value"] + assert isinstance(response.body["value"]["extensionId"], str) + assert response.body["value"]["extensionId"] diff --git a/webdriver/tests/classic/web_extensions/resources/extension/background.js b/webdriver/tests/classic/web_extensions/resources/extension/background.js new file mode 100644 index 00000000000000..a8141d3b18d342 --- /dev/null +++ b/webdriver/tests/classic/web_extensions/resources/extension/background.js @@ -0,0 +1 @@ +console.log("Hello, world!"); diff --git a/webdriver/tests/classic/web_extensions/resources/extension/manifest.json b/webdriver/tests/classic/web_extensions/resources/extension/manifest.json new file mode 100644 index 00000000000000..3d277a52a81289 --- /dev/null +++ b/webdriver/tests/classic/web_extensions/resources/extension/manifest.json @@ -0,0 +1,9 @@ +{ + "manifest_version": 3, + "name": "WPT Test Extension", + "description": "This extension is to be used in web platform tests.", + "version": "1.0", + "background": { + "scripts": [ "background.js" ] + } +} diff --git a/webdriver/tests/classic/web_extensions/resources/invalid_extension.zip b/webdriver/tests/classic/web_extensions/resources/invalid_extension.zip new file mode 100644 index 0000000000000000000000000000000000000000..01402216a0c87ef87b5c60fb3b46ef835f2f7287 GIT binary patch literal 1183 zcmWIWW@Zs#00GVVNs(X%ln`Q2V93lXOU%hkiBGL4NzE(H%+J#=t>9*0WckX-zyQ`3 z8p6xK9+#M$o(RMsIsj}Q2LlI&c``ur;^TcCo&AF&^!4H~jK*g&$n@j{(d6`mq=XN? zK4BmD!#V;Qm?lUts|!do7U~K#|9CCg!PKXy=op~pahyj%%su!}hk&^6x${@Obu>T&_gAE3o%#6)_{frE@Z{a)V>2q#d8UsUsH#>)TPoirQFa*{E zF~ToCm8fAOjWulaT!Q0+OY)0Sv3VsSEIByUv!>-{TAtmcus&WP@D z6tHa+|FB%C>5u_dE@XV<;-dS{N0tyg|KFAv ztAKsa)5Rw%AtwZkWB^PWM1>>%B(YH%m?T6U&M*W&R5;MUY|+-j;y6>(Aoc|$mbp6) zSeODGS^