summaryrefslogtreecommitdiffstats
path: root/remote/shared/messagehandler/test/browser/browser_bfcache.js
blob: f829d8b58d79c2d38738118c64ba30dc686910ce (plain)
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
/* Any copyright is dedicated to the Public Domain.
 * http://creativecommons.org/publicdomain/zero/1.0/ */

"use strict";

const { RootMessageHandler } = ChromeUtils.importESModule(
  "chrome://remote/content/shared/messagehandler/RootMessageHandler.sys.mjs"
);

const TEST_PREF = "remote.messagehandler.test.pref";

// Check that pages in bfcache no longer have message handlers attached to them,
// and that they will not emit unexpected events.
add_task(async function test_bfcache_broadcast() {
  const tab = await addTab("https://example.com/document-builder.sjs?html=tab");
  const rootMessageHandler = createRootMessageHandler("session-id-bfcache");

  try {
    const browsingContext = tab.linkedBrowser.browsingContext;
    const contextDescriptor = {
      type: ContextDescriptorType.TopBrowsingContext,
      id: browsingContext.browserId,
    };

    // Whenever a "preference-changed" event from the eventonprefchange module
    // will be received on the root MessageHandler, increment a counter.
    let preferenceChangeEventCount = 0;
    const onEvent = (evtName, wrappedEvt) => {
      if (wrappedEvt.name === "preference-changed") {
        preferenceChangeEventCount++;
      }
    };
    rootMessageHandler.on("message-handler-event", onEvent);

    // Initialize the preference, no eventonprefchange module should be created
    // yet so preferenceChangeEventCount is not expected to be updated.
    Services.prefs.setIntPref(TEST_PREF, 0);
    await TestUtils.waitForCondition(() => preferenceChangeEventCount >= 0);
    is(preferenceChangeEventCount, 0);

    // Broadcast a "ping" command to force the creation of the eventonprefchange
    // module
    let values = await sendPingCommand(rootMessageHandler, contextDescriptor);
    is(values.length, 1, "Broadcast returned a single value");

    Services.prefs.setIntPref(TEST_PREF, 1);
    await TestUtils.waitForCondition(() => preferenceChangeEventCount >= 1);
    is(preferenceChangeEventCount, 1);

    info("Navigate to another page");
    await loadURL(
      tab.linkedBrowser,
      "https://example.com/document-builder.sjs?html=othertab"
    );

    values = await sendPingCommand(rootMessageHandler, contextDescriptor);
    is(values.length, 1, "Broadcast returned a single value after navigation");

    info("Update the preference and check we only receive 1 event");
    Services.prefs.setIntPref(TEST_PREF, 2);
    await TestUtils.waitForCondition(() => preferenceChangeEventCount >= 2);
    is(preferenceChangeEventCount, 2);

    info("Navigate to another origin");
    await loadURL(
      tab.linkedBrowser,
      "https://example.org/document-builder.sjs?html=otherorigin"
    );

    values = await sendPingCommand(rootMessageHandler, contextDescriptor);
    is(
      values.length,
      1,
      "Broadcast returned a single value after cross origin navigation"
    );

    info("Update the preference and check again that we only receive 1 event");
    Services.prefs.setIntPref(TEST_PREF, 3);
    await TestUtils.waitForCondition(() => preferenceChangeEventCount >= 3);
    is(preferenceChangeEventCount, 3);
  } finally {
    rootMessageHandler.destroy();
    gBrowser.removeTab(tab);
    Services.prefs.clearUserPref(TEST_PREF);
  }
});

function sendPingCommand(rootMessageHandler, contextDescriptor) {
  return rootMessageHandler.handleCommand({
    moduleName: "eventonprefchange",
    commandName: "ping",
    params: {},
    destination: {
      contextDescriptor,
      type: WindowGlobalMessageHandler.type,
    },
  });
}