Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add web platform tests for WebExtensions API in WebDriver Classic #49786

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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!");
Copy link

@xeenon xeenon Dec 19, 2024

Choose a reason for hiding this comment

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

This is minor, but it might be better to use the browser.test.log method — as we plan to use the rest of the test namespace in these test extensions.

Suggested change
console.log("Hello, world!");
browser.test.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