summaryrefslogtreecommitdiffstats
path: root/remote/shared/messagehandler/test/browser/browser_handle_command_errors.js
diff options
context:
space:
mode:
Diffstat (limited to 'remote/shared/messagehandler/test/browser/browser_handle_command_errors.js')
-rw-r--r--remote/shared/messagehandler/test/browser/browser_handle_command_errors.js218
1 files changed, 218 insertions, 0 deletions
diff --git a/remote/shared/messagehandler/test/browser/browser_handle_command_errors.js b/remote/shared/messagehandler/test/browser/browser_handle_command_errors.js
new file mode 100644
index 0000000000..5f0bdb78df
--- /dev/null
+++ b/remote/shared/messagehandler/test/browser/browser_handle_command_errors.js
@@ -0,0 +1,218 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const { RootMessageHandler } = ChromeUtils.importESModule(
+ "chrome://remote/content/shared/messagehandler/RootMessageHandler.sys.mjs"
+);
+
+// Check that errors from WindowGlobal modules can be caught by the consumer
+// of the RootMessageHandler.
+add_task(async function test_module_error() {
+ const browsingContextId = gBrowser.selectedBrowser.browsingContext.id;
+
+ const rootMessageHandler = createRootMessageHandler("session-id-error");
+
+ info("Call a module method which will throw");
+ try {
+ await rootMessageHandler.handleCommand({
+ moduleName: "commandwindowglobalonly",
+ commandName: "testError",
+ destination: {
+ type: WindowGlobalMessageHandler.type,
+ id: browsingContextId,
+ },
+ });
+ ok(false, "Error from window global module was not caught");
+ } catch (e) {
+ ok(true, "Error from window global module caught");
+ }
+
+ rootMessageHandler.destroy();
+});
+
+// Check that sending commands to incorrect destinations creates an error which
+// can be caught by the consumer of the RootMessageHandler.
+add_task(async function test_destination_error() {
+ const rootMessageHandler = createRootMessageHandler("session-id-error");
+
+ const fakeBrowsingContextId = -1;
+ ok(
+ !BrowsingContext.get(fakeBrowsingContextId),
+ "No browsing context matches fakeBrowsingContextId"
+ );
+
+ info("Call a valid module method, but on a non-existent browsing context id");
+ Assert.throws(
+ () =>
+ rootMessageHandler.handleCommand({
+ moduleName: "commandwindowglobalonly",
+ commandName: "testOnlyInWindowGlobal",
+ destination: {
+ type: WindowGlobalMessageHandler.type,
+ id: fakeBrowsingContextId,
+ },
+ }),
+ err => err.message == `Unable to find a BrowsingContext for id -1`
+ );
+
+ rootMessageHandler.destroy();
+});
+
+add_task(async function test_invalid_module_error() {
+ const rootMessageHandler = createRootMessageHandler(
+ "session-id-missing_module"
+ );
+
+ info("Attempt to call a Root module which has a syntax error");
+ Assert.throws(
+ () =>
+ rootMessageHandler.handleCommand({
+ moduleName: "invalid",
+ commandName: "someMethod",
+ destination: {
+ type: RootMessageHandler.type,
+ },
+ }),
+ err =>
+ err.name === "SyntaxError" &&
+ err.message == "expected expression, got ';'"
+ );
+
+ rootMessageHandler.destroy();
+});
+
+add_task(async function test_missing_root_module_error() {
+ const rootMessageHandler = createRootMessageHandler(
+ "session-id-missing_module"
+ );
+
+ info("Attempt to call a Root module which doesn't exist");
+ Assert.throws(
+ () =>
+ rootMessageHandler.handleCommand({
+ moduleName: "missingmodule",
+ commandName: "someMethod",
+ destination: {
+ type: RootMessageHandler.type,
+ },
+ }),
+ err =>
+ err.name == "UnsupportedCommandError" &&
+ err.message ==
+ `missingmodule.someMethod not supported for destination ROOT`
+ );
+
+ rootMessageHandler.destroy();
+});
+
+add_task(async function test_missing_windowglobal_module_error() {
+ const browsingContextId = gBrowser.selectedBrowser.browsingContext.id;
+ const rootMessageHandler = createRootMessageHandler(
+ "session-id-missing_windowglobal_module"
+ );
+
+ info("Attempt to call a WindowGlobal module which doesn't exist");
+ Assert.throws(
+ () =>
+ rootMessageHandler.handleCommand({
+ moduleName: "missingmodule",
+ commandName: "someMethod",
+ destination: {
+ type: WindowGlobalMessageHandler.type,
+ id: browsingContextId,
+ },
+ }),
+ err =>
+ err.name == "UnsupportedCommandError" &&
+ err.message ==
+ `missingmodule.someMethod not supported for destination WINDOW_GLOBAL`
+ );
+
+ rootMessageHandler.destroy();
+});
+
+add_task(async function test_missing_root_method_error() {
+ const rootMessageHandler = createRootMessageHandler(
+ "session-id-missing_root_method"
+ );
+
+ info("Attempt to call an invalid method on a Root module");
+ Assert.throws(
+ () =>
+ rootMessageHandler.handleCommand({
+ moduleName: "command",
+ commandName: "wrongMethod",
+ destination: {
+ type: RootMessageHandler.type,
+ },
+ }),
+ err =>
+ err.name == "UnsupportedCommandError" &&
+ err.message == `command.wrongMethod not supported for destination ROOT`
+ );
+
+ rootMessageHandler.destroy();
+});
+
+add_task(async function test_missing_windowglobal_method_error() {
+ const browsingContextId = gBrowser.selectedBrowser.browsingContext.id;
+ const rootMessageHandler = createRootMessageHandler(
+ "session-id-missing_windowglobal_method"
+ );
+
+ info("Attempt to call an invalid method on a WindowGlobal module");
+ Assert.throws(
+ () =>
+ rootMessageHandler.handleCommand({
+ moduleName: "commandwindowglobalonly",
+ commandName: "wrongMethod",
+ destination: {
+ type: WindowGlobalMessageHandler.type,
+ id: browsingContextId,
+ },
+ }),
+ err =>
+ err.name == "UnsupportedCommandError" &&
+ err.message ==
+ `commandwindowglobalonly.wrongMethod not supported for destination WINDOW_GLOBAL`
+ );
+
+ rootMessageHandler.destroy();
+});
+
+/**
+ * This test checks that even if a command is rerouted to another command after
+ * the RootMessageHandler, we still check the new command and log a useful
+ * error message.
+ *
+ * This illustrates why it is important to perform the command check at each
+ * layer of the MessageHandler network.
+ */
+add_task(async function test_missing_intermediary_method_error() {
+ const browsingContextId = gBrowser.selectedBrowser.browsingContext.id;
+ const rootMessageHandler = createRootMessageHandler(
+ "session-id-missing_intermediary_method"
+ );
+
+ info(
+ "Call a (valid) command that relies on another (missing) command on a WindowGlobal module"
+ );
+ await Assert.rejects(
+ rootMessageHandler.handleCommand({
+ moduleName: "commandwindowglobalonly",
+ commandName: "testMissingIntermediaryMethod",
+ destination: {
+ type: WindowGlobalMessageHandler.type,
+ id: browsingContextId,
+ },
+ }),
+ err =>
+ err.name == "UnsupportedCommandError" &&
+ err.message ==
+ `commandwindowglobalonly.missingMethod not supported for destination WINDOW_GLOBAL`
+ );
+
+ rootMessageHandler.destroy();
+});