summaryrefslogtreecommitdiffstats
path: root/dom/worklet/tests
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
commit6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch)
treea68f146d7fa01f0134297619fbe7e33db084e0aa /dom/worklet/tests
parentInitial commit. (diff)
downloadthunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.tar.xz
thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.zip
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--dom/worklet/tests/common.js23
-rw-r--r--dom/worklet/tests/dynamic_import.js7
-rw-r--r--dom/worklet/tests/invalid_specifier.mjs3
-rw-r--r--dom/worklet/tests/mochitest.ini40
-rw-r--r--dom/worklet/tests/server_import_with_cache.sjs12
-rw-r--r--dom/worklet/tests/specifier_with_user.mjs3
-rw-r--r--dom/worklet/tests/test_audioWorklet.html53
-rw-r--r--dom/worklet/tests/test_audioWorkletGlobalScopeRegisterProcessor.html78
-rw-r--r--dom/worklet/tests/test_audioWorklet_WASM.html85
-rw-r--r--dom/worklet/tests/test_audioWorklet_insecureContext.html29
-rw-r--r--dom/worklet/tests/test_audioWorklet_options.html81
-rw-r--r--dom/worklet/tests/test_basic.html66
-rw-r--r--dom/worklet/tests/test_console.html54
-rw-r--r--dom/worklet/tests/test_dump.html30
-rw-r--r--dom/worklet/tests/test_dynamic_import.html54
-rw-r--r--dom/worklet/tests/test_exception.html73
-rw-r--r--dom/worklet/tests/test_fetch_failed.html39
-rw-r--r--dom/worklet/tests/test_import_with_cache.html49
-rw-r--r--dom/worklet/tests/test_paintWorklet.html49
-rw-r--r--dom/worklet/tests/test_promise.html57
-rw-r--r--dom/worklet/tests/worklet_audioWorklet.js16
-rw-r--r--dom/worklet/tests/worklet_audioWorklet_WASM.js16
-rw-r--r--dom/worklet/tests/worklet_audioWorklet_options.js12
-rw-r--r--dom/worklet/tests/worklet_console.js1
-rw-r--r--dom/worklet/tests/worklet_dump.js1
-rw-r--r--dom/worklet/tests/worklet_exception.js1
-rw-r--r--dom/worklet/tests/worklet_paintWorklet.js5
-rw-r--r--dom/worklet/tests/worklet_promise.js22
-rw-r--r--dom/worklet/tests/worklet_test_audioWorkletGlobalScopeRegisterProcessor.js384
29 files changed, 1343 insertions, 0 deletions
diff --git a/dom/worklet/tests/common.js b/dom/worklet/tests/common.js
new file mode 100644
index 0000000000..df6005cfe4
--- /dev/null
+++ b/dom/worklet/tests/common.js
@@ -0,0 +1,23 @@
+window.onload = function () {
+ // We are the parent. Let's load the test.
+ if (parent == this || !location.search.includes("worklet_iframe")) {
+ SimpleTest.waitForExplicitFinish();
+
+ configureTest().then(() => {
+ var iframe = document.createElement("iframe");
+ iframe.src = location.href + "?worklet_iframe";
+ document.body.appendChild(iframe);
+ });
+
+ return;
+ }
+
+ // Here we are in the iframe.
+ window.SimpleTest = parent.SimpleTest;
+ window.is = parent.is;
+ window.isnot = parent.isnot;
+ window.ok = parent.ok;
+ window.info = parent.info;
+
+ runTestInIframe();
+};
diff --git a/dom/worklet/tests/dynamic_import.js b/dom/worklet/tests/dynamic_import.js
new file mode 100644
index 0000000000..a5196d212f
--- /dev/null
+++ b/dom/worklet/tests/dynamic_import.js
@@ -0,0 +1,7 @@
+import("./empty-worklet-script.js")
+ .then(() => {
+ console.log("Fail");
+ })
+ .catch(e => {
+ console.log(e.name + ": Success");
+ });
diff --git a/dom/worklet/tests/invalid_specifier.mjs b/dom/worklet/tests/invalid_specifier.mjs
new file mode 100644
index 0000000000..128b60ffa6
--- /dev/null
+++ b/dom/worklet/tests/invalid_specifier.mjs
@@ -0,0 +1,3 @@
+/* eslint-disable import/no-unassigned-import */
+/* eslint-disable import/no-unresolved */
+import "foo";
diff --git a/dom/worklet/tests/mochitest.ini b/dom/worklet/tests/mochitest.ini
new file mode 100644
index 0000000000..ebc85359cb
--- /dev/null
+++ b/dom/worklet/tests/mochitest.ini
@@ -0,0 +1,40 @@
+[DEFAULT]
+scheme = https
+support-files =
+ common.js
+
+[test_audioWorklet.html]
+support-files=worklet_audioWorklet.js
+[test_audioWorkletGlobalScopeRegisterProcessor.html]
+support-files=worklet_test_audioWorkletGlobalScopeRegisterProcessor.js
+[test_audioWorklet_WASM.html]
+skip-if = release_or_beta # requires dom.postMessage.sharedArrayBuffer.bypassCOOP_COEP.insecure.enabled
+support-files=worklet_audioWorklet_WASM.js
+[test_audioWorklet_insecureContext.html]
+scheme = http
+skip-if =
+ http3
+[test_audioWorklet_options.html]
+skip-if = release_or_beta # requires dom.postMessage.sharedArrayBuffer.bypassCOOP_COEP.insecure.enabled
+support-files=worklet_audioWorklet_options.js
+[test_basic.html]
+[test_console.html]
+support-files=worklet_console.js
+[test_dump.html]
+support-files=worklet_dump.js
+[test_dynamic_import.html]
+support-files=dynamic_import.js
+[test_exception.html]
+support-files =
+ worklet_exception.js
+ invalid_specifier.mjs
+[test_fetch_failed.html]
+support-files=specifier_with_user.mjs
+[test_import_with_cache.html]
+skip-if = verify
+support-files=server_import_with_cache.sjs
+[test_paintWorklet.html]
+skip-if = release_or_beta
+support-files=worklet_paintWorklet.js
+[test_promise.html]
+support-files=worklet_promise.js
diff --git a/dom/worklet/tests/server_import_with_cache.sjs b/dom/worklet/tests/server_import_with_cache.sjs
new file mode 100644
index 0000000000..ed34a7a72f
--- /dev/null
+++ b/dom/worklet/tests/server_import_with_cache.sjs
@@ -0,0 +1,12 @@
+function handleRequest(request, response) {
+ response.setHeader("Content-Type", "text/javascript", false);
+
+ var state = getState("alreadySent");
+ if (!state) {
+ setState("alreadySent", "1");
+ } else {
+ response.setStatusLine("1.1", 404, "Not Found");
+ }
+
+ response.write("42");
+}
diff --git a/dom/worklet/tests/specifier_with_user.mjs b/dom/worklet/tests/specifier_with_user.mjs
new file mode 100644
index 0000000000..3d9bdb45cf
--- /dev/null
+++ b/dom/worklet/tests/specifier_with_user.mjs
@@ -0,0 +1,3 @@
+/* eslint-disable import/no-unassigned-import */
+/* eslint-disable import/no-unresolved */
+import "http://user@example1.com/a.js";
diff --git a/dom/worklet/tests/test_audioWorklet.html b/dom/worklet/tests/test_audioWorklet.html
new file mode 100644
index 0000000000..f7f3665e2f
--- /dev/null
+++ b/dom/worklet/tests/test_audioWorklet.html
@@ -0,0 +1,53 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test for AudioWorklet</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="common.js"></script>
+</head>
+<body>
+
+<script type="application/javascript">
+
+function configureTest() {
+ const ConsoleAPIStorage = SpecialPowers.Cc[
+ "@mozilla.org/consoleAPI-storage;1"
+ ].getService(SpecialPowers.Ci.nsIConsoleAPIStorage);
+
+ function consoleListener() {
+ this.observe = this.observe.bind(this);
+ ConsoleAPIStorage.addLogEventListener(this.observe, SpecialPowers.wrap(document).nodePrincipal);
+ }
+
+ consoleListener.prototype = {
+ observe(aSubject) {
+ var obj = aSubject.wrappedJSObject;
+ if (obj.arguments[0] == "So far so good") {
+ ok(true, "Message received \\o/");
+
+ ConsoleAPIStorage.removeLogEventListener(this.observe);
+ SimpleTest.finish();
+ return;
+ }
+ }
+ }
+
+ var cl = new consoleListener();
+
+ return SpecialPowers.pushPrefEnv(
+ {"set": [["dom.audioworklet.enabled", true],
+ ["dom.worklet.enabled", true]]});
+}
+
+// This function is called into an iframe.
+function runTestInIframe() {
+ ok(window.isSecureContext, "Test should run in secure context");
+ var audioContext = new AudioContext();
+ ok(audioContext.audioWorklet instanceof AudioWorklet,
+ "AudioContext.audioWorklet should be an instance of AudioWorklet");
+ audioContext.audioWorklet.addModule("worklet_audioWorklet.js")
+}
+</script>
+</body>
+</html>
diff --git a/dom/worklet/tests/test_audioWorkletGlobalScopeRegisterProcessor.html b/dom/worklet/tests/test_audioWorkletGlobalScopeRegisterProcessor.html
new file mode 100644
index 0000000000..c26df05ad0
--- /dev/null
+++ b/dom/worklet/tests/test_audioWorkletGlobalScopeRegisterProcessor.html
@@ -0,0 +1,78 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test for AudioWorklet</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="common.js"></script>
+</head>
+<body>
+
+<script type="application/javascript">
+
+function configureTest() {
+
+ var expected_errors = [
+ "TypeError: AudioWorkletGlobalScope.registerProcessor: Argument 2 is not a constructor.",
+ "NotSupportedError: AudioWorkletGlobalScope.registerProcessor: Argument 1 should not be an empty string.",
+ "TypeError: AudioWorkletGlobalScope.registerProcessor: Argument 2 is not an object.",
+ "TypeError: AudioWorkletGlobalScope.registerProcessor: Element 0 in parameterDescriptors can't be converted to a dictionary.",
+ "NotSupportedError: AudioWorkletGlobalScope.registerProcessor: Argument 1 is invalid: a class with the same name is already registered.",
+ "TypeError: AudioWorkletGlobalScope.registerProcessor: Missing required 'name' member of AudioParamDescriptor.",
+ "TypeError: AudioWorkletGlobalScope.registerProcessor: 'defaultValue' member of AudioParamDescriptor is not a finite floating-point value.",
+ "TypeError: AudioWorkletGlobalScope.registerProcessor: 'minValue' member of AudioParamDescriptor is not a finite floating-point value.",
+ "TypeError: AudioWorkletGlobalScope.registerProcessor: 'maxValue' member of AudioParamDescriptor is not a finite floating-point value.",
+ "NotSupportedError: AudioWorkletGlobalScope.registerProcessor: Duplicated name \"test\" in parameterDescriptors.",
+ "TypeError: AudioWorkletGlobalScope.registerProcessor: Element 0 in parameterDescriptors can't be converted to a dictionary.",
+ "InvalidStateError: AudioWorkletGlobalScope.registerProcessor: In parameterDescriptors, test defaultValue is out of the range defined by minValue and maxValue.",
+ "InvalidStateError: AudioWorkletGlobalScope.registerProcessor: In parameterDescriptors, test defaultValue is out of the range defined by minValue and maxValue.",
+ "InvalidStateError: AudioWorkletGlobalScope.registerProcessor: In parameterDescriptors, test minValue should be smaller than maxValue.",
+ ];
+
+ var expected_errors_i = 0;
+
+ const ConsoleAPIStorage = SpecialPowers.Cc[
+ "@mozilla.org/consoleAPI-storage;1"
+ ].getService(SpecialPowers.Ci.nsIConsoleAPIStorage);
+
+ function consoleListener() {
+ this.observe = this.observe.bind(this);
+ ConsoleAPIStorage.addLogEventListener(this.observe, SpecialPowers.wrap(document).nodePrincipal);
+ }
+
+ consoleListener.prototype = {
+ observe(aSubject) {
+ var obj = aSubject.wrappedJSObject;
+ if (obj.arguments[0] == expected_errors[expected_errors_i]) {
+ ok(true, "Expected error received: " + obj.arguments[0]);
+ expected_errors_i++;
+ }
+
+ if (expected_errors_i == expected_errors.length) {
+ // All errors have been received, this test has been completed
+ // succesfully!
+ ConsoleAPIStorage.removeLogEventListener(this.observe);
+ SimpleTest.finish();
+ return;
+ }
+ }
+ }
+
+ var cl = new consoleListener();
+
+ return SpecialPowers.pushPrefEnv(
+ {"set": [["dom.audioworklet.enabled", true],
+ ["dom.worklet.enabled", true]]});
+}
+
+// This function is called into an iframe.
+function runTestInIframe() {
+ ok(window.isSecureContext, "Test should run in secure context");
+ var audioContext = new AudioContext();
+ ok(audioContext.audioWorklet instanceof AudioWorklet,
+ "AudioContext.audioWorklet should be an instance of AudioWorklet");
+ audioContext.audioWorklet.addModule("worklet_test_audioWorkletGlobalScopeRegisterProcessor.js")
+}
+</script>
+</body>
+</html>
diff --git a/dom/worklet/tests/test_audioWorklet_WASM.html b/dom/worklet/tests/test_audioWorklet_WASM.html
new file mode 100644
index 0000000000..127cc8b924
--- /dev/null
+++ b/dom/worklet/tests/test_audioWorklet_WASM.html
@@ -0,0 +1,85 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test for AudioWorklet + WASM</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="common.js"></script>
+</head>
+<body>
+
+<script type="application/javascript">
+
+function configureTest() {
+ return SpecialPowers.pushPrefEnv(
+ {"set": [["dom.audioworklet.enabled", true],
+ ["dom.worklet.enabled", true],
+ ["dom.postMessage.sharedArrayBuffer.bypassCOOP_COEP.insecure.enabled", true],
+ ["browser.tabs.remote.useCrossOriginOpenerPolicy", true],
+ ["browser.tabs.remote.useCrossOriginEmbedderPolicy", true],
+ ["javascript.options.shared_memory", true],
+ ]});
+}
+
+function create_wasmModule() {
+ return new Promise(resolve => {
+ info("Checking if we can play with WebAssembly...");
+
+ if (!SpecialPowers.Cu.getJSTestingFunctions().wasmIsSupported()) {
+ resolve(null);
+ return;
+ }
+
+ ok(WebAssembly, "WebAssembly object should exist");
+ ok(WebAssembly.compile, "WebAssembly.compile function should exist");
+
+ const wasmTextToBinary = SpecialPowers.unwrap(SpecialPowers.Cu.getJSTestingFunctions().wasmTextToBinary);
+ /*
+ js -e '
+ t = wasmTextToBinary(`
+ (module
+ (func $foo (result i32) (i32.const 42))
+ (export "foo" (func $foo))
+ )
+ `);
+ print(t)
+ '
+ */
+ // eslint-disable-next-line
+ const fooModuleCode = new Uint8Array([0,97,115,109,1,0,0,0,1,5,1,96,0,1,127,3,2,1,0,7,7,1,3,102,111,111,0,0,10,6,1,4,0,65,42,11,0,13,4,110,97,109,101,1,6,1,0,3,102,111,111]);
+
+ WebAssembly.compile(fooModuleCode).then(m => {
+ ok(m instanceof WebAssembly.Module, "The WasmModule has been compiled.");
+ resolve(m);
+ }, () => {
+ ok(false, "The compilation of the wasmModule failed.");
+ resolve(null);
+ });
+ });
+}
+
+function runTestInIframe() {
+ let audioContext = new AudioContext();
+ audioContext.audioWorklet.addModule("worklet_audioWorklet_WASM.js")
+ .then(() => create_wasmModule())
+ .then(wasmModule => {
+ const node = new AudioWorkletNode(audioContext, 'wasm');
+ let msgId = 0;
+ node.port.onmessage = e => {
+ if (msgId++ == 0) {
+ ok(e.data.wasmModule instanceof WebAssembly.Module, "WasmModule received");
+ } else {
+ ok(e.data.sab instanceof SharedArrayBuffer, "SAB received");
+ SimpleTest.finish();
+ }
+ }
+
+ node.port.postMessage({wasmModule});
+ node.port.postMessage({sab: new SharedArrayBuffer(1024)});
+ node.connect(audioContext.destination);
+ });
+}
+</script>
+
+</body>
+</html>
diff --git a/dom/worklet/tests/test_audioWorklet_insecureContext.html b/dom/worklet/tests/test_audioWorklet_insecureContext.html
new file mode 100644
index 0000000000..3cbb419ac3
--- /dev/null
+++ b/dom/worklet/tests/test_audioWorklet_insecureContext.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test for No AudioWorklet in insecure context</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="common.js"></script>
+</head>
+<body>
+
+<script type="application/javascript">
+
+function configureTest() {
+ return SpecialPowers.pushPrefEnv(
+ {"set": [["dom.audioworklet.enabled", true],
+ ["dom.worklet.enabled", true]]});
+}
+
+// This function is called into an iframe.
+function runTestInIframe() {
+ ok(!window.isSecureContext, "Test should run in an insecure context");
+ var audioContext = new AudioContext();
+ ok(!("audioWorklet" in audioContext),
+ "AudioWorklet shouldn't be defined in AudioContext in a insecure context");
+ SimpleTest.finish();
+}
+</script>
+</body>
+</html>
diff --git a/dom/worklet/tests/test_audioWorklet_options.html b/dom/worklet/tests/test_audioWorklet_options.html
new file mode 100644
index 0000000000..df7a8b5649
--- /dev/null
+++ b/dom/worklet/tests/test_audioWorklet_options.html
@@ -0,0 +1,81 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test for AudioWorklet + Options + WASM</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="common.js"></script>
+</head>
+<body>
+<script type="application/javascript">
+
+function configureTest() {
+ return SpecialPowers.pushPrefEnv(
+ {"set": [["dom.audioworklet.enabled", true],
+ ["dom.worklet.enabled", true],
+ ["dom.postMessage.sharedArrayBuffer.bypassCOOP_COEP.insecure.enabled", true],
+ ["browser.tabs.remote.useCrossOriginOpenerPolicy", true],
+ ["browser.tabs.remote.useCrossOriginEmbedderPolicy", true],
+ ["javascript.options.shared_memory", true],
+ ]});
+}
+
+function create_wasmModule() {
+ return new Promise(resolve => {
+ info("Checking if we can play with WebAssembly...");
+
+ if (!SpecialPowers.Cu.getJSTestingFunctions().wasmIsSupported()) {
+ resolve(null);
+ return;
+ }
+
+ ok(WebAssembly, "WebAssembly object should exist");
+ ok(WebAssembly.compile, "WebAssembly.compile function should exist");
+
+ const wasmTextToBinary = SpecialPowers.unwrap(SpecialPowers.Cu.getJSTestingFunctions().wasmTextToBinary);
+
+ /*
+ js -e '
+ t = wasmTextToBinary(`
+ (module
+ (func $foo (result i32) (i32.const 42))
+ (export "foo" (func $foo))
+ )
+ `);
+ print(t)
+ '
+ */
+ // eslint-disable-next-line
+ const fooModuleCode = new Uint8Array([0,97,115,109,1,0,0,0,1,5,1,96,0,1,127,3,2,1,0,7,7,1,3,102,111,111,0,0,10,6,1,4,0,65,42,11,0,13,4,110,97,109,101,1,6,1,0,3,102,111,111]);
+
+ WebAssembly.compile(fooModuleCode).then(m => {
+ ok(m instanceof WebAssembly.Module, "The WasmModule has been compiled.");
+ resolve(m);
+ }, () => {
+ ok(false, "The compilation of the wasmModule failed.");
+ resolve(null);
+ });
+ });
+}
+
+function runTestInIframe() {
+ let audioContext = new AudioContext();
+ audioContext.audioWorklet.addModule("worklet_audioWorklet_options.js")
+ .then(() => create_wasmModule())
+ .then(wasmModule => {
+ const node = new AudioWorkletNode(audioContext, 'options', { processorOptions: {
+ wasmModule, sab: new SharedArrayBuffer(1024),
+ }});
+ node.port.onmessage = e => {
+ ok(e.data.wasmModule instanceof WebAssembly.Module, "WasmModule received");
+ ok(e.data.sab instanceof SharedArrayBuffer, "SAB received");
+ SimpleTest.finish();
+ }
+
+ node.connect(audioContext.destination);
+ });
+}
+
+</script>
+</body>
+</html>
diff --git a/dom/worklet/tests/test_basic.html b/dom/worklet/tests/test_basic.html
new file mode 100644
index 0000000000..b13cadd6d1
--- /dev/null
+++ b/dom/worklet/tests/test_basic.html
@@ -0,0 +1,66 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test for Worklet</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="common.js"></script>
+</head>
+<body>
+
+<script type="application/javascript">
+
+function configureTest() {
+ return SpecialPowers.pushPrefEnv(
+ {"set": [["dom.audioworklet.enabled", true],
+ ["dom.worklet.enabled", true]]});
+}
+
+// This function is called into an iframe.
+function runTestInIframe() {
+ var audioContext = new AudioContext();
+ ok(!!audioContext.audioWorklet, "audioContext.audioWorklet exists");
+
+ // First loading
+ audioContext.audioWorklet.addModule("common.js")
+ .then(() => {
+ ok(true, "Import should load a resource.");
+ })
+
+ // Second loading - same file
+ .then(() => {
+ return audioContext.audioWorklet.addModule("common.js")
+ })
+ .then(() => {
+ ok(true, "Import should load a resource.");
+ })
+
+ // 3rd loading - a network error
+ .then(() => {
+ return audioContext.audioWorklet.addModule("404.js");
+ })
+ .then(() => {
+ ok(false, "The loading should fail.");
+ }, () => {
+ ok(true, "The loading should fail.");
+ })
+
+ // 4th loading - a network error
+ .then(() => {
+ return audioContext.audioWorklet.addModule("404.js");
+ })
+ .then(() => {
+ ok(false, "The loading should fail.");
+ }, () => {
+ ok(true, "The loading should fail.");
+ })
+
+ // done
+ .then(() => {
+ SimpleTest.finish();
+ });
+}
+
+</script>
+</body>
+</html>
diff --git a/dom/worklet/tests/test_console.html b/dom/worklet/tests/test_console.html
new file mode 100644
index 0000000000..c33b93001f
--- /dev/null
+++ b/dom/worklet/tests/test_console.html
@@ -0,0 +1,54 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test for Worklet - Console</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="common.js"></script>
+</head>
+<body>
+
+<script type="application/javascript">
+const WORKLET_SCRIPT = "worklet_console.js";
+
+function configureTest() {
+ const ConsoleAPIStorage = SpecialPowers.Cc[
+ "@mozilla.org/consoleAPI-storage;1"
+ ].getService(SpecialPowers.Ci.nsIConsoleAPIStorage);
+
+ function consoleListener() {
+ this.observe = this.observe.bind(this);
+ ConsoleAPIStorage.addLogEventListener(this.observe, SpecialPowers.wrap(document).nodePrincipal);
+ }
+
+ consoleListener.prototype = {
+ observe(aSubject) {
+ var obj = aSubject.wrappedJSObject;
+ if (obj.arguments[0] == "Hello world from a worklet") {
+ ok(true, "Message received \\o/");
+ is(obj.filename,
+ new URL(WORKLET_SCRIPT, document.baseURI).toString());
+
+ ConsoleAPIStorage.removeLogEventListener(this.observe);
+ SimpleTest.finish();
+ return;
+ }
+ }
+ }
+
+ var cl = new consoleListener();
+
+ return SpecialPowers.pushPrefEnv(
+ {"set": [["dom.audioworklet.enabled", true],
+ ["dom.worklet.enabled", true]]});
+}
+
+// This function is called into an iframe.
+function runTestInIframe() {
+ var audioContext = new AudioContext();
+ audioContext.audioWorklet.addModule(WORKLET_SCRIPT);
+}
+
+</script>
+</body>
+</html>
diff --git a/dom/worklet/tests/test_dump.html b/dom/worklet/tests/test_dump.html
new file mode 100644
index 0000000000..f7885a1e21
--- /dev/null
+++ b/dom/worklet/tests/test_dump.html
@@ -0,0 +1,30 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test for Worklet - Console</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="common.js"></script>
+</head>
+<body>
+
+<script type="application/javascript">
+
+function configureTest() {
+ return SpecialPowers.pushPrefEnv(
+ {"set": [["dom.audioworklet.enabled", true],
+ ["dom.worklet.enabled", true]]});
+}
+
+// This function is called into an iframe.
+function runTestInIframe() {
+ var audioContext = new AudioContext();
+ audioContext.audioWorklet.addModule("worklet_dump.js")
+ .then(() => {
+ ok(true, "All good!");
+ SimpleTest.finish();
+ });
+}
+</script>
+</body>
+</html>
diff --git a/dom/worklet/tests/test_dynamic_import.html b/dom/worklet/tests/test_dynamic_import.html
new file mode 100644
index 0000000000..e0326b976c
--- /dev/null
+++ b/dom/worklet/tests/test_dynamic_import.html
@@ -0,0 +1,54 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test import() should throw a TypeError for Worklets</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="common.js"></script>
+</head>
+<body>
+
+<script type="application/javascript">
+const WORKLET_SCRIPT = "dynamic_import.js";
+
+function configureTest() {
+ const ConsoleAPIStorage = SpecialPowers.Cc[
+ "@mozilla.org/consoleAPI-storage;1"
+ ].getService(SpecialPowers.Ci.nsIConsoleAPIStorage);
+
+ // We use console API to check if a TypeError has been thrown, as worklets
+ // have limitations to post the result back to the main document:
+ // Worklets have a different global, and they don't have postMessage() APIs,
+ // and static import SimpleTest.js in worklets also don't work.
+ function consoleListener() {
+ this.observe = this.observe.bind(this);
+ ConsoleAPIStorage.addLogEventListener(this.observe, SpecialPowers.wrap(document).nodePrincipal);
+ }
+
+ consoleListener.prototype = {
+ observe(aSubject) {
+ var obj = aSubject.wrappedJSObject;
+ info("Got console message:" + obj.arguments[0]);
+ is(TypeError.name + ": Success", obj.arguments[0], "import() should throw");
+
+ ConsoleAPIStorage.removeLogEventListener(this.observe);
+ SimpleTest.finish();
+ }
+ }
+
+ var cl = new consoleListener();
+
+ return SpecialPowers.pushPrefEnv(
+ {"set": [["dom.audioworklet.enabled", true],
+ ["dom.worklet.enabled", true]]});
+}
+
+// This function is called into an iframe.
+function runTestInIframe() {
+ var audioContext = new AudioContext();
+ audioContext.audioWorklet.addModule(WORKLET_SCRIPT);
+}
+
+</script>
+</body>
+</html>
diff --git a/dom/worklet/tests/test_exception.html b/dom/worklet/tests/test_exception.html
new file mode 100644
index 0000000000..598dc859f3
--- /dev/null
+++ b/dom/worklet/tests/test_exception.html
@@ -0,0 +1,73 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test for Exception in Worklet script</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="common.js"></script>
+</head>
+<body>
+
+<script type="application/javascript">
+
+function configureTest() {
+ return SpecialPowers.pushPrefEnv(
+ {"set": [["dom.audioworklet.enabled", true],
+ ["dom.worklet.enabled", true]]});
+}
+
+// This function is called into an iframe.
+function runTestInIframe() {
+ let error;
+
+ // This loading should fail
+ var audioContext = new AudioContext();
+ audioContext.audioWorklet.addModule("404.js")
+ .then(() => {
+ ok(false, "We should not be called!");
+ }, () => {
+ ok(true, "The script thrown but we are still here.");
+ })
+
+ // This should throw from JS
+ .then(() => {
+ return audioContext.audioWorklet.addModule("worklet_exception.js")
+ })
+ .then(() => {
+ ok(true, "The script threw but we are still here.");
+ }, () => {
+ ok(false, "We should not be called!");
+ })
+
+ // invalid_specifier.mjs will throw a TypeError.
+ .then(() => {
+ return audioContext.audioWorklet.addModule("invalid_specifier.mjs")
+ })
+ .then(() => {
+ ok(false, "We should not be called!");
+ }, (e) => {
+ ok(true, "The script thrown but we are still here.");
+ ok(e instanceof TypeError, "The error should be a TypeError.");
+ error = e;
+ })
+
+ // import "invalid_specifier.mjs" again, this will reuse the response from the
+ // previous addModule("invalid_specifier.mjs") call.
+ .then(() => {
+ return audioContext.audioWorklet.addModule("invalid_specifier.mjs")
+ })
+ .then(() => {
+ ok(false, "We should not be called!");
+ }, (e) => {
+ ok(true, "The script thrown but we are still here.");
+ ok (e === error, "The TypeError object should be reused.");
+ })
+
+ .then(() => {
+ SimpleTest.finish();
+ });
+}
+
+</script>
+</body>
+</html>
diff --git a/dom/worklet/tests/test_fetch_failed.html b/dom/worklet/tests/test_fetch_failed.html
new file mode 100644
index 0000000000..b5d316805f
--- /dev/null
+++ b/dom/worklet/tests/test_fetch_failed.html
@@ -0,0 +1,39 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test fetch an child module script with an invalid uri for Worklet</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="common.js"></script>
+</head>
+<body>
+
+<script type="application/javascript">
+
+function configureTest() {
+ return SpecialPowers.pushPrefEnv(
+ {"set": [["dom.audioworklet.enabled", true],
+ ["dom.worklet.enabled", true]]});
+}
+
+// This function is called into an iframe.
+function runTestInIframe() {
+ var audioContext = new AudioContext();
+ ok(!!audioContext.audioWorklet, "audioContext.audioWorklet exists");
+
+ audioContext.audioWorklet.addModule("specifier_with_user.mjs")
+ .then(() => {
+ ok(false, "Error: load shouldn't succeed.");
+ }, () => {
+ ok(true, "OK: load should fail.");
+ })
+
+ // done
+ .then(() => {
+ SimpleTest.finish();
+ });
+}
+
+</script>
+</body>
+</html>
diff --git a/dom/worklet/tests/test_import_with_cache.html b/dom/worklet/tests/test_import_with_cache.html
new file mode 100644
index 0000000000..de1744f9cc
--- /dev/null
+++ b/dom/worklet/tests/test_import_with_cache.html
@@ -0,0 +1,49 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test for Worklet</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="common.js"></script>
+</head>
+<body>
+
+<script type="application/javascript">
+
+function configureTest() {
+ return SpecialPowers.pushPrefEnv(
+ {"set": [["dom.audioworklet.enabled", true],
+ ["dom.worklet.enabled", true]]});
+}
+
+// This function is called into an iframe.
+function runTestInIframe() {
+ var audioContext = new AudioContext();
+ function loading() {
+ audioContext.audioWorklet.addModule("server_import_with_cache.sjs")
+ .then(() => {
+ ok(true, "Import should load a resource.");
+ }, () => {
+ ok(false, "Import should load a resource.");
+ })
+ .then(() => {
+ done();
+ });
+ }
+
+ var count = 0;
+ const MAX = 10;
+
+ function done() {
+ if (++count == MAX) {
+ SimpleTest.finish();
+ }
+ }
+
+ for (var i = 0; i < MAX; ++i) {
+ loading();
+ }
+}
+</script>
+</body>
+</html>
diff --git a/dom/worklet/tests/test_paintWorklet.html b/dom/worklet/tests/test_paintWorklet.html
new file mode 100644
index 0000000000..a02a2757fb
--- /dev/null
+++ b/dom/worklet/tests/test_paintWorklet.html
@@ -0,0 +1,49 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test for PaintWorklet</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="common.js"></script>
+</head>
+<body>
+
+<script type="application/javascript">
+
+function configureTest() {
+ const ConsoleAPIStorage = SpecialPowers.Cc[
+ "@mozilla.org/consoleAPI-storage;1"
+ ].getService(SpecialPowers.Ci.nsIConsoleAPIStorage);
+
+ function consoleListener() {
+ this.observe = this.observe.bind(this);
+ ConsoleAPIStorage.addLogEventListener(this.observe, SpecialPowers.wrap(document).nodePrincipal);
+ }
+
+ consoleListener.prototype = {
+ observe(aSubject) {
+ var obj = aSubject.wrappedJSObject;
+ if (obj.arguments[0] == "So far so good") {
+ ok(true, "Message received \\o/");
+
+ ConsoleAPIStorage.removeLogEventListener(this.observe);
+ SimpleTest.finish();
+ return;
+ }
+ }
+ }
+
+ var cl = new consoleListener();
+
+ return SpecialPowers.pushPrefEnv(
+ {"set": [["dom.paintWorklet.enabled", true],
+ ["dom.worklet.enabled", true]]});
+}
+
+// This function is called into an iframe.
+function runTestInIframe() {
+ paintWorklet.addModule("worklet_paintWorklet.js")
+}
+</script>
+</body>
+</html>
diff --git a/dom/worklet/tests/test_promise.html b/dom/worklet/tests/test_promise.html
new file mode 100644
index 0000000000..8ea71af9a6
--- /dev/null
+++ b/dom/worklet/tests/test_promise.html
@@ -0,0 +1,57 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test for promise in worklet</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="common.js"></script>
+</head>
+<body>
+
+<script type="application/javascript">
+
+function configureTest() {
+ return SpecialPowers.pushPrefEnv(
+ {"set": [["dom.audioworklet.enabled", true],
+ ["dom.worklet.enabled", true]]});
+}
+
+function runTestInIframe() {
+ if (!SpecialPowers.Cu.getJSTestingFunctions().wasmIsSupported()) {
+ SimpleTest.finish();
+ return;
+ }
+
+ ok(window.isSecureContext, "Test should run in secure context");
+ var audioContext = new AudioContext();
+ ok(audioContext.audioWorklet instanceof AudioWorklet,
+ "AudioContext.audioWorklet should be an instance of AudioWorklet");
+ audioContext.audioWorklet.addModule("worklet_promise.js")
+ .then(() => {
+ const node = new AudioWorkletNode(audioContext, 'promise');
+ node.port.onmessage = e => {
+ ok(e.data instanceof WebAssembly.Module, "The WasmModule has been compiled into the worklet.");
+ SimpleTest.finish();
+ }
+
+ const wasmTextToBinary = SpecialPowers.unwrap(SpecialPowers.Cu.getJSTestingFunctions().wasmTextToBinary);
+ /*
+ js -e '
+ t = wasmTextToBinary(`
+ (module
+ (func $foo (result i32) (i32.const 42))
+ (export "foo" (func $foo))
+ )
+ `);
+ print(t)
+ '
+ */
+ // eslint-disable-next-line
+ const fooModuleCode = new Uint8Array([0,97,115,109,1,0,0,0,1,5,1,96,0,1,127,3,2,1,0,7,7,1,3,102,111,111,0,0,10,6,1,4,0,65,42,11,0,13,4,110,97,109,101,1,6,1,0,3,102,111,111]);
+
+ node.port.postMessage(fooModuleCode);
+ });
+}
+</script>
+</body>
+</html>
diff --git a/dom/worklet/tests/worklet_audioWorklet.js b/dom/worklet/tests/worklet_audioWorklet.js
new file mode 100644
index 0000000000..fa916d4359
--- /dev/null
+++ b/dom/worklet/tests/worklet_audioWorklet.js
@@ -0,0 +1,16 @@
+class DummyProcessWorkletProcessor extends AudioWorkletProcessor {
+ constructor() {
+ super();
+ }
+
+ process() {
+ // Do nothing, output silence
+ }
+}
+
+// We need to pass a valid AudioWorkletProcessor here, otherwise, it will fail,
+// and the console.log won't be executed
+registerProcessor("sure!", DummyProcessWorkletProcessor);
+console.log(
+ globalThis instanceof AudioWorkletGlobalScope ? "So far so good" : "error"
+);
diff --git a/dom/worklet/tests/worklet_audioWorklet_WASM.js b/dom/worklet/tests/worklet_audioWorklet_WASM.js
new file mode 100644
index 0000000000..1215b4c8d0
--- /dev/null
+++ b/dom/worklet/tests/worklet_audioWorklet_WASM.js
@@ -0,0 +1,16 @@
+class WasmProcessWorkletProcessor extends AudioWorkletProcessor {
+ constructor(...args) {
+ super(...args);
+ this.port.onmessage = e => {
+ // Let's send it back.
+ this.port.postMessage(e.data);
+ };
+ }
+
+ process(inputs, outputs, parameters) {
+ // Do nothing, output silence
+ return true;
+ }
+}
+
+registerProcessor("wasm", WasmProcessWorkletProcessor);
diff --git a/dom/worklet/tests/worklet_audioWorklet_options.js b/dom/worklet/tests/worklet_audioWorklet_options.js
new file mode 100644
index 0000000000..eb7a704234
--- /dev/null
+++ b/dom/worklet/tests/worklet_audioWorklet_options.js
@@ -0,0 +1,12 @@
+class OptionsProcessWorkletProcessor extends AudioWorkletProcessor {
+ constructor(...args) {
+ super(...args);
+ this.port.postMessage(args[0].processorOptions);
+ }
+
+ process(inputs, outputs, parameters) {
+ return true;
+ }
+}
+
+registerProcessor("options", OptionsProcessWorkletProcessor);
diff --git a/dom/worklet/tests/worklet_console.js b/dom/worklet/tests/worklet_console.js
new file mode 100644
index 0000000000..557beb1af2
--- /dev/null
+++ b/dom/worklet/tests/worklet_console.js
@@ -0,0 +1 @@
+console.log("Hello world from a worklet");
diff --git a/dom/worklet/tests/worklet_dump.js b/dom/worklet/tests/worklet_dump.js
new file mode 100644
index 0000000000..439d13f700
--- /dev/null
+++ b/dom/worklet/tests/worklet_dump.js
@@ -0,0 +1 @@
+dump("Hello world from a worklet");
diff --git a/dom/worklet/tests/worklet_exception.js b/dom/worklet/tests/worklet_exception.js
new file mode 100644
index 0000000000..f3b473756e
--- /dev/null
+++ b/dom/worklet/tests/worklet_exception.js
@@ -0,0 +1 @@
+foobar();
diff --git a/dom/worklet/tests/worklet_paintWorklet.js b/dom/worklet/tests/worklet_paintWorklet.js
new file mode 100644
index 0000000000..7cf5256e51
--- /dev/null
+++ b/dom/worklet/tests/worklet_paintWorklet.js
@@ -0,0 +1,5 @@
+// This should work for real... at some point.
+registerPaint("sure!", () => {});
+console.log(
+ globalThis instanceof PaintWorkletGlobalScope ? "So far so good" : "error"
+);
diff --git a/dom/worklet/tests/worklet_promise.js b/dom/worklet/tests/worklet_promise.js
new file mode 100644
index 0000000000..8c593fd001
--- /dev/null
+++ b/dom/worklet/tests/worklet_promise.js
@@ -0,0 +1,22 @@
+class WasmProcessWorkletProcessor extends AudioWorkletProcessor {
+ constructor(...args) {
+ super(...args);
+ this.port.onmessage = e => {
+ WebAssembly.compile(e.data).then(
+ m => {
+ this.port.postMessage(m);
+ },
+ () => {
+ this.port.postMessage("error");
+ }
+ );
+ };
+ }
+
+ process(inputs, outputs, parameters) {
+ // Do nothing, output silence
+ return true;
+ }
+}
+
+registerProcessor("promise", WasmProcessWorkletProcessor);
diff --git a/dom/worklet/tests/worklet_test_audioWorkletGlobalScopeRegisterProcessor.js b/dom/worklet/tests/worklet_test_audioWorkletGlobalScopeRegisterProcessor.js
new file mode 100644
index 0000000000..cddb9524ec
--- /dev/null
+++ b/dom/worklet/tests/worklet_test_audioWorkletGlobalScopeRegisterProcessor.js
@@ -0,0 +1,384 @@
+// Define several classes.
+class EmptyWorkletProcessor extends AudioWorkletProcessor {}
+
+class NoProcessWorkletProcessor extends AudioWorkletProcessor {
+ constructor() {
+ super();
+ }
+}
+
+class BadDescriptorsWorkletProcessor extends AudioWorkletProcessor {
+ constructor() {
+ super();
+ }
+
+ process() {
+ // Do nothing, output silence
+ }
+
+ static get parameterDescriptors() {
+ return "A string";
+ }
+}
+
+class GoodDescriptorsWorkletProcessor extends AudioWorkletProcessor {
+ constructor() {
+ super();
+ }
+
+ process() {
+ // Do nothing, output silence
+ }
+
+ static get parameterDescriptors() {
+ return [
+ {
+ name: "myParam",
+ defaultValue: 0.707,
+ },
+ ];
+ }
+}
+
+class DummyProcessWorkletProcessor extends AudioWorkletProcessor {
+ constructor() {
+ super();
+ }
+
+ process() {
+ // Do nothing, output silence
+ }
+}
+
+class DescriptorsNoNameWorkletProcessor extends AudioWorkletProcessor {
+ constructor() {
+ super();
+ }
+
+ process() {
+ // Do nothing, output silence
+ }
+
+ static get parameterDescriptors() {
+ return [
+ {
+ defaultValue: 0.707,
+ },
+ ];
+ }
+}
+
+class DescriptorsDefaultValueNotNumberWorkletProcessor extends AudioWorkletProcessor {
+ constructor() {
+ super();
+ }
+
+ process() {
+ // Do nothing, output silence
+ }
+
+ static get parameterDescriptors() {
+ return [
+ {
+ name: "test",
+ defaultValue: "test",
+ },
+ ];
+ }
+}
+
+class DescriptorsMinValueNotNumberWorkletProcessor extends AudioWorkletProcessor {
+ constructor() {
+ super();
+ }
+
+ process() {
+ // Do nothing, output silence
+ }
+
+ static get parameterDescriptors() {
+ return [
+ {
+ name: "test",
+ minValue: "test",
+ },
+ ];
+ }
+}
+
+class DescriptorsMaxValueNotNumberWorkletProcessor extends AudioWorkletProcessor {
+ constructor() {
+ super();
+ }
+
+ process() {
+ // Do nothing, output silence
+ }
+
+ static get parameterDescriptors() {
+ return [
+ {
+ name: "test",
+ maxValue: "test",
+ },
+ ];
+ }
+}
+
+class DescriptorsDuplicatedNameWorkletProcessor extends AudioWorkletProcessor {
+ constructor() {
+ super();
+ }
+
+ process() {
+ // Do nothing, output silence
+ }
+
+ static get parameterDescriptors() {
+ return [
+ {
+ name: "test",
+ },
+ {
+ name: "test",
+ },
+ ];
+ }
+}
+
+class DescriptorsNotDictWorkletProcessor extends AudioWorkletProcessor {
+ constructor() {
+ super();
+ }
+
+ process() {
+ // Do nothing, output silence
+ }
+
+ static get parameterDescriptors() {
+ return [42];
+ }
+}
+
+class DescriptorsOutOfRangeMinWorkletProcessor extends AudioWorkletProcessor {
+ constructor() {
+ super();
+ }
+
+ process() {
+ // Do nothing, output silence
+ }
+
+ static get parameterDescriptors() {
+ return [
+ {
+ name: "test",
+ defaultValue: 0,
+ minValue: 1,
+ maxValue: 2,
+ },
+ ];
+ }
+}
+
+class DescriptorsOutOfRangeMaxWorkletProcessor extends AudioWorkletProcessor {
+ constructor() {
+ super();
+ }
+
+ process() {
+ // Do nothing, output silence
+ }
+
+ static get parameterDescriptors() {
+ return [
+ {
+ name: "test",
+ defaultValue: 3,
+ minValue: 1,
+ maxValue: 2,
+ },
+ ];
+ }
+}
+
+class DescriptorsBadRangeMaxWorkletProcessor extends AudioWorkletProcessor {
+ constructor() {
+ super();
+ }
+
+ process() {
+ // Do nothing, output silence
+ }
+
+ static get parameterDescriptors() {
+ return [
+ {
+ name: "test",
+ defaultValue: 1.5,
+ minValue: 2,
+ maxValue: 1,
+ },
+ ];
+ }
+}
+
+// Test not a constructor
+// "TypeError: Argument 2 of AudioWorkletGlobalScope.registerProcessor is not a constructor."
+try {
+ registerProcessor("sure!", () => {});
+} catch (e) {
+ console.log(e);
+}
+
+// Test empty name
+// "NotSupportedError: Argument 1 of AudioWorkletGlobalScope.registerProcessor should not be an empty string."
+try {
+ registerProcessor("", EmptyWorkletProcessor);
+} catch (e) {
+ console.log(e);
+}
+
+// Test not an object
+// "TypeError: Argument 2 of AudioWorkletGlobalScope.registerProcessor is not an object."
+try {
+ registerProcessor("my-worklet-processor", "");
+} catch (e) {
+ console.log(e);
+}
+
+// Test Empty class definition
+registerProcessor("empty-worklet-processor", EmptyWorkletProcessor);
+
+// Test class with constructor but not process function
+registerProcessor("no-worklet-processor", NoProcessWorkletProcessor);
+
+// Test class with parameterDescriptors being iterable, but the elements are not
+// dictionaries.
+// "TypeError: AudioWorkletGlobalScope.registerProcessor: Element 0 in parameterDescriptors can't be converted to a dictionary.",
+try {
+ registerProcessor(
+ "bad-descriptors-worklet-processor",
+ BadDescriptorsWorkletProcessor
+ );
+} catch (e) {
+ console.log(e);
+}
+
+// Test class with good parameterDescriptors
+// No error expected here
+registerProcessor(
+ "good-descriptors-worklet-processor",
+ GoodDescriptorsWorkletProcessor
+);
+
+// Test class with constructor and process function
+// No error expected here
+registerProcessor("dummy-worklet-processor", DummyProcessWorkletProcessor);
+
+// Test class adding class with the same name twice
+// "NotSupportedError: Operation is not supported: Argument 1 of AudioWorkletGlobalScope.registerProcessor is invalid: a class with the same name is already registered."
+try {
+ registerProcessor("dummy-worklet-processor", DummyProcessWorkletProcessor);
+} catch (e) {
+ console.log(e);
+}
+
+// "name" is a mandatory field in descriptors
+// "TypeError: Missing required 'name' member of AudioParamDescriptor."
+try {
+ registerProcessor(
+ "descriptors-no-name-worklet-processor",
+ DescriptorsNoNameWorkletProcessor
+ );
+} catch (e) {
+ console.log(e);
+}
+
+// "defaultValue" should be a number
+// "TypeError: 'defaultValue' member of AudioParamDescriptor is not a finite floating-point value."
+try {
+ registerProcessor(
+ "descriptors-default-value-not-number-worklet-processor",
+ DescriptorsDefaultValueNotNumberWorkletProcessor
+ );
+} catch (e) {
+ console.log(e);
+}
+
+// "min" should be a number
+// "TypeError: 'minValue' member of AudioParamDescriptor is not a finite floating-point value."
+try {
+ registerProcessor(
+ "descriptors-min-value-not-number-worklet-processor",
+ DescriptorsMinValueNotNumberWorkletProcessor
+ );
+} catch (e) {
+ console.log(e);
+}
+
+// "max" should be a number
+// "TypeError: 'maxValue' member of AudioParamDescriptor is not a finite floating-point value."
+try {
+ registerProcessor(
+ "descriptors-max-value-not-number-worklet-processor",
+ DescriptorsMaxValueNotNumberWorkletProcessor
+ );
+} catch (e) {
+ console.log(e);
+}
+
+// Duplicated values are not allowed for "name"
+// "NotSupportedError: Duplicated name \"test\" in parameterDescriptors"
+try {
+ registerProcessor(
+ "descriptors-duplicated-name-worklet-processor",
+ DescriptorsDuplicatedNameWorkletProcessor
+ );
+} catch (e) {
+ console.log(e);
+}
+
+// Descriptors' elements should be dictionnary
+// "TypeError: Element 0 in parameterDescriptors can't be converted to a dictionary.",
+try {
+ registerProcessor(
+ "descriptors-not-dict-worklet-processor",
+ DescriptorsNotDictWorkletProcessor
+ );
+} catch (e) {
+ console.log(e);
+}
+
+// defaultValue value should be in range [minValue, maxValue]. defaultValue < minValue is not allowed
+// "NotSupportedError: In parameterDescriptors, test defaultValue is out of the range defined by minValue and maxValue.",
+try {
+ registerProcessor(
+ "descriptors-out-of-range-min-worklet-processor",
+ DescriptorsOutOfRangeMinWorkletProcessor
+ );
+} catch (e) {
+ console.log(e);
+}
+
+// defaultValue value should be in range [minValue, maxValue]. defaultValue > maxValue is not allowed
+// "NotSupportedError: In parameterDescriptors, test defaultValue is out of the range defined by minValue and maxValue.",
+try {
+ registerProcessor(
+ "descriptors-out-of-range-max-worklet-processor",
+ DescriptorsOutOfRangeMaxWorkletProcessor
+ );
+} catch (e) {
+ console.log(e);
+}
+
+// We should have minValue < maxValue to define a valid range
+// "NotSupportedError: In parameterDescriptors, test minValue should be smaller than maxValue.",
+try {
+ registerProcessor(
+ "descriptors-bad-range-max-worklet-processor",
+ DescriptorsBadRangeMaxWorkletProcessor
+ );
+} catch (e) {
+ console.log(e);
+}