summaryrefslogtreecommitdiffstats
path: root/browser/base/content/test/protectionsUI/browser_protectionsUI_report_breakage.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/base/content/test/protectionsUI/browser_protectionsUI_report_breakage.js')
-rw-r--r--browser/base/content/test/protectionsUI/browser_protectionsUI_report_breakage.js404
1 files changed, 404 insertions, 0 deletions
diff --git a/browser/base/content/test/protectionsUI/browser_protectionsUI_report_breakage.js b/browser/base/content/test/protectionsUI/browser_protectionsUI_report_breakage.js
new file mode 100644
index 0000000000..b5400954db
--- /dev/null
+++ b/browser/base/content/test/protectionsUI/browser_protectionsUI_report_breakage.js
@@ -0,0 +1,404 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const TRACKING_PAGE =
+ // eslint-disable-next-line @microsoft/sdl/no-insecure-url
+ "http://tracking.example.org/browser/browser/base/content/test/protectionsUI/trackingPage.html";
+const BENIGN_PAGE =
+ // eslint-disable-next-line @microsoft/sdl/no-insecure-url
+ "http://tracking.example.org/browser/browser/base/content/test/protectionsUI/benignPage.html";
+const COOKIE_PAGE =
+ // eslint-disable-next-line @microsoft/sdl/no-insecure-url
+ "http://not-tracking.example.com/browser/browser/base/content/test/protectionsUI/cookiePage.html";
+
+const CM_PREF = "privacy.trackingprotection.cryptomining.enabled";
+const FP_PREF = "privacy.trackingprotection.fingerprinting.enabled";
+const TP_PREF = "privacy.trackingprotection.enabled";
+const CB_PREF = "network.cookie.cookieBehavior";
+
+const PREF_REPORT_BREAKAGE_URL = "browser.contentblocking.reportBreakage.url";
+
+let { HttpServer } = ChromeUtils.import("resource://testing-common/httpd.js");
+let { CommonUtils } = ChromeUtils.importESModule(
+ "resource://services-common/utils.sys.mjs"
+);
+let { Preferences } = ChromeUtils.importESModule(
+ "resource://gre/modules/Preferences.sys.mjs"
+);
+
+add_setup(async function () {
+ await UrlClassifierTestUtils.addTestTrackers();
+
+ registerCleanupFunction(() => {
+ // Clear prefs that are touched in this test again for sanity.
+ Services.prefs.clearUserPref(TP_PREF);
+ Services.prefs.clearUserPref(CB_PREF);
+ Services.prefs.clearUserPref(FP_PREF);
+ Services.prefs.clearUserPref(CM_PREF);
+ Services.prefs.clearUserPref(PREF_REPORT_BREAKAGE_URL);
+
+ UrlClassifierTestUtils.cleanupTestTrackers();
+ });
+
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ [
+ "urlclassifier.features.fingerprinting.blacklistHosts",
+ "fingerprinting.example.com",
+ ],
+ [
+ "urlclassifier.features.fingerprinting.annotate.blacklistHosts",
+ "fingerprinting.example.com",
+ ],
+ ["privacy.trackingprotection.cryptomining.enabled", true],
+ [
+ "urlclassifier.features.cryptomining.blacklistHosts",
+ "cryptomining.example.com",
+ ],
+ [
+ "urlclassifier.features.cryptomining.annotate.blacklistHosts",
+ "cryptomining.example.com",
+ ],
+ ],
+ });
+});
+
+add_task(async function testReportBreakageCancel() {
+ Services.prefs.setBoolPref(TP_PREF, true);
+
+ await BrowserTestUtils.withNewTab(TRACKING_PAGE, async function () {
+ await openProtectionsPanel();
+ await TestUtils.waitForCondition(() =>
+ gProtectionsHandler._protectionsPopup.hasAttribute("blocking")
+ );
+
+ let siteNotWorkingButton = document.getElementById(
+ "protections-popup-tp-switch-breakage-link"
+ );
+ ok(
+ BrowserTestUtils.is_visible(siteNotWorkingButton),
+ "site not working button is visible"
+ );
+ let siteNotWorkingView = document.getElementById(
+ "protections-popup-siteNotWorkingView"
+ );
+ let viewShown = BrowserTestUtils.waitForEvent(
+ siteNotWorkingView,
+ "ViewShown"
+ );
+ siteNotWorkingButton.click();
+ await viewShown;
+
+ let sendReportButton = document.getElementById(
+ "protections-popup-siteNotWorkingView-sendReport"
+ );
+ let sendReportView = document.getElementById(
+ "protections-popup-sendReportView"
+ );
+ viewShown = BrowserTestUtils.waitForEvent(sendReportView, "ViewShown");
+ sendReportButton.click();
+ await viewShown;
+
+ ok(true, "Report breakage view was shown");
+
+ viewShown = BrowserTestUtils.waitForEvent(siteNotWorkingView, "ViewShown");
+ let cancelButton = document.getElementById(
+ "protections-popup-sendReportView-cancel"
+ );
+ cancelButton.click();
+ await viewShown;
+
+ ok(true, "Main view was shown");
+ });
+
+ Services.prefs.clearUserPref(TP_PREF);
+});
+
+add_task(async function testReportBreakageSiteException() {
+ Services.prefs.setBoolPref(TP_PREF, true);
+
+ let url = TRACKING_PAGE + "?a=b&1=abc&unicode=🦊";
+
+ await BrowserTestUtils.withNewTab(url, async browser => {
+ let loaded = BrowserTestUtils.browserLoaded(browser, false);
+ gProtectionsHandler.disableForCurrentPage();
+ await loaded;
+
+ await openProtectionsPanel();
+
+ let siteFixedButton = document.getElementById(
+ "protections-popup-tp-switch-breakage-fixed-link"
+ );
+ ok(
+ BrowserTestUtils.is_visible(siteFixedButton),
+ "site fixed button is visible"
+ );
+ let sendReportView = document.getElementById(
+ "protections-popup-sendReportView"
+ );
+ let viewShown = BrowserTestUtils.waitForEvent(sendReportView, "ViewShown");
+ siteFixedButton.click();
+ await viewShown;
+
+ ok(true, "Report breakage view was shown");
+
+ await testReportBreakageSubmit(
+ TRACKING_PAGE,
+ "trackingprotection",
+ false,
+ true
+ );
+
+ // Pass false for shouldReload - there's no need since the tab is going away.
+ gProtectionsHandler.enableForCurrentPage(false);
+ });
+
+ Services.prefs.clearUserPref(TP_PREF);
+});
+
+add_task(async function testNoTracking() {
+ await BrowserTestUtils.withNewTab(BENIGN_PAGE, async function () {
+ await openProtectionsPanel();
+
+ let siteNotWorkingButton = document.getElementById(
+ "protections-popup-tp-switch-breakage-link"
+ );
+ ok(
+ BrowserTestUtils.is_hidden(siteNotWorkingButton),
+ "site not working button is not visible"
+ );
+ });
+});
+
+add_task(async function testReportBreakageError() {
+ Services.prefs.setBoolPref(TP_PREF, true);
+ // Make sure that we correctly strip the query.
+ let url = TRACKING_PAGE + "?a=b&1=abc&unicode=🦊";
+ await BrowserTestUtils.withNewTab(url, async function () {
+ await openAndTestReportBreakage(TRACKING_PAGE, "trackingprotection", true);
+ });
+
+ Services.prefs.clearUserPref(TP_PREF);
+});
+
+add_task(async function testTP() {
+ Services.prefs.setBoolPref(TP_PREF, true);
+ // Make sure that we correctly strip the query.
+ let url = TRACKING_PAGE + "?a=b&1=abc&unicode=🦊";
+ await BrowserTestUtils.withNewTab(url, async function () {
+ await openAndTestReportBreakage(TRACKING_PAGE, "trackingprotection");
+ });
+
+ Services.prefs.clearUserPref(TP_PREF);
+});
+
+add_task(async function testCR() {
+ Services.prefs.setIntPref(
+ CB_PREF,
+ Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER
+ );
+ // Make sure that we correctly strip the query.
+ let url = COOKIE_PAGE + "?a=b&1=abc&unicode=🦊";
+ await BrowserTestUtils.withNewTab(url, async function () {
+ await openAndTestReportBreakage(COOKIE_PAGE, "cookierestrictions");
+ });
+
+ Services.prefs.clearUserPref(CB_PREF);
+});
+
+add_task(async function testFP() {
+ Services.prefs.setIntPref(CB_PREF, Ci.nsICookieService.BEHAVIOR_ACCEPT);
+ Services.prefs.setBoolPref(FP_PREF, true);
+ // Make sure that we correctly strip the query.
+ let url = TRACKING_PAGE + "?a=b&1=abc&unicode=🦊";
+ await BrowserTestUtils.withNewTab(url, async function (browser) {
+ let promise = waitForContentBlockingEvent();
+ await SpecialPowers.spawn(browser, [], function () {
+ content.postMessage("fingerprinting", "*");
+ });
+ await promise;
+
+ await openAndTestReportBreakage(TRACKING_PAGE, "fingerprinting", true);
+ });
+
+ Services.prefs.clearUserPref(FP_PREF);
+ Services.prefs.clearUserPref(CB_PREF);
+});
+
+add_task(async function testCM() {
+ Services.prefs.setIntPref(CB_PREF, Ci.nsICookieService.BEHAVIOR_ACCEPT);
+ Services.prefs.setBoolPref(CM_PREF, true);
+ // Make sure that we correctly strip the query.
+ let url = TRACKING_PAGE + "?a=b&1=abc&unicode=🦊";
+ await BrowserTestUtils.withNewTab(url, async function (browser) {
+ let promise = waitForContentBlockingEvent();
+ await SpecialPowers.spawn(browser, [], function () {
+ content.postMessage("cryptomining", "*");
+ });
+ await promise;
+
+ await openAndTestReportBreakage(TRACKING_PAGE, "cryptomining", true);
+ });
+
+ Services.prefs.clearUserPref(CM_PREF);
+ Services.prefs.clearUserPref(CB_PREF);
+});
+
+async function openAndTestReportBreakage(url, tags, error = false) {
+ await openProtectionsPanel();
+
+ let siteNotWorkingButton = document.getElementById(
+ "protections-popup-tp-switch-breakage-link"
+ );
+ ok(
+ BrowserTestUtils.is_visible(siteNotWorkingButton),
+ "site not working button is visible"
+ );
+ let siteNotWorkingView = document.getElementById(
+ "protections-popup-siteNotWorkingView"
+ );
+ let viewShown = BrowserTestUtils.waitForEvent(
+ siteNotWorkingView,
+ "ViewShown"
+ );
+ siteNotWorkingButton.click();
+ await viewShown;
+
+ let sendReportButton = document.getElementById(
+ "protections-popup-siteNotWorkingView-sendReport"
+ );
+ let sendReportView = document.getElementById(
+ "protections-popup-sendReportView"
+ );
+ viewShown = BrowserTestUtils.waitForEvent(sendReportView, "ViewShown");
+ sendReportButton.click();
+ await viewShown;
+
+ ok(true, "Report breakage view was shown");
+
+ await testReportBreakageSubmit(url, tags, error, false);
+}
+
+// This function assumes that the breakage report view is ready.
+async function testReportBreakageSubmit(url, tags, error, hasException) {
+ // Setup a mock server for receiving breakage reports.
+ let server = new HttpServer();
+ server.start(-1);
+ let i = server.identity;
+ let path =
+ i.primaryScheme + "://" + i.primaryHost + ":" + i.primaryPort + "/";
+
+ Services.prefs.setStringPref(PREF_REPORT_BREAKAGE_URL, path);
+
+ let comments = document.getElementById(
+ "protections-popup-sendReportView-collection-comments"
+ );
+ is(comments.value, "", "Comments textarea should initially be empty");
+
+ let submitButton = document.getElementById(
+ "protections-popup-sendReportView-submit"
+ );
+ let reportURL = document.getElementById(
+ "protections-popup-sendReportView-collection-url"
+ ).value;
+
+ is(reportURL, url, "Shows the correct URL in the report UI.");
+
+ // Make sure that sending the report closes the identity popup.
+ let popuphidden = BrowserTestUtils.waitForEvent(
+ gProtectionsHandler._protectionsPopup,
+ "popuphidden"
+ );
+
+ // Check that we're receiving a good report.
+ await new Promise(resolve => {
+ server.registerPathHandler("/", async (request, response) => {
+ is(request.method, "POST", "request was a post");
+
+ // Extract and "parse" the form data in the request body.
+ let body = CommonUtils.readBytesFromInputStream(request.bodyInputStream);
+ let boundary = request
+ .getHeader("Content-Type")
+ .match(/boundary=-+([^-]*)/i)[1];
+ let regex = new RegExp("-+" + boundary + "-*\\s+");
+ let sections = body.split(regex);
+
+ let prefs = [
+ "privacy.trackingprotection.enabled",
+ "privacy.trackingprotection.pbmode.enabled",
+ "urlclassifier.trackingTable",
+ "network.http.referer.defaultPolicy",
+ "network.http.referer.defaultPolicy.pbmode",
+ "network.cookie.cookieBehavior",
+ "privacy.annotate_channels.strict_list.enabled",
+ "privacy.restrict3rdpartystorage.expiration",
+ "privacy.trackingprotection.fingerprinting.enabled",
+ "privacy.trackingprotection.cryptomining.enabled",
+ ];
+ let prefsBody = "";
+
+ for (let pref of prefs) {
+ prefsBody += `${pref}: ${Preferences.get(pref)}\r\n`;
+ }
+
+ Assert.deepEqual(
+ sections,
+ [
+ "",
+ `Content-Disposition: form-data; name=\"title\"\r\n\r\n${
+ Services.io.newURI(reportURL).host
+ }\r\n`,
+ 'Content-Disposition: form-data; name="body"\r\n\r\n' +
+ `Full URL: ${reportURL + "?"}\r\n` +
+ `userAgent: ${navigator.userAgent}\r\n\r\n` +
+ "**Preferences**\r\n" +
+ `${prefsBody}\r\n` +
+ `hasException: ${hasException}\r\n\r\n` +
+ "**Comments**\r\n" +
+ "This is a comment\r\n",
+ 'Content-Disposition: form-data; name="labels"\r\n\r\n' +
+ `${hasException ? "" : tags}\r\n`,
+ "",
+ ],
+ "Should send the correct form data"
+ );
+
+ if (error) {
+ response.setStatusLine(request.httpVersion, 500, "Request failed");
+ } else {
+ response.setStatusLine(request.httpVersion, 201, "Entry created");
+ }
+
+ resolve();
+ });
+
+ comments.value = "This is a comment";
+ submitButton.click();
+ });
+
+ let errorMessage = document.getElementById(
+ "protections-popup-sendReportView-report-error"
+ );
+ if (error) {
+ await TestUtils.waitForCondition(() =>
+ BrowserTestUtils.is_visible(errorMessage)
+ );
+ is(
+ comments.value,
+ "This is a comment",
+ "Comment not cleared in case of an error"
+ );
+ gProtectionsHandler._protectionsPopup.hidePopup();
+ } else {
+ ok(BrowserTestUtils.is_hidden(errorMessage), "Error message not shown");
+ }
+
+ await popuphidden;
+
+ // Stop the server.
+ await new Promise(r => server.stop(r));
+
+ Services.prefs.clearUserPref(PREF_REPORT_BREAKAGE_URL);
+}