146 lines
4.4 KiB
JavaScript
146 lines
4.4 KiB
JavaScript
/* Any copyright is dedicated to the Public Domain.
|
|
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
|
|
/**
|
|
* Test `connectToFrame` method
|
|
*/
|
|
|
|
"use strict";
|
|
|
|
const {
|
|
connectToFrame,
|
|
} = require("resource://devtools/server/connectors/frame-connector.js");
|
|
|
|
add_task(async function () {
|
|
// Create a minimal browser with a message manager
|
|
const browser = document.createXULElement("browser");
|
|
browser.setAttribute("type", "content");
|
|
document.body.appendChild(browser);
|
|
|
|
await TestUtils.waitForCondition(
|
|
() => browser.browsingContext.currentWindowGlobal,
|
|
"browser has no window global"
|
|
);
|
|
|
|
// Register a test actor in the child process so that we can know if and when
|
|
// this fake actor is destroyed.
|
|
await SpecialPowers.spawn(browser, [], () => {
|
|
const { require } = ChromeUtils.importESModule(
|
|
"resource://devtools/shared/loader/Loader.sys.mjs"
|
|
);
|
|
const {
|
|
DevToolsServer,
|
|
} = require("resource://devtools/server/devtools-server.js");
|
|
const {
|
|
ActorRegistry,
|
|
} = require("resource://devtools/server/actors/utils/actor-registry.js");
|
|
|
|
DevToolsServer.init();
|
|
|
|
const { Actor } = require("resource://devtools/shared/protocol/Actor.js");
|
|
class ConnectToFrameTestActor extends Actor {
|
|
constructor(conn) {
|
|
super(conn, { typeName: "connectToFrameTest", methods: [] });
|
|
dump("instantiate test actor\n");
|
|
this.requestTypes = {
|
|
hello: this.hello,
|
|
};
|
|
}
|
|
hello() {
|
|
return { msg: "world" };
|
|
}
|
|
|
|
destroy() {
|
|
SpecialPowers.notifyObserversInParentProcess(
|
|
null,
|
|
"devtools-test-actor-destroyed",
|
|
""
|
|
);
|
|
}
|
|
}
|
|
|
|
ActorRegistry.addTargetScopedActor(
|
|
{
|
|
constructorName: "ConnectToFrameTestActor",
|
|
constructorFun: ConnectToFrameTestActor,
|
|
},
|
|
"connectToFrameTestActor"
|
|
);
|
|
});
|
|
|
|
// Instantiate a minimal server
|
|
DevToolsServer.init();
|
|
if (!DevToolsServer.createRootActor) {
|
|
DevToolsServer.registerAllActors();
|
|
}
|
|
|
|
async function initAndCloseFirstClient() {
|
|
// Fake a first connection to a browser
|
|
const transport = DevToolsServer.connectPipe();
|
|
const conn = transport._serverConnection;
|
|
const client = new DevToolsClient(transport);
|
|
// We aren't calling DevtoolsClient.connect, but still need to wait for the client to be connected
|
|
await client.once("connected");
|
|
const actor = await connectToFrame(conn, browser);
|
|
ok(actor.connectToFrameTestActor, "Got the test actor");
|
|
|
|
// Ensure sending at least one request to our actor,
|
|
// otherwise it won't be instantiated, nor be destroyed...
|
|
await client.request({
|
|
to: actor.connectToFrameTestActor,
|
|
type: "hello",
|
|
});
|
|
|
|
// Connect a second client in parallel to assert that it received a distinct set of
|
|
// target actors
|
|
await initAndCloseSecondClient(actor.connectToFrameTestActor);
|
|
|
|
ok(
|
|
DevToolsServer.initialized,
|
|
"DevToolsServer isn't destroyed until all clients are disconnected"
|
|
);
|
|
|
|
// Ensure that our test actor got cleaned up;
|
|
// its destroy method should be called
|
|
const onActorDestroyed = TestUtils.topicObserved(
|
|
"devtools-test-actor-destroyed"
|
|
);
|
|
|
|
// Then close the client. That should end up cleaning our test actor
|
|
await client.close();
|
|
|
|
await onActorDestroyed;
|
|
|
|
// This test loads a frame in the parent process, so that we end up sharing the same
|
|
// DevToolsServer instance
|
|
ok(
|
|
!DevToolsServer.initialized,
|
|
"DevToolsServer is destroyed when all clients are disconnected"
|
|
);
|
|
}
|
|
|
|
async function initAndCloseSecondClient(firstActor) {
|
|
// Then fake a second one, that should spawn a new set of target-scoped actors
|
|
const transport = DevToolsServer.connectPipe();
|
|
const conn = transport._serverConnection;
|
|
const client = new DevToolsClient(transport);
|
|
// We aren't calling DevtoolsClient.connect, but still need to wait for the client to be connected
|
|
await client.once("connected");
|
|
const actor = await connectToFrame(conn, browser);
|
|
ok(
|
|
actor.connectToFrameTestActor,
|
|
"Got a test actor for the second connection"
|
|
);
|
|
isnot(
|
|
actor.connectToFrameTestActor,
|
|
firstActor,
|
|
"We get different actor instances between two connections"
|
|
);
|
|
return client.close();
|
|
}
|
|
|
|
await initAndCloseFirstClient();
|
|
|
|
DevToolsServer.destroy();
|
|
browser.remove();
|
|
});
|