requestLongerTimeout(2); add_task(function* () { function pushPref(name, value) { return new Promise(resolve => SpecialPowers.pushPrefEnv({"set": [[name, value]]}, resolve)); } yield pushPref("general.autoScroll", true); const expectScrollNone = 0; const expectScrollVert = 1; const expectScrollHori = 2; const expectScrollBoth = 3; var allTests = [ {dataUri: 'data:text/html,\
\
\
\
\ \ \
\
\ \ '}, {elem: 'a', expected: expectScrollNone}, {elem: 'b', expected: expectScrollBoth}, {elem: 'c', expected: expectScrollHori}, {elem: 'd', expected: expectScrollVert}, {elem: 'e', expected: expectScrollVert}, {elem: 'f', expected: expectScrollNone}, {elem: 'g', expected: expectScrollBoth}, {elem: 'h', expected: expectScrollNone}, {dataUri: 'data:text/html,
\ \ '}, {elem: 'i', expected: expectScrollVert}, // bug 695121 {dataUri: 'data:text/html,\
\ \ '}, {elem: 'j', expected: expectScrollVert}, // bug 914251 {dataUri: 'data:text/html,\ \
'}, {elem: 't', expected: expectScrollBoth}, // bug 1308775 {dataUri: 'data:text/html,\
\ \
\
\ \
\ \
filler to make document overflow: scroll;
\ '}, {elem: 'k', expected: expectScrollBoth}, {elem: 'k', expected: expectScrollNone, testwindow: true}, {elem: 'l', expected: expectScrollNone}, {elem: 'm', expected: expectScrollVert, testwindow: true}, {dataUri: 'data:text/html,\ image map\ \ \ \ link\ \ \
\ '}, {elem: 'n', expected: expectScrollNone, testwindow: true}, {elem: 'o', expected: expectScrollNone, testwindow: true}, {elem: 'p', expected: expectScrollVert, testwindow: true, middlemousepastepref: false}, {elem: 'q', expected: expectScrollVert, testwindow: true, middlemousepastepref: false}, {dataUri: 'data:text/html,\ \ \
\ '}, {elem: 'r', expected: expectScrollNone, testwindow: true, middlemousepastepref: true}, {elem: 's', expected: expectScrollNone, testwindow: true, middlemousepastepref: true} ]; for (let test of allTests) { if (test.dataUri) { let loadedPromise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser); gBrowser.loadURI(test.dataUri); yield loadedPromise; continue; } let prefsChanged = (test.middlemousepastepref == false || test.middlemousepastepref == true); if (prefsChanged) { yield pushPref("middlemouse.paste", test.middlemousepastepref); } yield BrowserTestUtils.synthesizeMouse("#" + test.elem, 50, 80, { button: 1 }, gBrowser.selectedBrowser); // This ensures bug 605127 is fixed: pagehide in an unrelated document // should not cancel the autoscroll. yield ContentTask.spawn(gBrowser.selectedBrowser, { }, function* () { var iframe = content.document.getElementById("iframe"); if (iframe) { var e = new iframe.contentWindow.PageTransitionEvent("pagehide", { bubbles: true, cancelable: true, persisted: false }); iframe.contentDocument.dispatchEvent(e); iframe.contentDocument.documentElement.dispatchEvent(e); } }); is(document.activeElement, gBrowser.selectedBrowser, "Browser still focused after autoscroll started"); yield BrowserTestUtils.synthesizeMouse("#" + test.elem, 100, 100, { type: "mousemove", clickCount: "0" }, gBrowser.selectedBrowser); if (prefsChanged) { yield new Promise(resolve => SpecialPowers.popPrefEnv(resolve)); } // Start checking for the scroll. let firstTimestamp = undefined; let timeCompensation; do { let timestamp = yield new Promise(resolve => window.requestAnimationFrame(resolve)); if (firstTimestamp === undefined) { firstTimestamp = timestamp; } // This value is calculated similarly to the value of the same name in // ClickEventHandler.autoscrollLoop, except here it's cumulative across // all frames after the first one instead of being based only on the // current frame. timeCompensation = (timestamp - firstTimestamp) / 20; info("timestamp=" + timestamp + " firstTimestamp=" + firstTimestamp + " timeCompensation=" + timeCompensation); // Try to wait until enough time has passed to allow the scroll to happen. // autoscrollLoop incrementally scrolls during each animation frame, but // due to how its calculations work, when a frame is very close to the // previous frame, no scrolling may actually occur during that frame. // After 100ms's worth of frames, timeCompensation will be 1, making it // more likely that the accumulated scroll in autoscrollLoop will be >= 1, // although it also depends on acceleration, which here in this test // should be > 1 due to how it synthesizes mouse events below. } while (timeCompensation < 5); // Close the autoscroll popup by synthesizing Esc. EventUtils.synthesizeKey("VK_ESCAPE", {}); let scrollVert = test.expected & expectScrollVert; let scrollHori = test.expected & expectScrollHori; yield ContentTask.spawn(gBrowser.selectedBrowser, { scrollVert : scrollVert, scrollHori: scrollHori, elemid : test.elem, checkWindow: test.testwindow }, function* (args) { let msg = ""; if (args.checkWindow) { if (!((args.scrollVert && content.scrollY > 0) || (!args.scrollVert && content.scrollY == 0))) { msg += "Failed: "; } msg += 'Window for ' + args.elemid + ' should' + (args.scrollVert ? '' : ' not') + ' have scrolled vertically\n'; if (!((args.scrollHori && content.scrollX > 0) || (!args.scrollHori && content.scrollX == 0))) { msg += "Failed: "; } msg += ' Window for ' + args.elemid + ' should' + (args.scrollHori ? '' : ' not') + ' have scrolled horizontally\n'; } else { let elem = content.document.getElementById(args.elemid); if (!((args.scrollVert && elem.scrollTop > 0) || (!args.scrollVert && elem.scrollTop == 0))) { msg += "Failed: "; } msg += ' ' + args.elemid + ' should' + (args.scrollVert ? '' : ' not') + ' have scrolled vertically\n'; if (!((args.scrollHori && elem.scrollLeft > 0) || (!args.scrollHori && elem.scrollLeft == 0))) { msg += "Failed: "; } msg += args.elemid + ' should' + (args.scrollHori ? '' : ' not') + ' have scrolled horizontally'; } Assert.ok(msg.indexOf("Failed") == -1, msg); } ); // Before continuing the test, we need to ensure that the IPC // message that stops autoscrolling has had time to arrive. yield new Promise(resolve => executeSoon(resolve)); } // remove 2 tabs that were opened by middle-click on links while (gBrowser.visibleTabs.length > 1) { gBrowser.removeTab(gBrowser.visibleTabs[gBrowser.visibleTabs.length - 1]); } // wait for focus to fix a failure in the next test if the latter runs too soon. yield SimpleTest.promiseFocus(); });