Bug 1693491 - [devtools] Migrate TargetList to be a command r=nchevobbe,rpl

This changeset is incomplete and focus on places where we instantiate TargetList constructor

Differential Revision: https://phabricator.services.mozilla.com/D105611
This commit is contained in:
Alexandre Poirot 2021-03-11 12:53:18 +00:00
parent 4cf2f28556
commit 4a9e835d61
33 changed files with 277 additions and 299 deletions

View File

@ -69,9 +69,12 @@ async function setupToolboxTest(extensionId) {
`testNetworkRequestReceived(${JSON.stringify(requests)});`
);
const onToolboxClosed = gDevTools.once("toolbox-destroyed");
await toolbox.destroy();
return onToolboxClosed;
// Because this is an Addon target, the client isn't closed on toolbox close.
// (TargetMixin.shouldCloseClient only applies to local tabs)
// So that we have to do it manually from this test.
await client.close();
}
add_task(async function test_addon_debugging_netmonitor_panel() {

View File

@ -36,7 +36,6 @@ var Startup = Cc["@mozilla.org/devtools/startup-clh;1"].getService(
Ci.nsISupports
).wrappedJSObject;
const { TargetList } = require("devtools/shared/resources/target-list");
const {
ResourceWatcher,
} = require("devtools/shared/resources/resource-watcher");
@ -238,13 +237,6 @@ function Toolbox(
this.descriptorFront = descriptorFront;
this.targetList = new TargetList(descriptorFront);
this.targetList.on(
"target-thread-wrong-order-on-resume",
this._onTargetThreadFrontResumeWrongOrder.bind(this)
);
this.resourceWatcher = new ResourceWatcher(this.targetList);
// The session ID is used to determine which telemetry events belong to which
// toolbox session. Because we use Amplitude to analyse the telemetry data we
// must use the time since the system wide epoch as the session ID.
@ -415,7 +407,10 @@ Toolbox.prototype = {
get nodePicker() {
if (!this._nodePicker) {
this._nodePicker = new NodePicker(this.targetList, this.selection);
this._nodePicker = new NodePicker(
this.commands.targetCommand,
this.selection
);
this._nodePicker.on("picker-starting", this._onPickerStarting);
this._nodePicker.on("picker-started", this._onPickerStarted);
this._nodePicker.on("picker-stopped", this._onPickerStopped);
@ -547,14 +542,14 @@ Toolbox.prototype = {
* Get the current top level target the toolbox is debugging.
*
* This will only be defined *after* calling Toolbox.open(),
* after it has called `TargetList.startListening`.
* after it has called `targetCommands.startListening`.
*/
get target() {
return this.targetList.targetFront;
return this.commands.targetCommand.targetFront;
},
get threadFront() {
return this.targetList.targetFront.threadFront;
return this.commands.targetCommand.targetFront.threadFront;
},
/**
@ -729,7 +724,7 @@ Toolbox.prototype = {
if (targetFront.isTopLevel && isTargetSwitching) {
// These methods expect the target to be attached, which is guaranteed by the time
// _onTargetAvailable is called by the TargetList.
// _onTargetAvailable is called by the targetCommand.
await this._listFrames();
await this.initPerformance();
}
@ -785,17 +780,27 @@ Toolbox.prototype = {
// See devtools/shared/commands/README.md
this.commands = await this.descriptorFront.getCommands();
//TODO: complete the renaming of targetList everywhere
// But for now, still expose this name on Toolbox
this.targetList = this.commands.targetCommand;
this.commands.targetCommand.on(
"target-thread-wrong-order-on-resume",
this._onTargetThreadFrontResumeWrongOrder.bind(this)
);
this.resourceWatcher = new ResourceWatcher(this.commands.targetCommand);
// Optimization: fire up a few other things before waiting on
// the iframe being ready (makes startup faster)
await this.targetList.startListening();
// The TargetList is created from Toolbox's constructor,
// and Toolbox.open (i.e. this function) is called soon after.
// It means that this call to TargetList.watchTargets is the first,
await this.commands.targetCommand.startListening();
// The targetCommand is created right before this code.
// It means that this call to watchTargets is the first,
// and we are registering the first target listener, which means
// Toolbox._onTargetAvailable will be called first, before any other
// onTargetAvailable listener that might be registered on the targetList.
await this.targetList.watchTargets(
TargetList.ALL_TYPES,
// onTargetAvailable listener that might be registered on targetCommand.
await this.commands.targetCommand.watchTargets(
this.commands.targetCommand.ALL_TYPES,
this._onTargetAvailable,
this._onTargetDestroyed
);
@ -941,7 +946,9 @@ Toolbox.prototype = {
// Request the actor to restore the focus to the content page once the
// target is detached. This typically happens when the console closes.
// We restore the focus as it may have been stolen by the console input.
await this.targetList.updateConfiguration({ restoreFocus: true });
await this.commands.targetCommand.updateConfiguration({
restoreFocus: true,
});
}
// Lazily connect to the profiler here and don't wait for it to complete,
@ -2074,7 +2081,7 @@ Toolbox.prototype = {
const pref = "devtools.cache.disabled";
const cacheDisabled = Services.prefs.getBoolPref(pref);
await this.targetList.updateConfiguration({ cacheDisabled });
await this.commands.targetCommand.updateConfiguration({ cacheDisabled });
// This event is only emitted for tests in order to know when to reload
if (flags.testing) {
@ -2089,7 +2096,9 @@ Toolbox.prototype = {
_applyServiceWorkersTestingSettings: function() {
const pref = "devtools.serviceWorkers.testing.enabled";
const serviceWorkersTestingEnabled = Services.prefs.getBoolPref(pref);
this.targetList.updateConfiguration({ serviceWorkersTestingEnabled });
this.commands.targetCommand.updateConfiguration({
serviceWorkersTestingEnabled,
});
},
/**
@ -2098,7 +2107,7 @@ Toolbox.prototype = {
*/
_applyJavascriptEnabledSettings: function() {
const javascriptEnabled = this.target._javascriptEnabled;
this.targetList.updateConfiguration({ javascriptEnabled });
this.commands.targetCommand.updateConfiguration({ javascriptEnabled });
},
/**
@ -2143,7 +2152,7 @@ Toolbox.prototype = {
this.telemetry.toolClosed("paintflashing", this.sessionId, this);
}
this.isPaintFlashing = !this.isPaintFlashing;
return this.targetList.updateConfiguration({
return this.commands.targetCommand.updateConfiguration({
paintFlashing: this.isPaintFlashing,
});
},
@ -3746,8 +3755,8 @@ Toolbox.prototype = {
// Reset preferences set by the toolbox
outstanding.push(this.resetPreference());
this.targetList.unwatchTargets(
TargetList.ALL_TYPES,
this.commands.targetCommand.unwatchTargets(
this.commands.targetCommand.ALL_TYPES,
this._onTargetAvailable,
this._onTargetDestroyed
);
@ -3817,7 +3826,7 @@ Toolbox.prototype = {
// Notify toolbox-host-manager that the host can be destroyed.
this.emit("toolbox-unload");
// Targets need to be notified that the toolbox is being torn down.
// targetCommand need to be notified that the toolbox is being torn down.
// This is done after other destruction tasks since it may tear down
// fronts and the debugger transport which earlier destroy methods may
// require to complete.
@ -3826,7 +3835,7 @@ Toolbox.prototype = {
// other outstanding cleanup is done. Destroying the target list
// will lead to destroy frame targets which can temporarily make
// some fronts unresponsive and block the cleanup.
this.targetList.destroy();
this.commands.targetCommand.destroy();
return this.target.destroy();
}, console.error)
.then(() => {

View File

@ -5,7 +5,6 @@
"use strict";
loader.lazyRequireGetter(this, "EventEmitter", "devtools/shared/event-emitter");
const { TargetList } = require("devtools/shared/resources/target-list");
/**
* Client-side NodePicker module.
@ -149,7 +148,10 @@ class NodePicker extends EventEmitter {
this.emit("picker-starting");
this.targetList.watchTargets(TargetList.ALL_TYPES, this._onTargetAvailable);
this.targetList.watchTargets(
this.targetList.ALL_TYPES,
this._onTargetAvailable
);
this.emit("picker-started");
}
@ -166,7 +168,7 @@ class NodePicker extends EventEmitter {
this.doFocus = false;
this.targetList.unwatchTargets(
TargetList.ALL_TYPES,
this.targetList.ALL_TYPES,
this._onTargetAvailable
);

View File

@ -11,7 +11,6 @@ const {
getOrientation,
} = require("devtools/client/responsive/utils/orientation");
const Constants = require("devtools/client/responsive/constants");
const { TargetList } = require("devtools/shared/resources/target-list");
const {
ResourceWatcher,
} = require("devtools/shared/resources/resource-watcher");
@ -391,7 +390,8 @@ class ResponsiveUI {
// its corresponding target-list.
const descriptor = await this.client.mainRoot.getTab({ tab: this.tab });
this.targetList = new TargetList(descriptor);
const commands = await descriptor.getCommands();
this.targetList = commands.targetCommand;
this.resourceWatcher = new ResourceWatcher(this.targetList);
await this.targetList.startListening();

View File

@ -6,7 +6,6 @@
const Services = require("Services");
const WebConsole = require("devtools/client/webconsole/webconsole");
const { TargetList } = require("devtools/shared/resources/target-list");
const {
ResourceWatcher,
} = require("devtools/shared/resources/resource-watcher");
@ -46,8 +45,7 @@ class BrowserConsole extends WebConsole {
this._browserConsoleTarget = target;
this._descriptorFront = target.descriptorFront;
this._targetList = new TargetList(target.descriptorFront);
this._resourceWatcher = new ResourceWatcher(this._targetList);
this._resourceWatcher = new ResourceWatcher(this.targetList);
this._telemetry = new Telemetry();
this._bcInitializer = null;
this._bcDestroyer = null;
@ -57,10 +55,6 @@ class BrowserConsole extends WebConsole {
return this._browserConsoleTarget;
}
get targetList() {
return this._targetList;
}
get resourceWatcher() {
return this._resourceWatcher;
}

View File

@ -21,7 +21,7 @@ const { l10n } = require("devtools/client/webconsole/utils/messages");
const targetSelectors = require("devtools/client/framework/reducers/targets");
loader.lazyGetter(this, "TARGET_TYPES", function() {
return require("devtools/shared/resources/target-list").TargetList.TYPES;
return require("devtools/shared/commands/target/target-command").TYPES;
});
// Additional Components

View File

@ -31,9 +31,9 @@ async function createResourceWatcherForDescriptor(descriptor) {
const {
ResourceWatcher,
} = require("devtools/shared/resources/resource-watcher");
const { TargetList } = require("devtools/shared/resources/target-list");
const targetList = new TargetList(descriptor);
const commands = await descriptor.getCommands();
const targetList = commands.targetCommand;
await targetList.startListening();
return new ResourceWatcher(targetList);
}

View File

@ -102,7 +102,7 @@ class WebConsole {
}
get targetList() {
return this.toolbox.targetList;
return this.commands.targetCommand;
}
get resourceWatcher() {

View File

@ -16,9 +16,9 @@ add_task(async function() {
const {
ResourceWatcher,
} = require("devtools/shared/resources/resource-watcher");
const { TargetList } = require("devtools/shared/resources/target-list");
const targetList = new TargetList(target.descriptorFront);
const commands = await target.descriptorFront.getCommands();
const targetList = commands.targetCommand;
await targetList.startListening();
const resourceWatcher = new ResourceWatcher(targetList);

View File

@ -17,7 +17,6 @@ const {
DocumentWalker: _documentWalker,
} = require("devtools/server/actors/inspector/document-walker");
const { TargetList } = require("devtools/shared/resources/target-list");
const {
ResourceWatcher,
} = require("devtools/shared/resources/resource-watcher");
@ -146,7 +145,8 @@ function runNextTest() {
}
async function createResourceWatcher(target) {
const targetList = new TargetList(target.descriptorFront);
const commands = await target.descriptorFront.getCommands();
const targetList = commands.targetCommand;
await targetList.startListening();
return new ResourceWatcher(targetList);
}

View File

@ -7,7 +7,9 @@
// List of all command modules
// (please try to keep the list alphabetically sorted)
/*eslint sort-keys: "error"*/
const Commands = {};
const Commands = {
targetCommand: "devtools/shared/commands/target/target-command",
};
/**
* For a given descriptor and its related Targets, already initialized,
@ -24,7 +26,7 @@ async function createCommandsDictionary(descriptorFront) {
const dictionary = {};
for (const name in Commands) {
loader.lazyGetter(dictionary, name, () => {
const Constructor = require(Commands[name])[name];
const Constructor = require(Commands[name]);
return new Constructor({
// Commands can use other commands
commands: dictionary,

View File

@ -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/.
DIRS += [
"target",
]
DevToolsModules(
"index.js",
)

View File

@ -0,0 +1,7 @@
# 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/.
DevToolsModules(
"target-command.js",
)

View File

@ -22,7 +22,7 @@ const {
LegacyWorkersWatcher,
} = require("devtools/shared/resources/legacy-target-watchers/legacy-workers-watcher");
class TargetList extends EventEmitter {
class TargetCommand extends EventEmitter {
/**
* This class helps managing, iterating over and listening for Targets.
*
@ -41,7 +41,7 @@ class TargetList extends EventEmitter {
* @param {DescriptorFront} descriptorFront
* The context to inspector identified by this descriptor.
*/
constructor(descriptorFront) {
constructor({ descriptorFront }) {
super();
this.descriptorFront = descriptorFront;
@ -125,7 +125,7 @@ class TargetList extends EventEmitter {
// already registered.
if (targetFront != this.targetFront) {
console.error(
"Target is already registered in the TargetList",
"Target is already registered in the TargetCommand",
targetFront.actorID
);
}
@ -138,7 +138,7 @@ class TargetList extends EventEmitter {
// Handle top level target switching
// Note that, for now, `_onTargetAvailable` isn't called for the *initial* top level target.
// i.e. the one that is passed to TargetList constructor.
// i.e. the one that is passed to TargetCommand constructor.
if (targetFront.isTopLevel) {
// First report that all existing targets are destroyed
for (const target of this._targets) {
@ -250,7 +250,7 @@ class TargetList extends EventEmitter {
}
// Cache the Watcher once for all, the first time we call `startListening()`.
// This `watcherFront` attribute may be then used in any function in TargetList or ResourceWatcher after this.
// This `watcherFront` attribute may be then used in any function in TargetCommand or ResourceWatcher after this.
if (!this.watcherFront) {
// Bug 1675763: Watcher actor is not available in all situations yet.
const supportsWatcher = this.descriptorFront.traits?.watcher;
@ -265,25 +265,25 @@ class TargetList extends EventEmitter {
BROWSERTOOLBOX_FISSION_ENABLED
);
if (fissionBrowserToolboxEnabled) {
types = TargetList.ALL_TYPES;
types = TargetCommand.ALL_TYPES;
}
} else if (this.descriptorFront.isLocalTab) {
types = [TargetList.TYPES.FRAME];
types = [TargetCommand.TYPES.FRAME];
}
if (this.listenForWorkers && !types.includes(TargetList.TYPES.WORKER)) {
types.push(TargetList.TYPES.WORKER);
if (this.listenForWorkers && !types.includes(TargetCommand.TYPES.WORKER)) {
types.push(TargetCommand.TYPES.WORKER);
}
if (
this.listenForWorkers &&
!types.includes(TargetList.TYPES.SHARED_WORKER)
!types.includes(TargetCommand.TYPES.SHARED_WORKER)
) {
types.push(TargetList.TYPES.SHARED_WORKER);
types.push(TargetCommand.TYPES.SHARED_WORKER);
}
if (
this.listenForServiceWorkers &&
!types.includes(TargetList.TYPES.SERVICE_WORKER)
!types.includes(TargetCommand.TYPES.SERVICE_WORKER)
) {
types.push(TargetList.TYPES.SERVICE_WORKER);
types.push(TargetCommand.TYPES.SERVICE_WORKER);
}
// If no pref are set to true, nor is listenForWorkers set to true,
@ -330,7 +330,7 @@ class TargetList extends EventEmitter {
* but still unregister listeners set via Legacy Listeners.
*/
stopListening({ onlyLegacy = false } = {}) {
for (const type of TargetList.ALL_TYPES) {
for (const type of TargetCommand.ALL_TYPES) {
if (!this._isListening(type)) {
continue;
}
@ -358,26 +358,26 @@ class TargetList extends EventEmitter {
getTargetType(target) {
const { typeName } = target;
if (typeName == "browsingContextTarget") {
return TargetList.TYPES.FRAME;
return TargetCommand.TYPES.FRAME;
}
if (
typeName == "contentProcessTarget" ||
typeName == "parentProcessTarget"
) {
return TargetList.TYPES.PROCESS;
return TargetCommand.TYPES.PROCESS;
}
if (typeName == "workerDescriptor" || typeName == "workerTarget") {
if (target.isSharedWorker) {
return TargetList.TYPES.SHARED_WORKER;
return TargetCommand.TYPES.SHARED_WORKER;
}
if (target.isServiceWorker) {
return TargetList.TYPES.SERVICE_WORKER;
return TargetCommand.TYPES.SERVICE_WORKER;
}
return TargetList.TYPES.WORKER;
return TargetCommand.TYPES.WORKER;
}
throw new Error("Unsupported target typeName: " + typeName);
@ -391,7 +391,7 @@ class TargetList extends EventEmitter {
* Listen for the creation and/or destruction of target fronts matching one of the provided types.
*
* @param {Array<String>} types
* The type of target to listen for. Constant of TargetList.TYPES.
* The type of target to listen for. Constant of TargetCommand.TYPES.
* @param {Function} onAvailable
* Callback fired when a target has been just created or was already available.
* The function is called with the following arguments:
@ -405,7 +405,7 @@ class TargetList extends EventEmitter {
async watchTargets(types, onAvailable, onDestroy) {
if (typeof onAvailable != "function") {
throw new Error(
"TargetList.watchTargets expects a function as second argument"
"TargetCommand.watchTargets expects a function as second argument"
);
}
@ -477,7 +477,7 @@ class TargetList extends EventEmitter {
unwatchTargets(types, onAvailable, onDestroy) {
if (typeof onAvailable != "function") {
throw new Error(
"TargetList.unwatchTargets expects a function as second argument"
"TargetCommand.unwatchTargets expects a function as second argument"
);
}
@ -494,7 +494,7 @@ class TargetList extends EventEmitter {
* Retrieve all the current target fronts of a given type.
*
* @param {Array<String>} types
* The types of target to retrieve. Array of TargetList.TYPES
* The types of target to retrieve. Array of TargetCommand.TYPES
* @return {Array<TargetFront>} Array of target fronts matching any of the
* provided types.
*/
@ -514,7 +514,7 @@ class TargetList extends EventEmitter {
* For all the target fronts of a given type, retrieve all the target-scoped fronts of a given type.
*
* @param {String} targetType
* The type of target to iterate over. Constant of TargetList.TYPES.
* The type of target to iterate over. Constant of TargetCommand.TYPES.
* @param {String} frontType
* The type of target-scoped front to retrieve. It can be "inspector", "console", "thread",...
*/
@ -578,7 +578,7 @@ class TargetList extends EventEmitter {
/**
* Update the DevTools configuration on the server.
* TODO: This API is temporarily on the TargetList but should move to a
* TODO: This API is temporarily on the TargetCommand but should move to a
* command as soon as https://bugzilla.mozilla.org/show_bug.cgi?id=1691681
* lands.
*/
@ -593,7 +593,7 @@ class TargetList extends EventEmitter {
/**
* Check if JavaScript is currently enabled.
* TODO: This API is temporarily on the TargetList but should move to a
* TODO: This API is temporarily on the TargetCommand but should move to a
* command as soon as https://bugzilla.mozilla.org/show_bug.cgi?id=1691681
* lands.
*/
@ -628,15 +628,15 @@ class TargetList extends EventEmitter {
/**
* All types of target:
*/
TargetList.TYPES = TargetList.prototype.TYPES = {
TargetCommand.TYPES = TargetCommand.prototype.TYPES = {
PROCESS: "process",
FRAME: "frame",
WORKER: "worker",
SHARED_WORKER: "shared_worker",
SERVICE_WORKER: "service_worker",
};
TargetList.ALL_TYPES = TargetList.prototype.ALL_TYPES = Object.values(
TargetList.TYPES
TargetCommand.ALL_TYPES = TargetCommand.prototype.ALL_TYPES = Object.values(
TargetCommand.TYPES
);
module.exports = { TargetList };
module.exports = TargetCommand;

View File

@ -4,13 +4,6 @@
"use strict";
loader.lazyRequireGetter(
this,
"TargetList",
"devtools/shared/resources/target-list",
true
);
const {
LegacyProcessesWatcher,
} = require("devtools/shared/resources/legacy-target-watchers/legacy-processes-watcher");
@ -150,7 +143,7 @@ class LegacyWorkersWatcher {
if (this.target.isParentProcess) {
await this.targetList.watchTargets(
[TargetList.TYPES.PROCESS],
[this.targetList.TYPES.PROCESS],
this._onProcessAvailable,
this._onProcessDestroyed
);
@ -197,14 +190,14 @@ class LegacyWorkersWatcher {
}
_getProcessTargets() {
return this.targetList.getAllTargets([TargetList.TYPES.PROCESS]);
return this.targetList.getAllTargets([this.targetList.TYPES.PROCESS]);
}
unlisten() {
// Stop listening for new process targets.
if (this.target.isParentProcess) {
this.targetList.unwatchTargets(
[TargetList.TYPES.PROCESS],
[this.targetList.TYPES.PROCESS],
this._onProcessAvailable,
this._onProcessDestroyed
);

View File

@ -10,7 +10,6 @@ DIRS += [
DevToolsModules(
"resource-watcher.js",
"target-list.js",
)
if CONFIG["MOZ_BUILD_APP"] != "mobile/android":

View File

@ -5,7 +5,6 @@
// Test the ResourceWatcher API around DOCUMENT_EVENT
const { TargetList } = require("devtools/shared/resources/target-list");
const {
ResourceWatcher,
} = require("devtools/shared/resources/resource-watcher");
@ -21,15 +20,10 @@ async function testDocumentEventResources() {
// Open a test tab
const tab = await addTab("data:text/html,Document Events");
// Create a TargetList for the test tab
const client = await createLocalClient();
const descriptor = await client.mainRoot.getTab({ tab });
const targetList = new TargetList(descriptor);
await targetList.startListening();
// Activate ResourceWatcher
const listener = new ResourceListener();
const resourceWatcher = new ResourceWatcher(targetList);
const { client, resourceWatcher, targetList } = await initResourceWatcher(
tab
);
info(
"Check whether the document events are fired correctly even when the document was already loaded"

View File

@ -3,10 +3,7 @@
"use strict";
// Test the TargetList API around workers
const { TargetList } = require("devtools/shared/resources/target-list");
const { TYPES } = TargetList;
// Test the TargetCommand API around workers
const FISSION_TEST_URL = URL_ROOT_SSL + "fission_document.html";
const WORKER_FILE = "test_worker.js";
@ -14,7 +11,7 @@ const CHROME_WORKER_URL = CHROME_URL_ROOT + WORKER_FILE;
const SERVICE_WORKER_URL = URL_ROOT_SSL + "test_service_worker.js";
add_task(async function() {
// Enabled fission's pref as the TargetList is almost disabled without it
// Enabled fission's pref as the TargetCommand is almost disabled without it
await pushPref("devtools.browsertoolbox.fission", true);
// Disable the preloaded process as it creates processes intermittently
@ -25,7 +22,7 @@ add_task(async function() {
const mainRoot = client.mainRoot;
const tab = await addTab(FISSION_TEST_URL);
info("Test TargetList against workers via the parent process target");
info("Test TargetCommand against workers via the parent process target");
// Instantiate a worker in the parent process
// eslint-disable-next-line no-unused-vars
@ -34,7 +31,9 @@ add_task(async function() {
const sharedWorker = new SharedWorker(CHROME_WORKER_URL + "#shared-worker");
const targetDescriptor = await mainRoot.getMainProcess();
const targetList = new TargetList(targetDescriptor);
const commands = await targetDescriptor.getCommands();
const targetList = commands.targetCommand;
const { TYPES } = targetList;
await targetList.startListening();
// Very naive sanity check against getAllTargets([workerType])

View File

@ -3,9 +3,7 @@
"use strict";
// Test the TargetList API around frames
const { TargetList } = require("devtools/shared/resources/target-list");
// Test the TargetCommand API around frames
const FISSION_TEST_URL = URL_ROOT_SSL + "fission_document.html";
const IFRAME_URL = URL_ROOT_ORG_SSL + "fission_iframe.html";
@ -33,21 +31,23 @@ add_task(async function() {
});
async function testBrowserFrames(mainRoot) {
info("Test TargetList against frames via the parent process target");
info("Test TargetCommand against frames via the parent process target");
const targetDescriptor = await mainRoot.getMainProcess();
const targetList = new TargetList(targetDescriptor);
const commands = await targetDescriptor.getCommands();
const targetList = commands.targetCommand;
const { TYPES } = targetList;
await targetList.startListening();
// Very naive sanity check against getAllTargets([frame])
const frames = await targetList.getAllTargets([TargetList.TYPES.FRAME]);
const frames = await targetList.getAllTargets([TYPES.FRAME]);
const hasBrowserDocument = frames.find(
frameTarget => frameTarget.url == window.location.href
);
ok(hasBrowserDocument, "retrieve the target for the browser document");
// Check that calling getAllTargets([frame]) return the same target instances
const frames2 = await targetList.getAllTargets([TargetList.TYPES.FRAME]);
const frames2 = await targetList.getAllTargets([TYPES.FRAME]);
is(frames2.length, frames.length, "retrieved the same number of frames");
function sortFronts(f1, f2) {
@ -65,7 +65,7 @@ async function testBrowserFrames(mainRoot) {
const onAvailable = ({ targetFront }) => {
is(
targetFront.targetType,
TargetList.TYPES.FRAME,
TYPES.FRAME,
"We are only notified about frame targets"
);
ok(
@ -76,7 +76,7 @@ async function testBrowserFrames(mainRoot) {
);
targets.push(targetFront);
};
await targetList.watchTargets([TargetList.TYPES.FRAME], onAvailable);
await targetList.watchTargets([TYPES.FRAME], onAvailable);
is(
targets.length,
frames.length,
@ -92,7 +92,7 @@ async function testBrowserFrames(mainRoot) {
`frame ${i} targets are the same via watchTargets`
);
}
targetList.unwatchTargets([TargetList.TYPES.FRAME], onAvailable);
targetList.unwatchTargets([TYPES.FRAME], onAvailable);
/* NOT READY YET, need to implement frame listening
// Open a new tab and see if the frame target is reported by watchTargets and getAllTargets
@ -101,7 +101,7 @@ async function testBrowserFrames(mainRoot) {
is(targets.length, frames.length + 1, "Opening a tab reported a new frame");
is(targets[targets.length - 1].url, TEST_URL, "This frame target is about the new tab");
const frames3 = await targetList.getAllTargets([TargetList.TYPES.FRAME]);
const frames3 = await targetList.getAllTargets([TYPES.FRAME]);
const hasTabDocument = frames3.find(target => target.url == TEST_URL);
ok(hasTabDocument, "retrieve the target for tab via getAllTargets");
*/
@ -111,17 +111,19 @@ async function testBrowserFrames(mainRoot) {
}
async function testTabFrames(mainRoot) {
info("Test TargetList against frames via a tab target");
info("Test TargetCommand against frames via a tab target");
// Create a TargetList for a given test tab
// Create a TargetCommand for a given test tab
const tab = await addTab(FISSION_TEST_URL);
const descriptor = await mainRoot.getTab({ tab });
const targetList = new TargetList(descriptor);
const commands = await descriptor.getCommands();
const targetList = commands.targetCommand;
const { TYPES } = targetList;
await targetList.startListening();
// Check that calling getAllTargets([frame]) return the same target instances
const frames = await targetList.getAllTargets([TargetList.TYPES.FRAME]);
const frames = await targetList.getAllTargets([TYPES.FRAME]);
// When fission is enabled, we also get the remote example.org iframe.
const expectedFramesCount = isFissionEnabled() ? 2 : 1;
is(
@ -137,7 +139,7 @@ async function testTabFrames(mainRoot) {
const onAvailable = ({ targetFront, isTargetSwitching }) => {
is(
targetFront.targetType,
TargetList.TYPES.FRAME,
TYPES.FRAME,
"We are only notified about frame targets"
);
targets.push({ targetFront, isTargetSwitching });
@ -145,7 +147,7 @@ async function testTabFrames(mainRoot) {
const onDestroyed = ({ targetFront, isTargetSwitching }) => {
is(
targetFront.targetType,
TargetList.TYPES.FRAME,
TYPES.FRAME,
"We are only notified about frame targets"
);
ok(
@ -156,11 +158,7 @@ async function testTabFrames(mainRoot) {
);
destroyedTargets.push({ targetFront, isTargetSwitching });
};
await targetList.watchTargets(
[TargetList.TYPES.FRAME],
onAvailable,
onDestroyed
);
await targetList.watchTargets([TYPES.FRAME], onAvailable, onDestroyed);
is(
targets.length,
frames.length,
@ -283,7 +281,7 @@ async function testTabFrames(mainRoot) {
);
}
targetList.unwatchTargets([TargetList.TYPES.FRAME], onAvailable);
targetList.unwatchTargets([TYPES.FRAME], onAvailable);
targetList.destroy();

View File

@ -3,10 +3,7 @@
"use strict";
// Test the TargetList API getAllTargets.
const { TargetList } = require("devtools/shared/resources/target-list");
const { ALL_TYPES, TYPES } = TargetList;
// Test the TargetCommand API getAllTargets.
const FISSION_TEST_URL = URL_ROOT_SSL + "fission_document.html";
const CHROME_WORKER_URL = CHROME_URL_ROOT + "test_worker.js";
@ -33,7 +30,9 @@ add_task(async function() {
info("Create a target list for the main process target");
const targetDescriptor = await mainRoot.getMainProcess();
const targetList = new TargetList(targetDescriptor);
const commands = await targetDescriptor.getCommands();
const targetList = commands.targetCommand;
const { TYPES } = targetList;
await targetList.startListening();
info("Check getAllTargets will throw when providing invalid arguments");
@ -81,16 +80,16 @@ add_task(async function() {
...processTargets,
...frameTargets,
];
const allTargets = targetList.getAllTargets(ALL_TYPES);
const allTargets = targetList.getAllTargets(targetList.ALL_TYPES);
is(
allTargets.length,
allTargetsReference.length,
"getAllTargets(TYPES.ALL_TYPES) returned the expected number of targets"
"getAllTargets(ALL_TYPES) returned the expected number of targets"
);
ok(
allTargets.every(t => allTargetsReference.includes(t)),
"getAllTargets(TYPES.ALL_TYPES) returned the expected targets"
"getAllTargets(ALL_TYPES) returned the expected targets"
);
targetList.destroy();

View File

@ -3,9 +3,7 @@
"use strict";
// Test the TargetList API when DevTools Fission preference is false
const { TargetList } = require("devtools/shared/resources/target-list");
// Test the TargetCommand API when DevTools Fission preference is false
add_task(async function() {
// Disable the preloaded process as it gets created lazily and may interfere
@ -16,36 +14,38 @@ add_task(async function() {
const client = await createLocalClient();
const mainRoot = client.mainRoot;
const targetDescriptor = await mainRoot.getMainProcess();
const mainProcess = await targetDescriptor.getTarget();
// Assert the limited behavior of this API with fission preffed off
await pushPref("devtools.browsertoolbox.fission", false);
// Test with Main process targets as top level target
await testPreffedOffMainProcess(mainProcess);
await testPreffedOffMainProcess(mainRoot);
await client.close();
});
async function testPreffedOffMainProcess(mainProcess) {
async function testPreffedOffMainProcess(mainRoot) {
info(
"Test TargetList when devtools's fission pref is false, via the parent process target"
"Test TargetCommand when devtools's fission pref is false, via the parent process target"
);
const targetList = new TargetList(mainProcess.descriptorFront);
const targetDescriptor = await mainRoot.getMainProcess();
const mainProcess = await targetDescriptor.getTarget();
const commands = await targetDescriptor.getCommands();
const targetList = commands.targetCommand;
const { TYPES } = targetList;
await targetList.startListening();
// The API should only report the top level target,
// i.e. the Main process target, which is considered as frame
// and not as process.
const processes = await targetList.getAllTargets([TargetList.TYPES.PROCESS]);
const processes = await targetList.getAllTargets([TYPES.PROCESS]);
is(
processes.length,
0,
"We only get a frame target for the top level target"
);
const frames = await targetList.getAllTargets([TargetList.TYPES.FRAME]);
const frames = await targetList.getAllTargets([TYPES.FRAME]);
is(frames.length, 1, "We get only one frame when preffed-off");
is(
frames[0],
@ -57,15 +57,15 @@ async function testPreffedOffMainProcess(mainProcess) {
const onProcessAvailable = ({ targetFront }) => {
processTargets.push(targetFront);
};
await targetList.watchTargets([TargetList.TYPES.PROCESS], onProcessAvailable);
await targetList.watchTargets([TYPES.PROCESS], onProcessAvailable);
is(processTargets.length, 0, "We get no process when preffed-off");
targetList.unwatchTargets([TargetList.TYPES.PROCESS], onProcessAvailable);
targetList.unwatchTargets([TYPES.PROCESS], onProcessAvailable);
const frameTargets = [];
const onFrameAvailable = ({ targetFront }) => {
is(
targetFront.targetType,
TargetList.TYPES.FRAME,
TYPES.FRAME,
"We are only notified about frame targets"
);
ok(
@ -74,7 +74,7 @@ async function testPreffedOffMainProcess(mainProcess) {
);
frameTargets.push(targetFront);
};
await targetList.watchTargets([TargetList.TYPES.FRAME], onFrameAvailable);
await targetList.watchTargets([TYPES.FRAME], onFrameAvailable);
is(
frameTargets.length,
1,
@ -85,7 +85,7 @@ async function testPreffedOffMainProcess(mainProcess) {
mainProcess,
"The target is the top level one via watchTargets"
);
targetList.unwatchTargets([TargetList.TYPES.FRAME], onFrameAvailable);
targetList.unwatchTargets([TYPES.FRAME], onFrameAvailable);
targetList.destroy();
}

View File

@ -3,15 +3,13 @@
"use strict";
// Test the TargetList API around processes
const { TargetList } = require("devtools/shared/resources/target-list");
// Test the TargetCommand API around processes
const TEST_URL =
"data:text/html;charset=utf-8," + encodeURIComponent(`<div id="test"></div>`);
add_task(async function() {
// Enabled fission's pref as the TargetList is almost disabled without it
// Enabled fission's pref as the TargetCommand is almost disabled without it
await pushPref("devtools.browsertoolbox.fission", true);
// Disable the preloaded process as it gets created lazily and may interfere
// with process count assertions
@ -22,7 +20,8 @@ add_task(async function() {
const client = await createLocalClient();
const targetDescriptor = await client.mainRoot.getMainProcess();
const targetList = new TargetList(targetDescriptor);
const commands = await targetDescriptor.getCommands();
const targetList = commands.targetCommand;
await targetList.startListening();
await testProcesses(targetList, targetList.targetFront);
@ -42,7 +41,8 @@ add_task(async function() {
const client = await createLocalClient();
const targetDescriptor = await client.mainRoot.getMainProcess();
const targetList = new TargetList(targetDescriptor);
const commands = await targetDescriptor.getCommands();
const targetList = commands.targetCommand;
await targetList.startListening();
const created = [];
@ -54,7 +54,7 @@ add_task(async function() {
destroyed.push(targetFront);
};
await targetList.watchTargets(
[TargetList.TYPES.PROCESS],
[targetList.TYPES.PROCESS],
onAvailable,
onDestroyed
);
@ -84,18 +84,19 @@ add_task(async function() {
});
async function testProcesses(targetList, target) {
info("Test TargetList against processes");
info("Test TargetCommand against processes");
const { TYPES } = targetList;
// Note that ppmm also includes the parent process, which is considered as a frame rather than a process
const originalProcessesCount = Services.ppmm.childCount - 1;
const processes = await targetList.getAllTargets([TargetList.TYPES.PROCESS]);
const processes = await targetList.getAllTargets([TYPES.PROCESS]);
is(
processes.length,
originalProcessesCount,
"Get a target for all content processes"
);
const processes2 = await targetList.getAllTargets([TargetList.TYPES.PROCESS]);
const processes2 = await targetList.getAllTargets([TYPES.PROCESS]);
is(
processes2.length,
originalProcessesCount,
@ -118,7 +119,7 @@ async function testProcesses(targetList, target) {
}
is(
targetFront.targetType,
TargetList.TYPES.PROCESS,
TYPES.PROCESS,
"We are only notified about process targets"
);
ok(
@ -136,7 +137,7 @@ async function testProcesses(targetList, target) {
}
is(
targetFront.targetType,
TargetList.TYPES.PROCESS,
TYPES.PROCESS,
"We are only notified about process targets"
);
ok(
@ -145,11 +146,7 @@ async function testProcesses(targetList, target) {
);
targets.delete(targetFront);
};
await targetList.watchTargets(
[TargetList.TYPES.PROCESS],
onAvailable,
onDestroyed
);
await targetList.watchTargets([TYPES.PROCESS], onAvailable, onDestroyed);
is(
targets.size,
originalProcessesCount,
@ -169,10 +166,10 @@ async function testProcesses(targetList, target) {
if (previousTargets.has(targetFront)) {
return;
}
targetList.unwatchTargets([TargetList.TYPES.PROCESS], onAvailable2);
targetList.unwatchTargets([TYPES.PROCESS], onAvailable2);
resolve(targetFront);
};
targetList.watchTargets([TargetList.TYPES.PROCESS], onAvailable2);
targetList.watchTargets([TYPES.PROCESS], onAvailable2);
});
const tab1 = await BrowserTestUtils.openNewForegroundTab({
gBrowser,
@ -191,17 +188,9 @@ async function testProcesses(targetList, target) {
const onAvailable3 = () => {};
const onDestroyed3 = ({ targetFront }) => {
resolve(targetFront);
targetList.unwatchTargets(
[TargetList.TYPES.PROCESS],
onAvailable3,
onDestroyed3
);
targetList.unwatchTargets([TYPES.PROCESS], onAvailable3, onDestroyed3);
};
targetList.watchTargets(
[TargetList.TYPES.PROCESS],
onAvailable3,
onDestroyed3
);
targetList.watchTargets([TYPES.PROCESS], onAvailable3, onDestroyed3);
});
BrowserTestUtils.removeTab(tab1);
@ -222,14 +211,10 @@ async function testProcesses(targetList, target) {
"The destroyed target is the one that has been reported as created"
);
targetList.unwatchTargets(
[TargetList.TYPES.PROCESS],
onAvailable,
onDestroyed
);
targetList.unwatchTargets([TYPES.PROCESS], onAvailable, onDestroyed);
// Ensure that getAllTargets still works after the call to unwatchTargets
const processes3 = await targetList.getAllTargets([TargetList.TYPES.PROCESS]);
const processes3 = await targetList.getAllTargets([TYPES.PROCESS]);
is(
processes3.length,
processCountAfterTabOpen - 1,

View File

@ -3,10 +3,7 @@
"use strict";
// Test the TargetList API for service workers in content tabs.
const { TargetList } = require("devtools/shared/resources/target-list");
const { TYPES } = TargetList;
// Test the TargetCommand API for service workers in content tabs.
const FISSION_TEST_URL = URL_ROOT_SSL + "fission_document.html";
@ -25,14 +22,20 @@ add_task(async function() {
info("Create a target list for a tab target");
const descriptor = await client.mainRoot.getTab({ tab });
const targetList = new TargetList(descriptor);
const commands = await descriptor.getCommands();
const targetList = commands.targetCommand;
const { TYPES } = targetList;
// Enable Service Worker listening.
targetList.listenForServiceWorkers = true;
await targetList.startListening();
const serviceWorkerTargets = targetList.getAllTargets([TYPES.SERVICE_WORKER]);
is(serviceWorkerTargets.length, 1, "TargetList has 1 service worker target");
is(
serviceWorkerTargets.length,
1,
"TargetCommmand has 1 service worker target"
);
info("Check that the onAvailable is done when watchTargets resolves");
const targets = [];

View File

@ -3,14 +3,11 @@
"use strict";
// Test the TargetList API for service workers when navigating in content tabs.
// Test the TargetCommand API for service workers when navigating in content tabs.
// When the top level target navigates, we manually call onTargetAvailable for
// service workers which now match the page domain. We assert that the callbacks
// will be called the expected number of times here.
const { TargetList } = require("devtools/shared/resources/target-list");
const { TYPES } = TargetList;
const COM_PAGE_URL = URL_ROOT_SSL + "test_sw_page.html";
const COM_WORKER_URL = URL_ROOT_SSL + "test_sw_page_worker.js";
const ORG_PAGE_URL = URL_ROOT_ORG_SSL + "test_sw_page.html";
@ -191,9 +188,9 @@ add_task(async function test_NavigationBetweenTwoDomains_WithDestroy() {
/**
* In this test we load a service worker in a page prior to starting the
* TargetList. We start the target list on another page, and then we go back to
* TargetCommand. We start the target list on another page, and then we go back to
* the first page. We want to check that we are correctly notified about the
* worker that was spawned before TargetList.
* worker that was spawned before TargetCommand.
*
* Steps:
* - navigate to .com page
@ -307,7 +304,8 @@ async function watchServiceWorkerTargets({
}) {
info("Create a target list for a tab target");
const descriptor = await mainRoot.getTab({ tab });
const targetList = new TargetList(descriptor);
const commands = await descriptor.getCommands();
const targetList = commands.targetCommand;
// Enable Service Worker listening.
targetList.listenForServiceWorkers = true;
@ -337,7 +335,7 @@ async function watchServiceWorkerTargets({
};
await targetList.watchTargets(
[TYPES.SERVICE_WORKER],
[targetList.TYPES.SERVICE_WORKER],
onAvailable,
onDestroyed
);

View File

@ -3,9 +3,7 @@
"use strict";
// Test the TargetList API switchToTarget function
const { TargetList } = require("devtools/shared/resources/target-list");
// Test the TargetCommand API switchToTarget function
add_task(async function() {
const client = await createLocalClient();
@ -16,7 +14,7 @@ add_task(async function() {
});
async function testSwitchToTarget(client) {
info("Test TargetList.switchToTarget method");
info("Test TargetCommand.switchToTarget method");
const { mainRoot } = client;
// Create a first target to switch from, a new tab with an iframe
@ -26,7 +24,9 @@ async function testSwitchToTarget(client) {
const firstDescriptor = await mainRoot.getTab({ tab: gBrowser.selectedTab });
const firstTarget = await firstDescriptor.getTarget();
const targetList = new TargetList(firstTarget.descriptorFront);
const commands = await firstDescriptor.getCommands();
const targetList = commands.targetCommand;
const { TYPES } = targetList;
await targetList.startListening();
@ -48,7 +48,7 @@ async function testSwitchToTarget(client) {
const onFrameAvailable = ({ targetFront, isTargetSwitching }) => {
is(
targetFront.targetType,
TargetList.TYPES.FRAME,
TYPES.FRAME,
"We are only notified about frame targets"
);
ok(
@ -73,7 +73,7 @@ async function testSwitchToTarget(client) {
const onFrameDestroyed = ({ targetFront, isTargetSwitching }) => {
is(
targetFront.targetType,
TargetList.TYPES.FRAME,
TYPES.FRAME,
"target-destroyed: We are only notified about frame targets"
);
ok(
@ -97,7 +97,7 @@ async function testSwitchToTarget(client) {
destroyedTargets.push(targetFront);
};
await targetList.watchTargets(
[TargetList.TYPES.FRAME],
[TYPES.FRAME],
onFrameAvailable,
onFrameDestroyed
);

View File

@ -3,10 +3,7 @@
"use strict";
// Test the TargetList API around workers
const { TargetList } = require("devtools/shared/resources/target-list");
const { TYPES } = TargetList;
// Test the TargetCommand API around workers
const FISSION_TEST_URL = URL_ROOT_SSL + "fission_document.html";
const IFRAME_FILE = "fission_iframe.html";
@ -31,10 +28,10 @@ add_task(async function() {
await addTab(`${FISSION_TEST_URL}?id=first-untargetted-tab&noServiceWorker`);
await addTab(`${FISSION_TEST_URL}?id=second-untargetted-tab&noServiceWorker`);
info("Test TargetList against workers via a tab target");
info("Test TargetCommand against workers via a tab target");
const tab = await addTab(`${FISSION_TEST_URL}?&noServiceWorker`);
// Create a TargetList for the tab
// Create a TargetCommand for the tab
const descriptor = await mainRoot.getTab({ tab });
const target = await descriptor.getTarget();
@ -43,7 +40,9 @@ add_task(async function() {
// It isn't clear if this assertion is meaningful?
await target.attach();
const targetList = new TargetList(target.descriptorFront);
const commands = await descriptor.getCommands();
const targetList = commands.targetCommand;
const { TYPES } = targetList;
// Workaround to allow listening for workers in the content toolbox
// without the fission preferences

View File

@ -3,9 +3,7 @@
"use strict";
// Test the TargetList API with all possible descriptors
const { TargetList } = require("devtools/shared/resources/target-list");
// Test the TargetCommand API with all possible descriptors
const TEST_URL = "https://example.org/document-builder.sjs?html=org";
const CHROME_WORKER_URL = CHROME_URL_ROOT + "test_worker.js";
@ -32,13 +30,14 @@ add_task(async function() {
});
async function testParentProcess(rootFront) {
info("Test TargetList against parent process descriptor");
info("Test TargetCommand against parent process descriptor");
const descriptor = await rootFront.getMainProcess();
const targetList = new TargetList(descriptor);
const commands = await descriptor.getCommands();
const targetList = commands.targetCommand;
await targetList.startListening();
const targets = await targetList.getAllTargets(TargetList.ALL_TYPES);
const targets = await targetList.getAllTargets(targetList.ALL_TYPES);
ok(
targets.length > 1,
"We get many targets when debugging the parent process"
@ -47,7 +46,7 @@ async function testParentProcess(rootFront) {
is(targetFront, targetList.targetFront, "The first is the top level one");
is(
targetFront.targetType,
TargetList.TYPES.FRAME,
targetList.TYPES.FRAME,
"the parent process target is of frame type, because it inherits from BrowsingContextTargetActor"
);
is(targetFront.isTopLevel, true, "This is flagged as top level");
@ -57,22 +56,23 @@ async function testParentProcess(rootFront) {
}
async function testTab(rootFront) {
info("Test TargetList against tab descriptor");
info("Test TargetCommand against tab descriptor");
const tab = await addTab(TEST_URL);
const descriptor = await rootFront.getTab({ tab });
const targetList = new TargetList(descriptor);
const commands = await descriptor.getCommands();
const targetList = commands.targetCommand;
await targetList.startListening();
// Avoid the target to close the client when we destroy the target list and the target
targetList.targetFront.shouldCloseClient = false;
const targets = await targetList.getAllTargets(TargetList.ALL_TYPES);
const targets = await targetList.getAllTargets(targetList.ALL_TYPES);
is(targets.length, 1, "Got a unique target");
const targetFront = targets[0];
is(targetFront, targetList.targetFront, "The first is the top level one");
is(
targetFront.targetType,
TargetList.TYPES.FRAME,
targetList.TYPES.FRAME,
"the tab target is of frame type"
);
is(targetFront.isTopLevel, true, "This is flagged as top level");
@ -83,7 +83,7 @@ async function testTab(rootFront) {
}
async function testWebExtension(rootFront) {
info("Test TargetList against webextension descriptor");
info("Test TargetCommand against webextension descriptor");
const extension = ExtensionTestUtils.loadExtension({
useAddonManager: "temporary",
@ -95,16 +95,17 @@ async function testWebExtension(rootFront) {
await extension.startup();
const descriptor = await rootFront.getAddon({ id: extension.id });
const targetList = new TargetList(descriptor);
const commands = await descriptor.getCommands();
const targetList = commands.targetCommand;
await targetList.startListening();
const targets = await targetList.getAllTargets(TargetList.ALL_TYPES);
const targets = await targetList.getAllTargets(targetList.ALL_TYPES);
is(targets.length, 1, "Got a unique target");
const targetFront = targets[0];
is(targetFront, targetList.targetFront, "The first is the top level one");
is(
targetFront.targetType,
TargetList.TYPES.FRAME,
targetList.TYPES.FRAME,
"the web extension target is of frame type, because it inherits from BrowsingContextTargetActor"
);
is(targetFront.isTopLevel, true, "This is flagged as top level");
@ -115,7 +116,7 @@ async function testWebExtension(rootFront) {
}
async function testContentProcess(rootFront) {
info("Test TargetList against content process descriptor");
info("Test TargetCommand against content process descriptor");
const tab = await BrowserTestUtils.openNewForegroundTab({
gBrowser,
@ -126,16 +127,17 @@ async function testContentProcess(rootFront) {
const { osPid } = tab.linkedBrowser.browsingContext.currentWindowGlobal;
const descriptor = await rootFront.getProcess(osPid);
const targetList = new TargetList(descriptor);
const commands = await descriptor.getCommands();
const targetList = commands.targetCommand;
await targetList.startListening();
const targets = await targetList.getAllTargets(TargetList.ALL_TYPES);
const targets = await targetList.getAllTargets(targetList.ALL_TYPES);
is(targets.length, 1, "Got a unique target");
const targetFront = targets[0];
is(targetFront, targetList.targetFront, "The first is the top level one");
is(
targetFront.targetType,
TargetList.TYPES.PROCESS,
targetList.TYPES.PROCESS,
"the content process target is of process type"
);
is(targetFront.isTopLevel, true, "This is flagged as top level");
@ -146,23 +148,24 @@ async function testContentProcess(rootFront) {
}
async function testWorker(rootFront) {
info("Test TargetList against worker descriptor");
info("Test TargetCommand against worker descriptor");
const workerUrl = CHROME_WORKER_URL + "#descriptor";
new Worker(workerUrl);
const { workers } = await rootFront.listWorkers();
const descriptor = workers.find(w => w.url == workerUrl);
const targetList = new TargetList(descriptor);
const commands = await descriptor.getCommands();
const targetList = commands.targetCommand;
await targetList.startListening();
const targets = await targetList.getAllTargets(TargetList.ALL_TYPES);
const targets = await targetList.getAllTargets(targetList.ALL_TYPES);
is(targets.length, 1, "Got a unique target");
const targetFront = targets[0];
is(targetFront, targetList.targetFront, "The first is the top level one");
is(
targetFront.targetType,
TargetList.TYPES.WORKER,
targetList.TYPES.WORKER,
"the worker target is of worker type"
);
is(targetFront.isTopLevel, true, "This is flagged as top level");

View File

@ -3,15 +3,13 @@
"use strict";
// Test the TargetList's `watchTargets` function
const { TargetList } = require("devtools/shared/resources/target-list");
// Test the TargetCommand's `watchTargets` function
const TEST_URL =
"data:text/html;charset=utf-8," + encodeURIComponent(`<div id="test"></div>`);
add_task(async function() {
// Enabled fission's pref as the TargetList is almost disabled without it
// Enabled fission's pref as the TargetCommand is almost disabled without it
await pushPref("devtools.browsertoolbox.fission", true);
// Disable the preloaded process as it gets created lazily and may interfere
// with process count assertions
@ -30,10 +28,12 @@ add_task(async function() {
});
async function testWatchTargets(mainRoot) {
info("Test TargetList watchTargets function");
info("Test TargetCommand watchTargets function");
const targetDescriptor = await mainRoot.getMainProcess();
const targetList = new TargetList(targetDescriptor);
const commands = await targetDescriptor.getCommands();
const targetList = commands.targetCommand;
const { TYPES } = targetList;
await targetList.startListening();
@ -51,7 +51,7 @@ async function testWatchTargets(mainRoot) {
}
is(
targetFront.targetType,
TargetList.TYPES.PROCESS,
TYPES.PROCESS,
"We are only notified about process targets"
);
ok(
@ -71,7 +71,7 @@ async function testWatchTargets(mainRoot) {
}
is(
targetFront.targetType,
TargetList.TYPES.PROCESS,
TYPES.PROCESS,
"We are only notified about process targets"
);
ok(
@ -80,11 +80,7 @@ async function testWatchTargets(mainRoot) {
);
targets.delete(targetFront);
};
await targetList.watchTargets(
[TargetList.TYPES.PROCESS],
onAvailable,
onDestroyed
);
await targetList.watchTargets([TYPES.PROCESS], onAvailable, onDestroyed);
is(
targets.size,
originalProcessesCount,
@ -111,10 +107,10 @@ async function testWatchTargets(mainRoot) {
if (previousTargets.has(targetFront)) {
return;
}
targetList.unwatchTargets([TargetList.TYPES.PROCESS], onAvailable2);
targetList.unwatchTargets([TYPES.PROCESS], onAvailable2);
resolve(targetFront);
};
targetList.watchTargets([TargetList.TYPES.PROCESS], onAvailable2);
targetList.watchTargets([TYPES.PROCESS], onAvailable2);
});
const tab1 = await BrowserTestUtils.openNewForegroundTab({
gBrowser,
@ -134,17 +130,9 @@ async function testWatchTargets(mainRoot) {
const onAvailable3 = () => {};
const onDestroyed3 = ({ targetFront }) => {
resolve(targetFront);
targetList.unwatchTargets(
[TargetList.TYPES.PROCESS],
onAvailable3,
onDestroyed3
);
targetList.unwatchTargets([TYPES.PROCESS], onAvailable3, onDestroyed3);
};
targetList.watchTargets(
[TargetList.TYPES.PROCESS],
onAvailable3,
onDestroyed3
);
targetList.watchTargets([TYPES.PROCESS], onAvailable3, onDestroyed3);
});
BrowserTestUtils.removeTab(tab1);
@ -165,20 +153,22 @@ async function testWatchTargets(mainRoot) {
"The destroyed target is the one that has been reported as created"
);
targetList.unwatchTargets(
[TargetList.TYPES.PROCESS],
onAvailable,
onDestroyed
);
targetList.unwatchTargets([TYPES.PROCESS], onAvailable, onDestroyed);
targetList.destroy();
// Also destroy the descriptor so that testThrowingInOnAvailable can get a fresh
// commands object and also a fresh TargetList instance
targetDescriptor.destroy();
}
async function testContentProcessTarget(mainRoot) {
info("Test TargetList watchTargets with a content process target");
info("Test TargetCommand watchTargets with a content process target");
const processes = await mainRoot.listProcesses();
const targetList = new TargetList(processes[1]);
const commands = await processes[1].getCommands();
const targetList = commands.targetCommand;
const { TYPES } = targetList;
await targetList.startListening();
@ -190,12 +180,12 @@ async function testContentProcessTarget(mainRoot) {
const onAvailable = ({ targetFront }) => {
if (targets.has(targetFront)) {
// This may fail if the top level target is reported by LegacyImplementation
// to TargetList and emits an available event for it.
// to TargetCommand and emits an available event for it.
ok(false, "The same target is notified multiple times via onAvailable");
}
is(
targetFront.targetType,
TargetList.TYPES.PROCESS,
TYPES.PROCESS,
"We are only notified about process targets"
);
is(targetFront, topLevelTarget, "This is the existing top level target");
@ -208,26 +198,25 @@ async function testContentProcessTarget(mainRoot) {
const onDestroyed = _ => {
ok(false, "onDestroyed should never be called in this test");
};
await targetList.watchTargets(
[TargetList.TYPES.PROCESS],
onAvailable,
onDestroyed
);
await targetList.watchTargets([TYPES.PROCESS], onAvailable, onDestroyed);
// This may fail if the top level target is reported by LegacyImplementation
// to TargetList and registers a duplicated entry
// to TargetCommand and registers a duplicated entry
is(targets.size, 1, "We were only notified about the top level target");
targetList.unwatchTargets([TYPES.PROCESS], onAvailable, onDestroyed);
targetList.destroy();
}
async function testThrowingInOnAvailable(mainRoot) {
info(
"Test TargetList watchTargets function when an exception is thrown in onAvailable callback"
"Test TargetCommand watchTargets function when an exception is thrown in onAvailable callback"
);
const targetDescriptor = await mainRoot.getMainProcess();
const targetList = new TargetList(targetDescriptor);
const commands = await targetDescriptor.getCommands();
const targetList = commands.targetCommand;
const { TYPES } = targetList;
await targetList.startListening();
@ -246,7 +235,7 @@ async function testThrowingInOnAvailable(mainRoot) {
}
targets.add(targetFront);
};
await targetList.watchTargets([TargetList.TYPES.PROCESS], onAvailable);
await targetList.watchTargets([TYPES.PROCESS], onAvailable);
is(
targets.size,
originalProcessesCount - 1,

View File

@ -5,8 +5,6 @@
// Test that watcher front/actor APIs do not lead to create duplicate actors.
const { TargetList } = require("devtools/shared/resources/target-list");
const TEST_URL = "data:text/html;charset=utf-8,Actor caching test";
add_task(async function() {
@ -16,7 +14,8 @@ add_task(async function() {
info("Create a target list for a tab target");
const descriptor = await client.mainRoot.getTab({ tab });
const targetList = new TargetList(descriptor);
const commands = await descriptor.getCommands();
const targetList = commands.targetCommand;
await targetList.startListening();
const { watcherFront } = targetList;

View File

@ -5,8 +5,6 @@
// Test the watcher's target-configuration actor API.
const { TargetList } = require("devtools/shared/resources/target-list");
add_task(async function() {
info("Setup the test page with workers of all types");
const client = await createLocalClient();
@ -15,7 +13,8 @@ add_task(async function() {
info("Create a target list for a tab target");
const descriptor = await mainRoot.getTab({ tab });
const targetList = new TargetList(descriptor);
const commands = await descriptor.getCommands();
const targetList = commands.targetCommand;
await targetList.startListening();
const { watcherFront } = targetList;

View File

@ -33,12 +33,12 @@ async function _initResourceWatcherFromDescriptor(
descriptor,
{ listenForWorkers = false } = {}
) {
const { TargetList } = require("devtools/shared/resources/target-list");
const {
ResourceWatcher,
} = require("devtools/shared/resources/resource-watcher");
const targetList = new TargetList(descriptor);
const commands = await descriptor.getCommands();
const targetList = commands.targetCommand;
if (listenForWorkers) {
targetList.listenForWorkers = true;
}

View File

@ -19,9 +19,9 @@ add_task(async function() {
const {
ResourceWatcher,
} = require("devtools/shared/resources/resource-watcher");
const { TargetList } = require("devtools/shared/resources/target-list");
const targetList = new TargetList(target.descriptorFront);
const commands = await target.descriptorFront.getCommands();
const targetList = commands.targetCommand;
await targetList.startListening();
const resourceWatcher = new ResourceWatcher(targetList);

View File

@ -121,9 +121,9 @@ async function createResourceWatcherForTab() {
const {
ResourceWatcher,
} = require("devtools/shared/resources/resource-watcher");
const { TargetList } = require("devtools/shared/resources/target-list");
const targetList = new TargetList(targetDescriptor);
const commands = await targetDescriptor.getCommands();
const targetList = commands.targetCommand;
await targetList.startListening();
const resourceWatcher = new ResourceWatcher(targetList);