Bug 1732919 - Update tests for new Storage Access API user activation behavior. r=anti-tracking-reviewers,timhuang
authorPaul Zuehlcke <pbz@mozilla.com>
Thu, 14 Oct 2021 12:22:03 +0000
changeset 595882 bf5c1bc311c8216f460b1f3bb06ef4dcf373ec0b
parent 595881 93edca563ab67e4477adce481c4347a8396d77cb
child 595883 80776c2142e0952b13ba0b16a2d175ba4b026547
push id151487
push userpzuhlcke@mozilla.com
push dateThu, 14 Oct 2021 12:24:40 +0000
treeherderautoland@37b33717e0b6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersanti-tracking-reviewers, timhuang
bugs1732919
milestone95.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 1732919 - Update tests for new Storage Access API user activation behavior. r=anti-tracking-reviewers,timhuang Differential Revision: https://phabricator.services.mozilla.com/D127152
js/xpconnect/tests/browser/browser_promise_userInteractionHandling.html
js/xpconnect/tests/browser/browser_promise_userInteractionHandling.js
toolkit/components/antitracking/test/browser/browser_allowPermissionForTracker.js
toolkit/components/antitracking/test/browser/browser_denyPermissionForTracker.js
toolkit/components/antitracking/test/browser/browser_storageAccessPrivilegeAPI.js
toolkit/components/antitracking/test/browser/browser_storageAccessPromiseRejectHandlerUserInteraction.js
toolkit/components/antitracking/test/browser/browser_storageAccessPromiseResolveHandlerUserInteraction.js
toolkit/components/antitracking/test/browser/storageAccessAPIHelpers.js
--- a/js/xpconnect/tests/browser/browser_promise_userInteractionHandling.html
+++ b/js/xpconnect/tests/browser/browser_promise_userInteractionHandling.html
@@ -11,15 +11,15 @@ const domWindowUtils = SpecialPowers.get
 
 is(domWindowUtils.isHandlingUserInput, false, "not yet handling user input");
 
 const button = document.getElementById("button")
 
 button.addEventListener("click", () => {
   is(domWindowUtils.isHandlingUserInput, true, "handling user input");
 
-  document.requestStorageAccess().then(() => {
+  document.hasStorageAccess().then(() => {
     is(domWindowUtils.isHandlingUserInput, true, "still handling user input");
   });
 });
 </script>
 </body>
 </html>
--- a/js/xpconnect/tests/browser/browser_promise_userInteractionHandling.js
+++ b/js/xpconnect/tests/browser/browser_promise_userInteractionHandling.js
@@ -17,17 +17,17 @@ add_task(async function test_explicit_ob
          "not yet handling user input");
       const button = content.document.getElementById("button");
 
       let resolve;
       const p = new Promise(r => { resolve = r; });
 
       button.addEventListener("click", () => {
         is(DOMWindowUtils.isHandlingUserInput, true, "handling user input");
-        content.document.requestStorageAccess().then(() => {
+        content.document.hasStorageAccess().then(() => {
           is(DOMWindowUtils.isHandlingUserInput, true,
              "still handling user input");
           Promise.resolve().then(() => {
             is(DOMWindowUtils.isHandlingUserInput, false,
                "no more handling user input");
             resolve();
           });
         });
--- a/toolkit/components/antitracking/test/browser/browser_allowPermissionForTracker.js
+++ b/toolkit/components/antitracking/test/browser/browser_allowPermissionForTracker.js
@@ -32,27 +32,26 @@ AntiTracking._createTask({
   cookieBehavior: BEHAVIOR_REJECT_TRACKER,
   blockingByContentBlockingRTUI: false,
   allowList: false,
   callback: async _ => {
     document.cookie = "name=value";
     ok(document.cookie != "", "Nothing is blocked");
 
     // requestStorageAccess should resolve
-    let dwu = SpecialPowers.getDOMWindowUtils(window);
-    let helper = dwu.setHandlingUserInput(true);
+    SpecialPowers.wrap(document).notifyUserGestureActivation();
     await document
       .requestStorageAccess()
       .then(() => {
         ok(true, "Should grant storage access");
       })
       .catch(() => {
         ok(false, "Should grant storage access");
       });
-    helper.destruct();
+    SpecialPowers.wrap(document).clearUserGestureActivation();
   },
   extraPrefs: null,
   expectedBlockingNotifications: 0,
   runInPrivateWindow: false,
   iframeSandbox: null,
   accessRemoval: null,
   callbackAfterRemoval: null,
 });
--- a/toolkit/components/antitracking/test/browser/browser_denyPermissionForTracker.js
+++ b/toolkit/components/antitracking/test/browser/browser_denyPermissionForTracker.js
@@ -32,27 +32,26 @@ AntiTracking._createTask({
   cookieBehavior: BEHAVIOR_REJECT_TRACKER,
   blockingByContentBlockingRTUI: true,
   allowList: false,
   callback: async _ => {
     document.cookie = "name=value";
     ok(document.cookie == "", "All is blocked");
 
     // requestStorageAccess should reject
-    let dwu = SpecialPowers.getDOMWindowUtils(window);
-    let helper = dwu.setHandlingUserInput(true);
+    SpecialPowers.wrap(document).notifyUserGestureActivation();
     await document
       .requestStorageAccess()
       .then(() => {
         ok(false, "Should not grant storage access");
       })
       .catch(() => {
         ok(true, "Should not grant storage access");
       });
-    helper.destruct();
+    SpecialPowers.wrap(document).clearUserGestureActivation();
   },
   extraPrefs: null,
   expectedBlockingNotifications:
     Ci.nsIWebProgressListener.STATE_COOKIES_BLOCKED_BY_PERMISSION,
   runInPrivateWindow: false,
   iframeSandbox: null,
   accessRemoval: null,
   callbackAfterRemoval: null,
--- a/toolkit/components/antitracking/test/browser/browser_storageAccessPrivilegeAPI.js
+++ b/toolkit/components/antitracking/test/browser/browser_storageAccessPrivilegeAPI.js
@@ -172,30 +172,29 @@ add_task(async function test_privilege_a
   });
 
   let storagePermissionPromise = waitStoragePermission(
     "https://tracking.example.org"
   );
 
   // Call the privilege API.
   await SpecialPowers.spawn(browser, [], async _ => {
-    // The privilege API requires a user gesture. So, we set the user handling
-    // flag before we call the API.
-    let dwu = SpecialPowers.getDOMWindowUtils(content);
-    let helper = dwu.setHandlingUserInput(true);
+    // The privilege API requires user activation. So, we set the user
+    // activation flag before we call the API.
+    content.document.notifyUserGestureActivation();
 
     try {
       await content.document.requestStorageAccessForOrigin(
         "https://tracking.example.org/"
       );
     } catch (e) {
       ok(false, "The API shouldn't throw.");
     }
 
-    helper.destruct();
+    content.document.clearUserGestureActivation();
   });
 
   // Verify if the storage access permission is set correctly.
   await storagePermissionPromise;
 
   // Verify if the existing third-party tracker iframe gains the storage
   // access.
   await runScriptInSubFrame(browser, "test", async _ => {
@@ -269,28 +268,27 @@ add_task(async function test_privilege_a
   let storagePermissionPromise = waitStoragePermission(
     "http://not-tracking.example.com"
   );
 
   // Call the privilege API.
   await SpecialPowers.spawn(browser, [], async _ => {
     // The privilege API requires a user gesture. So, we set the user handling
     // flag before we call the API.
-    let dwu = SpecialPowers.getDOMWindowUtils(content);
-    let helper = dwu.setHandlingUserInput(true);
+    content.document.notifyUserGestureActivation();
 
     try {
       await content.document.requestStorageAccessForOrigin(
         "http://not-tracking.example.com/"
       );
     } catch (e) {
       ok(false, "The API shouldn't throw.");
     }
 
-    helper.destruct();
+    content.document.clearUserGestureActivation();
   });
 
   // Verify if the storage access permission is set correctly.
   await storagePermissionPromise;
 
   // Verify if the existing third-party iframe gains the storage access.
   await runScriptInSubFrame(browser, "test", async _ => {
     await hasStorageAccessInitially();
@@ -360,31 +358,30 @@ add_task(async function test_prompt() {
       PopupNotifications.panel,
       "popuphidden"
     );
 
     // Call the privilege API.
     let callAPIPromise = SpecialPowers.spawn(browser, [allow], async allow => {
       // The privilege API requires a user gesture. So, we set the user handling
       // flag before we call the API.
-      let dwu = SpecialPowers.getDOMWindowUtils(content);
-      let helper = dwu.setHandlingUserInput(true);
+      content.document.notifyUserGestureActivation();
       let isThrown = false;
 
       try {
         await content.document.requestStorageAccessForOrigin(
           "https://tracking.example.org"
         );
       } catch (e) {
         isThrown = true;
       }
 
       is(isThrown, !allow, `The API ${allow ? "shouldn't" : "should"} throw.`);
 
-      helper.destruct();
+      content.document.clearUserGestureActivation();
     });
 
     await shownPromise;
 
     let notification = await TestUtils.waitForCondition(_ =>
       PopupNotifications.getNotification("storage-access", browser)
     );
     ok(notification, "Should have gotten the notification");
@@ -442,42 +439,42 @@ add_task(async function test_invalid_inp
       await content.document.requestStorageAccessForOrigin(
         "https://tracking.example.org"
       );
     } catch (e) {
       isThrown = true;
     }
     ok(isThrown, "The API should throw without user gesture.");
 
-    let dwu = SpecialPowers.getDOMWindowUtils(content);
-    let helper = dwu.setHandlingUserInput(true);
-
+    content.document.notifyUserGestureActivation();
     isThrown = false;
     try {
       await content.document.requestStorageAccessForOrigin();
     } catch (e) {
       isThrown = true;
     }
     ok(isThrown, "The API should throw with no input.");
 
+    content.document.notifyUserGestureActivation();
     isThrown = false;
     try {
       await content.document.requestStorageAccessForOrigin("");
     } catch (e) {
       isThrown = true;
       is(e.name, "NS_ERROR_MALFORMED_URI", "The input is not a valid url");
     }
     ok(isThrown, "The API should throw with empty string.");
 
+    content.document.notifyUserGestureActivation();
     isThrown = false;
     try {
       await content.document.requestStorageAccessForOrigin("invalid url");
     } catch (e) {
       isThrown = true;
       is(e.name, "NS_ERROR_MALFORMED_URI", "The input is not a valid url");
     }
     ok(isThrown, "The API should throw with invalid url.");
 
-    helper.destruct();
+    content.document.clearUserGestureActivation();
   });
 
   BrowserTestUtils.removeTab(tab);
 });
--- a/toolkit/components/antitracking/test/browser/browser_storageAccessPromiseRejectHandlerUserInteraction.js
+++ b/toolkit/components/antitracking/test/browser/browser_storageAccessPromiseRejectHandlerUserInteraction.js
@@ -1,19 +1,19 @@
 /* import-globals-from antitracking_head.js */
 
 AntiTracking.runTest(
-  "Storage Access API returns promises that maintain user activation for calling its reject handler",
+  "Storage Access API returns promises that do not maintain user activation for calling its reject handler",
   // blocking callback
   async _ => {
     /* import-globals-from storageAccessAPIHelpers.js */
-    let [threw, rejected] = await callRequestStorageAccess(dwu => {
+    let [threw, rejected] = await callRequestStorageAccess(() => {
       ok(
-        dwu.isHandlingUserInput,
-        "Promise reject handler must run as if we're handling user input"
+        !SpecialPowers.wrap(document).hasValidTransientUserGestureActivation,
+        "Promise reject handler must not have user activation"
       );
     }, true);
     ok(!threw, "requestStorageAccess should not throw");
     ok(rejected, "requestStorageAccess should not be available");
   },
 
   null, // non-blocking callback
   // cleanup function
--- a/toolkit/components/antitracking/test/browser/browser_storageAccessPromiseResolveHandlerUserInteraction.js
+++ b/toolkit/components/antitracking/test/browser/browser_storageAccessPromiseResolveHandlerUserInteraction.js
@@ -1,39 +1,32 @@
 /* import-globals-from antitracking_head.js */
 
 AntiTracking.runTest(
   "Storage Access API returns promises that maintain user activation",
   // blocking callback
   async _ => {
     /* import-globals-from storageAccessAPIHelpers.js */
-    let [threw, rejected] = await callRequestStorageAccess(dwu => {
+    let [threw, rejected] = await callRequestStorageAccess(() => {
       ok(
-        dwu.isHandlingUserInput,
+        SpecialPowers.wrap(document).hasValidTransientUserGestureActivation,
         "Promise handler must run as if we're handling user input"
       );
     });
     ok(!threw, "requestStorageAccess should not throw");
     ok(!rejected, "requestStorageAccess should be available");
 
-    let dwu = SpecialPowers.getDOMWindowUtils(window);
-    let helper = dwu.setHandlingUserInput(true);
+    SpecialPowers.wrap(document).notifyUserGestureActivation();
+
+    await document.hasStorageAccess();
 
-    let promise;
-    try {
-      promise = document.hasStorageAccess();
-    } finally {
-      helper.destruct();
-    }
-    await promise.then(_ => {
-      ok(
-        dwu.isHandlingUserInput,
-        "Promise handler must run as if we're handling user input"
-      );
-    });
+    ok(
+      SpecialPowers.wrap(document).hasValidTransientUserGestureActivation,
+      "Promise handler must run as if we're handling user input"
+    );
   },
 
   null, // non-blocking callback
   // cleanup function
   async _ => {
     await new Promise(resolve => {
       Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, value =>
         resolve()
--- a/toolkit/components/antitracking/test/browser/storageAccessAPIHelpers.js
+++ b/toolkit/components/antitracking/test/browser/storageAccessAPIHelpers.js
@@ -11,18 +11,17 @@ async function noStorageAccessInitially(
 }
 
 async function stillNoStorageAccess() {
   let hasAccess = await document.hasStorageAccess();
   ok(!hasAccess, "Still doesn't have storage access");
 }
 
 async function callRequestStorageAccess(callback, expectFail) {
-  let dwu = SpecialPowers.getDOMWindowUtils(window);
-  let helper = dwu.setHandlingUserInput(true);
+  SpecialPowers.wrap(document).notifyUserGestureActivation();
 
   let origin = new URL(location.href).origin;
 
   let effectiveCookieBehavior = SpecialPowers.isContentWindowPrivate(window)
     ? SpecialPowers.Services.prefs.getIntPref(
         "network.cookie.cookieBehavior.pbmode"
       )
     : SpecialPowers.Services.prefs.getIntPref("network.cookie.cookieBehavior");
@@ -42,96 +41,96 @@ async function callRequestStorageAccess(
   if (origin != TEST_ANOTHER_3RD_PARTY_ORIGIN) {
     if (rejectTrackers) {
       let p;
       let threw = false;
       try {
         p = document.requestStorageAccess();
       } catch (e) {
         threw = true;
-      } finally {
-        helper.destruct();
       }
       ok(!threw, "requestStorageAccess should not throw");
       try {
         if (callback) {
           if (expectFail) {
-            await p.catch(_ => callback(dwu));
+            await p.catch(_ => callback());
             success = false;
           } else {
-            await p.then(_ => callback(dwu));
+            await p.then(_ => callback());
           }
         } else {
           await p;
         }
       } catch (e) {
         success = false;
+      } finally {
+        SpecialPowers.wrap(document).clearUserGestureActivation();
       }
       ok(!success, "Should not have worked without user interaction");
 
       await noStorageAccessInitially();
 
       await interactWithTracker();
 
-      helper = dwu.setHandlingUserInput(true);
+      SpecialPowers.wrap(document).notifyUserGestureActivation();
     }
     if (
       effectiveCookieBehavior ==
         SpecialPowers.Ci.nsICookieService.BEHAVIOR_ACCEPT &&
       !isOnContentBlockingAllowList()
     ) {
       try {
         if (callback) {
           if (expectFail) {
-            await document.requestStorageAccess().catch(_ => callback(dwu));
+            await document.requestStorageAccess().catch(_ => callback());
             success = false;
           } else {
-            await document.requestStorageAccess().then(_ => callback(dwu));
+            await document.requestStorageAccess().then(_ => callback());
           }
         } else {
           await document.requestStorageAccess();
         }
       } catch (e) {
         success = false;
       } finally {
-        helper.destruct();
+        SpecialPowers.wrap(document).clearUserGestureActivation();
       }
       ok(success, "Should not have thrown");
 
       await hasStorageAccessInitially();
 
       await interactWithTracker();
 
-      helper = dwu.setHandlingUserInput(true);
+      SpecialPowers.wrap(document).notifyUserGestureActivation();
     }
   }
 
   let p;
   let threw = false;
   try {
     p = document.requestStorageAccess();
   } catch (e) {
     threw = true;
-  } finally {
-    helper.destruct();
   }
   let rejected = false;
   try {
     if (callback) {
       if (expectFail) {
-        await p.catch(_ => callback(dwu));
+        await p.catch(_ => callback());
         rejected = true;
       } else {
-        await p.then(_ => callback(dwu));
+        await p.then(_ => callback());
       }
     } else {
       await p;
     }
   } catch (e) {
     rejected = true;
+  } finally {
+    SpecialPowers.wrap(document).clearUserGestureActivation();
   }
 
   success = !threw && !rejected;
   let hasAccess = await document.hasStorageAccess();
   is(
     hasAccess,
     success,
     "Should " + (success ? "" : "not ") + "have storage access now"