tor-browser

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

browser_test_scrolling.js (9075B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 "use strict";
      6 
      7 /* import-globals-from ../../mochitest/role.js */
      8 loadScripts({ name: "role.js", dir: MOCHITESTS_DIR });
      9 
     10 addAccessibleTask(
     11  `
     12    <div style="height: 100vh" id="one">one</div>
     13    <div style="height: 100vh" id="two">two</div>
     14    <div style="height: 100vh; width: 200vw; overflow: auto;" id="three">
     15      <div style="height: 300%;">three</div>
     16    </div>
     17    <textarea id="textarea" rows="1">a
     18 b
     19 c</textarea>
     20  `,
     21  async function (browser, accDoc) {
     22    let onScrolling = waitForEvents([
     23      [EVENT_SCROLLING, accDoc],
     24      [EVENT_SCROLLING_END, accDoc],
     25    ]);
     26    await SpecialPowers.spawn(browser, [], () => {
     27      content.location.hash = "#two";
     28    });
     29    let [scrollEvent1, scrollEndEvent1] = await onScrolling;
     30    scrollEvent1.QueryInterface(nsIAccessibleScrollingEvent);
     31    Assert.greaterOrEqual(
     32      scrollEvent1.maxScrollY,
     33      scrollEvent1.scrollY,
     34      "scrollY is within max"
     35    );
     36    scrollEndEvent1.QueryInterface(nsIAccessibleScrollingEvent);
     37    Assert.greaterOrEqual(
     38      scrollEndEvent1.maxScrollY,
     39      scrollEndEvent1.scrollY,
     40      "scrollY is within max"
     41    );
     42 
     43    onScrolling = waitForEvents([
     44      [EVENT_SCROLLING, accDoc],
     45      [EVENT_SCROLLING_END, accDoc],
     46    ]);
     47    await SpecialPowers.spawn(browser, [], () => {
     48      content.location.hash = "#three";
     49    });
     50    let [scrollEvent2, scrollEndEvent2] = await onScrolling;
     51    scrollEvent2.QueryInterface(nsIAccessibleScrollingEvent);
     52    Assert.greater(
     53      scrollEvent2.scrollY,
     54      scrollEvent1.scrollY,
     55      `${scrollEvent2.scrollY} > ${scrollEvent1.scrollY}`
     56    );
     57    scrollEndEvent2.QueryInterface(nsIAccessibleScrollingEvent);
     58    Assert.greaterOrEqual(
     59      scrollEndEvent2.maxScrollY,
     60      scrollEndEvent2.scrollY,
     61      "scrollY is within max"
     62    );
     63 
     64    onScrolling = waitForEvents([
     65      [EVENT_SCROLLING, accDoc],
     66      [EVENT_SCROLLING_END, accDoc],
     67    ]);
     68    await SpecialPowers.spawn(browser, [], () => {
     69      content.scrollTo(10, 0);
     70    });
     71    let [scrollEvent3, scrollEndEvent3] = await onScrolling;
     72    scrollEvent3.QueryInterface(nsIAccessibleScrollingEvent);
     73    Assert.greaterOrEqual(
     74      scrollEvent3.maxScrollX,
     75      scrollEvent3.scrollX,
     76      "scrollX is within max"
     77    );
     78    scrollEndEvent3.QueryInterface(nsIAccessibleScrollingEvent);
     79    Assert.greaterOrEqual(
     80      scrollEndEvent3.maxScrollX,
     81      scrollEndEvent3.scrollX,
     82      "scrollY is within max"
     83    );
     84    Assert.greater(
     85      scrollEvent3.scrollX,
     86      scrollEvent2.scrollX,
     87      `${scrollEvent3.scrollX} > ${scrollEvent2.scrollX}`
     88    );
     89 
     90    // non-doc scrolling
     91    onScrolling = waitForEvents([
     92      [EVENT_SCROLLING, "three"],
     93      [EVENT_SCROLLING_END, "three"],
     94    ]);
     95    await SpecialPowers.spawn(browser, [], () => {
     96      content.document.querySelector("#three").scrollTo(0, 10);
     97    });
     98    let [scrollEvent4, scrollEndEvent4] = await onScrolling;
     99    scrollEvent4.QueryInterface(nsIAccessibleScrollingEvent);
    100    Assert.greaterOrEqual(
    101      scrollEvent4.maxScrollY,
    102      scrollEvent4.scrollY,
    103      "scrollY is within max"
    104    );
    105    scrollEndEvent4.QueryInterface(nsIAccessibleScrollingEvent);
    106    Assert.greaterOrEqual(
    107      scrollEndEvent4.maxScrollY,
    108      scrollEndEvent4.scrollY,
    109      "scrollY is within max"
    110    );
    111 
    112    // textarea scrolling
    113    info("Moving textarea caret to c");
    114    onScrolling = waitForEvents([
    115      [EVENT_SCROLLING, "textarea"],
    116      [EVENT_SCROLLING_END, "textarea"],
    117    ]);
    118    await invokeContentTask(browser, [], () => {
    119      const textareaDom = content.document.getElementById("textarea");
    120      textareaDom.focus();
    121      textareaDom.selectionStart = 4;
    122    });
    123    await onScrolling;
    124  }
    125 );
    126 
    127 // Verify that the scrolling start event is fired for an anchor change.
    128 addAccessibleTask(
    129  `
    130    <p>a</p>
    131    <p>b</p>
    132    <p id="c">c</p>
    133  `,
    134  async function (browser) {
    135    let onScrollingStart = waitForEvent(EVENT_SCROLLING_START, "c");
    136    await SpecialPowers.spawn(browser, [], () => {
    137      content.location.hash = "#c";
    138    });
    139    await onScrollingStart;
    140  },
    141  { chrome: true, topLevel: true }
    142 );
    143 
    144 // Ensure that a scrollable, focused non-interactive element receives a
    145 // scrolling start event when an anchor jump to that element is triggered.
    146 addAccessibleTask(
    147  `
    148 <div style="height: 100vh; width: 100vw; overflow: auto;" id="scrollable">
    149  <h1 style="height: 300%;" id="inside-scrollable">test</h1>
    150 </div>
    151  `,
    152  async function (browser) {
    153    let onScrollingStart = waitForEvent(
    154      EVENT_SCROLLING_START,
    155      "inside-scrollable"
    156    );
    157    await invokeContentTask(browser, [], () => {
    158      const scrollable = content.document.getElementById("scrollable");
    159      scrollable.focus();
    160      content.location.hash = "#inside-scrollable";
    161    });
    162    await onScrollingStart;
    163  },
    164  { chrome: true, topLevel: true, iframe: true, remoteIframe: true }
    165 );
    166 
    167 /**
    168 * Test that slow loading pages fire scrolling start events correctly.
    169 */
    170 add_task(async function testSlowLoad() {
    171  // We use add_task because this document won't fire a doc load complete event
    172  // until it is fully loaded.
    173  const scriptUrl =
    174    "https://example.com/browser/accessible/tests/browser/events/slow_doc.sjs";
    175  info("Testing first (already in tree when anchor jump occurs)");
    176  let url = `${scriptUrl}?second#:~:text=first`;
    177  let focused = waitForEvent(
    178    EVENT_FOCUS,
    179    evt =>
    180      evt.accessible.role == ROLE_DOCUMENT && evt.accessibleDocument.URL == url
    181  );
    182  await BrowserTestUtils.withNewTab(
    183    { url, gBrowser, waitForLoad: false },
    184    async function () {
    185      await focused;
    186      // At this point, the document contains only "first".
    187      info("Finishing load");
    188      let scrolled = waitForEvent(
    189        EVENT_SCROLLING_START,
    190        evt => evt.accessible.name == "first"
    191      );
    192      await fetch(`${scriptUrl}?scriptFinish`);
    193      info("Wait for scroll");
    194      await scrolled;
    195    }
    196  );
    197 
    198  info("Testing second (container already in tree when anchor jump occurs)");
    199  url = `${scriptUrl}?secondInContainer#:~:text=second`;
    200  focused = waitForEvent(
    201    EVENT_FOCUS,
    202    evt =>
    203      evt.accessible.role == ROLE_DOCUMENT && evt.accessibleDocument.URL == url
    204  );
    205  await BrowserTestUtils.withNewTab(
    206    { url, gBrowser, waitForLoad: false },
    207    async function () {
    208      await focused;
    209      // At this point, the document contains only "first".
    210      info("Finishing load");
    211      let scrolled = waitForEvent(
    212        EVENT_SCROLLING_START,
    213        evt => evt.accessible.name == "second"
    214      );
    215      await fetch(`${scriptUrl}?scriptFinish`);
    216      await scrolled;
    217    }
    218  );
    219 
    220  info("Testing second (not in tree when anchor jump occurs)");
    221  url = `${scriptUrl}?second#:~:text=second`;
    222  focused = waitForEvent(
    223    EVENT_FOCUS,
    224    evt =>
    225      evt.accessible.role == ROLE_DOCUMENT && evt.accessibleDocument.URL == url
    226  );
    227  await BrowserTestUtils.withNewTab(
    228    { url, gBrowser, waitForLoad: false },
    229    async function () {
    230      await focused;
    231      // At this point, the document contains only "first".
    232      info("Finishing load");
    233      let scrolled = waitForEvent(
    234        EVENT_SCROLLING_START,
    235        evt => evt.accessible.name == "second"
    236      );
    237      await fetch(`${scriptUrl}?scriptFinish`);
    238      await scrolled;
    239    }
    240  );
    241 
    242  info("Testing jump while in background");
    243  url = `${scriptUrl}?second#:~:text=second`;
    244  focused = waitForEvent(
    245    EVENT_FOCUS,
    246    evt =>
    247      evt.accessible.role == ROLE_DOCUMENT && evt.accessibleDocument.URL == url
    248  );
    249  await BrowserTestUtils.withNewTab(
    250    { url, gBrowser, waitForLoad: false },
    251    async function () {
    252      await focused;
    253      // At this point, the document contains only "first".
    254      info("Opening second tab in foreground");
    255      const secondUrl = "about:mozilla";
    256      focused = waitForEvent(
    257        EVENT_FOCUS,
    258        evt =>
    259          evt.accessible.role == ROLE_DOCUMENT &&
    260          evt.accessibleDocument.URL == secondUrl
    261      );
    262      let secondTab = await BrowserTestUtils.openNewForegroundTab({
    263        url: secondUrl,
    264        gBrowser,
    265      });
    266      await focused;
    267      // We shouldn't get a scrolling start event until focus returns to the
    268      // first document.
    269      let events = waitForEvents({
    270        expected: [[EVENT_SHOW, "second"]],
    271        unexpected: [
    272          [EVENT_SCROLLING_START, evt => evt.accessible.name == "second"],
    273        ],
    274      });
    275      info("Finishing load");
    276      await fetch(`${scriptUrl}?scriptFinish`);
    277      await events;
    278      info("Closing second tab");
    279      events = waitForEvents([
    280        [
    281          EVENT_FOCUS,
    282          evt =>
    283            evt.accessible.role == ROLE_DOCUMENT &&
    284            evt.accessibleDocument.URL == url,
    285        ],
    286        [EVENT_SCROLLING_START, evt => evt.accessible.name == "second"],
    287      ]);
    288      BrowserTestUtils.removeTab(secondTab);
    289      await events;
    290    }
    291  );
    292 });