aboutsummaryrefslogtreecommitdiffstats
path: root/python
diff options
context:
space:
mode:
Diffstat (limited to 'python')
-rw-r--r--python/requirements.txt3
-rw-r--r--python/servo/devtools_tests.py116
-rw-r--r--python/servo/devtools_tests/sources/classic.js1
-rw-r--r--python/servo/devtools_tests/sources/module.js2
-rw-r--r--python/servo/devtools_tests/sources/test.html11
-rw-r--r--python/servo/devtools_tests/sources/worker.js1
-rw-r--r--python/servo/testing_commands.py7
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',