summaryrefslogtreecommitdiffstats
path: root/remote/cdp/test/xpcshell
diff options
context:
space:
mode:
Diffstat (limited to 'remote/cdp/test/xpcshell')
-rw-r--r--remote/cdp/test/xpcshell/test_CDPConnection.js27
-rw-r--r--remote/cdp/test/xpcshell/test_DomainCache.js127
-rw-r--r--remote/cdp/test/xpcshell/test_Error.js119
-rw-r--r--remote/cdp/test/xpcshell/test_Session.js42
-rw-r--r--remote/cdp/test/xpcshell/test_StreamRegistry.js168
-rw-r--r--remote/cdp/test/xpcshell/xpcshell.ini9
6 files changed, 492 insertions, 0 deletions
diff --git a/remote/cdp/test/xpcshell/test_CDPConnection.js b/remote/cdp/test/xpcshell/test_CDPConnection.js
new file mode 100644
index 0000000000..41044702d1
--- /dev/null
+++ b/remote/cdp/test/xpcshell/test_CDPConnection.js
@@ -0,0 +1,27 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const { splitMethod } = ChromeUtils.importESModule(
+ "chrome://remote/content/cdp/CDPConnection.sys.mjs"
+);
+
+add_test(function test_Connection_splitMethod() {
+ for (const t of [42, null, true, {}, [], undefined]) {
+ Assert.throws(() => splitMethod(t), /TypeError/, `${typeof t} throws`);
+ }
+ for (const s of ["", ".", "foo.", ".bar", "foo.bar.baz"]) {
+ Assert.throws(
+ () => splitMethod(s),
+ /Invalid method format: '.*'/,
+ `"${s}" throws`
+ );
+ }
+ deepEqual(splitMethod("foo.bar"), {
+ domain: "foo",
+ command: "bar",
+ });
+
+ run_next_test();
+});
diff --git a/remote/cdp/test/xpcshell/test_DomainCache.js b/remote/cdp/test/xpcshell/test_DomainCache.js
new file mode 100644
index 0000000000..8f303361be
--- /dev/null
+++ b/remote/cdp/test/xpcshell/test_DomainCache.js
@@ -0,0 +1,127 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const { Domain } = ChromeUtils.importESModule(
+ "chrome://remote/content/cdp/domains/Domain.sys.mjs"
+);
+const { DomainCache } = ChromeUtils.importESModule(
+ "chrome://remote/content/cdp/domains/DomainCache.sys.mjs"
+);
+
+class MockSession {
+ onEvent() {}
+}
+
+const noopSession = new MockSession();
+
+add_test(function test_DomainCache_constructor() {
+ new DomainCache(noopSession, {});
+
+ run_next_test();
+});
+
+add_test(function test_DomainCache_domainSupportsMethod() {
+ const modules = {
+ Foo: class extends Domain {
+ bar() {}
+ },
+ };
+ const domains = new DomainCache(noopSession, modules);
+
+ ok(domains.domainSupportsMethod("Foo", "bar"));
+ ok(!domains.domainSupportsMethod("Foo", "baz"));
+ ok(!domains.domainSupportsMethod("foo", "bar"));
+
+ run_next_test();
+});
+
+add_test(function test_DomainCache_get_invalidModule() {
+ Assert.throws(() => {
+ const domains = new DomainCache(noopSession, { Foo: undefined });
+ domains.get("Foo");
+ }, /UnknownMethodError/);
+
+ run_next_test();
+});
+
+add_test(function test_DomainCache_get_missingConstructor() {
+ Assert.throws(() => {
+ const domains = new DomainCache(noopSession, { Foo: {} });
+ domains.get("Foo");
+ }, /TypeError/);
+
+ run_next_test();
+});
+
+add_test(function test_DomainCache_get_superClassNotDomain() {
+ Assert.throws(() => {
+ const domains = new DomainCache(noopSession, { Foo: class {} });
+ domains.get("Foo");
+ }, /TypeError/);
+
+ run_next_test();
+});
+
+add_test(function test_DomainCache_get_constructs() {
+ let eventFired;
+ class Session {
+ onEvent(event) {
+ eventFired = event;
+ }
+ }
+
+ let constructed = false;
+ class Foo extends Domain {
+ constructor() {
+ super();
+ constructed = true;
+ }
+ }
+
+ const session = new Session();
+ const domains = new DomainCache(session, { Foo });
+
+ const foo = domains.get("Foo");
+ ok(constructed);
+ ok(foo instanceof Foo);
+
+ const event = {};
+ foo.emit(event);
+ equal(event, eventFired);
+
+ run_next_test();
+});
+
+add_test(function test_DomainCache_size() {
+ class Foo extends Domain {}
+ const domains = new DomainCache(noopSession, { Foo });
+
+ equal(domains.size, 0);
+ domains.get("Foo");
+ equal(domains.size, 1);
+
+ run_next_test();
+});
+
+add_test(function test_DomainCache_clear() {
+ let dtorCalled = false;
+ class Foo extends Domain {
+ destructor() {
+ dtorCalled = true;
+ }
+ }
+
+ const domains = new DomainCache(noopSession, { Foo });
+
+ equal(domains.size, 0);
+ domains.get("Foo");
+ equal(domains.size, 1);
+
+ domains.clear();
+ equal(domains.size, 0);
+ ok(dtorCalled);
+
+ run_next_test();
+});
diff --git a/remote/cdp/test/xpcshell/test_Error.js b/remote/cdp/test/xpcshell/test_Error.js
new file mode 100644
index 0000000000..13ffc90566
--- /dev/null
+++ b/remote/cdp/test/xpcshell/test_Error.js
@@ -0,0 +1,119 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+/* eslint-disable no-tabs */
+
+const {
+ RemoteAgentError,
+ UnknownMethodError,
+ UnsupportedError,
+} = ChromeUtils.importESModule("chrome://remote/content/cdp/Error.sys.mjs");
+
+add_test(function test_RemoteAgentError_ctor() {
+ const e1 = new RemoteAgentError();
+ equal(e1.name, "RemoteAgentError");
+ equal(e1.message, "");
+ equal(e1.cause, e1.message);
+
+ const e2 = new RemoteAgentError("message");
+ equal(e2.message, "message");
+ equal(e2.cause, e2.message);
+
+ const e3 = new RemoteAgentError("message", "cause");
+ equal(e3.message, "message");
+ equal(e3.cause, "cause");
+
+ run_next_test();
+});
+
+add_test(function test_RemoteAgentError_notify() {
+ // nothing much we can test, except test that it doesn't throw
+ new RemoteAgentError().notify();
+
+ run_next_test();
+});
+
+add_test(function test_RemoteAgentError_toString() {
+ const e = new RemoteAgentError("message");
+ equal(e.toString(), RemoteAgentError.format(e));
+ equal(
+ e.toString({ stack: true }),
+ RemoteAgentError.format(e, { stack: true })
+ );
+
+ run_next_test();
+});
+
+add_test(function test_RemoteAgentError_format() {
+ const { format } = RemoteAgentError;
+
+ equal(format({ name: "HippoError" }), "HippoError");
+ equal(format({ name: "HorseError", message: "neigh" }), "HorseError: neigh");
+
+ const dog = {
+ name: "DogError",
+ message: "woof",
+ stack: " one\ntwo\nthree ",
+ };
+ equal(format(dog), "DogError: woof");
+ equal(
+ format(dog, { stack: true }),
+ `DogError: woof:
+ one
+ two
+ three`
+ );
+
+ const cat = {
+ name: "CatError",
+ message: "meow",
+ stack: "four\nfive\nsix",
+ cause: dog,
+ };
+ equal(format(cat), "CatError: meow");
+ equal(
+ format(cat, { stack: true }),
+ `CatError: meow:
+ four
+ five
+ six
+caused by: DogError: woof:
+ one
+ two
+ three`
+ );
+
+ run_next_test();
+});
+
+add_test(function test_RemoteAgentError_fromJSON() {
+ const cdpErr = {
+ message: `TypeError: foo:
+ bar
+ baz`,
+ };
+ const err = RemoteAgentError.fromJSON(cdpErr);
+
+ equal(err.message, "TypeError: foo");
+ equal(err.stack, "bar\nbaz");
+ equal(err.cause, null);
+
+ run_next_test();
+});
+
+add_test(function test_UnsupportedError() {
+ ok(new UnsupportedError() instanceof RemoteAgentError);
+ run_next_test();
+});
+
+add_test(function test_UnknownMethodError() {
+ ok(new UnknownMethodError() instanceof RemoteAgentError);
+ ok(new UnknownMethodError("domain").message.endsWith("domain"));
+ ok(
+ new UnknownMethodError("domain", "command").message.endsWith(
+ "domain.command"
+ )
+ );
+ run_next_test();
+});
diff --git a/remote/cdp/test/xpcshell/test_Session.js b/remote/cdp/test/xpcshell/test_Session.js
new file mode 100644
index 0000000000..00758baa69
--- /dev/null
+++ b/remote/cdp/test/xpcshell/test_Session.js
@@ -0,0 +1,42 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const { Session } = ChromeUtils.importESModule(
+ "chrome://remote/content/cdp/sessions/Session.sys.mjs"
+);
+
+const connection = {
+ registerSession: () => {},
+ transport: {
+ on: () => {},
+ },
+};
+
+class MockTarget {
+ constructor() {}
+
+ get browsingContext() {
+ return { id: 42 };
+ }
+
+ get mm() {
+ return {
+ addMessageListener() {},
+ removeMessageListener() {},
+ loadFrameScript() {},
+ sendAsyncMessage() {},
+ };
+ }
+}
+
+add_test(function test_Session_destructor() {
+ const session = new Session(connection, new MockTarget());
+ session.domains.get("Browser");
+ equal(session.domains.size, 1);
+ session.destructor();
+ equal(session.domains.size, 0);
+
+ run_next_test();
+});
diff --git a/remote/cdp/test/xpcshell/test_StreamRegistry.js b/remote/cdp/test/xpcshell/test_StreamRegistry.js
new file mode 100644
index 0000000000..ffc1e59c52
--- /dev/null
+++ b/remote/cdp/test/xpcshell/test_StreamRegistry.js
@@ -0,0 +1,168 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
+
+const { StreamRegistry } = ChromeUtils.importESModule(
+ "chrome://remote/content/cdp/StreamRegistry.sys.mjs"
+);
+
+add_test(function test_constructor() {
+ const registry = new StreamRegistry();
+ equal(registry.streams.size, 0);
+
+ run_next_test();
+});
+
+add_test(async function test_destructor() {
+ const registry = new StreamRegistry();
+ const { file: file1, path: path1 } = await createFile("foo bar");
+ const { file: file2, path: path2 } = await createFile("foo bar");
+
+ registry.add(file1);
+ registry.add(file2);
+
+ equal(registry.streams.size, 2);
+
+ await registry.destructor();
+ equal(registry.streams.size, 0);
+ ok(!(await OS.File.exists(path1)), "temporary file has been removed");
+ ok(!(await OS.File.exists(path2)), "temporary file has been removed");
+
+ run_next_test();
+});
+
+add_test(async function test_addValidStreamType() {
+ const registry = new StreamRegistry();
+ const { file } = await createFile("foo bar");
+
+ const handle = registry.add(file);
+ equal(registry.streams.size, 1, "A single stream has been added");
+ equal(typeof handle, "string", "Handle is of type string");
+ ok(registry.streams.has(handle), "Handle has been found");
+ equal(registry.streams.get(handle), file, "Expected OS.File stream found");
+
+ run_next_test();
+});
+
+add_test(async function test_addCreatesDifferentHandles() {
+ const registry = new StreamRegistry();
+ const { file } = await createFile("foo bar");
+
+ const handle1 = registry.add(file);
+ equal(registry.streams.size, 1, "A single stream has been added");
+ equal(typeof handle1, "string", "Handle is of type string");
+ ok(registry.streams.has(handle1), "Handle has been found");
+ equal(registry.streams.get(handle1), file, "Expected OS.File stream found");
+
+ const handle2 = registry.add(file);
+ equal(registry.streams.size, 2, "A single stream has been added");
+ equal(typeof handle2, "string", "Handle is of type string");
+ ok(registry.streams.has(handle2), "Handle has been found");
+ equal(registry.streams.get(handle2), file, "Expected OS.File stream found");
+
+ notEqual(handle1, handle2, "Different handles have been generated");
+
+ run_next_test();
+});
+
+add_test(async function test_addInvalidStreamType() {
+ const registry = new StreamRegistry();
+ Assert.throws(() => registry.add(new Blob([])), /UnsupportedError/);
+
+ run_next_test();
+});
+
+add_test(async function test_getForValidHandle() {
+ const registry = new StreamRegistry();
+ const { file } = await createFile("foo bar");
+ const handle = registry.add(file);
+
+ equal(registry.streams.size, 1, "A single stream has been added");
+ equal(registry.get(handle), file, "Expected OS.File stream found");
+
+ run_next_test();
+});
+
+add_test(async function test_getForInvalidHandle() {
+ const registry = new StreamRegistry();
+ const { file } = await createFile("foo bar");
+ registry.add(file);
+
+ equal(registry.streams.size, 1, "A single stream has been added");
+ Assert.throws(() => registry.get("foo"), /TypeError/);
+
+ run_next_test();
+});
+
+add_test(async function test_removeForValidHandle() {
+ const registry = new StreamRegistry();
+ const { file: file1, path: path1 } = await createFile("foo bar");
+ const { file: file2, path: path2 } = await createFile("foo bar");
+
+ const handle1 = registry.add(file1);
+ const handle2 = registry.add(file2);
+
+ equal(registry.streams.size, 2);
+
+ await registry.remove(handle1);
+ equal(registry.streams.size, 1);
+ ok(
+ !(await OS.File.exists(path1)),
+ "temporary file for first stream has been removed"
+ );
+ equal(registry.get(handle2), file2, "Second stream has not been closed");
+ ok(
+ await OS.File.exists(path2),
+ "temporary file for second stream hasn't been removed"
+ );
+
+ run_next_test();
+});
+
+add_test(async function test_removeForInvalidHandle() {
+ const registry = new StreamRegistry();
+ const { file } = await createFile("foo bar");
+ registry.add(file);
+
+ equal(registry.streams.size, 1, "A single stream has been added");
+ await Assert.rejects(registry.remove("foo"), /TypeError/);
+
+ run_next_test();
+});
+
+async function createFile(contents, options = {}) {
+ let { path = null, remove = true } = options;
+
+ if (!path) {
+ const basePath = OS.Path.join(OS.Constants.Path.tmpDir, "remote-agent.txt");
+ const { file, path: tmpPath } = await OS.File.openUnique(basePath, {
+ humanReadable: true,
+ });
+ await file.close();
+ path = tmpPath;
+ }
+
+ let encoder = new TextEncoder();
+ let array = encoder.encode(contents);
+
+ const count = await OS.File.writeAtomic(path, array, {
+ encoding: "utf-8",
+ tmpPath: path + ".tmp",
+ });
+ equal(count, contents.length, "All data has been written to file");
+
+ const file = await OS.File.open(path);
+
+ // Automatically remove the file once the test has finished
+ if (remove) {
+ registerCleanupFunction(async () => {
+ await file.close();
+ await OS.File.remove(path, { ignoreAbsent: true });
+ });
+ }
+
+ return { file, path };
+}
diff --git a/remote/cdp/test/xpcshell/xpcshell.ini b/remote/cdp/test/xpcshell/xpcshell.ini
new file mode 100644
index 0000000000..c1f1856fde
--- /dev/null
+++ b/remote/cdp/test/xpcshell/xpcshell.ini
@@ -0,0 +1,9 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+[test_CDPConnection.js]
+[test_DomainCache.js]
+[test_Error.js]
+[test_Session.js]
+[test_StreamRegistry.js]