Bug 1514824 - Add an MDN link for cookie/storage warning messages in console; r=bgrins.
authorNicolas Chevobbe <nchevobbe@mozilla.com>
Fri, 15 Feb 2019 13:29:26 +0000
changeset 459539 317b67e93f3712bc573aa3fa46fecf2e30efe1f6
parent 459538 b1ac22673987e759400e5fd2fb56bd8fb119aa55
child 459540 d4e4095c9584edc865fdd924c389429980992bd9
push id111964
push usercsabou@mozilla.com
push dateFri, 15 Feb 2019 18:54:44 +0000
treeherdermozilla-inbound@db3c4f905082 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbgrins
bugs1514824
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1514824 - Add an MDN link for cookie/storage warning messages in console; r=bgrins. Differential Revision: https://phabricator.services.mozilla.com/D18812
devtools/client/webconsole/test/mochitest/browser_webconsole_trackingprotection_errors.js
devtools/client/webconsole/test/mochitest/test-trackingprotection-securityerrors.html
devtools/server/actors/errordocs.js
--- a/devtools/client/webconsole/test/mochitest/browser_webconsole_trackingprotection_errors.js
+++ b/devtools/client/webconsole/test/mochitest/browser_webconsole_trackingprotection_errors.js
@@ -2,50 +2,154 @@
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // Load a page with tracking elements that get blocked and make sure that a
 // 'learn more' link shows up in the webconsole.
 
 "use strict";
+requestLongerTimeout(2);
 
-const TEST_URI = "http://tracking.example.org/browser/devtools/client/" +
-                 "webconsole/test/mochitest/" +
-                 "test-trackingprotection-securityerrors.html";
-const LEARN_MORE_URI = "https://developer.mozilla.org/Firefox/Privacy/" +
-                       "Tracking_Protection" + DOCS_GA_PARAMS;
+const TEST_FILE = "browser/devtools/client/webconsole/test/mochitest/" +
+                          "test-trackingprotection-securityerrors.html";
+const TEST_URI = "http://example.com/" + TEST_FILE;
+const TRACKER_URL = "http://tracking.example.org/";
+const BLOCKED_URL = `\u201c${TRACKER_URL}\u201d`;
+
+const COOKIE_BEHAVIOR_PREF = "network.cookie.cookieBehavior";
+const COOKIE_BEHAVIORS = {
+// reject all third-party cookies
+  REJECT_FOREIGN: 1,
+// reject all cookies
+  REJECT: 2,
+// reject third-party cookies unless the eTLD already has at least one cookie
+  LIMIT_FOREIGN: 3,
+// reject trackers
+  REJECT_TRACKER: 4,
+};
 
 const {UrlClassifierTestUtils} = ChromeUtils.import("resource://testing-common/UrlClassifierTestUtils.jsm");
 
 registerCleanupFunction(function() {
   UrlClassifierTestUtils.cleanupTestTrackers();
 });
 
