forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			149 lines
		
	
	
	
		
			5.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			149 lines
		
	
	
	
		
			5.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
/* Any copyright is dedicated to the Public Domain.
 | 
						|
   http://creativecommons.org/publicdomain/zero/1.0/ */
 | 
						|
 | 
						|
"use strict";
 | 
						|
 | 
						|
const ACTOR_NAME = "TopLevelNavigationDelegate";
 | 
						|
const ACTOR_MODULE_URI =
 | 
						|
  getRootDirectory(gTestPath) + "TestTopLevelNavigationDelegate.jsm";
 | 
						|
const IFRAME_PAGE =
 | 
						|
  getRootDirectory(gTestPath).replace(
 | 
						|
    "chrome://mochitests/content",
 | 
						|
    "http://example.com"
 | 
						|
  ) + "dummy_iframe_page.html";
 | 
						|
 | 
						|
/**
 | 
						|
 * Tests that when browser navigates to uriString, that the
 | 
						|
 * TopLevelNavigationDelegateChild detects it, prevents the navigation,
 | 
						|
 * and that the TopLevelNavigationDelegateParent is notified
 | 
						|
 * about the navigation attempt.
 | 
						|
 *
 | 
						|
 * @param {Element} browser The <xul:browser> to attempt the navigation with.
 | 
						|
 * @param {String} uriString The URI to navigate browser to.
 | 
						|
 * @return {Promise}
 | 
						|
 * @resolves {undefined} Once the delegation has been detected.
 | 
						|
 */
 | 
						|
