File: test_smooth_scroll_preference.html

package info (click to toggle)
firefox 147.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 4,683,324 kB
  • sloc: cpp: 7,607,156; javascript: 6,532,492; ansic: 3,775,158; python: 1,415,368; xml: 634,556; asm: 438,949; java: 186,241; sh: 62,751; makefile: 18,079; objc: 13,092; perl: 12,808; yacc: 4,583; cs: 3,846; pascal: 3,448; lex: 1,720; ruby: 1,003; php: 436; lisp: 258; awk: 247; sql: 66; sed: 54; csh: 10; exp: 6
file content (144 lines) | stat: -rw-r--r-- 5,059 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Tests for smooth scroll preferences changes triggered by prefers-reduced-motion setting</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/gfx/layers/apz/test/mochitest/apz_test_native_event_utils.js"></script>
<script type="text/javascript" src="/tests/gfx/layers/apz/test/mochitest/apz_test_utils.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
<style>
.spacer {
  height: 500vh;
}
</style>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test"></pre>
<div class="spacer"></div>
<script>
async function changePrefersReducedMotion(aValue) {
  const uiPrefChangedPromise = new Promise(resolve => {
    SpecialPowers.addAsyncObserver(function LookAndFeelChanged() {
      SpecialPowers.removeAsyncObserver(LookAndFeelChanged, "look-and-feel-changed");
      resolve();
    }, "look-and-feel-changed");
  });

  await SpecialPowers.pushPrefEnv({
    set: [["ui.prefersReducedMotion", aValue]],
  });
  await uiPrefChangedPromise;

  // NOTE: Changing "ui.prefersReducedMotion" takes some amount of time for
  // some reasons, without this `promiseWaitForCondition`
  // `SpecialPowers.getBoolPref("general.smoothScroll")` checks in this test
  // intermittently fail specifically in verify runs.
  await SimpleTest.promiseWaitForCondition(() =>
    SpecialPowers.getIntPref("ui.prefersReducedMotion") == aValue, "");
  // Give a chance to reflect the "ui.prefersReducedMotion" change to
  // "general.smoothScroll".
  await new Promise(resolve => requestAnimationFrame(resolve));
}

add_setup(async () => {
  if (SpecialPowers.Services.prefs.prefHasUserValue("general.smoothScroll")) {
    const original = SpecialPowers.getBoolPref("general.smoothScroll");
    await SpecialPowers.clearUserPref("general.smoothScroll");
    // Restore the original value when this test finished.
    SimpleTest.registerCleanupFunction(async () => {
      await SpecialPowers.setBoolPref("general.smoothScroll", original);
    });
  }

  // Clear out `ui.prefersReducedMotion`.
  await SpecialPowers.pushPrefEnv({
    clear: [["ui.prefersReducedMotion"]],
  });

  SimpleTest.registerCleanupFunction(async () => {
    await SpecialPowers.clearUserPref("ui.prefersReducedMotion");
  });

  await changePrefersReducedMotion(0);
});

function promiseTwoScrollEvents(aTarget) {
  return new Promise(resolve => {
    let count = 0;
    const listener = event => {
      if (++count == 2) {
        aTarget.removeEventListener("scroll", listener);
        resolve();
      }
    }
    aTarget.addEventListener("scroll", listener);
  });
}

add_task(async () => {
  // This test assumes that the default value of `general.smoothScroll` is
  // true.
  ok(SpecialPowers.getBoolPref("general.smoothScroll"),
     "The default smoothScroll is true");

  // Do a smooth scroll operation.
  let twoScrollEventsPromise = promiseTwoScrollEvents(window);
  window.scrollBy({top: 500, behavior: "smooth"});
  await twoScrollEventsPromise;

  // Clobber the smooth scrolling.
  window.scrollTo({top: 0, behavior: "instant"});
  is(window.scrollY, 0);

  // Set preferes-reduced-motion.
  await changePrefersReducedMotion(1);
  ok(!SpecialPowers.getBoolPref("general.smoothScroll"),
     "The default smoothScroll is now false");

  // Do a smooth scroll operation, but it should be now instant.
  let scrollEventPromise = promiseOneEvent(window, "scroll");
  window.scrollBy({top: 500, behavior: "smooth"});
  await scrollEventPromise;
  // Allow 1px difference here since this test document gets loaded in an
  // iframe and the top level content document doesn't have any meta viewport
  // tag, thus this test document gets scaled down by < 1.0 value.
  isfuzzy(window.scrollY, 500, 1);

  // Reset the scroll position.
  window.scrollTo({top: 0, behavior: "instant"});
  is(window.scrollY, 0);

  // Disable preferes-reduced-motion.
  await changePrefersReducedMotion(0);
  ok(SpecialPowers.getBoolPref("general.smoothScroll"),
     "The default smoothScroll is now true again");

  // Set `general.smoothScroll` to true.
  await SpecialPowers.setBoolPref("general.smoothScroll", true);
  await new Promise(resolve => requestAnimationFrame(resolve));

  // Do a smooth scroll operation.
  twoScrollEventsPromise = promiseTwoScrollEvents(window);
  window.scrollBy({top: 500, behavior: "smooth"});
  await twoScrollEventsPromise;

  // Clobber the smooth scrolling.
  window.scrollTo({top: 0, behavior: "instant"});
  is(window.scrollY, 0);

  // Set preferes-reduced-motion again.
  await changePrefersReducedMotion(1);
  ok(SpecialPowers.getBoolPref("general.smoothScroll"),
     "The default smoothScroll is no longer be able to be changed by prefers-reduced-motion");

  // Do a smooth scroll operation again, it should be smooth.
  twoScrollEventsPromise = promiseTwoScrollEvents(window);
  window.scrollBy({top: 500, behavior: "smooth"});
  await twoScrollEventsPromise;
});
</script>
</body>
</html>