-add_task(async function testMessagesAppear() {
+add_task(async function testContentBlockingMessage() {
   await UrlClassifierTestUtils.addTestTrackers();
+
   await pushPref("privacy.trackingprotection.enabled", true);
+  const hud = await openNewTabAndConsole(TRACKER_URL + TEST_FILE);
 
-  const hud = await openNewTabAndConsole(TEST_URI);
+  info("Test content blocking message");
+  const message = await waitFor(() => findMessage(hud,
+    `The resource at \u201chttp://tracking.example.com/\u201d was blocked because ` +
+    `content blocking is enabled`));
+
+  await testLearnMoreClickOpenNewTab(message,
+    "https://developer.mozilla.org/Firefox/Privacy/Tracking_Protection" + DOCS_GA_PARAMS);
+});
+
+add_task(async function testForeignCookieBlockedMessage() {
+  info("Test foreign cookie blocked message");
+  // We change the pref and open a new window to ensure it will be taken into account.
+  await pushPref(COOKIE_BEHAVIOR_PREF, COOKIE_BEHAVIORS.REJECT_FOREIGN);
+  const {hud, win} = await openNewWindowAndConsole(TEST_URI);
+  const message = await waitFor(() => findMessage(hud,
+    `Request to access cookie or storage on ${BLOCKED_URL} was blocked because we are ` +
+    `blocking all third-party storage access requests and content blocking is enabled`));
+  await testLearnMoreClickOpenNewTab(message, getStorageErrorUrl("CookieBlockedForeign"));
+  win.close();
+});
+
+add_task(async function testLimitForeignCookieBlockedMessage() {
+  info("Test unvisited eTLD foreign cookies blocked message");
+  // We change the pref and open a new window to ensure it will be taken into account.
+  await pushPref(COOKIE_BEHAVIOR_PREF, COOKIE_BEHAVIORS.LIMIT_FOREIGN);
+  const {hud, win} = await openNewWindowAndConsole(TEST_URI);
+
+  const message = await waitFor(() => findMessage(hud,
+    `Request to access cookie or storage on ${BLOCKED_URL} was blocked because we are ` +
+    `blocking all third-party storage access requests and content blocking is enabled`));
+  await testLearnMoreClickOpenNewTab(message, getStorageErrorUrl("CookieBlockedForeign"));
+  win.close();
+});
+
+add_task(async function testAllCookieBlockedMessage() {
+  info("Test all cookies blocked message");
+  // We change the pref and open a new window to ensure it will be taken into account.
+  await pushPref(COOKIE_BEHAVIOR_PREF, COOKIE_BEHAVIORS.REJECT);
+  const {hud, win} = await openNewWindowAndConsole(TEST_URI);
 
   const message = await waitFor(() => findMessage(hud,
-    "The resource at \u201chttp://tracking.example.com/\u201d was " +
-    "blocked because content blocking is enabled"));
+    `Request to access cookie or storage on ${BLOCKED_URL} was blocked because we are ` +
+    `blocking all storage access requests`));
+  await testLearnMoreClickOpenNewTab(message,
+    getStorageErrorUrl("CookieBlockedAll"));
+  win.close();
+});
 
-  await testClickOpenNewTab(hud, message);
+add_task(async function testTrackerCookieBlockedMessage() {
+  info("Test tracker cookie blocked message");
+  // We change the pref and open a new window to ensure it will be taken into account.
+  await pushPref(COOKIE_BEHAVIOR_PREF, COOKIE_BEHAVIORS.REJECT_TRACKER);
+  const {hud, win} = await openNewWindowAndConsole(TEST_URI);
+
+  const message = await waitFor(() => findMessage(hud,
+    `Request to access cookie or storage on ${BLOCKED_URL} was blocked because it came ` +
+    `from a tracker and content blocking is enabled`));
+  await testLearnMoreClickOpenNewTab(message, getStorageErrorUrl("CookieBlockedTracker"));
+  win.close();
 });
 