async function doesDelegateFor(browser, uriString) {
 | 
						|
  let delegatePromise = BrowserTestUtils.waitForContentEvent(
 | 
						|
    browser,
 | 
						|
    "TopLevelNavigationDelegateEvent",
 | 
						|
    false,
 | 
						|
    null,
 | 
						|
    true
 | 
						|
  );
 | 
						|
  BrowserTestUtils.loadURI(browser, uriString);
 | 
						|
  await delegatePromise;
 | 
						|
  Assert.ok(true, `Delegated navigation for ${uriString}`);
 | 
						|
  let parentActor = browser.browsingContext.currentWindowGlobal.getActor(
 | 
						|
    ACTOR_NAME
 | 
						|
  );
 | 
						|
  Assert.equal(
 | 
						|
    parentActor.seenURIStrings.shift(),
 | 
						|
    uriString,
 | 
						|
    "TopLevelNavigationDelegateParent saw the load attempt."
 | 
						|
  );
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Tests that when browser navigates to uriString, that the
 | 
						|
 * TopLevelNavigationDelegateChild does not prevent the navigation,
 | 
						|
 * and that the load event properly fires after reaching the new
 | 
						|
 * location.
 | 
						|
 *
 | 
						|
 * @param {Element} browser The <xul:browser> to attempt the navigation with.
 | 
						|
 * @param {String} uriString The URI to navigate browser to.
 | 
						|
 * @param {Boolean} hashChange The URI to navigate to is a same-document fragment
 | 
						|
 *   navigation.
 | 
						|
 * @return {Promise}
 | 
						|
 * @resolves {undefined} Once the successful load has been detected.
 | 
						|
 */
 | 
						|
async function doesNotDelegateFor(browser, uriString, hashChange = false) {
 | 
						|
  let loaded = hashChange
 | 
						|
    ? BrowserTestUtils.waitForContentEvent(browser, "hashchange", true)
 | 
						|
    : BrowserTestUtils.browserLoaded(browser, false, uriString);
 | 
						|
  BrowserTestUtils.loadURI(browser, uriString);
 | 
						|
  await loaded;
 | 
						|
  Assert.ok(true, `Successfully navigated to ${uriString}`);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Registers a test nsITopLevelNavigationDelegate JSWindowActorChild that
 | 
						|
 * stops attempts to reach example.org on top-level BrowsingContexts, and
 | 
						|
 * then ensures that example.org sites cannot be loaded, but example.com
 | 
						|
 * sites can. Also tests that iframes can load both example.org and
 | 
						|
 * example.com sites successfully. Finally, unregisters the
 | 
						|
 * JSWindowActorChild and ensures that top-level example.org navigations
 | 
						|
 * are no longer prevented.
 | 
						|
 */
 | 
						|
add_task(async function() {
 | 
						|
  await SpecialPowers.pushPrefEnv({
 | 
						|
    set: [["dom.security.https_first", false]],
 | 
						|
  });
 | 
						|
  await BrowserTestUtils.withNewTab("http://example.com", async browser => {
 | 
						|
    ChromeUtils.registerWindowActor(ACTOR_NAME, {
 | 
						|
      child: {
 | 
						|
        moduleURI: ACTOR_MODULE_URI,
 | 
						|
      },
 | 
						|
      parent: {
 | 
						|
        moduleURI: ACTOR_MODULE_URI,
 | 
						|
      },
 | 
						|
      messageManagerGroups: ["browsers"],
 | 
						|
    });
 | 
						|
 | 
						|
    // This is normally done towards the end of the test, but just in case that
 | 
						|
    // task exits early for some reason, we unregister the JSWindowActorChild
 | 
						|
    // to ensure we don't contaminate other tests. Doing this when the
 | 
						|
    // JSWindowActorChild is already unregistered is a no-op.
 | 
						|
    registerCleanupFunction(() => {
 | 
						|
      ChromeUtils.unregisterWindowActor(ACTOR_NAME);
 | 
						|
    });
 | 
						|
 | 
						|
    await doesDelegateFor(browser, "http://example.org/");
 | 
						|
    await doesDelegateFor(browser, "http://example.org/2");
 | 
						|
    // We still want to delegate for a fragment navigation when we're
 | 
						|
    // transitioning from example.com to example.org, and is not a
 | 
						|
    // same document navigation.
 | 
						|
    await doesDelegateFor(browser, "http://example.org/2#test");
 | 
						|
 | 
						|
    await doesNotDelegateFor(browser, "https://example.com/");
 | 
						|
    await doesNotDelegateFor(
 | 
						|
      browser,
 | 
						|
      "https://example.com/#test",
 | 
						|
      true /* hashChange */
 | 
						|
    );
 | 
						|
    await doesNotDelegateFor(browser, "http://example.com/2");
 | 
						|
    await doesNotDelegateFor(browser, "https://example.com/3");
 | 
						|
 | 
						|
    await doesNotDelegateFor(browser, IFRAME_PAGE);
 | 
						|
 | 
						|
    // Now check that iframes don't qualify for delegation
 | 
						|
    await SpecialPowers.spawn(browser, [], async () => {
 | 
						|
      let iframe1 = content.document.getElementById("frame1");
 | 
						|
      iframe1.remove();
 | 
						|
      iframe1.src = "http://example.com";
 | 
						|
      let load1 = ContentTaskUtils.waitForEvent(iframe1, "load");
 | 
						|
      content.document.body.appendChild(iframe1);
 | 
						|
      await load1;
 | 
						|
 | 
						|
      let iframe2 = content.document.getElementById("frame2");
 | 
						|
      iframe2.remove();
 | 
						|
      iframe2.src = "http://example.org";
 | 
						|
      let load2 = ContentTaskUtils.waitForEvent(iframe2, "load");
 | 
						|
      content.document.body.appendChild(iframe2);
 | 
						|
      await load2;
 | 
						|
    });
 | 
						|
 | 
						|
    ChromeUtils.unregisterWindowActor(ACTOR_NAME);
 | 
						|
 | 
						|
    await doesNotDelegateFor(browser, "http://example.org/2");
 | 
						|
    await doesNotDelegateFor(browser, "https://example.org/3");
 | 
						|
    await doesNotDelegateFor(browser, "https://example.org/");
 | 
						|
    // We expect a same-document fragment navigation to succeed
 | 
						|
    // on example.org now.
 | 
						|
    await doesNotDelegateFor(
 | 
						|
      browser,
 | 
						|
      "https://example.org/#test",
 | 
						|
      true /* hashChange */
 | 
						|
    );
 | 
						|
  });
 | 
						|
});
 |