summaryrefslogtreecommitdiffstats
path: root/dom/base/test/chrome/test_chromeOuterWindowID.xhtml
blob: 3aa482b636833036933952ceec0f8e04ffe319ed (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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1474662
Test that the chromeOuterWindowID on the MessageManager interface
works, and that it properly updates when swapping frameloaders between
windows.
-->
<window title="Mozilla Bug 1474662"
        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
  <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>

  <!-- test results are displayed in the html:body -->
  <body xmlns="http://www.w3.org/1999/xhtml">
  <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1474662"
     target="_blank">Mozilla Bug 1474662</a>
  </body>

  <!-- test code goes here -->
  <script type="application/javascript"><![CDATA[
  SimpleTest.waitForExplicitFinish();
  const {BrowserTestUtils} = ChromeUtils.importESModule(
    "resource://testing-common/BrowserTestUtils.sys.mjs"
  );

  const BROWSER_DOC = "window_chromeOuterWindowID.xhtml";
  const TEST_PAGE = "http://example.com";
  const TEST_PAGE_2 = "http://example.com/browser";

  function getOuterWindowID(win) {
    return win.docShell.outerWindowID;
  }

  /**
   * Takes two <xul:browser>'s that should be in the same document, and
   * ensures that their frame script environments know the correct value
   * of the host window's outerWindowID.
   */
  async function ensureExpectedChromeOuterWindowIDs(browser1, browser2) {
    is(browser1.ownerDocument, browser2.ownerDocument,
       "Both browsers should belong to the same document.");
    let winID = getOuterWindowID(browser1.ownerGlobal);

    let getChildRootOuterId = () => { 
      try {
        return docShell.browserChild?.chromeOuterWindowID;
      } catch(ex) { }

      // Not a remote tab
      return content.top.windowRoot.ownerGlobal.docShell.outerWindowID;
    };

    let browser1ID = await SpecialPowers.spawn(browser1, [], getChildRootOuterId);
    let browser2ID = await SpecialPowers.spawn(browser2, [], getChildRootOuterId);

    is(browser1ID, winID,
       "Browser 1 frame script environment should have the correct chromeOuterWindowID");
    is(browser2ID, winID,
       "Browser 1 frame script environment should have the correct chromeOuterWindowID");
  }

  /**
   * Opens up a BROWSER_DOC test window, and points each browser to a particular
   * page.
   *
   * @param num (Number)
   *        An identifier number for this window. Mainly used as a suffix for the
   *        returned values.
   * @param page (String)
   *        A URL to load in each <xul:browser>
   * @returns Promise
   *        The Promise resolves with an object with the following properties:
   *
   *        win<num>: a reference to the opened window
   *        remote<num>: a reference to the remote browser in the window
   *        nonRemote<num>: a reference to the non-remote browser in the window
   */
  async function prepareWindow(num, page) {
    let win = window.browsingContext.topChromeWindow.open(BROWSER_DOC, "bug1474662-" + num, "chrome,width=200,height=200");
    await BrowserTestUtils.waitForEvent(win, "load");
    let remote = win.document.getElementById("remote");
    let nonRemote = win.document.getElementById("non-remote");

    ok(remote && remote.isRemoteBrowser,
       "Should have found a remote browser in test window " + num);
    ok(nonRemote && !nonRemote.isRemoteBrowser,
       "Should have found a non-remote browser in test window " + num);

    BrowserTestUtils.startLoadingURIString(remote, page);
    await BrowserTestUtils.browserLoaded(remote);
    BrowserTestUtils.startLoadingURIString(nonRemote, page);
    await BrowserTestUtils.browserLoaded(nonRemote);

    let result = {};
    result["win" + num] = win;
    result["remote" + num] = remote;
    result["nonRemote" + num] = nonRemote;
    return result;
  }

  add_task(async () => {
    let { win1, remote1, nonRemote1 } = await prepareWindow(1, TEST_PAGE);
    let { win2, remote2, nonRemote2 } = await prepareWindow(2, TEST_PAGE_2);

    let win1ID = getOuterWindowID(win1);
    let win2ID = getOuterWindowID(win2);

    // Quick sanity-test here - if something has gone horribly wrong
    // and the windows have the same IDs, then the rest of this test
    // is meaningless.
    isnot(win1ID, win2ID,
          "The windows should definitely have different IDs.");

    await ensureExpectedChromeOuterWindowIDs(remote1, nonRemote1);
    await ensureExpectedChromeOuterWindowIDs(remote2, nonRemote2);

    // Swap the frameloaders! This doesn't swap the <browser> elements though,
    // so what's expected is that the IDs should remain the same within
    // the browsers despite the underlying content changing.
    remote1.swapFrameLoaders(remote2);
    nonRemote1.swapFrameLoaders(nonRemote2);

    await ensureExpectedChromeOuterWindowIDs(remote1, nonRemote1);
    await ensureExpectedChromeOuterWindowIDs(remote2, nonRemote2);

    // Now swap them back.
    remote1.swapFrameLoaders(remote2);
    nonRemote1.swapFrameLoaders(nonRemote2);

    await ensureExpectedChromeOuterWindowIDs(remote1, nonRemote1);
    await ensureExpectedChromeOuterWindowIDs(remote2, nonRemote2);

    await BrowserTestUtils.closeWindow(win1);
    await BrowserTestUtils.closeWindow(win2);
  });
  ]]></script>
</window>