-async function testClickOpenNewTab(hud, message) {
+add_task(async function testCookieBlockedByPermissionMessage() {
+  info("Test cookie blocked by permission message");
+  // Turn off tracking protection and add a block permission on the URL.
+  await pushPref("privacy.trackingprotection.enabled", false);
+  const p = Services.scriptSecurityManager.createCodebasePrincipalFromOrigin(TRACKER_URL);
+  Services.perms.addFromPrincipal(p, "cookie", Ci.nsIPermissionManager.DENY_ACTION);
+
+  const {hud, win} = await openNewWindowAndConsole(TEST_URI);
+  const message = await waitFor(() => findMessage(hud, `Request to access cookies or ` +
+    `storage on ${BLOCKED_URL} was blocked because of custom cookie permission`));
+  await testLearnMoreClickOpenNewTab(message,
+    getStorageErrorUrl("CookieBlockedByPermission"));
+  win.close();
+
+  // Remove the custom permission.
+  Services.perms.removeFromPrincipal(p, "cookie");
+});
+
+async function openNewWindowAndConsole(url) {
+  const win = await openNewBrowserWindow();
+  const tab = await addTab(url, {window: win});
+  win.gBrowser.selectedTab = tab;
+  const hud = await openConsole(tab);
+  return {win, hud};
+}
+
+function getStorageErrorUrl(category) {
+  const BASE_STORAGE_ERROR_URL = "https://developer.mozilla.org/docs/Mozilla/Firefox/" +
+                                 "Privacy/Storage_access_policy/Errors/";
+  const STORAGE_ERROR_URL_PARAMS = new URLSearchParams({
+    utm_source: "devtools",
+    utm_medium: "firefox-cookie-errors",
+    utm_campaign: "default",
+  }).toString();
+  return `${BASE_STORAGE_ERROR_URL}${category}?${STORAGE_ERROR_URL_PARAMS}`;
+}
+
+async function testLearnMoreClickOpenNewTab(message, expectedUrl) {
   info("Clicking on the Learn More link");
 
   const learnMoreLink = message.querySelector(".learn-more-link");
   const linkSimulation = await simulateLinkClick(learnMoreLink);
   checkLink({
     ...linkSimulation,
-    expectedLink: LEARN_MORE_URI,
+    expectedLink: expectedUrl,
     expectedTab: "tab",
   });
 }
 
 function checkLink({ link, where, expectedLink, expectedTab }) {
   is(link, expectedLink, `Clicking the provided link opens ${link}`);
   is(where, expectedTab, `Clicking the provided link opens in expected tab`);
 }
--- a/devtools/client/webconsole/test/mochitest/test-trackingprotection-securityerrors.html
+++ b/devtools/client/webconsole/test/mochitest/test-trackingprotection-securityerrors.html
@@ -2,11 +2,12 @@
 <!-- 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/. -->
 <html dir="ltr" xml:lang="en-US" lang="en-US">
   <head>
     <meta charset="utf8">
   </head>
   <body>
+    <iframe src="http://tracking.example.org/"></iframe>
     <iframe src="http://tracking.example.com/"></iframe>
   </body>
 </html>
--- a/devtools/server/actors/errordocs.js
+++ b/devtools/server/actors/errordocs.js
@@ -127,29 +127,48 @@ const CorsErrorDocs = {
   CORSMethodNotFound: "CORSMethodNotFound",
   CORSMissingAllowCredentials: "CORSMissingAllowCredentials",
   CORSPreflightDidNotSucceed: "CORSPreflightDidNotSucceed",
   CORSInvalidAllowMethod: "CORSInvalidAllowMethod",
   CORSInvalidAllowHeader: "CORSInvalidAllowHeader",
   CORSMissingAllowHeaderFromPreflight: "CORSMissingAllowHeaderFromPreflight",
 };
 
+const baseStorageAccessPolicyErrorUrl = "https://developer.mozilla.org/docs/Mozilla/Firefox/Privacy/Storage_access_policy/Errors/";
+const storageAccessPolicyParams =
+  "?utm_source=devtools&utm_medium=firefox-cookie-errors&utm_campaign=default";
+const StorageAccessPolicyErrorDocs = {
+  cookieBlockedPermission: "CookieBlockedByPermission",
+  cookieBlockedTracker: "CookieBlockedTracker",
+  cookieBlockedAll: "CookieBlockedAll",
+  cookieBlockedForeign: "CookieBlockedForeign",
+};
+
 exports.GetURL = (error) => {
   if (!error) {
     return undefined;
   }
 
   const doc = ErrorDocs[error.errorMessageName];
   if (doc) {
     return baseErrorURL + doc + params;
   }
 
   const corsDoc = CorsErrorDocs[error.category];
   if (corsDoc) {
     return baseCorsErrorUrl + corsDoc + corsParams;
   }
 
+  const storageAccessPolicyDoc = StorageAccessPolicyErrorDocs[error.category];
+  if (storageAccessPolicyDoc) {
+    return (
+      baseStorageAccessPolicyErrorUrl +
+      storageAccessPolicyDoc +
+      storageAccessPolicyParams
+    );
+  }
+
   const categoryURL = ErrorCategories[error.category];
   if (categoryURL) {
     return categoryURL + params;
   }
   return undefined;
 };