Source code
Revision control
Copy as Markdown
Other Tools
Test Info:
- Manifest: dom/base/test/chrome/chrome.toml
<?xml version="1.0"?>
<!--
Test that the chromeOuterWindowID on the MessageManager interface
works, and that it properly updates when swapping frameloaders between
windows.
-->
  <!-- test results are displayed in the html:body -->
  </body>
  <!-- test code goes here -->
  <script type="application/javascript"><![CDATA[
  SimpleTest.waitForExplicitFinish();
  const {BrowserTestUtils} = ChromeUtils.importESModule(
  );
  const BROWSER_DOC = "window_chromeOuterWindowID.xhtml";
  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>