Skip to content

Commit

Permalink
Add web platform tests for WebExtensions API in WebDriver Classic
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Elijah Sawyers committed Dec 19, 2024
1 parent c67ae73 commit 6a613b1
Show file tree
Hide file tree
Showing 8 changed files with 195 additions and 1 deletion.
1 change: 1 addition & 0 deletions lint.ignore
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Empty file.
143 changes: 143 additions & 0 deletions webdriver/tests/classic/web_extensions/load.py
Original file line number Diff line number Diff line change
@@ -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"]
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log("Hello, world!");
Original file line number Diff line number Diff line change
@@ -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" ]
}
}
Binary file not shown.
38 changes: 38 additions & 0 deletions webdriver/tests/classic/web_extensions/unload.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import os
import pytest

from tests.support.asserts import assert_error, assert_success
from urllib.parse import quote

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 unload_extension(session, extension_id):
return session.transport.send("DELETE", "session/%s/webextension/%s" % (session.session_id, extension_id))


def test_no_top_browsing_context(session, closed_window):
response = unload_extension(session, "extension_id")
assert_error(response, "no such window")


def test_unload_extension_invalid_extension_id(session):
response = unload_extension(session, "extension_id")
assert_error(response, "no such extension")


def test_unload_extension(session):
extension = {
"type": "path",
"value": os.path.join(os.path.dirname(__file__), "resources/extension/")
}

response = load_extension(session, extension)
assert_success(response)

extension_id = quote(response.body["value"]["extensionId"])
response = unload_extension(session, extension_id)
assert_success(response)
4 changes: 3 additions & 1 deletion webdriver/tests/support/asserts.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,17 @@
"no such alert": 404,
"no such cookie": 404,
"no such element": 404,
"no such extension": 404,
"no such frame": 404,
"no such shadow root": 404,
"no such window": 404,
"script timeout": 500,
"session not created": 500,
"stale element reference": 404,
"timeout": 500,
"unable to set cookie": 500,
"unable to capture screen": 500,
"unable to load extension": 500,
"unable to set cookie": 500,
"unexpected alert open": 500,
"unknown command": 404,
"unknown error": 500,
Expand Down

1 comment on commit 6a613b1

@community-tc-integration
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uh oh! Looks like an error!

HttpError: Invalid request.

Only 65535 characters are allowed; 6253907 were supplied.

Please sign in to comment.