michael@0: /* Any copyright is dedicated to the Public Domain. michael@0: * http://creativecommons.org/publicdomain/zero/1.0/ */ michael@0: michael@0: "use strict"; michael@0: michael@0: const URL = ROOT + "browser_scrollPositions_sample.html"; michael@0: const URL_FRAMESET = ROOT + "browser_scrollPositions_sample_frameset.html"; michael@0: michael@0: // Randomized set of scroll positions we will use in this test. michael@0: const SCROLL_X = Math.round(100 * (1 + Math.random())); michael@0: const SCROLL_Y = Math.round(200 * (1 + Math.random())); michael@0: const SCROLL_STR = SCROLL_X + "," + SCROLL_Y; michael@0: michael@0: const SCROLL2_X = Math.round(300 * (1 + Math.random())); michael@0: const SCROLL2_Y = Math.round(400 * (1 + Math.random())); michael@0: const SCROLL2_STR = SCROLL2_X + "," + SCROLL2_Y; michael@0: michael@0: /** michael@0: * This test ensures that we properly serialize and restore scroll positions michael@0: * for an average page without any frames. michael@0: */ michael@0: add_task(function test_scroll() { michael@0: let tab = gBrowser.addTab(URL); michael@0: let browser = tab.linkedBrowser; michael@0: yield promiseBrowserLoaded(browser); michael@0: michael@0: // Scroll down a little. michael@0: yield sendMessage(browser, "ss-test:setScrollPosition", {x: SCROLL_X, y: SCROLL_Y}); michael@0: checkScroll(tab, {scroll: SCROLL_STR}, "scroll is fine"); michael@0: michael@0: // Duplicate and check that the scroll position is restored. michael@0: let tab2 = ss.duplicateTab(window, tab); michael@0: let browser2 = tab2.linkedBrowser; michael@0: yield promiseTabRestored(tab2); michael@0: michael@0: let scroll = yield sendMessage(browser2, "ss-test:getScrollPosition"); michael@0: is(JSON.stringify(scroll), JSON.stringify({x: SCROLL_X, y: SCROLL_Y}), michael@0: "scroll position has been duplicated correctly"); michael@0: michael@0: // Check that reloading retains the scroll positions. michael@0: browser2.reload(); michael@0: yield promiseBrowserLoaded(browser2); michael@0: checkScroll(tab2, {scroll: SCROLL_STR}, "reloading retains scroll positions"); michael@0: michael@0: // Check that a force-reload resets scroll positions. michael@0: browser2.reloadWithFlags(Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE); michael@0: yield promiseBrowserLoaded(browser2); michael@0: checkScroll(tab2, null, "force-reload resets scroll positions"); michael@0: michael@0: // Scroll back to the top and check that the position has been reset. We michael@0: // expect the scroll position to be "null" here because there is no data to michael@0: // be stored if the frame is in its default scroll position. michael@0: yield sendMessage(browser, "ss-test:setScrollPosition", {x: 0, y: 0}); michael@0: checkScroll(tab, null, "no scroll stored"); michael@0: michael@0: // Cleanup. michael@0: gBrowser.removeTab(tab); michael@0: gBrowser.removeTab(tab2); michael@0: }); michael@0: michael@0: /** michael@0: * This tests ensures that we properly serialize and restore scroll positions michael@0: * for multiple frames of pages with framesets. michael@0: */ michael@0: add_task(function test_scroll_nested() { michael@0: let tab = gBrowser.addTab(URL_FRAMESET); michael@0: let browser = tab.linkedBrowser; michael@0: yield promiseBrowserLoaded(browser); michael@0: michael@0: // Scroll the first child frame down a little. michael@0: yield sendMessage(browser, "ss-test:setScrollPosition", {x: SCROLL_X, y: SCROLL_Y, frame: 0}); michael@0: checkScroll(tab, {children: [{scroll: SCROLL_STR}]}, "scroll is fine"); michael@0: michael@0: // Scroll the second child frame down a little. michael@0: yield sendMessage(browser, "ss-test:setScrollPosition", {x: SCROLL2_X, y: SCROLL2_Y, frame: 1}); michael@0: checkScroll(tab, {children: [{scroll: SCROLL_STR}, {scroll: SCROLL2_STR}]}, "scroll is fine"); michael@0: michael@0: // Duplicate and check that the scroll position is restored. michael@0: let tab2 = ss.duplicateTab(window, tab); michael@0: let browser2 = tab2.linkedBrowser; michael@0: yield promiseTabRestored(tab2); michael@0: michael@0: let scroll = yield sendMessage(browser2, "ss-test:getScrollPosition", {frame: 0}); michael@0: is(JSON.stringify(scroll), JSON.stringify({x: SCROLL_X, y: SCROLL_Y}), michael@0: "scroll position #1 has been duplicated correctly"); michael@0: michael@0: scroll = yield sendMessage(browser2, "ss-test:getScrollPosition", {frame: 1}); michael@0: is(JSON.stringify(scroll), JSON.stringify({x: SCROLL2_X, y: SCROLL2_Y}), michael@0: "scroll position #2 has been duplicated correctly"); michael@0: michael@0: // Check that resetting one frame's scroll position removes it from the michael@0: // serialized value. michael@0: yield sendMessage(browser, "ss-test:setScrollPosition", {x: 0, y: 0, frame: 0}); michael@0: checkScroll(tab, {children: [null, {scroll: SCROLL2_STR}]}, "scroll is fine"); michael@0: michael@0: // Check the resetting all frames' scroll positions nulls the stored value. michael@0: yield sendMessage(browser, "ss-test:setScrollPosition", {x: 0, y: 0, frame: 1}); michael@0: checkScroll(tab, null, "no scroll stored"); michael@0: michael@0: // Cleanup. michael@0: gBrowser.removeTab(tab); michael@0: gBrowser.removeTab(tab2); michael@0: }); michael@0: michael@0: /** michael@0: * This test ensures that by moving scroll positions out of tabData.entries[] michael@0: * we still support the old scroll data format stored per shistory entry. michael@0: */ michael@0: add_task(function test_scroll_old_format() { michael@0: const TAB_STATE = { entries: [{url: URL, scroll: SCROLL_STR}] }; michael@0: michael@0: // Add a blank tab. michael@0: let tab = gBrowser.addTab("about:blank"); michael@0: let browser = tab.linkedBrowser; michael@0: yield promiseBrowserLoaded(browser); michael@0: michael@0: // Apply the tab state with the old format. michael@0: ss.setTabState(tab, JSON.stringify(TAB_STATE)); michael@0: yield promiseTabRestored(tab); michael@0: michael@0: // Check that the scroll positions has been applied. michael@0: let scroll = yield sendMessage(browser, "ss-test:getScrollPosition"); michael@0: is(JSON.stringify(scroll), JSON.stringify({x: SCROLL_X, y: SCROLL_Y}), michael@0: "scroll position has been restored correctly"); michael@0: michael@0: // Cleanup. michael@0: gBrowser.removeTab(tab); michael@0: }); michael@0: michael@0: function checkScroll(tab, expected, msg) { michael@0: let browser = tab.linkedBrowser; michael@0: SyncHandlers.get(browser).flush(); michael@0: michael@0: let scroll = JSON.parse(ss.getTabState(tab)).scroll || null; michael@0: is(JSON.stringify(scroll), JSON.stringify(expected), msg); michael@0: }