diff options
Diffstat (limited to 'browser/base/content/test/referrer')
16 files changed, 949 insertions, 0 deletions
diff --git a/browser/base/content/test/referrer/browser.ini b/browser/base/content/test/referrer/browser.ini new file mode 100644 index 0000000000..12a90659c7 --- /dev/null +++ b/browser/base/content/test/referrer/browser.ini @@ -0,0 +1,35 @@ +[DEFAULT] +support-files = + file_referrer_policyserver.sjs + file_referrer_policyserver_attr.sjs + file_referrer_testserver.sjs + head.js + +[browser_referrer_middle_click.js] +https_first_disabled = true +[browser_referrer_middle_click_in_container.js] +https_first_disabled = true +[browser_referrer_open_link_in_private.js] +skip-if = os == 'linux' # Bug 1145199 +[browser_referrer_open_link_in_tab.js] +https_first_disabled = true +skip-if = + os == 'linux' # Bug 1144816 +[browser_referrer_open_link_in_window.js] +https_first_disabled = true +skip-if = os == 'linux' # Bug 1145199 +[browser_referrer_open_link_in_window_in_container.js] +https_first_disabled = true +skip-if = os == 'linux' # Bug 1145199 +[browser_referrer_simple_click.js] +https_first_disabled = true +[browser_referrer_click_pinned_tab.js] +https_first_disabled = true +[browser_referrer_open_link_in_container_tab.js] +skip-if = os == 'linux' # Bug 1144816 +[browser_referrer_open_link_in_container_tab2.js] +https_first_disabled = true +skip-if = + os == 'linux' # Bug 1144816 +[browser_referrer_open_link_in_container_tab3.js] +skip-if = os == 'linux' # Bug 1144816 diff --git a/browser/base/content/test/referrer/browser_referrer_click_pinned_tab.js b/browser/base/content/test/referrer/browser_referrer_click_pinned_tab.js new file mode 100644 index 0000000000..876f79bf02 --- /dev/null +++ b/browser/base/content/test/referrer/browser_referrer_click_pinned_tab.js @@ -0,0 +1,75 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// We will open a new tab if clicking on a cross domain link in pinned tab +// So, override the tests data in head.js, adding "cross: true". + +_referrerTests = [ + { + fromScheme: "http://", + toScheme: "http://", + cross: true, + result: "http://test1.example.com/", // origin + }, + { + fromScheme: "https://", + toScheme: "http://", + cross: true, + result: "", // no referrer when downgrade + }, + { + fromScheme: "https://", + toScheme: "http://", + policy: "origin", + cross: true, + result: "https://test1.example.com/", // origin, even on downgrade + }, + { + fromScheme: "https://", + toScheme: "http://", + policy: "origin", + rel: "noreferrer", + cross: true, + result: "", // rel=noreferrer trumps meta-referrer + }, + { + fromScheme: "https://", + toScheme: "https://", + policy: "no-referrer", + cross: true, + result: "", // same origin https://test1.example.com/browser + }, + { + fromScheme: "http://", + toScheme: "https://", + policy: "no-referrer", + cross: true, + result: "", // cross origin http://test1.example.com + }, +]; + +async function startClickPinnedTabTestCase(aTestNumber) { + info( + "browser_referrer_click_pinned_tab: " + + getReferrerTestDescription(aTestNumber) + ); + let browser = gTestWindow.gBrowser; + + browser.pinTab(browser.selectedTab); + someTabLoaded(gTestWindow).then(function(aNewTab) { + checkReferrerAndStartNextTest( + aTestNumber, + null, + aNewTab, + startClickPinnedTabTestCase + ); + }); + + clickTheLink(gTestWindow, "testlink", {}); +} + +function test() { + requestLongerTimeout(10); // slowwww shutdown on e10s + startReferrerTest(startClickPinnedTabTestCase); +} diff --git a/browser/base/content/test/referrer/browser_referrer_middle_click.js b/browser/base/content/test/referrer/browser_referrer_middle_click.js new file mode 100644 index 0000000000..f4d3cbc7ca --- /dev/null +++ b/browser/base/content/test/referrer/browser_referrer_middle_click.js @@ -0,0 +1,25 @@ +// Tests referrer on middle-click navigation. +// Middle-clicks on the link, which opens it in a new tab. + +function startMiddleClickTestCase(aTestNumber) { + info( + "browser_referrer_middle_click: " + getReferrerTestDescription(aTestNumber) + ); + someTabLoaded(gTestWindow).then(function(aNewTab) { + BrowserTestUtils.switchTab(gTestWindow.gBrowser, aNewTab).then(() => { + checkReferrerAndStartNextTest( + aTestNumber, + null, + aNewTab, + startMiddleClickTestCase + ); + }); + }); + + clickTheLink(gTestWindow, "testlink", { button: 1 }); +} + +function test() { + requestLongerTimeout(10); // slowwww shutdown on e10s + startReferrerTest(startMiddleClickTestCase); +} diff --git a/browser/base/content/test/referrer/browser_referrer_middle_click_in_container.js b/browser/base/content/test/referrer/browser_referrer_middle_click_in_container.js new file mode 100644 index 0000000000..69a9f6a393 --- /dev/null +++ b/browser/base/content/test/referrer/browser_referrer_middle_click_in_container.js @@ -0,0 +1,33 @@ +// Tests referrer on middle-click navigation. +// Middle-clicks on the link, which opens it in a new tab, same container. + +function startMiddleClickTestCase(aTestNumber) { + info( + "browser_referrer_middle_click: " + getReferrerTestDescription(aTestNumber) + ); + someTabLoaded(gTestWindow).then(function(aNewTab) { + BrowserTestUtils.switchTab(gTestWindow.gBrowser, aNewTab).then(() => { + checkReferrerAndStartNextTest( + aTestNumber, + null, + aNewTab, + startMiddleClickTestCase, + { userContextId: 3 } + ); + }); + }); + + clickTheLink(gTestWindow, "testlink", { button: 1 }); +} + +function test() { + waitForExplicitFinish(); + + SpecialPowers.pushPrefEnv( + { set: [["privacy.userContext.enabled", true]] }, + function() { + requestLongerTimeout(10); // slowwww shutdown on e10s + startReferrerTest(startMiddleClickTestCase, { userContextId: 3 }); + } + ); +} diff --git a/browser/base/content/test/referrer/browser_referrer_open_link_in_container_tab.js b/browser/base/content/test/referrer/browser_referrer_open_link_in_container_tab.js new file mode 100644 index 0000000000..fcea8fb501 --- /dev/null +++ b/browser/base/content/test/referrer/browser_referrer_open_link_in_container_tab.js @@ -0,0 +1,80 @@ +// Tests referrer on context menu navigation - open link in new container tab. +// Selects "open link in new container tab" from the context menu. + +function getReferrerTest(aTestNumber) { + let testCase = _referrerTests[aTestNumber]; + if (testCase) { + // We want all the referrer tests to fail! + testCase.result = ""; + } + + return testCase; +} + +function startNewTabTestCase(aTestNumber) { + info( + "browser_referrer_open_link_in_container_tab: " + + getReferrerTestDescription(aTestNumber) + ); + contextMenuOpened(gTestWindow, "testlink").then(function(aContextMenu) { + someTabLoaded(gTestWindow).then(function(aNewTab) { + gTestWindow.gBrowser.selectedTab = aNewTab; + + checkReferrerAndStartNextTest( + aTestNumber, + null, + aNewTab, + startNewTabTestCase + ); + }); + + let menu = gTestWindow.document.getElementById( + "context-openlinkinusercontext-menu" + ); + + let menupopup = menu.menupopup; + menu.addEventListener( + "popupshown", + function() { + is(menupopup.nodeType, Node.ELEMENT_NODE, "We have a menupopup."); + ok(menupopup.firstElementChild, "We have a first container entry."); + + let firstContext = menupopup.firstElementChild; + is( + firstContext.nodeType, + Node.ELEMENT_NODE, + "We have a first container entry." + ); + ok( + firstContext.hasAttribute("data-usercontextid"), + "We have a usercontextid value." + ); + + aContextMenu.addEventListener( + "popuphidden", + function() { + firstContext.doCommand(); + }, + { once: true } + ); + + aContextMenu.hidePopup(); + }, + { once: true } + ); + + menu.openMenu(true); + }); +} + +function test() { + waitForExplicitFinish(); + + SpecialPowers.pushPrefEnv( + { set: [["privacy.userContext.enabled", true]] }, + function() { + requestLongerTimeout(10); // slowwww shutdown on e10s + startReferrerTest(startNewTabTestCase); + } + ); +} diff --git a/browser/base/content/test/referrer/browser_referrer_open_link_in_container_tab2.js b/browser/base/content/test/referrer/browser_referrer_open_link_in_container_tab2.js new file mode 100644 index 0000000000..853e532739 --- /dev/null +++ b/browser/base/content/test/referrer/browser_referrer_open_link_in_container_tab2.js @@ -0,0 +1,43 @@ +// Tests referrer on context menu navigation - open link in new container tab. +// Selects "open link in new container tab" from the context menu. + +// The test runs from a container ID 1. +// Output: we have the correct referrer policy applied. + +function startNewTabTestCase(aTestNumber) { + info( + "browser_referrer_open_link_in_container_tab: " + + getReferrerTestDescription(aTestNumber) + ); + contextMenuOpened(gTestWindow, "testlink").then(function(aContextMenu) { + someTabLoaded(gTestWindow).then(function(aNewTab) { + gTestWindow.gBrowser.selectedTab = aNewTab; + + checkReferrerAndStartNextTest( + aTestNumber, + null, + aNewTab, + startNewTabTestCase, + { userContextId: 1 } + ); + }); + + doContextMenuCommand( + gTestWindow, + aContextMenu, + "context-openlinkincontainertab" + ); + }); +} + +function test() { + waitForExplicitFinish(); + + SpecialPowers.pushPrefEnv( + { set: [["privacy.userContext.enabled", true]] }, + function() { + requestLongerTimeout(10); // slowwww shutdown on e10s + startReferrerTest(startNewTabTestCase, { userContextId: 1 }); + } + ); +} diff --git a/browser/base/content/test/referrer/browser_referrer_open_link_in_container_tab3.js b/browser/base/content/test/referrer/browser_referrer_open_link_in_container_tab3.js new file mode 100644 index 0000000000..d200b0edf9 --- /dev/null +++ b/browser/base/content/test/referrer/browser_referrer_open_link_in_container_tab3.js @@ -0,0 +1,81 @@ +// Tests referrer on context menu navigation - open link in new container tab. +// Selects "open link in new container tab" from the context menu. + +// The test runs from a container ID 2. +// Output: we have no referrer. + +getReferrerTest = getRemovedReferrerTest; + +function startNewTabTestCase(aTestNumber) { + info( + "browser_referrer_open_link_in_container_tab: " + + getReferrerTestDescription(aTestNumber) + ); + contextMenuOpened(gTestWindow, "testlink").then(function(aContextMenu) { + someTabLoaded(gTestWindow).then(function(aNewTab) { + gTestWindow.gBrowser.selectedTab = aNewTab; + + checkReferrerAndStartNextTest( + aTestNumber, + null, + aNewTab, + startNewTabTestCase, + { userContextId: 2 } + ); + }); + + let menu = gTestWindow.document.getElementById( + "context-openlinkinusercontext-menu" + ); + + let menupopup = menu.menupopup; + menu.addEventListener( + "popupshown", + function() { + is(menupopup.nodeType, Node.ELEMENT_NODE, "We have a menupopup."); + ok(menupopup.firstElementChild, "We have a first container entry."); + + let firstContext = menupopup.firstElementChild; + is( + firstContext.nodeType, + Node.ELEMENT_NODE, + "We have a first container entry." + ); + ok( + firstContext.hasAttribute("data-usercontextid"), + "We have a usercontextid value." + ); + is( + "0", + firstContext.getAttribute("data-usercontextid"), + "We have the right usercontextid value." + ); + + aContextMenu.addEventListener( + "popuphidden", + function() { + firstContext.doCommand(); + }, + { once: true } + ); + + aContextMenu.hidePopup(); + }, + { once: true } + ); + + menu.openMenu(true); + }); +} + +function test() { + waitForExplicitFinish(); + + SpecialPowers.pushPrefEnv( + { set: [["privacy.userContext.enabled", true]] }, + function() { + requestLongerTimeout(10); // slowwww shutdown on e10s + startReferrerTest(startNewTabTestCase, { userContextId: 2 }); + } + ); +} diff --git a/browser/base/content/test/referrer/browser_referrer_open_link_in_private.js b/browser/base/content/test/referrer/browser_referrer_open_link_in_private.js new file mode 100644 index 0000000000..347263a7af --- /dev/null +++ b/browser/base/content/test/referrer/browser_referrer_open_link_in_private.js @@ -0,0 +1,33 @@ +// Tests referrer on context menu navigation - open link in new private window. +// Selects "open link in new private window" from the context menu. + +// The test runs from a regular browsing window. +// Output: we have no referrer. + +getReferrerTest = getRemovedReferrerTest; + +function startNewPrivateWindowTestCase(aTestNumber) { + info( + "browser_referrer_open_link_in_private: " + + getReferrerTestDescription(aTestNumber) + ); + contextMenuOpened(gTestWindow, "testlink").then(function(aContextMenu) { + newWindowOpened().then(function(aNewWindow) { + BrowserTestUtils.firstBrowserLoaded(aNewWindow, false).then(function() { + checkReferrerAndStartNextTest( + aTestNumber, + aNewWindow, + null, + startNewPrivateWindowTestCase + ); + }); + }); + + doContextMenuCommand(gTestWindow, aContextMenu, "context-openlinkprivate"); + }); +} + +function test() { + requestLongerTimeout(10); // slowwww shutdown on e10s + startReferrerTest(startNewPrivateWindowTestCase); +} diff --git a/browser/base/content/test/referrer/browser_referrer_open_link_in_tab.js b/browser/base/content/test/referrer/browser_referrer_open_link_in_tab.js new file mode 100644 index 0000000000..da3215c5dd --- /dev/null +++ b/browser/base/content/test/referrer/browser_referrer_open_link_in_tab.js @@ -0,0 +1,27 @@ +// Tests referrer on context menu navigation - open link in new tab. +// Selects "open link in new tab" from the context menu. + +function startNewTabTestCase(aTestNumber) { + info( + "browser_referrer_open_link_in_tab: " + + getReferrerTestDescription(aTestNumber) + ); + contextMenuOpened(gTestWindow, "testlink").then(function(aContextMenu) { + someTabLoaded(gTestWindow).then(function(aNewTab) { + gTestWindow.gBrowser.selectedTab = aNewTab; + checkReferrerAndStartNextTest( + aTestNumber, + null, + aNewTab, + startNewTabTestCase + ); + }); + + doContextMenuCommand(gTestWindow, aContextMenu, "context-openlinkintab"); + }); +} + +function test() { + requestLongerTimeout(10); // slowwww shutdown on e10s + startReferrerTest(startNewTabTestCase); +} diff --git a/browser/base/content/test/referrer/browser_referrer_open_link_in_window.js b/browser/base/content/test/referrer/browser_referrer_open_link_in_window.js new file mode 100644 index 0000000000..9bdd50d809 --- /dev/null +++ b/browser/base/content/test/referrer/browser_referrer_open_link_in_window.js @@ -0,0 +1,28 @@ +// Tests referrer on context menu navigation - open link in new window. +// Selects "open link in new window" from the context menu. + +function startNewWindowTestCase(aTestNumber) { + info( + "browser_referrer_open_link_in_window: " + + getReferrerTestDescription(aTestNumber) + ); + contextMenuOpened(gTestWindow, "testlink").then(function(aContextMenu) { + newWindowOpened().then(function(aNewWindow) { + BrowserTestUtils.firstBrowserLoaded(aNewWindow, false).then(function() { + checkReferrerAndStartNextTest( + aTestNumber, + aNewWindow, + null, + startNewWindowTestCase + ); + }); + }); + + doContextMenuCommand(gTestWindow, aContextMenu, "context-openlink"); + }); +} + +function test() { + requestLongerTimeout(10); // slowwww shutdown on e10s + startReferrerTest(startNewWindowTestCase); +} diff --git a/browser/base/content/test/referrer/browser_referrer_open_link_in_window_in_container.js b/browser/base/content/test/referrer/browser_referrer_open_link_in_window_in_container.js new file mode 100644 index 0000000000..3852ad9983 --- /dev/null +++ b/browser/base/content/test/referrer/browser_referrer_open_link_in_window_in_container.js @@ -0,0 +1,39 @@ +// Tests referrer on context menu navigation - open link in new window. +// Selects "open link in new window" from the context menu. + +// This test runs from a container tab. The new tab/window will be loaded in +// the same container. + +function startNewWindowTestCase(aTestNumber) { + info( + "browser_referrer_open_link_in_window: " + + getReferrerTestDescription(aTestNumber) + ); + contextMenuOpened(gTestWindow, "testlink").then(function(aContextMenu) { + newWindowOpened().then(function(aNewWindow) { + BrowserTestUtils.firstBrowserLoaded(aNewWindow, false).then(function() { + checkReferrerAndStartNextTest( + aTestNumber, + aNewWindow, + null, + startNewWindowTestCase, + { userContextId: 1 } + ); + }); + }); + + doContextMenuCommand(gTestWindow, aContextMenu, "context-openlink"); + }); +} + +function test() { + waitForExplicitFinish(); + + SpecialPowers.pushPrefEnv( + { set: [["privacy.userContext.enabled", true]] }, + function() { + requestLongerTimeout(10); // slowwww shutdown on e10s + startReferrerTest(startNewWindowTestCase, { userContextId: 1 }); + } + ); +} diff --git a/browser/base/content/test/referrer/browser_referrer_simple_click.js b/browser/base/content/test/referrer/browser_referrer_simple_click.js new file mode 100644 index 0000000000..b35f3bb160 --- /dev/null +++ b/browser/base/content/test/referrer/browser_referrer_simple_click.js @@ -0,0 +1,27 @@ +// Tests referrer on simple click navigation. +// Clicks on the link, which opens it in the same tab. + +function startSimpleClickTestCase(aTestNumber) { + info( + "browser_referrer_simple_click: " + getReferrerTestDescription(aTestNumber) + ); + BrowserTestUtils.browserLoaded( + gTestWindow.gBrowser.selectedBrowser, + false, + url => url.endsWith("file_referrer_testserver.sjs") + ).then(function() { + checkReferrerAndStartNextTest( + aTestNumber, + null, + null, + startSimpleClickTestCase + ); + }); + + clickTheLink(gTestWindow, "testlink", {}); +} + +function test() { + requestLongerTimeout(10); // slowwww shutdown on e10s + startReferrerTest(startSimpleClickTestCase); +} diff --git a/browser/base/content/test/referrer/file_referrer_policyserver.sjs b/browser/base/content/test/referrer/file_referrer_policyserver.sjs new file mode 100644 index 0000000000..6695d417f4 --- /dev/null +++ b/browser/base/content/test/referrer/file_referrer_policyserver.sjs @@ -0,0 +1,41 @@ +/** + * Renders a link with the provided referrer policy. + * Used in browser_referrer_*.js, bug 1113431. + * Arguments: ?scheme=http://&policy=origin&rel=noreferrer + */ +function handleRequest(request, response) { + Cu.importGlobalProperties(["URLSearchParams"]); + let query = new URLSearchParams(request.queryString); + + let scheme = query.get("scheme"); + let policy = query.get("policy"); + let rel = query.get("rel"); + let cross = query.get("cross"); + + let host = cross ? "example.com" : "test1.example.com"; + let linkUrl = + scheme + + host + + "/browser/browser/base/content/test/referrer/" + + "file_referrer_testserver.sjs"; + let metaReferrerTag = policy + ? `<meta name='referrer' content='${policy}'>` + : ""; + + let html = `<!DOCTYPE HTML> + <html> + <head> + <meta charset='utf-8'> + ${metaReferrerTag} + <title>Test referrer</title> + </head> + <body> + <a id='testlink' href='${linkUrl}' ${rel ? ` rel='${rel}'` : ""}> + referrer test link</a> + </body> + </html>`; + + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "text/html", false); + response.write(html); +} diff --git a/browser/base/content/test/referrer/file_referrer_policyserver_attr.sjs b/browser/base/content/test/referrer/file_referrer_policyserver_attr.sjs new file mode 100644 index 0000000000..b0104f292e --- /dev/null +++ b/browser/base/content/test/referrer/file_referrer_policyserver_attr.sjs @@ -0,0 +1,41 @@ +/** + * Renders a link with the provided referrer policy. + * Used in browser_referrer_*.js, bug 1113431. + * Arguments: ?scheme=http://&policy=origin&rel=noreferrer + */ +function handleRequest(request, response) { + Cu.importGlobalProperties(["URLSearchParams"]); + let query = new URLSearchParams(request.queryString); + + let scheme = query.get("scheme"); + let policy = query.get("policy"); + let rel = query.get("rel"); + let cross = query.get("cross"); + + let host = cross ? "example.com" : "test1.example.com"; + let linkUrl = + scheme + + host + + "/browser/browser/base/content/test/referrer/" + + "file_referrer_testserver.sjs"; + + let referrerPolicy = policy ? `referrerpolicy="${policy}"` : ""; + + let html = `<!DOCTYPE HTML> + <html> + <head> + <meta charset='utf-8'> + <title>Test referrer</title> + </head> + <body> + <a id='testlink' href='${linkUrl}' ${referrerPolicy} ${ + rel ? ` rel='${rel}'` : "" + }> + referrer test link</a> + </body> + </html>`; + + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "text/html", false); + response.write(html); +} diff --git a/browser/base/content/test/referrer/file_referrer_testserver.sjs b/browser/base/content/test/referrer/file_referrer_testserver.sjs new file mode 100644 index 0000000000..b98f628053 --- /dev/null +++ b/browser/base/content/test/referrer/file_referrer_testserver.sjs @@ -0,0 +1,33 @@ +/** + * Renders the HTTP Referer header up to the second path slash. + * Used in browser_referrer_*.js, bug 1113431. + */ +function handleRequest(request, response) { + let referrer = ""; + try { + referrer = request.getHeader("referer"); + } catch (e) { + referrer = ""; + } + + // Strip it past the first path slash. Makes tests easier to read. + referrer = referrer + .split("/") + .slice(0, 4) + .join("/"); + + let html = `<!DOCTYPE HTML> + <html> + <head> + <meta charset='utf-8'> + <title>Test referrer</title> + </head> + <body> + <div id='testdiv'>${referrer}</div> + </body> + </html>`; + + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "text/html", false); + response.write(html); +} diff --git a/browser/base/content/test/referrer/head.js b/browser/base/content/test/referrer/head.js new file mode 100644 index 0000000000..f0360eaaaf --- /dev/null +++ b/browser/base/content/test/referrer/head.js @@ -0,0 +1,308 @@ +var { XPCOMUtils } = ChromeUtils.importESModule( + "resource://gre/modules/XPCOMUtils.sys.mjs" +); + +const REFERRER_URL_BASE = "/browser/browser/base/content/test/referrer/"; +const REFERRER_POLICYSERVER_URL = + "test1.example.com" + REFERRER_URL_BASE + "file_referrer_policyserver.sjs"; +const REFERRER_POLICYSERVER_URL_ATTRIBUTE = + "test1.example.com" + + REFERRER_URL_BASE + + "file_referrer_policyserver_attr.sjs"; + +var gTestWindow = null; +var rounds = 0; + +// We test that the UI code propagates three pieces of state - the referrer URI +// itself, the referrer policy, and the triggering principal. After that, we +// trust nsIWebNavigation to do the right thing with the info it's given, which +// is covered more exhaustively by dom/base/test/test_bug704320.html (which is +// a faster content-only test). So, here, we limit ourselves to cases that +// would break when the UI code drops either of these pieces; we don't try to +// duplicate the entire cross-product test in bug 704320 - that would be slow, +// especially when we're opening a new window for each case. +var _referrerTests = [ + // 1. Normal cases - no referrer policy, no special attributes. + // We expect a full referrer normally, and no referrer on downgrade. + { + fromScheme: "http://", + toScheme: "http://", + result: "http://test1.example.com/browser", // full referrer + }, + { + fromScheme: "https://", + toScheme: "http://", + result: "", // no referrer when downgrade + }, + // 2. Origin referrer policy - we expect an origin referrer, + // even on downgrade. But rel=noreferrer trumps this. + { + fromScheme: "https://", + toScheme: "http://", + policy: "origin", + result: "https://test1.example.com/", // origin, even on downgrade + }, + { + fromScheme: "https://", + toScheme: "http://", + policy: "origin", + rel: "noreferrer", + result: "", // rel=noreferrer trumps meta-referrer + }, + // 3. XXX: using no-referrer here until we support all attribute values (bug 1178337) + // Origin-when-cross-origin policy - this depends on the triggering + // principal. We expect full referrer for same-origin requests, + // and origin referrer for cross-origin requests. + { + fromScheme: "https://", + toScheme: "https://", + policy: "no-referrer", + result: "", // same origin https://test1.example.com/browser + }, + { + fromScheme: "http://", + toScheme: "https://", + policy: "no-referrer", + result: "", // cross origin http://test1.example.com + }, +]; + +/** + * Returns the test object for a given test number. + * @param aTestNumber The test number - 0, 1, 2, ... + * @return The test object, or undefined if the number is out of range. + */ +function getReferrerTest(aTestNumber) { + return _referrerTests[aTestNumber]; +} + +/** + * Returns shimmed test object for a given test number. + * + * @param aTestNumber The test number - 0, 1, 2, ... + * @return The test object with result hard-coded to "", + * or undefined if the number is out of range. + */ +function getRemovedReferrerTest(aTestNumber) { + let testCase = _referrerTests[aTestNumber]; + if (testCase) { + // We want all the referrer tests to fail! + testCase.result = ""; + } + + return testCase; +} + +/** + * Returns a brief summary of the test, for logging. + * @param aTestNumber The test number - 0, 1, 2... + * @return The test description. + */ +function getReferrerTestDescription(aTestNumber) { + let test = getReferrerTest(aTestNumber); + return ( + "policy=[" + + test.policy + + "] " + + "rel=[" + + test.rel + + "] " + + test.fromScheme + + " -> " + + test.toScheme + ); +} + +/** + * Clicks the link. + * @param aWindow The window to click the link in. + * @param aLinkId The id of the link element. + * @param aOptions The options for synthesizeMouseAtCenter. + */ +function clickTheLink(aWindow, aLinkId, aOptions) { + return BrowserTestUtils.synthesizeMouseAtCenter( + "#" + aLinkId, + aOptions, + aWindow.gBrowser.selectedBrowser + ); +} + +/** + * Extracts the referrer result from the target window. + * @param aWindow The window where the referrer target has loaded. + * @return {Promise} + * @resolves When extacted, with the text of the (trimmed) referrer. + */ +function referrerResultExtracted(aWindow) { + return SpecialPowers.spawn(aWindow.gBrowser.selectedBrowser, [], function() { + return content.document.getElementById("testdiv").textContent; + }); +} + +/** + * Waits for browser delayed startup to finish. + * @param aWindow The window to wait for. + * @return {Promise} + * @resolves When the window is loaded. + */ +function delayedStartupFinished(aWindow) { + return new Promise(function(resolve) { + Services.obs.addObserver(function observer(aSubject, aTopic) { + if (aWindow == aSubject) { + Services.obs.removeObserver(observer, aTopic); + resolve(); + } + }, "browser-delayed-startup-finished"); + }); +} + +/** + * Waits for some (any) tab to load. The caller triggers the load. + * @param aWindow The window where to wait for a tab to load. + * @return {Promise} + * @resolves With the tab once it's loaded. + */ +function someTabLoaded(aWindow) { + return BrowserTestUtils.waitForNewTab(gTestWindow.gBrowser, null, true); +} + +/** + * Waits for a new window to open and load. The caller triggers the open. + * @return {Promise} + * @resolves With the new window once it's open and loaded. + */ +function newWindowOpened() { + return TestUtils.topicObserved("browser-delayed-startup-finished").then( + ([win]) => win + ); +} + +/** + * Opens the context menu. + * @param aWindow The window to open the context menu in. + * @param aLinkId The id of the link to open the context menu on. + * @return {Promise} + * @resolves With the menu popup when the context menu is open. + */ +function contextMenuOpened(aWindow, aLinkId) { + let popupShownPromise = BrowserTestUtils.waitForEvent( + aWindow.document, + "popupshown" + ); + // Simulate right-click. + clickTheLink(aWindow, aLinkId, { type: "contextmenu", button: 2 }); + return popupShownPromise.then(e => e.target); +} + +/** + * Performs a context menu command. + * @param aWindow The window with the already open context menu. + * @param aMenu The menu popup to hide. + * @param aItemId The id of the menu item to activate. + */ +function doContextMenuCommand(aWindow, aMenu, aItemId) { + let command = aWindow.document.getElementById(aItemId); + command.doCommand(); + aMenu.hidePopup(); +} + +/** + * Loads a single test case, i.e., a source url into gTestWindow. + * @param aTestNumber The test case number - 0, 1, 2... + * @return {Promise} + * @resolves When the source url for this test case is loaded. + */ +function referrerTestCaseLoaded(aTestNumber, aParams) { + let test = getReferrerTest(aTestNumber); + let server = + rounds == 0 + ? REFERRER_POLICYSERVER_URL + : REFERRER_POLICYSERVER_URL_ATTRIBUTE; + let url = + test.fromScheme + + server + + "?scheme=" + + escape(test.toScheme) + + "&policy=" + + escape(test.policy || "") + + "&rel=" + + escape(test.rel || "") + + "&cross=" + + escape(test.cross || ""); + let browser = gTestWindow.gBrowser; + return BrowserTestUtils.openNewForegroundTab( + browser, + () => { + browser.selectedTab = BrowserTestUtils.addTab(browser, url, aParams); + }, + false, + true + ); +} + +/** + * Checks the result of the referrer test, and moves on to the next test. + * @param aTestNumber The test number - 0, 1, 2, ... + * @param aNewWindow The new window where the referrer target opened, or null. + * @param aNewTab The new tab where the referrer target opened, or null. + * @param aStartTestCase The callback to start the next test, aTestNumber + 1. + */ +function checkReferrerAndStartNextTest( + aTestNumber, + aNewWindow, + aNewTab, + aStartTestCase, + aParams = {} +) { + referrerResultExtracted(aNewWindow || gTestWindow).then(function(result) { + // Compare the actual result against the expected one. + let test = getReferrerTest(aTestNumber); + let desc = getReferrerTestDescription(aTestNumber); + is(result, test.result, desc); + + // Clean up - close new tab / window, and then the source tab. + aNewTab && (aNewWindow || gTestWindow).gBrowser.removeTab(aNewTab); + aNewWindow && aNewWindow.close(); + is(gTestWindow.gBrowser.tabs.length, 2, "two tabs open"); + gTestWindow.gBrowser.removeTab(gTestWindow.gBrowser.tabs[1]); + + // Move on to the next test. Or finish if we're done. + var nextTestNumber = aTestNumber + 1; + if (getReferrerTest(nextTestNumber)) { + referrerTestCaseLoaded(nextTestNumber, aParams).then(function() { + aStartTestCase(nextTestNumber); + }); + } else if (rounds == 0) { + nextTestNumber = 0; + rounds = 1; + referrerTestCaseLoaded(nextTestNumber, aParams).then(function() { + aStartTestCase(nextTestNumber); + }); + } else { + finish(); + } + }); +} + +/** + * Fires up the complete referrer test. + * @param aStartTestCase The callback to start a single test case, called with + * the test number - 0, 1, 2... Needs to trigger the navigation from the source + * page, and call checkReferrerAndStartNextTest() when the target is loaded. + */ +function startReferrerTest(aStartTestCase, params = {}) { + waitForExplicitFinish(); + + // Open the window where we'll load the source URLs. + gTestWindow = openDialog(location, "", "chrome,all,dialog=no", "about:blank"); + registerCleanupFunction(function() { + gTestWindow && gTestWindow.close(); + }); + + // Load and start the first test. + delayedStartupFinished(gTestWindow).then(function() { + referrerTestCaseLoaded(0, params).then(function() { + aStartTestCase(0); + }); + }); +} |