mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 07:13:20 +00:00
Bug 1717724 - [devtools] Remove attachConsole sequence. r=nchevobbe
This is one step forward removing target attach sequence on the client side. So that we can notify about target front immediately from TargetCommand. I had to tweak TargetMixin destroy to avoid failures in browser_dbg_listtabs-01.js a call to targetFront.reconfigure was never resolving, because the target destroy was stuck on this call to detach(). We were trying to call detach() while the descriptor was destroyed (from a server side notification). The target being a child of descriptor it ends up destroy itself, but the request is meant to fail. Depends on D118585 Differential Revision: https://phabricator.services.mozilla.com/D118586
This commit is contained in:
parent
716014661a
commit
971e021dba
@ -20,8 +20,9 @@ add_task(async function() {
|
||||
const tabDescriptors = await mainRoot.listTabs();
|
||||
|
||||
await testGetTargetWithConcurrentCalls(tabDescriptors, tabTarget => {
|
||||
// Tab Target is attached when it has a console front.
|
||||
return !!tabTarget.getCachedFront("console");
|
||||
// We only call BrowsingContextTargetFront.attach and not TargetMixin.attachAndInitThread.
|
||||
// So very few things are done.
|
||||
return !!tabTarget.traits;
|
||||
});
|
||||
|
||||
await client.close();
|
||||
@ -40,8 +41,9 @@ add_task(async function() {
|
||||
// happens between the instantiation of ContentProcessTarget and its call to attach() from getTarget
|
||||
// function.
|
||||
await testGetTargetWithConcurrentCalls(processes, processTarget => {
|
||||
// Content Process Target is attached when it has a console front.
|
||||
return !!processTarget.getCachedFront("console");
|
||||
// We only call ContentProcessTargetFront.attach and not TargetMixin.attachAndInitThread.
|
||||
// So nothing is done for content process targets.
|
||||
return true;
|
||||
});
|
||||
|
||||
await client.close();
|
||||
|
@ -95,8 +95,7 @@ class WorkerDescriptorFront extends DescriptorMixin(
|
||||
|
||||
const workerTargetForm = await super.getTarget();
|
||||
|
||||
// Set the console actor ID on the form to expose it to Target.attachConsole
|
||||
// Set the ThreadActor on the target form so it is accessible by getFront
|
||||
// Set the console and thread actor IDs on the form so it is accessible by TargetMixin.getFront
|
||||
this.targetForm.consoleActor = workerTargetForm.consoleActor;
|
||||
this.targetForm.threadActor = workerTargetForm.threadActor;
|
||||
|
||||
@ -104,7 +103,6 @@ class WorkerDescriptorFront extends DescriptorMixin(
|
||||
return this;
|
||||
}
|
||||
|
||||
await this.attachConsole();
|
||||
return this;
|
||||
})();
|
||||
return this._attach;
|
||||
|
@ -44,11 +44,6 @@ class ContentProcessTargetFront extends TargetMixin(
|
||||
}
|
||||
|
||||
attach() {
|
||||
// All target actors have a console actor to attach.
|
||||
// All but xpcshell test actors... which is using a ContentProcessTargetActor
|
||||
if (this.targetForm.consoleActor) {
|
||||
return this.attachConsole();
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
|
@ -468,19 +468,6 @@ function TargetMixin(parentClass) {
|
||||
}
|
||||
}
|
||||
|
||||
// Attach the console actor
|
||||
async attachConsole() {
|
||||
const consoleFront = await this.getFront("console");
|
||||
|
||||
if (this.isDestroyedOrBeingDestroyed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Calling startListeners will populate the traits as it's the first request we
|
||||
// make to the front.
|
||||
await consoleFront.startListeners([]);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method attaches the target and then attaches its related thread, sending it
|
||||
* the options it needs (e.g. breakpoints, pause on exception setting, …).
|
||||
|
@ -125,12 +125,6 @@ class WindowGlobalTargetFront extends TargetMixin(
|
||||
// @backward-compat { version 93 } Remove this. All the traits are on form and can be accessed
|
||||
// using getTraits.
|
||||
this.traits = response.traits || {};
|
||||
|
||||
// xpcshell tests from devtools/server/tests/xpcshell/ are implementing
|
||||
// fake WindowGlobalTargetActor which do not expose any console actor.
|
||||
if (this.targetForm.consoleActor) {
|
||||
await this.attachConsole();
|
||||
}
|
||||
})();
|
||||
return this._attach;
|
||||
}
|
||||
|
@ -13,98 +13,68 @@ var { DevToolsClient } = require("devtools/client/devtools-client");
|
||||
const TAB1_URL = EXAMPLE_URL + "doc_empty-tab-01.html";
|
||||
const TAB2_URL = EXAMPLE_URL + "doc_empty-tab-02.html";
|
||||
|
||||
var gTab1, gTab1Front, gTab2, gTab2Front, gClient;
|
||||
|
||||
function test() {
|
||||
add_task(async function test() {
|
||||
DevToolsServer.init();
|
||||
DevToolsServer.registerAllActors();
|
||||
|
||||
const transport = DevToolsServer.connectPipe();
|
||||
gClient = new DevToolsClient(transport);
|
||||
gClient.connect().then(([aType, aTraits]) => {
|
||||
is(aType, "browser", "Root actor should identify itself as a browser.");
|
||||
const client = new DevToolsClient(transport);
|
||||
const [aType] = await client.connect();
|
||||
is(aType, "browser", "Root actor should identify itself as a browser.");
|
||||
|
||||
Promise.resolve(null)
|
||||
.then(testFirstTab)
|
||||
.then(testSecondTab)
|
||||
.then(testRemoveTab)
|
||||
.then(testAttachRemovedTab)
|
||||
.then(() => gClient.close())
|
||||
.then(finish)
|
||||
.catch(error => {
|
||||
ok(false, "Got an error: " + error.message + "\n" + error.stack);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testFirstTab() {
|
||||
return addTab(TAB1_URL).then(tab => {
|
||||
gTab1 = tab;
|
||||
|
||||
return getTargetActorForUrl(gClient, TAB1_URL).then(front => {
|
||||
ok(front, "Should find a target actor for the first tab.");
|
||||
gTab1Front = front;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testSecondTab() {
|
||||
return addTab(TAB2_URL).then(tab => {
|
||||
gTab2 = tab;
|
||||
|
||||
return getTargetActorForUrl(gClient, TAB1_URL).then(firstFront => {
|
||||
return getTargetActorForUrl(gClient, TAB2_URL).then(secondFront => {
|
||||
is(firstFront, gTab1Front, "First tab's actor shouldn't have changed.");
|
||||
ok(secondFront, "Should find a target actor for the second tab.");
|
||||
gTab2Front = secondFront;
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testRemoveTab() {
|
||||
return removeTab(gTab1).then(() => {
|
||||
return getTargetActorForUrl(gClient, TAB1_URL).then(front => {
|
||||
ok(!front, "Shouldn't find a target actor for the first tab anymore.");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testAttachRemovedTab() {
|
||||
return removeTab(gTab2).then(() => {
|
||||
return new Promise((resolve, reject) => {
|
||||
gClient.on("paused", () => {
|
||||
ok(
|
||||
false,
|
||||
"Attaching to an exited target actor shouldn't generate a pause."
|
||||
);
|
||||
reject();
|
||||
});
|
||||
|
||||
const { actorID } = gTab2Front;
|
||||
gTab2Front.reconfigure({}).then(null, error => {
|
||||
ok(
|
||||
error.message.includes(
|
||||
`Connection closed, pending request to ${actorID}, type reconfigure failed`
|
||||
),
|
||||
"Actor is gone since the tab was removed."
|
||||
);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab1 = null;
|
||||
gTab1Front = null;
|
||||
gTab2 = null;
|
||||
gTab2Front = null;
|
||||
gClient = null;
|
||||
const firstTab = await testFirstTab(client);
|
||||
const secondTab = await testSecondTab(client, firstTab.front);
|
||||
await testRemoveTab(client, firstTab.tab);
|
||||
await testAttachRemovedTab(secondTab.tab, secondTab.front);
|
||||
await client.close();
|
||||
});
|
||||
|
||||
async function getTargetActorForUrl(client, url) {
|
||||
async function testFirstTab(client) {
|
||||
const tab = await addTab(TAB1_URL);
|
||||
|
||||
const front = await getDescriptorActorForUrl(client, TAB1_URL);
|
||||
ok(front, "Should find a target actor for the first tab.");
|
||||
return { tab, front };
|
||||
}
|
||||
|
||||
async function testSecondTab(client, firstTabFront) {
|
||||
const tab = await addTab(TAB2_URL);
|
||||
|
||||
const firstFront = await getDescriptorActorForUrl(client, TAB1_URL);
|
||||
const secondFront = await getDescriptorActorForUrl(client, TAB2_URL);
|
||||
is(firstFront, firstTabFront, "First tab's actor shouldn't have changed.");
|
||||
ok(secondFront, "Should find a target actor for the second tab.");
|
||||
return { tab, front: secondFront };
|
||||
}
|
||||
|
||||
async function testRemoveTab(client, firstTab) {
|
||||
await removeTab(firstTab);
|
||||
const front = await getDescriptorActorForUrl(client, TAB1_URL);
|
||||
ok(!front, "Shouldn't find a target actor for the first tab anymore.");
|
||||
}
|
||||
|
||||
async function testAttachRemovedTab(secondTab, secondTabFront) {
|
||||
await removeTab(secondTab);
|
||||
|
||||
const { actorID } = secondTabFront;
|
||||
try {
|
||||
await secondTabFront.getFavicon({});
|
||||
ok(
|
||||
false,
|
||||
"any request made to the descriptor for a closed tab should have failed"
|
||||
);
|
||||
} catch (error) {
|
||||
ok(
|
||||
error.message.includes(
|
||||
`Connection closed, pending request to ${actorID}, type getFavicon failed`
|
||||
),
|
||||
"Actor is gone since the tab was removed."
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async function getDescriptorActorForUrl(client, url) {
|
||||
const tabDescriptors = await client.mainRoot.listTabs();
|
||||
const tabDescriptor = tabDescriptors.find(front => front.url == url);
|
||||
return tabDescriptor?.getTarget();
|
||||
return tabDescriptor;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user