tor-browser

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

browser_scrollPositions.js (7908B)


      1 /* Any copyright is dedicated to the Public Domain.
      2 * http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 const BASE = "http://example.com/browser/browser/components/sessionstore/test/";
      7 const URL2 = BASE + "browser_scrollPositions_sample2.html";
      8 const URL_FRAMESET = BASE + "browser_scrollPositions_sample_frameset.html";
      9 
     10 // Randomized set of scroll positions we will use in this test.
     11 const SCROLL_X = Math.round(100 * (1 + Math.random()));
     12 const SCROLL_Y = Math.round(200 * (1 + Math.random()));
     13 const SCROLL_STR = SCROLL_X + "," + SCROLL_Y;
     14 
     15 const SCROLL2_X = Math.round(300 * (1 + Math.random()));
     16 const SCROLL2_Y = Math.round(400 * (1 + Math.random()));
     17 const SCROLL2_STR = SCROLL2_X + "," + SCROLL2_Y;
     18 
     19 requestLongerTimeout(10);
     20 
     21 add_task(test_scroll_nested);
     22 
     23 if (gFissionBrowser) {
     24  addCoopTask("browser_scrollPositions_sample.html", test_scroll, HTTPSROOT);
     25 }
     26 addNonCoopTask("browser_scrollPositions_sample.html", test_scroll, HTTPROOT);
     27 addNonCoopTask("browser_scrollPositions_sample.html", test_scroll, HTTPSROOT);
     28 
     29 addCoopTask(
     30  "browser_scrollPositions_sample.html",
     31  test_scroll_background_tabs,
     32  HTTPSROOT
     33 );
     34 addNonCoopTask(
     35  "browser_scrollPositions_sample.html",
     36  test_scroll_background_tabs,
     37  HTTPROOT
     38 );
     39 
     40 addNonCoopTask(
     41  "browser_scrollPositions_sample.html",
     42  test_scroll_background_tabs,
     43  HTTPSROOT
     44 );
     45 
     46 function getScrollPosition(bc) {
     47  return SpecialPowers.spawn(bc, [], () => {
     48    let x = {},
     49      y = {};
     50    content.windowUtils.getVisualViewportOffset(x, y);
     51    return { x: x.value, y: y.value };
     52  });
     53 }
     54 
     55 /**
     56 * This test ensures that we properly serialize and restore scroll positions
     57 * for an average page without any frames.
     58 */
     59 async function test_scroll(aURL) {
     60  let tab = BrowserTestUtils.addTab(gBrowser, aURL);
     61  let browser = tab.linkedBrowser;
     62  await promiseBrowserLoaded(browser);
     63 
     64  // Scroll down a little.
     65  await setScrollPosition(browser, SCROLL_X, SCROLL_Y);
     66  await checkScroll(tab, { scroll: SCROLL_STR }, "scroll is fine");
     67 
     68  // Duplicate and check that the scroll position is restored.
     69  let tab2 = ss.duplicateTab(window, tab);
     70  let browser2 = tab2.linkedBrowser;
     71  await promiseTabRestored(tab2);
     72 
     73  let scroll = await getScrollPosition(browser2);
     74  is(
     75    JSON.stringify(scroll),
     76    JSON.stringify({ x: SCROLL_X, y: SCROLL_Y }),
     77    "scroll position has been duplicated correctly"
     78  );
     79 
     80  // Check that reloading retains the scroll positions.
     81  browser2.reload();
     82  await promiseBrowserLoaded(browser2);
     83  await checkScroll(
     84    tab2,
     85    { scroll: SCROLL_STR },
     86    "reloading retains scroll positions"
     87  );
     88 
     89  // Check that a force-reload resets scroll positions.
     90  browser2.reloadWithFlags(Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE);
     91  await promiseBrowserLoaded(browser2);
     92  await checkScroll(tab2, null, "force-reload resets scroll positions");
     93 
     94  // Scroll back to the top and check that the position has been reset. We
     95  // expect the scroll position to be "null" here because there is no data to
     96  // be stored if the frame is in its default scroll position.
     97  await setScrollPosition(browser, 0, 0);
     98  await checkScroll(tab, null, "no scroll stored");
     99 
    100  // Cleanup.
    101  BrowserTestUtils.removeTab(tab);
    102  BrowserTestUtils.removeTab(tab2);
    103 }
    104 
    105 /**
    106 * This tests ensures that we properly serialize and restore scroll positions
    107 * for multiple frames of pages with framesets.
    108 */
    109 async function test_scroll_nested() {
    110  let tab = BrowserTestUtils.addTab(gBrowser, URL_FRAMESET);
    111  let browser = tab.linkedBrowser;
    112  await promiseBrowserLoaded(browser);
    113 
    114  // Scroll the first child frame down a little.
    115  await setScrollPosition(
    116    browser.browsingContext.children[0],
    117    SCROLL_X,
    118    SCROLL_Y
    119  );
    120  await checkScroll(
    121    tab,
    122    { children: [{ scroll: SCROLL_STR }] },
    123    "scroll is fine"
    124  );
    125 
    126  // Scroll the second child frame down a little.
    127  await setScrollPosition(
    128    browser.browsingContext.children[1],
    129    SCROLL2_X,
    130    SCROLL2_Y
    131  );
    132  await checkScroll(
    133    tab,
    134    { children: [{ scroll: SCROLL_STR }, { scroll: SCROLL2_STR }] },
    135    "scroll is fine"
    136  );
    137 
    138  // Duplicate and check that the scroll position is restored.
    139  let tab2 = ss.duplicateTab(window, tab);
    140  let browser2 = tab2.linkedBrowser;
    141  await promiseTabRestored(tab2);
    142 
    143  let scroll = await getScrollPosition(browser2.browsingContext.children[0]);
    144  is(
    145    JSON.stringify(scroll),
    146    JSON.stringify({ x: SCROLL_X, y: SCROLL_Y }),
    147    "scroll position #1 has been duplicated correctly"
    148  );
    149 
    150  scroll = await getScrollPosition(browser2.browsingContext.children[1]);
    151  is(
    152    JSON.stringify(scroll),
    153    JSON.stringify({ x: SCROLL2_X, y: SCROLL2_Y }),
    154    "scroll position #2 has been duplicated correctly"
    155  );
    156 
    157  // Check that resetting one frame's scroll position removes it from the
    158  // serialized value.
    159  await setScrollPosition(browser.browsingContext.children[0], 0, 0);
    160  await checkScroll(
    161    tab,
    162    { children: [null, { scroll: SCROLL2_STR }] },
    163    "scroll is fine"
    164  );
    165 
    166  // Check the resetting all frames' scroll positions nulls the stored value.
    167  await setScrollPosition(browser.browsingContext.children[1], 0, 0);
    168  await checkScroll(tab, null, "no scroll stored");
    169 
    170  // Cleanup.
    171  BrowserTestUtils.removeTab(tab);
    172  BrowserTestUtils.removeTab(tab2);
    173 }
    174 
    175 /**
    176 * Test that scroll positions persist after restoring background tabs in
    177 * a restored window (bug 1228518).
    178 * Also test that scroll positions for previous session history entries
    179 * are preserved as well (bug 1265818).
    180 */
    181 async function test_scroll_background_tabs(aURL) {
    182  await pushPrefs(["browser.sessionstore.restore_on_demand", true]);
    183 
    184  let newWin = await BrowserTestUtils.openNewBrowserWindow();
    185  let tab = BrowserTestUtils.addTab(newWin.gBrowser, aURL);
    186  let browser = tab.linkedBrowser;
    187  await BrowserTestUtils.browserLoaded(browser);
    188 
    189  // Add user interaction to the first entry.
    190  await SpecialPowers.spawn(browser, [], () => {
    191    content.document.notifyUserGestureActivation();
    192  });
    193 
    194  // Scroll down a little.
    195  await setScrollPosition(browser, SCROLL_X, SCROLL_Y);
    196  await checkScroll(
    197    tab,
    198    { scroll: SCROLL_STR },
    199    "scroll on first page is fine"
    200  );
    201 
    202  // Navigate to a different page and scroll there as well.
    203  let browser2loaded = BrowserTestUtils.browserLoaded(browser, false, URL2);
    204  BrowserTestUtils.startLoadingURIString(browser, URL2);
    205  await browser2loaded;
    206 
    207  // Scroll down a little.
    208  await setScrollPosition(browser, SCROLL2_X, SCROLL2_Y);
    209  await checkScroll(
    210    tab,
    211    { scroll: SCROLL2_STR },
    212    "scroll on second page is fine"
    213  );
    214 
    215  // Close the window
    216  await BrowserTestUtils.closeWindow(newWin);
    217 
    218  await forceSaveState();
    219 
    220  // Now restore the window
    221  newWin = ss.undoCloseWindow(0);
    222 
    223  // Make sure to wait for the window to be restored.
    224  await BrowserTestUtils.waitForEvent(newWin, "SSWindowStateReady");
    225 
    226  is(newWin.gBrowser.tabs.length, 2, "There should be two tabs");
    227 
    228  // The second tab should be the one we loaded aURL at still
    229  tab = newWin.gBrowser.tabs[1];
    230 
    231  ok(tab.hasAttribute("pending"), "Tab should be pending");
    232  browser = tab.linkedBrowser;
    233 
    234  // Ensure there are no pending queued messages in the child.
    235  await TabStateFlusher.flush(browser);
    236 
    237  // Now check to see if the background tab remembers where it
    238  // should be scrolled to.
    239  newWin.gBrowser.selectedTab = tab;
    240  await promiseTabRestored(tab);
    241 
    242  await checkScroll(
    243    tab,
    244    { scroll: SCROLL2_STR },
    245    "scroll is correct for restored tab"
    246  );
    247 
    248  // Now go back in history and check that the scroll position
    249  // is restored there as well.
    250  is(browser.canGoBack, true, "can go back");
    251  browser.goBack();
    252 
    253  await BrowserTestUtils.browserLoaded(browser);
    254  await TabStateFlusher.flush(browser);
    255 
    256  await checkScroll(
    257    tab,
    258    { scroll: SCROLL_STR },
    259    "scroll is correct after navigating back within the restored tab"
    260  );
    261 
    262  await BrowserTestUtils.closeWindow(newWin);
    263 }