tor-browser

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

test_coalesce_mousewheel.html (9986B)


      1 <!DOCTYPE HTML>
      2 <html>
      3 <head>
      4  <meta charset="utf-8">
      5  <title>mousewheel coalescing</title>
      6  <script src="/tests/SimpleTest/SimpleTest.js"></script>
      7  <script src="/tests/SimpleTest/EventUtils.js"></script>
      8  <script src="apz_test_utils.js"></script>
      9  <script src="apz_test_native_event_utils.js"></script>
     10  <link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
     11  <script>
     12  let wheelEvents = [];
     13  function mousewheel(aWheelEvent) {
     14    // Make mousewheel handling slow
     15    var start = performance.now();
     16    while (performance.now() < (start + 10));
     17    wheelEvents.push(aWheelEvent);
     18  }
     19 
     20  function resolveIfProcessed(resolve, minamount) {
     21    if (wheelEvents.length >= minamount) {
     22      SimpleTest.requestFlakyTimeout("Make sure we got all events.");
     23      setTimeout(function() { resolve(); }, 20);
     24    } else {
     25      setTimeout(function() { resolveIfProcessed(resolve, minamount); });
     26    }
     27  }
     28 
     29  const kLineDeltaFactor =
     30    SpecialPowers.getBoolPref("mousewheel.system_scroll_override.enabled", false)
     31      ? SpecialPowers.getIntPref("mousewheel.system_scroll_override.vertical.factor", 200) / 100
     32      : 1;
     33 
     34  function checkWheelEvents(aExpectedDeltaMode, aExpectedSumOfDeltaY, aDescription) {
     35    const lineDeltaFactor =
     36      aExpectedDeltaMode === WheelEvent.DOM_DELTA_LINE ? kLineDeltaFactor : 1;
     37    let succeeded = true;
     38    let deltaY = 0;
     39    for (const wheelEvent of wheelEvents) {
     40      succeeded &= wheelEvent.deltaMode === aExpectedDeltaMode;
     41      is(wheelEvent.deltaMode, aExpectedDeltaMode,
     42        `When ${aDescription}, the deltaMode of all wheel events should be ${aExpectedDeltaMode}`);
     43      deltaY += wheelEvent.deltaY;
     44    }
     45    succeeded &= deltaY == aExpectedSumOfDeltaY * lineDeltaFactor;
     46    is(deltaY, aExpectedSumOfDeltaY * lineDeltaFactor,
     47      `When ${aDescription}, sum of the deltaY of all wheel events should be ${aExpectedSumOfDeltaY * lineDeltaFactor}`);
     48    return succeeded;
     49  }
     50 
     51  async function testOneSingleWheelEvent() {
     52    await new Promise(function(resolve) {
     53      wheelEvents = [];
     54      var element = document.getElementById("wheelEventReceiver");
     55      element.addEventListener("wheel", mousewheel, true);
     56 
     57      synthesizeWheel(element, 10, 10, { deltaY: 3.0, deltaMode: WheelEvent.DOM_DELTA_LINE });
     58 
     59      setTimeout(function() { resolveIfProcessed(resolve, 1); });
     60    });
     61    is(wheelEvents.length, 1,
     62      "Synthesizing a wheel event via the parent process should cause 1 wheel event");
     63    is(wheelEvents[0]?.deltaMode, WheelEvent.DOM_DELTA_LINE,
     64      "When Synthesizing a wheel event via the parent process, the deltaMode of a wheel event should be WheelEvent.DOM_DELTA_LINE");
     65    is(wheelEvents[0]?.deltaY, 3 * kLineDeltaFactor,
     66      `When Synthesizing a wheel event via the parent process, the deltaY of a wheel event should be ${3 * kLineDeltaFactor}`);
     67  }
     68 
     69  const kMaxRetry = 10;
     70 
     71  async function testTwoSingleWheelEvents() {
     72    function tryIt() {
     73      return new Promise(function(resolve) {
     74        info("Synthesizing 2 wheel events via the parent process...");
     75        wheelEvents = [];
     76        var element = document.getElementById("wheelEventReceiver");
     77        element.addEventListener("wheel", mousewheel, true);
     78 
     79        synthesizeWheel(element, 10, 10, { deltaY: 3.0, deltaMode: WheelEvent.DOM_DELTA_LINE });
     80        synthesizeWheel(element, 10, 10, { deltaY: 3.0, deltaMode: WheelEvent.DOM_DELTA_LINE });
     81 
     82        setTimeout(function() { resolveIfProcessed(resolve, 1); });
     83      });
     84    }
     85    for (let i = 0; i < kMaxRetry; i++) {
     86      await tryIt();
     87      if (wheelEvents.length == 2) {
     88        // Even if failed to coalescing, the sum of deltaY values should be same
     89        // as sum of the synthesized ones.
     90        if (!checkWheelEvents(WheelEvent.DOM_DELTA_LINE, 6,
     91                              "synthesizing 2 wheel events via the parent process")) {
     92          return;
     93        }
     94        continue;  // retry
     95      }
     96      is(wheelEvents.length, 1,
     97        "Synthesizing 2 wheel events via the parent process should cause only 1 wheel event");
     98      checkWheelEvents(WheelEvent.DOM_DELTA_LINE, 6,
     99                       "synthesizing 2 wheel events via the parent process");
    100      return;
    101    }
    102  }
    103 
    104  async function testManySingleWheelEvents() {
    105    function tryIt() {
    106      return new Promise(function(resolve) {
    107        info("Synthesizing 5 wheel events via the parent process...");
    108        wheelEvents = [];
    109        var element = document.getElementById("wheelEventReceiver");
    110        element.addEventListener("wheel", mousewheel, true);
    111 
    112        synthesizeWheel(element, 10, 10, { deltaY: 3.0, deltaMode: WheelEvent.DOM_DELTA_LINE });
    113        synthesizeWheel(element, 10, 10, { deltaY: 3.0, deltaMode: WheelEvent.DOM_DELTA_LINE });
    114        synthesizeWheel(element, 10, 10, { deltaY: 3.0, deltaMode: WheelEvent.DOM_DELTA_LINE });
    115        synthesizeWheel(element, 10, 10, { deltaY: 3.0, deltaMode: WheelEvent.DOM_DELTA_LINE });
    116        synthesizeWheel(element, 10, 10, { deltaY: 3.0, deltaMode: WheelEvent.DOM_DELTA_LINE });
    117 
    118        setTimeout(function() { resolveIfProcessed(resolve, 1); });
    119      });
    120    }
    121    for (let i = 0; i < kMaxRetry; i++) {
    122      await tryIt();
    123      if (wheelEvents.length > 1 && wheelEvents.length <= 5) {
    124        // Even if failed to coalescing, the sum of deltaY values should be same
    125        // as sum of the synthesized ones.
    126        if (!checkWheelEvents(WheelEvent.DOM_DELTA_LINE, 15,
    127                              "synthesizing 5 wheel events via the parent process")) {
    128          return;
    129        }
    130        continue;  // retry
    131      }
    132      is(wheelEvents.length, 1,
    133        "Synthesizing 5 wheel events via the parent process should cause only 1 wheel event");
    134      checkWheelEvents(WheelEvent.DOM_DELTA_LINE, 15,
    135                       "synthesizing 5 wheel events via the parent process");
    136      return;
    137    }
    138  }
    139 
    140  async function testMixedWheelEvents() {
    141    function tryIt() {
    142      return new Promise(function(resolve) {
    143        info("Synthesizing 2 line wheel events, 1 page wheel event and 1 line wheel event...");
    144        wheelEvents = [];
    145        var element = document.getElementById("wheelEventReceiver");
    146        element.addEventListener("wheel", mousewheel, true);
    147 
    148        synthesizeWheel(element, 10, 10, { deltaY: 3.0, deltaMode: WheelEvent.DOM_DELTA_LINE });
    149        synthesizeWheel(element, 10, 10, { deltaY: 3.0, deltaMode: WheelEvent.DOM_DELTA_LINE });
    150        synthesizeWheel(element, 10, 10, { deltaY: 3.0, deltaMode: WheelEvent.DOM_DELTA_PAGE });
    151        synthesizeWheel(element, 10, 10, { deltaY: 3.0, deltaMode: WheelEvent.DOM_DELTA_LINE });
    152 
    153        setTimeout(function() { resolveIfProcessed(resolve, 3); });
    154      });
    155    }
    156    function checkGroupsOfWheelEvents() {
    157      let succeeded = true;
    158      let deltaY = [0, 0, 0];
    159      let index = 0;
    160      const description = "synthesizing 2 line wheel events, 1 page wheel event and 1 line wheel event";
    161      for (const wheelEvent of wheelEvents) {
    162        switch (index) {
    163          case 0:
    164            if (wheelEvent.deltaMode === WheelEvent.DOM_DELTA_LINE) {
    165              is(wheelEvent.deltaMode, WheelEvent.DOM_DELTA_LINE,
    166                `When ${description}, the deltaMode of the first group should be WheelEvent.DOM_DELTA_LINE`);
    167              break;
    168            }
    169            index++;
    170            // fallthrough
    171          case 1:
    172            if (wheelEvent.deltaMode === WheelEvent.DOM_DELTA_PAGE) {
    173              is(wheelEvent.deltaMode, WheelEvent.DOM_DELTA_PAGE,
    174                `When ${description}, the deltaMode of the seconde group should be WheelEvent.DOM_DELTA_PAGE`);
    175              break;
    176            }
    177            index++;
    178            // fallthrough
    179          case 2:
    180            succeeded &= wheelEvent.deltaMode === WheelEvent.DOM_DELTA_LINE;
    181            is(wheelEvent.deltaMode, WheelEvent.DOM_DELTA_LINE,
    182              `When ${description}, the deltaMode of the last group should be WheelEvent.DOM_DELTA_LINE`);
    183            break;
    184        }
    185        deltaY[index] += wheelEvent.deltaY;
    186      }
    187      succeeded &= deltaY == [6 * kLineDeltaFactor, 3, 3 * kLineDeltaFactor];
    188      isDeeply(deltaY, [6 * kLineDeltaFactor, 3, 3 * kLineDeltaFactor],
    189        `When ${description}, sum of the deltaY of the each wheel event group should be same as sum of the synthesized ones`);
    190      return succeeded;
    191    }
    192    for (let i = 0; i < kMaxRetry; i++) {
    193      await tryIt();
    194      if (wheelEvents.length != 3 && wheelEvents.length > 1 && wheelEvents.length <= 5) {
    195        // Even if failed to coalescing, the sum of deltaY values should be same
    196        // as sum of the synthesized ones and the wheel events shouldn't be
    197        // reordered.
    198        if (!checkGroupsOfWheelEvents()) {
    199          return;
    200        }
    201        continue;  // retry
    202      }
    203      is(wheelEvents.length, 3,
    204        "Synthesizing 2 line wheel events, 1 page wheel event and 1 line wheel event via the parent process should cause only 3 wheel events");
    205      checkGroupsOfWheelEvents();
    206      return;
    207    }
    208  }
    209 
    210  async function runTests() {
    211    var enabled = SpecialPowers.getDOMWindowUtils(window).asyncPanZoomEnabled;
    212 
    213    // Avoid synthesized mousemove events to be fired at the system cursor.
    214    await promiseNativeMouseEvent({
    215      type: "mousemove",
    216      screenX: 0,
    217      screenY: 0,
    218    });
    219 
    220    await SpecialPowers.pushPrefEnv({set: [
    221      ["test.events.async.enabled", true],
    222      ["dom.event.wheel-coalesced.testing", true],
    223    ]});
    224    await promiseElementReadyForUserInput(document.documentElement);
    225    await SpecialPowers.pushPrefEnv({clear: [["test.events.async.enabled"]]});
    226 
    227    await testOneSingleWheelEvent();
    228    await testTwoSingleWheelEvents();
    229    await testManySingleWheelEvents();
    230    await testMixedWheelEvents();
    231 
    232    setTimeout(SimpleTest.finish);
    233    window.close();
    234  }
    235 
    236  </script>
    237 </head>
    238 <body onload="SimpleTest.waitForFocus(runTests);">
    239  <div id="wheelEventReceiver" style="width:100px;height:100px;"></div>
    240 </body>
    241 </html>