diff options
Diffstat (limited to 'python')
-rw-r--r-- | python/requirements.txt | 3 | ||||
-rw-r--r-- | python/servo/devtools_tests.py | 116 | ||||
-rw-r--r-- | python/servo/devtools_tests/sources/classic.js | 1 | ||||
-rw-r--r-- | python/servo/devtools_tests/sources/module.js | 2 | ||||
-rw-r--r-- | python/servo/devtools_tests/sources/test.html | 11 | ||||
-rw-r--r-- | python/servo/devtools_tests/sources/worker.js | 1 | ||||
-rw-r--r-- | python/servo/testing_commands.py | 7 |
7 files changed, 141 insertions, 0 deletions
diff --git a/python/requirements.txt b/python/requirements.txt index 20d42065dde..d026ce3ee5f 100644 --- a/python/requirements.txt +++ b/python/requirements.txt @@ -37,3 +37,6 @@ types-requests # For mach package on macOS. Mako == 1.2.2 + +# For devtools tests. +geckordp == 1.0.3 diff --git a/python/servo/devtools_tests.py b/python/servo/devtools_tests.py new file mode 100644 index 00000000000..2a305e656a4 --- /dev/null +++ b/python/servo/devtools_tests.py @@ -0,0 +1,116 @@ +# Copyright 2013 The Servo Project Developers. See the COPYRIGHT +# file at the top-level directory of this distribution. +# +# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +# option. This file may not be copied, modified, or distributed +# except according to those terms. + +from concurrent.futures import Future +from geckordp.actors.root import RootActor +from geckordp.actors.descriptors.tab import TabActor +from geckordp.actors.watcher import WatcherActor +from geckordp.actors.resources import Resources +from geckordp.actors.events import Events +from geckordp.rdp_client import RDPClient +import http.server +import os.path +import socketserver +import subprocess +import sys +import time +from threading import Thread + + +def run_tests(script_path): + run_test(sources_test, os.path.join(script_path, "devtools_tests/sources")) + + +def run_test(test_fun, test_dir): + print(f">>> {test_dir}", file=sys.stderr) + server = None + base_url = Future() + + class Handler(http.server.SimpleHTTPRequestHandler): + def __init__(self, *args, **kwargs): + super().__init__(*args, directory=test_dir, **kwargs) + + def log_message(self, format, *args): + # Uncomment this to log requests. + # return super().log_message(format, *args) + pass + + def server_thread(): + nonlocal server + server = socketserver.TCPServer(("0.0.0.0", 0), Handler) + base_url.set_result(f"http://127.0.0.1:{server.server_address[1]}") + server.serve_forever() + + # Start a web server for the test. + thread = Thread(target=server_thread) + thread.start() + base_url = base_url.result(1) + + # Change this setting if you want to debug Servo. + os.environ["RUST_LOG"] = "error,devtools=warn" + + # Run servoshell. + servoshell = subprocess.Popen(["target/release/servo", "--devtools=6080", f"{base_url}/test.html"]) + + # FIXME: Don’t do this + time.sleep(1) + + try: + client = RDPClient() + client.connect("127.0.0.1", 6080) + test_fun(client, base_url) + except Exception as e: + raise e + finally: + # Terminate servoshell. + servoshell.terminate() + + # Stop the web server. + server.shutdown() + thread.join() + + +def sources_test(client, base_url): + root = RootActor(client) + tabs = root.list_tabs() + tab_dict = tabs[0] + tab = TabActor(client, tab_dict["actor"]) + watcher = tab.get_watcher() + watcher = WatcherActor(client, watcher["actor"]) + + target = Future() + + def on_target(data): + if data["target"]["browsingContextID"] == tab_dict["browsingContextID"]: + target.set_result(data["target"]) + + client.add_event_listener( + watcher.actor_id, Events.Watcher.TARGET_AVAILABLE_FORM, on_target, + ) + watcher.watch_targets(WatcherActor.Targets.FRAME) + + done = Future() + target = target.result(1) + + def on_source_resource(data): + for [resource_type, sources] in data["array"]: + # FIXME: If these assertions fail, we just see TimeoutError with no further information + assert resource_type == "source" + assert [source["url"] for source in sources] == [f"{base_url}/classic.js", f"{base_url}/test.html", "https://servo.org/js/load-table.js"] + done.set_result(True) + + client.add_event_listener( + target["actor"], + Events.Watcher.RESOURCES_AVAILABLE_ARRAY, + on_source_resource, + ) + watcher.watch_resources([Resources.SOURCE]) + + assert done.result(1) + client.disconnect() diff --git a/python/servo/devtools_tests/sources/classic.js b/python/servo/devtools_tests/sources/classic.js new file mode 100644 index 00000000000..84fd1671805 --- /dev/null +++ b/python/servo/devtools_tests/sources/classic.js @@ -0,0 +1 @@ +console.log("external classic"); diff --git a/python/servo/devtools_tests/sources/module.js b/python/servo/devtools_tests/sources/module.js new file mode 100644 index 00000000000..a1d0f1f37cf --- /dev/null +++ b/python/servo/devtools_tests/sources/module.js @@ -0,0 +1,2 @@ +export default 1; +console.log("external module"); diff --git a/python/servo/devtools_tests/sources/test.html b/python/servo/devtools_tests/sources/test.html new file mode 100644 index 00000000000..b8e1aa0e334 --- /dev/null +++ b/python/servo/devtools_tests/sources/test.html @@ -0,0 +1,11 @@ +<!doctype html><meta charset=utf-8> +<script src="classic.js"></script> +<script> + console.log("inline classic"); + new Worker("worker.js"); +</script> +<script type="module"> + import module from "./module.js"; + console.log("inline module"); +</script> +<script src="https://servo.org/js/load-table.js"></script> diff --git a/python/servo/devtools_tests/sources/worker.js b/python/servo/devtools_tests/sources/worker.js new file mode 100644 index 00000000000..a7993a8b5fb --- /dev/null +++ b/python/servo/devtools_tests/sources/worker.js @@ -0,0 +1 @@ +console.log("external classic worker"); diff --git a/python/servo/testing_commands.py b/python/servo/testing_commands.py index 8cc33e665b7..e9f66054e56 100644 --- a/python/servo/testing_commands.py +++ b/python/servo/testing_commands.py @@ -19,6 +19,7 @@ import subprocess import textwrap import json +import servo.devtools_tests from servo.post_build_commands import PostBuildCommands import wpt import wpt.manifestupdate @@ -326,6 +327,12 @@ class MachCommands(CommandBase): return 0 if passed else 1 + @Command('test-devtools', + description='Run tests for devtools.', + category='testing') + def test_devtools(self): + servo.devtools_tests.run_tests(SCRIPT_PATH) + @Command('test-wpt-failure', description='Run the tests harness that verifies that the test failures are reported correctly', category='testing', |