1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
const { MessageManagerProxy } = ChromeUtils.importESModule(
"resource://gre/modules/MessageManagerProxy.sys.mjs"
);
const { PromiseUtils } = ChromeUtils.importESModule(
"resource://gre/modules/PromiseUtils.sys.mjs"
);
class TestMessageManagerProxy extends MessageManagerProxy {
constructor(contentPage, identifier) {
super(contentPage.browser);
this.identifier = identifier;
this.contentPage = contentPage;
this.deferred = null;
}
// Registers message listeners. Call dispose() once you've finished.
async setupPingPongListeners() {
await this.contentPage.loadFrameScript(`() => {
this.addMessageListener("test:MessageManagerProxy:Ping", ({data}) => {
this.sendAsyncMessage("test:MessageManagerProxy:Pong", "${this.identifier}:" + data);
});
}`);
// Register the listener here instead of during testPingPong, to make sure
// that the listener is correctly registered during the whole test.
this.addMessageListener("test:MessageManagerProxy:Pong", event => {
ok(
this.deferred,
`[${this.identifier}] expected to be waiting for ping-pong`
);
this.deferred.resolve(event.data);
this.deferred = null;
});
}
async testPingPong(description) {
equal(this.deferred, null, "should not be waiting for a message");
this.deferred = PromiseUtils.defer();
this.sendAsyncMessage("test:MessageManagerProxy:Ping", description);
let result = await this.deferred.promise;
equal(result, `${this.identifier}:${description}`, "Expected ping-pong");
}
}
// Tests that MessageManagerProxy continues to proxy messages after docshells
// have been swapped.
add_task(async function test_message_after_swapdocshells() {
let page1 = await ExtensionTestUtils.loadContentPage("about:blank");
let page2 = await ExtensionTestUtils.loadContentPage("about:blank");
let testProxyOne = new TestMessageManagerProxy(page1, "page1");
let testProxyTwo = new TestMessageManagerProxy(page2, "page2");
await testProxyOne.setupPingPongListeners();
await testProxyTwo.setupPingPongListeners();
await testProxyOne.testPingPong("after setup (to 1)");
await testProxyTwo.testPingPong("after setup (to 2)");
page1.browser.swapDocShells(page2.browser);
await testProxyOne.testPingPong("after docshell swap (to 1)");
await testProxyTwo.testPingPong("after docshell swap (to 2)");
// Swap again to verify that listeners are repeatedly moved when needed.
page1.browser.swapDocShells(page2.browser);
await testProxyOne.testPingPong("after another docshell swap (to 1)");
await testProxyTwo.testPingPong("after another docshell swap (to 2)");
// Verify that dispose() works regardless of the browser's validity.
await testProxyOne.dispose();
await page1.close();
await page2.close();
await testProxyTwo.dispose();
});
|