зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1713439 - [remote] Add mochitests to exercize message-handler API r=webdriver-reviewers,whimboo
Depends on 120083 Differential Revision: https://phabricator.services.mozilla.com/D120084
This commit is contained in:
Родитель
24d060cac5
Коммит
ee4b6dd666
|
@ -11,6 +11,8 @@ const { XPCOMUtils } = ChromeUtils.import(
|
|||
);
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetters(this, {
|
||||
Services: "resource://gre/modules/Services.jsm",
|
||||
|
||||
Log: "chrome://remote/content/shared/Log.jsm",
|
||||
getMessageHandlerClass:
|
||||
"chrome://remote/content/shared/messagehandler/MessageHandlerRegistry.jsm",
|
||||
|
@ -23,6 +25,9 @@ XPCOMUtils.defineLazyGetter(this, "logger", () => Log.get());
|
|||
// the protocol owning the MessageHandler. See Bug 1722464.
|
||||
const MODULES_FOLDER = "chrome://remote/content/webdriver-bidi/modules";
|
||||
|
||||
const TEST_MODULES_FOLDER =
|
||||
"chrome://mochitests/content/browser/remote/shared/messagehandler/test/browser/resources/modules";
|
||||
|
||||
/**
|
||||
* ModuleCache instances are dedicated to lazily create and cache the instances
|
||||
* of all the modules related to a specific MessageHandler instance.
|
||||
|
@ -63,6 +68,19 @@ class ModuleCache {
|
|||
this.messageHandler = messageHandler;
|
||||
this._messageHandlerPath = messageHandler.constructor.modulePath;
|
||||
|
||||
this._modulesRootFolder = MODULES_FOLDER;
|
||||
// TODO: Temporary workaround to use a different folder for tests.
|
||||
// After Bug 1722464 lands, we should be able to set custom root folders
|
||||
// per session and we can remove this workaround.
|
||||
if (
|
||||
Services.prefs.getBoolPref(
|
||||
"remote.messagehandler.modulecache.useBrowserTestRoot",
|
||||
false
|
||||
)
|
||||
) {
|
||||
this._modulesRootFolder = TEST_MODULES_FOLDER;
|
||||
}
|
||||
|
||||
// Map of absolute module paths to module instances.
|
||||
this._modules = new Map();
|
||||
}
|
||||
|
@ -127,6 +145,6 @@ class ModuleCache {
|
|||
moduleFolder = `${destinationPath}-in-${this._messageHandlerPath}`;
|
||||
}
|
||||
|
||||
return `${MODULES_FOLDER}/${moduleFolder}/${moduleName}.jsm`;
|
||||
return `${this._modulesRootFolder}/${moduleFolder}/${moduleName}.jsm`;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
[DEFAULT]
|
||||
tags = remote
|
||||
subsuite = remote
|
||||
support-files =
|
||||
head.js
|
||||
resources/*
|
||||
prefs =
|
||||
remote.messagehandler.modulecache.useBrowserTestRoot=true
|
||||
|
||||
[browser_handle_simple_command.js]
|
||||
[browser_registry.js]
|
|
@ -0,0 +1,205 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const { RootMessageHandler } = ChromeUtils.import(
|
||||
"chrome://remote/content/shared/messagehandler/RootMessageHandler.jsm"
|
||||
);
|
||||
const { WindowGlobalMessageHandler } = ChromeUtils.import(
|
||||
"chrome://remote/content/shared/messagehandler/WindowGlobalMessageHandler.jsm"
|
||||
);
|
||||
|
||||
// Test calling methods only implemented in the root version of a module.
|
||||
add_task(async function test_rootModule_command() {
|
||||
const rootMessageHandler = createRootMessageHandler("session-id-rootModule");
|
||||
const rootValue = await rootMessageHandler.handleCommand({
|
||||
moduleName: "TestModule",
|
||||
commandName: "testRootModule",
|
||||
destination: {
|
||||
type: RootMessageHandler.type,
|
||||
},
|
||||
});
|
||||
|
||||
is(
|
||||
rootValue,
|
||||
"root-value",
|
||||
"Retrieved the expected value from testRootModule"
|
||||
);
|
||||
|
||||
rootMessageHandler.destroy();
|
||||
});
|
||||
|
||||
// Test calling methods only implemented in the windowglobal-in-root version of
|
||||
// a module.
|
||||
add_task(async function test_windowglobalInRootModule_command() {
|
||||
const browsingContextId = gBrowser.selectedBrowser.browsingContext.id;
|
||||
|
||||
const rootMessageHandler = createRootMessageHandler(
|
||||
"session-id-windowglobalInRootModule"
|
||||
);
|
||||
const interceptedValue = await rootMessageHandler.handleCommand({
|
||||
moduleName: "TestModule",
|
||||
commandName: "testInterceptModule",
|
||||
destination: {
|
||||
type: WindowGlobalMessageHandler.type,
|
||||
id: browsingContextId,
|
||||
},
|
||||
});
|
||||
|
||||
is(
|
||||
interceptedValue,
|
||||
"intercepted-value",
|
||||
"Retrieved the expected value from testInterceptModule"
|
||||
);
|
||||
|
||||
rootMessageHandler.destroy();
|
||||
});
|
||||
|
||||
// Test calling methods only implemented in the windowglobal version of a
|
||||
// module.
|
||||
add_task(async function test_windowglobalModule_command() {
|
||||
const browsingContextId = gBrowser.selectedBrowser.browsingContext.id;
|
||||
|
||||
const rootMessageHandler = createRootMessageHandler(
|
||||
"session-id-windowglobalModule"
|
||||
);
|
||||
const windowGlobalValue = await rootMessageHandler.handleCommand({
|
||||
moduleName: "TestModule",
|
||||
commandName: "testWindowGlobalModule",
|
||||
destination: {
|
||||
type: WindowGlobalMessageHandler.type,
|
||||
id: browsingContextId,
|
||||
},
|
||||
});
|
||||
|
||||
is(
|
||||
windowGlobalValue,
|
||||
"windowglobal-value",
|
||||
"Retrieved the expected value from testWindowGlobalModule"
|
||||
);
|
||||
|
||||
rootMessageHandler.destroy();
|
||||
});
|
||||
|
||||
// Test calling a method on a module which is only available in the "windowglobal"
|
||||
// folder. This will check that the MessageHandler/ModuleCache correctly moves
|
||||
// on to the next layer when no implementation can be found in the root layer.
|
||||
add_task(async function test_windowglobalOnlyModule_command() {
|
||||
const browsingContextId = gBrowser.selectedBrowser.browsingContext.id;
|
||||
|
||||
const rootMessageHandler = createRootMessageHandler(
|
||||
"session-id-windowglobalOnlyModule"
|
||||
);
|
||||
const windowGlobalOnlyValue = await rootMessageHandler.handleCommand({
|
||||
moduleName: "TestOnlyInWindowGlobalModule",
|
||||
commandName: "testOnlyInWindowGlobal",
|
||||
destination: {
|
||||
type: WindowGlobalMessageHandler.type,
|
||||
id: browsingContextId,
|
||||
},
|
||||
});
|
||||
|
||||
is(
|
||||
windowGlobalOnlyValue,
|
||||
"only-in-windowglobal",
|
||||
"Retrieved the expected value from testOnlyInWindowGlobal"
|
||||
);
|
||||
|
||||
rootMessageHandler.destroy();
|
||||
});
|
||||
|
||||
// Try to create 2 sessions which will both set values in individual modules
|
||||
// via a command `testSetValue`, and then retrieve the values via another
|
||||
// command `testGetValue`.
|
||||
// This will ensure that different sessions use different module instances.
|
||||
add_task(async function test_multisession() {
|
||||
const browsingContextId = gBrowser.selectedBrowser.browsingContext.id;
|
||||
|
||||
const rootMessageHandler1 = createRootMessageHandler(
|
||||
"session-id-multisession-1"
|
||||
);
|
||||
const rootMessageHandler2 = createRootMessageHandler(
|
||||
"session-id-multisession-2"
|
||||
);
|
||||
|
||||
info("Set value for session 1");
|
||||
await rootMessageHandler1.handleCommand({
|
||||
moduleName: "TestModule",
|
||||
commandName: "testSetValue",
|
||||
destination: {
|
||||
type: WindowGlobalMessageHandler.type,
|
||||
id: browsingContextId,
|
||||
},
|
||||
params: "session1-value",
|
||||
});
|
||||
|
||||
info("Set value for session 2");
|
||||
await rootMessageHandler2.handleCommand({
|
||||
moduleName: "TestModule",
|
||||
commandName: "testSetValue",
|
||||
destination: {
|
||||
type: WindowGlobalMessageHandler.type,
|
||||
id: browsingContextId,
|
||||
},
|
||||
params: "session2-value",
|
||||
});
|
||||
|
||||
const session1Value = await rootMessageHandler1.handleCommand({
|
||||
moduleName: "TestModule",
|
||||
commandName: "testGetValue",
|
||||
destination: {
|
||||
type: WindowGlobalMessageHandler.type,
|
||||
id: browsingContextId,
|
||||
},
|
||||
});
|
||||
|
||||
is(
|
||||
session1Value,
|
||||
"session1-value",
|
||||
"Retrieved the expected value for session 1"
|
||||
);
|
||||
|
||||
const session2Value = await rootMessageHandler2.handleCommand({
|
||||
moduleName: "TestModule",
|
||||
commandName: "testGetValue",
|
||||
destination: {
|
||||
type: WindowGlobalMessageHandler.type,
|
||||
id: browsingContextId,
|
||||
},
|
||||
});
|
||||
|
||||
is(
|
||||
session2Value,
|
||||
"session2-value",
|
||||
"Retrieved the expected value for session 2"
|
||||
);
|
||||
|
||||
rootMessageHandler1.destroy();
|
||||
rootMessageHandler2.destroy();
|
||||
});
|
||||
|
||||
// Test calling a method from the windowglobal-in-root module which will
|
||||
// internally forward to the windowglobal module and will return a composite
|
||||
// result built both in parent and content process.
|
||||
add_task(async function test_forwarding_command() {
|
||||
const browsingContextId = gBrowser.selectedBrowser.browsingContext.id;
|
||||
|
||||
const rootMessageHandler = createRootMessageHandler("session-id-forwarding");
|
||||
const interceptAndForwardValue = await rootMessageHandler.handleCommand({
|
||||
moduleName: "TestModule",
|
||||
commandName: "testInterceptAndForwardModule",
|
||||
destination: {
|
||||
type: WindowGlobalMessageHandler.type,
|
||||
id: browsingContextId,
|
||||
},
|
||||
});
|
||||
|
||||
is(
|
||||
interceptAndForwardValue,
|
||||
"intercepted-and-forward+forward-to-windowglobal-value",
|
||||
"Retrieved the expected value from testInterceptAndForwardModule"
|
||||
);
|
||||
|
||||
rootMessageHandler.destroy();
|
||||
});
|
|
@ -0,0 +1,45 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const { MessageHandlerRegistry } = ChromeUtils.import(
|
||||
"chrome://remote/content/shared/messagehandler/MessageHandlerRegistry.jsm"
|
||||
);
|
||||
const { RootMessageHandler } = ChromeUtils.import(
|
||||
"chrome://remote/content/shared/messagehandler/RootMessageHandler.jsm"
|
||||
);
|
||||
|
||||
add_task(async function test_messageHandlerRegistry_API() {
|
||||
const sessionId = 1;
|
||||
const type = RootMessageHandler.type;
|
||||
|
||||
const rootMessageHandler = MessageHandlerRegistry.getOrCreateMessageHandler(
|
||||
sessionId,
|
||||
type
|
||||
);
|
||||
ok(rootMessageHandler, "Valid ROOT MessageHandler created");
|
||||
|
||||
const contextId = rootMessageHandler.contextId;
|
||||
ok(contextId, "ROOT MessageHandler has a valid contextId");
|
||||
|
||||
is(
|
||||
rootMessageHandler,
|
||||
MessageHandlerRegistry.getExistingMessageHandler(
|
||||
sessionId,
|
||||
type,
|
||||
contextId
|
||||
),
|
||||
"ROOT MessageHandler can be retrieved from the registry"
|
||||
);
|
||||
|
||||
rootMessageHandler.destroy();
|
||||
ok(
|
||||
!MessageHandlerRegistry.getExistingMessageHandler(
|
||||
sessionId,
|
||||
type,
|
||||
contextId
|
||||
),
|
||||
"Destroyed ROOT MessageHandler is no longer returned by the Registry"
|
||||
);
|
||||
});
|
|
@ -0,0 +1,18 @@
|
|||
/* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
function createRootMessageHandler(sessionId) {
|
||||
const { MessageHandlerRegistry } = ChromeUtils.import(
|
||||
"chrome://remote/content/shared/messagehandler/MessageHandlerRegistry.jsm"
|
||||
);
|
||||
const { RootMessageHandler } = ChromeUtils.import(
|
||||
"chrome://remote/content/shared/messagehandler/RootMessageHandler.jsm"
|
||||
);
|
||||
return MessageHandlerRegistry.getOrCreateMessageHandler(
|
||||
sessionId,
|
||||
RootMessageHandler.type
|
||||
);
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
/* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const EXPORTED_SYMBOLS = ["TestModule"];
|
||||
|
||||
class TestModule {
|
||||
constructor(messageHandler) {
|
||||
this.messageHandler = messageHandler;
|
||||
}
|
||||
|
||||
destroy() {}
|
||||
|
||||
/**
|
||||
* Commands
|
||||
*/
|
||||
|
||||
testRootModule() {
|
||||
return "root-value";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const EXPORTED_SYMBOLS = ["TestModule"];
|
||||
|
||||
class TestModule {
|
||||
constructor(messageHandler) {
|
||||
this.messageHandler = messageHandler;
|
||||
}
|
||||
|
||||
destroy() {}
|
||||
|
||||
/**
|
||||
* Commands
|
||||
*/
|
||||
|
||||
testInterceptModule() {
|
||||
return "intercepted-value";
|
||||
}
|
||||
|
||||
async testInterceptAndForwardModule(destination) {
|
||||
const windowGlobalValue = await this.messageHandler.handleCommand({
|
||||
moduleName: "TestModule",
|
||||
commandName: "testForwardToWindowGlobal",
|
||||
destination,
|
||||
});
|
||||
return "intercepted-and-forward+" + windowGlobalValue;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const EXPORTED_SYMBOLS = ["TestModule"];
|
||||
|
||||
class TestModule {
|
||||
constructor(messageHandler) {
|
||||
this.messageHandler = messageHandler;
|
||||
}
|
||||
|
||||
destroy() {}
|
||||
|
||||
/**
|
||||
* Commands
|
||||
*/
|
||||
|
||||
testWindowGlobalModule() {
|
||||
return "windowglobal-value";
|
||||
}
|
||||
|
||||
testSetValue(destination, value) {
|
||||
this._testValue = value;
|
||||
}
|
||||
|
||||
testGetValue() {
|
||||
return this._testValue;
|
||||
}
|
||||
|
||||
testForwardToWindowGlobal() {
|
||||
return "forward-to-windowglobal-value";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
/* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const EXPORTED_SYMBOLS = ["TestOnlyInWindowGlobalModule"];
|
||||
|
||||
class TestOnlyInWindowGlobalModule {
|
||||
constructor(messageHandler) {
|
||||
this.messageHandler = messageHandler;
|
||||
}
|
||||
|
||||
destroy() {}
|
||||
|
||||
/**
|
||||
* Commands
|
||||
*/
|
||||
|
||||
testOnlyInWindowGlobal() {
|
||||
return "only-in-windowglobal";
|
||||
}
|
||||
}
|
|
@ -2,6 +2,10 @@
|
|||
# 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/.
|
||||
|
||||
BROWSER_CHROME_MANIFESTS += [
|
||||
"messagehandler/test/browser/browser.ini",
|
||||
]
|
||||
|
||||
XPCSHELL_TESTS_MANIFESTS += [
|
||||
"test/xpcshell/xpcshell.ini",
|
||||
"webdriver/test/xpcshell/xpcshell.ini",
|
||||
|
|
Загрузка…
Ссылка в новой задаче