Backed out changeset 1119f9458b5d (bug 1484255) for browser_aboutCertError_telemetry.js failures CLOSED TREE
authorCiure Andrei <aciure@mozilla.com>
Tue, 16 Oct 2018 03:33:42 +0300
changeset 489707 111455f16f4b52fe6c398fc337d48fe64a29608c
parent 489706 344d0af4e60c610d39e5f314233d605e1e92cfc9
child 489708 783ec708b98b02c22368ef1f1da587dbf6fe4294
push id247
push userfmarier@mozilla.com
push dateSat, 27 Oct 2018 01:06:44 +0000
bugs1484255
milestone64.0a1
backs out1119f9458b5d76cef62577b526c508f7908f4710
Backed out changeset 1119f9458b5d (bug 1484255) for browser_aboutCertError_telemetry.js failures CLOSED TREE
browser/actors/NetErrorChild.jsm
browser/app/profile/firefox.js
browser/base/content/aboutNetError-new.xhtml
browser/base/content/aboutNetError.xhtml
browser/base/content/browser.js
browser/base/content/test/about/browser.ini
browser/base/content/test/about/browser_aboutCertError.js
browser/base/content/test/about/browser_aboutCertError_telemetry.js
browser/base/content/test/about/head.js
browser/components/nsBrowserGlue.js
docshell/base/nsDocShell.cpp
security/manager/ssl/nsISecurityUITelemetry.idl
toolkit/components/telemetry/Events.yaml
--- a/browser/actors/NetErrorChild.jsm
+++ b/browser/actors/NetErrorChild.jsm
@@ -9,18 +9,16 @@ ChromeUtils.import("resource://gre/modul
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
 
 ChromeUtils.defineModuleGetter(this, "BrowserUtils",
                                "resource://gre/modules/BrowserUtils.jsm");
 ChromeUtils.defineModuleGetter(this, "WebNavigationFrames",
                                "resource://gre/modules/WebNavigationFrames.jsm");
 
-XPCOMUtils.defineLazyGlobalGetters(this, ["URL"]);
-
 XPCOMUtils.defineLazyGetter(this, "gPipNSSBundle", function() {
   return Services.strings.createBundle("chrome://pipnss/locale/pipnss.properties");
 });
 XPCOMUtils.defineLazyGetter(this, "gBrandBundle", function() {
   return Services.strings.createBundle("chrome://branding/locale/brand.properties");
 });
 XPCOMUtils.defineLazyPreferenceGetter(this, "newErrorPagesEnabled",
   "browser.security.newcerterrorpage.enabled");
@@ -319,17 +317,16 @@ class NetErrorChild extends ActorChild {
     technicalInfo.append("\n");
 
     // Add link to certificate and error message.
     let linkPrefix = gPipNSSBundle.GetStringFromName("certErrorCodePrefix3");
     let detailLink = doc.createElement("a");
     detailLink.append(input.data.codeString);
     detailLink.title = input.data.codeString;
     detailLink.id = "errorCode";
-    detailLink.dataset.telemetryId = "error_code_link";
     let fragment = BrowserUtils.getLocalizedFragment(doc, linkPrefix, detailLink);
     technicalInfo.appendChild(fragment);
     var errorCode = doc.getElementById("errorCode");
     if (errorCode) {
       errorCode.href = "javascript:void(0)";
       errorCode.addEventListener("click", () => {
         let debugInfo = doc.getElementById("certificateErrorDebugInformation");
         debugInfo.style.display = "block";
@@ -351,22 +348,16 @@ class NetErrorChild extends ActorChild {
     this._setTechDetails(msg, doc);
     let learnMoreLink = doc.getElementById("learnMoreLink");
     let baseURL = Services.urlFormatter.formatURLPref("app.support.baseURL");
     let errWhatToDo = doc.getElementById("es_nssBadCert_" + msg.data.codeString);
     let es = doc.getElementById("errorWhatToDoText");
     let errWhatToDoTitle = doc.getElementById("edd_nssBadCert");
     let est = doc.getElementById("errorWhatToDoTitleText");
 
-    doc.body.setAttribute("code", msg.data.codeString);
-
-    // Need to do this here (which is not exactly at load but a few ticks later),
-    // because this is the first time we have access to the error code.
-    this.recordLoadEvent(doc);
-
     switch (msg.data.code) {
       case SSL_ERROR_BAD_CERT_DOMAIN:
       case SEC_ERROR_OCSP_INVALID_SIGNING_CERT:
       case SEC_ERROR_UNKNOWN_ISSUER:
         if (!newErrorPagesEnabled) {
           break;
         }
         if (es) {
@@ -534,23 +525,21 @@ class NetErrorChild extends ActorChild {
       this.onSetAutomatic(aEvent);
       break;
     case "AboutNetErrorResetPreferences":
       this.onResetPreferences(aEvent);
       break;
     case "click":
       if (aEvent.button == 0) {
         if (this.isAboutCertError(doc)) {
-          this.recordClick(aEvent.originalTarget);
           this.onCertError(aEvent.originalTarget, doc.defaultView);
         } else {
           this.onClick(aEvent);
         }
       }
-      break;
     }
   }
 
   receiveMessage(msg) {
     if (msg.name == "CertErrorDetails") {
       let frameDocShell = WebNavigationFrames.findDocShell(msg.data.frameId, this.docShell);
       // We need nsIWebNavigation to access docShell.document.
       frameDocShell && frameDocShell.QueryInterface(Ci.nsIWebNavigation);
@@ -702,48 +691,16 @@ class NetErrorChild extends ActorChild {
       frameId: WebNavigationFrames.getFrameId(win),
       location: win.document.location.href,
       elementId: target.getAttribute("id"),
       isTopFrame: (win.parent === win),
       securityInfoAsString: getSerializedSecurityInfo(win.docShell),
     });
   }
 
-  getCSSClass(doc) {
-    let searchParams = new URL(doc.documentURI).searchParams;
-    return searchParams.get("s");
-  }
-
-  recordLoadEvent(doc) {
-    let cssClass = this.getCSSClass(doc);
-    // Telemetry values for events are max. 80 bytes.
-    let errorCode = doc.body.getAttribute("code").substring(0, 40);
-    Services.telemetry.recordEvent("security.ui.certerror", "load", "aboutcerterror", errorCode, {
-      "has_sts": (cssClass == "badStsCert").toString(),
-      "is_frame": (doc.ownerGlobal.parent != doc.ownerGlobal).toString(),
-    });
-  }
-
-  recordClick(element) {
-    let telemetryId = element.dataset.telemetryId;
-    if (!telemetryId) {
-      return;
-    }
-    let doc = element.ownerDocument;
-    let cssClass = this.getCSSClass(doc);
-    // Telemetry values for events are max. 80 bytes.
-    let errorCode = doc.body.getAttribute("code").substring(0, 40);
-    let panel = doc.getElementById("badCertAdvancedPanel");
-    Services.telemetry.recordEvent("security.ui.certerror", "click", telemetryId, errorCode, {
-      "panel_open": (panel.style.display == "none").toString(),
-      "has_sts": (cssClass == "badStsCert").toString(),
-      "is_frame": (doc.ownerGlobal.parent != doc.ownerGlobal).toString(),
-    });
-  }
-
   onClick(event) {
     let {documentURI} = event.target.ownerDocument;
 
     let elmId = event.originalTarget.getAttribute("id");
     if (elmId == "returnButton") {
       this.mm.sendAsyncMessage("Browser:SSLErrorGoBack", {});
       return;
     }
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -952,18 +952,16 @@ pref("security.alternate_certificate_err
 
 // Enable the new certificate error page only for Nightly
 #if defined(NIGHTLY_BUILD)
 pref("browser.security.newcerterrorpage.enabled", true);
 #else
 pref("browser.security.newcerterrorpage.enabled", false);
 #endif
 
-pref("security.certerrors.recordEventTelemetry", true);
-
 // Whether to start the private browsing mode at application startup
 pref("browser.privatebrowsing.autostart", false);
 
 // Whether the bookmark panel should be shown when bookmarking a page.
 pref("browser.bookmarks.editDialog.showForNewBookmarks", true);
 
 // Don't try to alter this pref, it'll be reset the next time you use the
 // bookmarking dialog
--- a/browser/base/content/aboutNetError-new.xhtml
+++ b/browser/base/content/aboutNetError-new.xhtml
@@ -159,61 +159,61 @@
           <div id="wrongSystemTimeWithoutReferencePanel">
             &certerror.wrongSystemTimeWithoutReference;
           </div>
 
           <!-- Long Description (Note: See netError.dtd for used XHTML tags) -->
           <div id="errorLongDesc" />
 
           <div id="learnMoreContainer">
-            <p><a href="https://support.mozilla.org/kb/what-does-your-connection-is-not-secure-mean" id="learnMoreLink" target="new" data-telemetry-id="learn_more_link">&errorReporting.learnMore;</a></p>
+            <p><a href="https://support.mozilla.org/kb/what-does-your-connection-is-not-secure-mean" id="learnMoreLink" target="new">&errorReporting.learnMore;</a></p>
           </div>
         </div>
 
         <!-- UI for option to report certificate errors to Mozilla. Removed on
              init for other error types .-->
         <div id="prefChangeContainer" class="button-container">
           <p>&prefReset.longDesc;</p>
           <button id="prefResetButton" class="primary" autocomplete="off">&prefReset.label;</button>
         </div>
 
         <div id="certErrorAndCaptivePortalButtonContainer" class="button-container">
-          <button id="returnButton" class="primary" autocomplete="off" data-telemetry-id="return_button_top">&returnToPreviousPage1.label;</button>
+          <button id="returnButton" class="primary" autocomplete="off">&returnToPreviousPage1.label;</button>
           <button id="openPortalLoginPageButton" class="primary" autocomplete="off">&openPortalLoginPage.label2;</button>
           <button id="errorTryAgain" class="primary" autocomplete="off">&retry.label;</button>
-          <button id="advancedButton" data-telemetry-id="advanced_button" autocomplete="off">&continue2.label;</button>
+          <button id="advancedButton" autocomplete="off">&continue2.label;</button>
           <button id="moreInformationButton" autocomplete="off">&moreInformation.label;</button>
         </div>
       </div>
 
       <div id="netErrorButtonContainer" class="button-container">
         <button id="errorTryAgain" class="primary" autocomplete="off">&retry.label;</button>
       </div>
 
       <div id="advancedPanelContainer">
         <div id="badCertAdvancedPanel" class="advanced-panel">
           <p id="badCertTechnicalInfo"/>
           <div id="advancedPanelButtonContainer" class="button-container">
-            <button id="advancedPanelReturnButton" class="primary" autocomplete="off" data-telemetry-id="return_button_adv">&returnToPreviousPage1.label;</button>
+            <button id="advancedPanelReturnButton" class="primary" autocomplete="off">&returnToPreviousPage1.label;</button>
             <button id="advancedPanelErrorTryAgain" class="primary" autocomplete="off">&retry.label;</button>
             <div class="exceptionDialogButtonContainer">
-              <button id="exceptionDialogButton" data-telemetry-id="exception_button">&securityOverride.exceptionButton1Label;</button>
+              <button id="exceptionDialogButton">&securityOverride.exceptionButton1Label;</button>
             </div>
           </div>
         </div>
 
         <div id="certificateErrorReporting">
             <p class="toggle-container-with-text">
-                <input type="checkbox" id="automaticallyReportInFuture" role="checkbox" data-telemetry-id="auto_report_cb"/>
+                <input type="checkbox" id="automaticallyReportInFuture" role="checkbox" />
                 <label for="automaticallyReportInFuture" id="automaticallyReportInFuture">&errorReporting.automatic2;</label>
             </p>
         </div>
 
         <div id="certificateErrorDebugInformation">
-          <button id="copyToClipboard" data-telemetry-id="clipboard_button_top">&certerror.copyToClipboard.label;</button>
+          <button id="copyToClipboard">&certerror.copyToClipboard.label;</button>
           <div id="certificateErrorText"/>
-          <button id="copyToClipboard" data-telemetry-id="clipboard_button_bot">&certerror.copyToClipboard.label;</button>
+          <button id="copyToClipboard">&certerror.copyToClipboard.label;</button>
         </div>
       </div>
     </div>
   </body>
   <script type="application/javascript" src="chrome://browser/content/aboutNetError.js"/>
 </html>
--- a/browser/base/content/aboutNetError.xhtml
+++ b/browser/base/content/aboutNetError.xhtml
@@ -128,59 +128,59 @@
           <div id="wrongSystemTimeWithoutReferencePanel">
             &certerror.wrongSystemTimeWithoutReference;
           </div>
 
           <!-- Long Description (Note: See netError.dtd for used XHTML tags) -->
           <div id="errorLongDesc" />
 
           <div id="learnMoreContainer">
-            <p><a href="https://support.mozilla.org/kb/what-does-your-connection-is-not-secure-mean" id="learnMoreLink" target="new" data-telemetry-id="learn_more_link">&errorReporting.learnMore;</a></p>
+            <p><a href="https://support.mozilla.org/kb/what-does-your-connection-is-not-secure-mean" id="learnMoreLink" target="new">&errorReporting.learnMore;</a></p>
           </div>
         </div>
 
         <!-- UI for option to report certificate errors to Mozilla. Removed on
              init for other error types .-->
         <div id="certificateErrorReporting">
           <p class="toggle-container-with-text">
-            <input type="checkbox" id="automaticallyReportInFuture" role="checkbox"  data-telemetry-id="auto_report_cb"/>
+            <input type="checkbox" id="automaticallyReportInFuture" role="checkbox" />
             <label for="automaticallyReportInFuture" id="automaticallyReportInFuture">&errorReporting.automatic2;</label>
           </p>
         </div>
 
         <div id="prefChangeContainer" class="button-container">
           <p>&prefReset.longDesc;</p>
           <button id="prefResetButton" class="primary" autocomplete="off">&prefReset.label;</button>
         </div>
 
         <div id="certErrorAndCaptivePortalButtonContainer" class="button-container">
-          <button id="returnButton" class="primary" autocomplete="off" data-telemetry-id="return_button_top">&returnToPreviousPage.label;</button>
+          <button id="returnButton" class="primary" autocomplete="off">&returnToPreviousPage.label;</button>
           <button id="openPortalLoginPageButton" class="primary" autocomplete="off">&openPortalLoginPage.label2;</button>
-          <button id="advancedButton" data-telemetry-id="advanced_button" autocomplete="off">&advanced.label;</button>
+          <button id="advancedButton" autocomplete="off">&advanced.label;</button>
           <button id="moreInformationButton" autocomplete="off">&moreInformation.label;</button>
         </div>
       </div>
 
       <div id="netErrorButtonContainer" class="button-container">
         <button id="errorTryAgain" class="primary" autocomplete="off">&retry.label;</button>
       </div>
 
       <div id="advancedPanelContainer">
         <div id="badCertAdvancedPanel" class="advanced-panel">
           <p id="badCertTechnicalInfo"/>
           <div id="advancedPanelButtonContainer" class="button-container">
             <button id="advancedPanelErrorTryAgain" class="primary" autocomplete="off">&retry.label;</button>
           </div>
           <div class="exceptionDialogButtonContainer">
-            <button id="exceptionDialogButton" data-telemetry-id="exception_button">&securityOverride.exceptionButtonLabel;</button>
+            <button id="exceptionDialogButton">&securityOverride.exceptionButtonLabel;</button>
           </div>
         </div>
 
         <div id="certificateErrorDebugInformation">
-          <button id="copyToClipboard" data-telemetry-id="clipboard_button_top">&certerror.copyToClipboard.label;</button>
+          <button id="copyToClipboard">&certerror.copyToClipboard.label;</button>
           <div id="certificateErrorText"/>
-          <button id="copyToClipboard" data-telemetry-id="clipboard_button_bot">&certerror.copyToClipboard.label;</button>
+          <button id="copyToClipboard">&certerror.copyToClipboard.label;</button>
         </div>
       </div>
     </div>
   </body>
   <script type="application/javascript" src="chrome://browser/content/aboutNetError.js"/>
 </html>
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -3036,20 +3036,25 @@ var BrowserOnClick = {
       break;
       case "Browser:SSLErrorGoBack":
         goBackFromErrorPage();
       break;
     }
   },
 
   onCertError(browser, elementId, isTopFrame, location, securityInfoAsString, frameId) {
+    let secHistogram = Services.telemetry.getHistogramById("SECURITY_UI");
     let securityInfo;
 
     switch (elementId) {
       case "exceptionDialogButton":
+        if (isTopFrame) {
+          secHistogram.add(Ci.nsISecurityUITelemetry.WARNING_BAD_CERT_TOP_CLICK_ADD_EXCEPTION);
+        }
+
         securityInfo = getSecurityInfo(securityInfoAsString);
         let params = { exceptionAdded: false,
                        securityInfo };
         if (Services.prefs.getBoolPref("browser.security.newcerterrorpage.enabled", false)) {
           let overrideService = Cc["@mozilla.org/security/certoverride;1"]
                                   .getService(Ci.nsICertOverrideService);
           let flags = 0;
           if (securityInfo.isUntrusted) {
@@ -3088,25 +3093,32 @@ var BrowserOnClick = {
 
         // If the user added the exception cert, attempt to reload the page
         if (params.exceptionAdded) {
           browser.reload();
         }
         break;
 
       case "returnButton":
+        if (isTopFrame) {
+          secHistogram.add(Ci.nsISecurityUITelemetry.WARNING_BAD_CERT_TOP_GET_ME_OUT_OF_HERE);
+        }
         goBackFromErrorPage();
         break;
 
       case "advancedPanelReturnButton":
         goBackFromErrorPage();
         break;
 
       case "advancedButton":
       case "moreInformationButton":
+        if (isTopFrame) {
+          secHistogram.add(Ci.nsISecurityUITelemetry.WARNING_BAD_CERT_TOP_UNDERSTAND_RISKS);
+        }
+
         securityInfo = getSecurityInfo(securityInfoAsString);
         let errorInfo = getDetailedCertErrorInfo(location,
                                                  securityInfo);
         let validityInfo = {
           notAfter: securityInfo.serverCert.validity.notAfter,
           notBefore: securityInfo.serverCert.validity.notBefore,
           notAfterLocalTime: securityInfo.serverCert.validity.notAfterLocalTime,
           notBeforeLocalTime: securityInfo.serverCert.validity.notBeforeLocalTime,
--- a/browser/base/content/test/about/browser.ini
+++ b/browser/base/content/test/about/browser.ini
@@ -1,19 +1,19 @@
 [DEFAULT]
 support-files =
   head.js
   print_postdata.sjs
   searchSuggestionEngine.sjs
   searchSuggestionEngine.xml
   POSTSearchEngine.xml
-  dummy_page.html
 
 [browser_aboutCertError.js]
-[browser_aboutCertError_telemetry.js]
+support-files =
+  dummy_page.html
 [browser_aboutHome_search_POST.js]
 [browser_aboutHome_search_composing.js]
 [browser_aboutHome_search_searchbar.js]
 [browser_aboutHome_search_suggestion.js]
 skip-if = os == "mac" || (os == "linux" && (!debug || bits == 64)) # Bug 1399648, bug 1402502
 [browser_aboutHome_search_telemetry.js]
 [browser_aboutNetError.js]
 [browser_aboutStopReload.js]
--- a/browser/base/content/test/about/browser_aboutCertError.js
+++ b/browser/base/content/test/about/browser_aboutCertError.js
@@ -2,21 +2,57 @@
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
 // This is testing the aboutCertError page (Bug 1207107).
 
 const GOOD_PAGE = "https://example.com/";
 const GOOD_PAGE_2 = "https://example.org/";
+const DUMMY_PAGE = getRootDirectory(gTestPath).replace("chrome://mochitests/content", GOOD_PAGE) + "dummy_page.html";
 const BAD_CERT = "https://expired.example.com/";
 const UNKNOWN_ISSUER = "https://self-signed.example.com ";
 const BAD_STS_CERT = "https://badchain.include-subdomains.pinning.example.com:443";
 const {TabStateFlusher} = ChromeUtils.import("resource:///modules/sessionstore/TabStateFlusher.jsm", {});
 
+function injectErrorPageFrame(tab, src) {
+  return ContentTask.spawn(tab.linkedBrowser, {frameSrc: src}, async function({frameSrc}) {
+    let loaded = ContentTaskUtils.waitForEvent(content.wrappedJSObject, "DOMFrameContentLoaded");
+    let iframe = content.document.createElement("iframe");
+    iframe.src = frameSrc;
+    content.document.body.appendChild(iframe);
+    await loaded;
+    // We will have race conditions when accessing the frame content after setting a src,
+    // so we can't wait for AboutNetErrorLoad. Let's wait for the certerror class to
+    // appear instead (which should happen at the same time as AboutNetErrorLoad).
+    await ContentTaskUtils.waitForCondition(() =>
+      iframe.contentDocument.body.classList.contains("certerror"));
+  });
+}
+
+async function openErrorPage(src, useFrame) {
+  let tab;
+  if (useFrame) {
+    info("Loading cert error page in an iframe");
+    tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, DUMMY_PAGE);
+    await injectErrorPageFrame(tab, src);
+  } else {
+    let certErrorLoaded;
+    tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, () => {
+      gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, src);
+      let browser = gBrowser.selectedBrowser;
+      certErrorLoaded = BrowserTestUtils.waitForErrorPage(browser);
+    }, false);
+    info("Loading and waiting for the cert error");
+    await certErrorLoaded;
+  }
+
+  return tab;
+}
+
 add_task(async function checkReturnToAboutHome() {
   info("Loading a bad cert page directly and making sure 'return to previous page' goes to about:home");
   for (let useFrame of [false, true]) {
     let tab = await openErrorPage(BAD_CERT, useFrame);
     let browser = tab.linkedBrowser;
 
     is(browser.webNavigation.canGoBack, false, "!webNavigation.canGoBack");
     is(browser.webNavigation.canGoForward, false, "!webNavigation.canGoForward");
deleted file mode 100644
--- a/browser/base/content/test/about/browser_aboutCertError_telemetry.js
+++ /dev/null
@@ -1,102 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-requestLongerTimeout(2);
-
-const BAD_CERT = "https://expired.example.com/";
-const BAD_STS_CERT = "https://badchain.include-subdomains.pinning.example.com:443";
-
-add_task(async function checkTelemetryClickEvents() {
-  info("Loading a bad cert page and verifying telemetry click events arrive.");
-
-  let oldCanRecord = Services.telemetry.canRecordExtended;
-  Services.telemetry.canRecordExtended = true;
-
-  registerCleanupFunction(() => {
-    Services.telemetry.canRecordExtended = oldCanRecord;
-  });
-
-  // For obvious reasons event telemetry seems to sync with the content
-  // processes asynchronously, so we need to wait for the main process
-  // to catch up through the entire test.
-  Services.telemetry.clearEvents();
-  await TestUtils.waitForCondition(() => {
-    let events = Services.telemetry.snapshotEvents(
-      Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, true).content;
-    return !events || !events.length;
-  });
-
-  for (let useFrame of [false, true]) {
-    let recordedObjects = [
-      "advanced_button",
-      "learn_more_link",
-      "auto_report_cb",
-      "error_code_link",
-      "clipboard_button_top",
-      "clipboard_button_bot",
-      "return_button_top",
-      "return_button_adv",
-    ];
-
-    if (!useFrame) {
-      recordedObjects.push("exception_button");
-    }
-
-    for (let object of recordedObjects) {
-      let tab = await openErrorPage(BAD_CERT, useFrame);
-      let browser = tab.linkedBrowser;
-
-      let loadEvents = await TestUtils.waitForCondition(() => {
-        let events = Services.telemetry.snapshotEvents(
-          Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, true).content;
-        if (events && events.length) {
-          events = events.filter(e => e[1] == "security.ui.certerror" && e[2] == "load");
-          if (events.length == 1 && events[0][5].is_frame == useFrame.toString()) {
-            return events;
-          }
-        }
-        return null;
-      });
-
-      is(loadEvents.length, 1, `recorded telemetry for the load testing ${object}, useFrame: ${useFrame}`);
-
-      await ContentTask.spawn(browser, {frame: useFrame, objectId: object}, async function({frame, objectId}) {
-        let doc = frame ? content.document.querySelector("iframe").contentDocument : content.document;
-
-        await ContentTaskUtils.waitForCondition(() => doc.body.classList.contains("certerror"), "Wait for certerror to be loaded");
-
-        let domElement = doc.querySelector(`[data-telemetry-id='${objectId}']`);
-        domElement.click();
-      });
-
-      let clickEvents = await TestUtils.waitForCondition(() => {
-        let events = Services.telemetry.snapshotEvents(
-          Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, true).content;
-        if (events && events.length) {
-          events = events.filter(e => e[1] == "security.ui.certerror" && e[2] == "click" && e[3] == object);
-          if (events.length == 1 && events[0][5].is_frame == useFrame.toString()) {
-            return events;
-          }
-        }
-        return null;
-      }, "Has captured telemetry events.");
-
-      is(clickEvents.length, 1, `recorded telemetry for the click on ${object}, useFrame: ${useFrame}`);
-
-      // We opened an extra tab for the SUMO page, need to close it.
-      if (object == "learn_more_link") {
-        BrowserTestUtils.removeTab(gBrowser.selectedTab);
-      }
-
-      if (object == "exception_button") {
-        let certOverrideService = Cc["@mozilla.org/security/certoverride;1"]
-                                    .getService(Ci.nsICertOverrideService);
-        certOverrideService.clearValidityOverride("expired.example.com", -1);
-      }
-
-      BrowserTestUtils.removeTab(gBrowser.selectedTab);
-    }
-  }
-});
--- a/browser/base/content/test/about/head.js
+++ b/browser/base/content/test/about/head.js
@@ -1,47 +1,10 @@
 /* eslint-env mozilla/frame-script */
 
-function injectErrorPageFrame(tab, src) {
-  return ContentTask.spawn(tab.linkedBrowser, {frameSrc: src}, async function({frameSrc}) {
-    let loaded = ContentTaskUtils.waitForEvent(content.wrappedJSObject, "DOMFrameContentLoaded");
-    let iframe = content.document.createElement("iframe");
-    iframe.src = frameSrc;
-    content.document.body.appendChild(iframe);
-    await loaded;
-    // We will have race conditions when accessing the frame content after setting a src,
-    // so we can't wait for AboutNetErrorLoad. Let's wait for the certerror class to
-    // appear instead (which should happen at the same time as AboutNetErrorLoad).
-    await ContentTaskUtils.waitForCondition(() =>
-      iframe.contentDocument.body.classList.contains("certerror"));
-  });
-}
-
-async function openErrorPage(src, useFrame) {
-  let dummyPage = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "https://example.com") + "dummy_page.html";
-
-  let tab;
-  if (useFrame) {
-    info("Loading cert error page in an iframe");
-    tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, dummyPage);
-    await injectErrorPageFrame(tab, src);
-  } else {
-    let certErrorLoaded;
-    tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, () => {
-      gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, src);
-      let browser = gBrowser.selectedBrowser;
-      certErrorLoaded = BrowserTestUtils.waitForErrorPage(browser);
-    }, false);
-    info("Loading and waiting for the cert error");
-    await certErrorLoaded;
-  }
-
-  return tab;
-}
-
 function waitForCondition(condition, nextTest, errorMsg, retryTimes) {
   retryTimes = typeof retryTimes !== "undefined" ? retryTimes : 30;
   var tries = 0;
   var interval = setInterval(function() {
     if (tries >= retryTimes) {
       ok(false, errorMsg);
       moveOn();
     }
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -1548,23 +1548,16 @@ BrowserGlue.prototype = {
    * but it will not make it happen later (and out of order) compared
    * to the other ones scheduled together.
    */
   _scheduleStartupIdleTasks() {
     Services.tm.idleDispatchToMainThread(() => {
       ContextualIdentityService.load();
     });
 
-    Services.tm.idleDispatchToMainThread(() => {
-      let enableCertErrorUITelemetry =
-        Services.prefs.getBoolPref("security.certerrors.recordEventTelemetry", false);
-      Services.telemetry.setEventRecordingEnabled("security.ui.certerror",
-        enableCertErrorUITelemetry);
-    });
-
     // Load the Login Manager data from disk off the main thread, some time
     // after startup.  If the data is required before this runs, for example
     // because a restored page contains a password field, it will be loaded on
     // the main thread, and this initialization request will be ignored.
     Services.tm.idleDispatchToMainThread(() => {
       try {
         Services.logins;
       } catch (ex) {
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -4540,24 +4540,37 @@ nsDocShell::DisplayLoadError(nsresult aE
       // HSTS/pinning takes precedence over the expert bad cert pref. We
       // never want to show the "Add Exception" button for these sites.
       // In the future we should differentiate between an HSTS host and a
       // pinned host and display a more informative message to the user.
       if (isStsHost || isPinnedHost) {
         cssClass.AssignLiteral("badStsCert");
       }
 
+      uint32_t bucketId;
+      if (isStsHost) {
+        // measuring STS separately allows us to measure click through
+        // rates easily
+        bucketId = nsISecurityUITelemetry::WARNING_BAD_CERT_TOP_STS;
+      } else {
+        bucketId = nsISecurityUITelemetry::WARNING_BAD_CERT_TOP;
+      }
+
       // See if an alternate cert error page is registered
       nsAutoCString alternateErrorPage;
       nsresult rv =
         Preferences::GetCString("security.alternate_certificate_error_page",
                                 alternateErrorPage);
       if (NS_SUCCEEDED(rv)) {
         errorPage.Assign(alternateErrorPage);
       }
+
+      if (!IsFrame() && errorPage.EqualsIgnoreCase("certerror")) {
+        Telemetry::Accumulate(mozilla::Telemetry::SECURITY_UI, bucketId);
+      }
     } else {
       error = "nssFailure2";
     }
   } else if (NS_ERROR_PHISHING_URI == aError ||
              NS_ERROR_MALWARE_URI == aError ||
              NS_ERROR_UNWANTED_URI == aError ||
              NS_ERROR_HARMFUL_URI == aError) {
     nsAutoCString host;
--- a/security/manager/ssl/nsISecurityUITelemetry.idl
+++ b/security/manager/ssl/nsISecurityUITelemetry.idl
@@ -111,23 +111,23 @@ const uint32_t WARNING_GEOLOCATION_REQUE
 // const uint32_t WARNING_MALWARE_PAGE_FRAME_GET_ME_OUT_OF_HERE = 62;
 // const uint32_t WARNING_MALWARE_PAGE_FRAME_IGNORE_WARNING = 63;
 
 // const uint32_t WARNING_PHISHING_PAGE_FRAME = 64;
 // const uint32_t WARNING_PHISHING_PAGE_FRAME_WHY_BLOCKED = 65;
 // const uint32_t WARNING_PHISHING_PAGE_FRAME_GET_ME_OUT_OF_HERE = 66;
 // const uint32_t WARNING_PHISHING_PAGE_FRAME_IGNORE_WARNING = 67;
 
-//const uint32_t WARNING_BAD_CERT_TOP = 68;
-//const uint32_t WARNING_BAD_CERT_TOP_STS = 69;
-//const uint32_t WARNING_BAD_CERT_TOP_CLICK_ADD_EXCEPTION = 70;
+const uint32_t WARNING_BAD_CERT_TOP = 68;
+const uint32_t WARNING_BAD_CERT_TOP_STS = 69;
+const uint32_t WARNING_BAD_CERT_TOP_CLICK_ADD_EXCEPTION = 70;
 const uint32_t WARNING_BAD_CERT_TOP_CLICK_VIEW_CERT = 71;
 const uint32_t WARNING_BAD_CERT_TOP_DONT_REMEMBER_EXCEPTION = 72;
-//const uint32_t WARNING_BAD_CERT_TOP_GET_ME_OUT_OF_HERE = 73;
-//const uint32_t WARNING_BAD_CERT_TOP_UNDERSTAND_RISKS = 74;
+const uint32_t WARNING_BAD_CERT_TOP_GET_ME_OUT_OF_HERE = 73;
+const uint32_t WARNING_BAD_CERT_TOP_UNDERSTAND_RISKS = 74;
 //     removed WARNING_BAD_CERT_TOP_TECHNICAL_DETAILS = 75;
 
 const uint32_t WARNING_BAD_CERT_TOP_ADD_EXCEPTION_BASE = 76;
 const uint32_t WARNING_BAD_CERT_TOP_ADD_EXCEPTION_FLAG_UNTRUSTED = 1;
 const uint32_t WARNING_BAD_CERT_TOP_ADD_EXCEPTION_FLAG_DOMAIN = 2;
 const uint32_t WARNING_BAD_CERT_TOP_ADD_EXCEPTION_FLAG_TIME = 4;
 
 const uint32_t WARNING_BAD_CERT_TOP_CONFIRM_ADD_EXCEPTION_BASE = 84;
--- a/toolkit/components/telemetry/Events.yaml
+++ b/toolkit/components/telemetry/Events.yaml
@@ -547,63 +547,16 @@ devtools.main:
     description: The amount of time a tool was opened for.
     release_channel_collection: opt-out
     expiry_version: never
     extra_keys:
       time_open: Time open.
       os: The OS name and version e.g. "Linux 4.4.0-1014-aws", "Darwin 14.5.0", "Windows_NT 6.1.7601" or "Windows_NT 10.0.15063." This can be used to make sense of data when a feature is only available from a particular operating system build number.
       session_id: The start time of the session in milliseconds since epoch (Unix Timestamp) e.g. 1396381378123.
 
-security.ui.certerror:
-  load:
-    objects: ["aboutcerterror"]
-    bug_numbers:
-      - 1484255
-    description: >
-      The about:certerror page is loaded, keyed by error code, see https://searchfox.org/mozilla-central/source/security/nss/lib/mozpkix/include/pkix/Result.h
-    expiry_version: "70"
-    notification_emails:
-      - jhofmann@mozilla.com
-      - seceng-telemetry@mozilla.com
-    release_channel_collection: opt-in
-    record_in_processes: ["content"]
-    products:
-      - firefox
-    extra_keys:
-      is_frame: If the error page is loaded in an iframe.
-      has_sts: If the error page is for a site with HSTS headers or with a pinned key.
-  click:
-    objects: [
-      "advanced_button",
-      "exception_button",
-      "return_button_top",
-      "return_button_adv",
-      "learn_more_link",
-      "auto_report_cb",
-      "error_code_link",
-      "clipboard_button_top",
-      "clipboard_button_bot",
-    ]
-    bug_numbers:
-      - 1484255
-    description: >
-      User interaction by click events on the cert error page. Keyed by error code, see https://searchfox.org/mozilla-central/source/security/nss/lib/mozpkix/include/pkix/Result.h
-    expiry_version: "70"
-    notification_emails:
-      - jhofmann@mozilla.com
-      - seceng-telemetry@mozilla.com
-    release_channel_collection: opt-in
-    record_in_processes: ["content"]
-    products:
-      - firefox
-    extra_keys:
-      is_frame: If the error page is loaded in an iframe.
-      has_sts: If the error page is for a site with HSTS headers or with a pinned key.
-      panel_open: If the advanced panel was open at the time of the interaction.
-
 security.ui.identitypopup:
   open:
     objects: ["identity_popup"]
     bug_numbers:
       - 1484251
     description: >
       How many times the control center was opened.
       Keyed by the state of the content blocking shield, where the shield-showing key indicates