tor-browser

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

browser_bug1701027-1.js (5934B)


      1 /* This test is based on
      2     https://searchfox.org/mozilla-central/rev/e082df56bbfeaff0f388e7da9da401ff414df18f/gfx/layers/apz/test/mochitest/browser_test_select_zoom.js
      3 */
      4 
      5 // In order for this test to test the original bug we need:
      6 // 1) At least e10s enabled so that apz is enabled so we can create an
      7 //    nsDisplayAsyncZoom item
      8 //    (the insertion of this item without marking the required frame modified
      9 //     is what causes the bug in the retained display list merging)
     10 // 2) a root content document, again so that we can create a nsDisplayAsyncZoom
     11 //    item
     12 // 3) the root content document cannot have a display port to start
     13 //    (if it has a display port then it gets a nsDisplayAsyncZoom, but we need
     14 //     that to be created after the anonymous content we insert into the
     15 //     document)
     16 // Point 3) requires the root content document to be in the parent process,
     17 // since if it is in a content process it will get a displayport for being at
     18 // the root of a process.
     19 // Creating an in-process root content document I think is not possible in
     20 // mochitest-plain. mochitest-chrome does not have e10s enabled. So this has to
     21 // be a mochitest-browser-chrome test.
     22 
     23 // Outline of this test:
     24 // Open a new tab with a pretty simple content file, that is not scrollable
     25 // Use the anonymous content api to insert into that content doc
     26 // Send a mouse click over the content doc
     27 // The click hits fixed pos content.
     28 // This sets a displayport on the root scroll frame of the content doc.
     29 // (This is because we call GetAsyncScrollableAncestorFrame in
     30 // PrepareForSetTargetAPZCNotification
     31 // https://searchfox.org/mozilla-central/rev/e082df56bbfeaff0f388e7da9da401ff414df18f/gfx/layers/apz/util/APZCCallbackHelper.cpp#624
     32 // which passes the SCROLLABLE_FIXEDPOS_FINDS_ROOT flag
     33 // https://searchfox.org/mozilla-central/rev/e082df56bbfeaff0f388e7da9da401ff414df18f/layout/base/nsLayoutUtils.cpp#2884
     34 // so starting from fixed pos content means we always find the root scroll
     35 // frame, whereas if we started from non-fixed content we'd walk pass the root
     36 // scroll frame becase it isn't scrollable.)
     37 // Then we have to be careful not to do anything that causes a full display
     38 // list rebuild.
     39 // And finally we change the color of the fixed element which covers the whole
     40 // viewport which causes us to do a partial display list update including the
     41 // anonymous content, which hits the assert we are aiming to test.
     42 
     43 add_task(async function () {
     44  function getChromeURL(filename) {
     45    let chromeURL = getRootDirectory(gTestPath) + filename;
     46    return chromeURL;
     47  }
     48 
     49  // We need this otherwise there is a burst animation on the new tab when it
     50  // loads and that somehow scrolls a scroll frame, which makes it active,
     51  // which makes the scrolled frame an AGR, which means we have multiple AGRs
     52  // (the display port makes the root scroll frame active and an AGR) so we hit
     53  // this
     54  // https://searchfox.org/mozilla-central/rev/e082df56bbfeaff0f388e7da9da401ff414df18f/layout/painting/RetainedDisplayListBuilder.cpp#1179
     55  // and are forced to do a full display list rebuild and that prevents us from
     56  // testing the original bug.
     57  await SpecialPowers.pushPrefEnv({
     58    set: [["ui.prefersReducedMotion", 1]],
     59  });
     60 
     61  const pageUrl = getChromeURL("helper_bug1701027-1.html");
     62  let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, pageUrl);
     63 
     64  const [theX, theY] = await SpecialPowers.spawn(
     65    tab.linkedBrowser,
     66    [],
     67    async () => {
     68      content.document.body.offsetWidth;
     69 
     70      await new Promise(r => content.window.requestAnimationFrame(r));
     71 
     72      const rect = content.document
     73        .getElementById("fd")
     74        .getBoundingClientRect();
     75      const x = content.window.mozInnerScreenX + rect.left + rect.width / 2;
     76      const y = content.window.mozInnerScreenY + rect.top + rect.height / 2;
     77 
     78      let doc = SpecialPowers.wrap(content.document);
     79      var bq = doc.createElement("blockquote");
     80      bq.textContent = "This blockquote text.";
     81      var div = doc.createElement("div");
     82      div.textContent = " This div text.";
     83      bq.appendChild(div);
     84      var ac = doc.insertAnonymousContent(bq);
     85      content.document.body.offsetWidth;
     86 
     87      await new Promise(r => content.window.requestAnimationFrame(r));
     88      await new Promise(r => content.window.requestAnimationFrame(r));
     89 
     90      return [x, y];
     91    }
     92  );
     93 
     94  // We intentionally turn off a11y_checks, because the following click
     95  // is targeting test content that's not meant to be interactive and
     96  // is not expected to be accessible:
     97  AccessibilityUtils.setEnv({
     98    mustHaveAccessibleRule: false,
     99  });
    100  EventUtils.synthesizeNativeMouseEvent({
    101    type: "click",
    102    target: window.document.documentElement,
    103    screenX: theX,
    104    screenY: theY,
    105  });
    106 
    107  await new Promise(resolve => setTimeout(resolve, 0));
    108  await SpecialPowers.spawn(tab.linkedBrowser, [], async () => {
    109    await new Promise(r => content.window.requestAnimationFrame(r));
    110    await new Promise(r => content.window.requestAnimationFrame(r));
    111  });
    112 
    113  await SpecialPowers.spawn(tab.linkedBrowser, [], async () => {
    114    content.document.getElementById("fd").style.backgroundColor = "blue";
    115  });
    116 
    117  await new Promise(resolve => setTimeout(resolve, 0));
    118  await SpecialPowers.spawn(tab.linkedBrowser, [], async () => {
    119    await new Promise(r => content.window.requestAnimationFrame(r));
    120    await new Promise(r => content.window.requestAnimationFrame(r));
    121  });
    122 
    123  await SpecialPowers.spawn(tab.linkedBrowser, [], async () => {
    124    content.document.getElementById("fd").style.backgroundColor = "red";
    125  });
    126 
    127  await new Promise(resolve => setTimeout(resolve, 0));
    128  await SpecialPowers.spawn(tab.linkedBrowser, [], async () => {
    129    await new Promise(r => content.window.requestAnimationFrame(r));
    130    await new Promise(r => content.window.requestAnimationFrame(r));
    131  });
    132 
    133  BrowserTestUtils.removeTab(tab);
    134 
    135  ok(true, "didn't crash");
    136 });