tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_smooth_scroll_preference.html (5059B)


      1 <!DOCTYPE HTML>
      2 <html>
      3 <head>
      4 <meta charset="utf-8">
      5 <title>Tests for smooth scroll preferences changes triggered by prefers-reduced-motion setting</title>
      6 <script src="/tests/SimpleTest/SimpleTest.js"></script>
      7 <script type="text/javascript" src="/tests/gfx/layers/apz/test/mochitest/apz_test_native_event_utils.js"></script>
      8 <script type="text/javascript" src="/tests/gfx/layers/apz/test/mochitest/apz_test_utils.js"></script>
      9 <link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
     10 <style>
     11 .spacer {
     12  height: 500vh;
     13 }
     14 </style>
     15 </head>
     16 <body>
     17 <p id="display"></p>
     18 <div id="content" style="display: none"></div>
     19 <pre id="test"></pre>
     20 <div class="spacer"></div>
     21 <script>
     22 async function changePrefersReducedMotion(aValue) {
     23  const uiPrefChangedPromise = new Promise(resolve => {
     24    SpecialPowers.addAsyncObserver(function LookAndFeelChanged() {
     25      SpecialPowers.removeAsyncObserver(LookAndFeelChanged, "look-and-feel-changed");
     26      resolve();
     27    }, "look-and-feel-changed");
     28  });
     29 
     30  await SpecialPowers.pushPrefEnv({
     31    set: [["ui.prefersReducedMotion", aValue]],
     32  });
     33  await uiPrefChangedPromise;
     34 
     35  // NOTE: Changing "ui.prefersReducedMotion" takes some amount of time for
     36  // some reasons, without this `promiseWaitForCondition`
     37  // `SpecialPowers.getBoolPref("general.smoothScroll")` checks in this test
     38  // intermittently fail specifically in verify runs.
     39  await SimpleTest.promiseWaitForCondition(() =>
     40    SpecialPowers.getIntPref("ui.prefersReducedMotion") == aValue, "");
     41  // Give a chance to reflect the "ui.prefersReducedMotion" change to
     42  // "general.smoothScroll".
     43  await new Promise(resolve => requestAnimationFrame(resolve));
     44 }
     45 
     46 add_setup(async () => {
     47  if (SpecialPowers.Services.prefs.prefHasUserValue("general.smoothScroll")) {
     48    const original = SpecialPowers.getBoolPref("general.smoothScroll");
     49    await SpecialPowers.clearUserPref("general.smoothScroll");
     50    // Restore the original value when this test finished.
     51    SimpleTest.registerCleanupFunction(async () => {
     52      await SpecialPowers.setBoolPref("general.smoothScroll", original);
     53    });
     54  }
     55 
     56  // Clear out `ui.prefersReducedMotion`.
     57  await SpecialPowers.pushPrefEnv({
     58    clear: [["ui.prefersReducedMotion"]],
     59  });
     60 
     61  SimpleTest.registerCleanupFunction(async () => {
     62    await SpecialPowers.clearUserPref("ui.prefersReducedMotion");
     63  });
     64 
     65  await changePrefersReducedMotion(0);
     66 });
     67 
     68 function promiseTwoScrollEvents(aTarget) {
     69  return new Promise(resolve => {
     70    let count = 0;
     71    const listener = event => {
     72      if (++count == 2) {
     73        aTarget.removeEventListener("scroll", listener);
     74        resolve();
     75      }
     76    }
     77    aTarget.addEventListener("scroll", listener);
     78  });
     79 }
     80 
     81 add_task(async () => {
     82  // This test assumes that the default value of `general.smoothScroll` is
     83  // true.
     84  ok(SpecialPowers.getBoolPref("general.smoothScroll"),
     85     "The default smoothScroll is true");
     86 
     87  // Do a smooth scroll operation.
     88  let twoScrollEventsPromise = promiseTwoScrollEvents(window);
     89  window.scrollBy({top: 500, behavior: "smooth"});
     90  await twoScrollEventsPromise;
     91 
     92  // Clobber the smooth scrolling.
     93  window.scrollTo({top: 0, behavior: "instant"});
     94  is(window.scrollY, 0);
     95 
     96  // Set preferes-reduced-motion.
     97  await changePrefersReducedMotion(1);
     98  ok(!SpecialPowers.getBoolPref("general.smoothScroll"),
     99     "The default smoothScroll is now false");
    100 
    101  // Do a smooth scroll operation, but it should be now instant.
    102  let scrollEventPromise = promiseOneEvent(window, "scroll");
    103  window.scrollBy({top: 500, behavior: "smooth"});
    104  await scrollEventPromise;
    105  // Allow 1px difference here since this test document gets loaded in an
    106  // iframe and the top level content document doesn't have any meta viewport
    107  // tag, thus this test document gets scaled down by < 1.0 value.
    108  isfuzzy(window.scrollY, 500, 1);
    109 
    110  // Reset the scroll position.
    111  window.scrollTo({top: 0, behavior: "instant"});
    112  is(window.scrollY, 0);
    113 
    114  // Disable preferes-reduced-motion.
    115  await changePrefersReducedMotion(0);
    116  ok(SpecialPowers.getBoolPref("general.smoothScroll"),
    117     "The default smoothScroll is now true again");
    118 
    119  // Set `general.smoothScroll` to true.
    120  await SpecialPowers.setBoolPref("general.smoothScroll", true);
    121  await new Promise(resolve => requestAnimationFrame(resolve));
    122 
    123  // Do a smooth scroll operation.
    124  twoScrollEventsPromise = promiseTwoScrollEvents(window);
    125  window.scrollBy({top: 500, behavior: "smooth"});
    126  await twoScrollEventsPromise;
    127 
    128  // Clobber the smooth scrolling.
    129  window.scrollTo({top: 0, behavior: "instant"});
    130  is(window.scrollY, 0);
    131 
    132  // Set preferes-reduced-motion again.
    133  await changePrefersReducedMotion(1);
    134  ok(SpecialPowers.getBoolPref("general.smoothScroll"),
    135     "The default smoothScroll is no longer be able to be changed by prefers-reduced-motion");
    136 
    137  // Do a smooth scroll operation again, it should be smooth.
    138  twoScrollEventsPromise = promiseTwoScrollEvents(window);
    139  window.scrollBy({top: 500, behavior: "smooth"});
    140  await twoScrollEventsPromise;
    141 });
    142 </script>
    143 </body>
    144 </html>