Bug 810981 - Part 4 - Test session store scroll position and zoom level handling. r=margaret
MozReview-Commit-ID: 4jZ0ixoJmOO
--- a/mobile/android/components/SessionStore.js
+++ b/mobile/android/components/SessionStore.js
@@ -710,16 +710,18 @@ SessionStore.prototype = {
scrolldata.zoom.autoSize = viewportInfo.autoSize;
log("onTabScroll() autoSize: " + scrolldata.zoom.autoSize);
scrolldata.zoom.windowWidth = aWindow.outerWidth;
log("onTabScroll() windowWidth: " + scrolldata.zoom.windowWidth);
// Save zoom and scroll data.
data.scrolldata = scrolldata;
log("onTabScroll() ran for tab " + aWindow.BrowserApp.getTabForBrowser(aBrowser).id);
+ let evt = new Event("SSTabScrollCaptured", {"bubbles":true, "cancelable":false});
+ aBrowser.dispatchEvent(evt);
this.saveStateDelayed();
},
_getViewportInfo: function ss_getViewportInfo(aDisplayWidth, aDisplayHeight, aWindow) {
let viewportInfo = {};
let defaultZoom = {}, allowZoom = {}, minZoom = {}, maxZoom ={},
width = {}, height = {}, autoSize = {};
aWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(
new file mode 100644
--- /dev/null
+++ b/mobile/android/tests/browser/chrome/basic_article_mobile.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Article title</title>
+<meta name="description" content="This is the article description." />
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+</head>
+<body>
+<header>Site header</header>
+<div>
+<h1>Article title</h1>
+<h2 class="author">by Jane Doe</h2>
+<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id dolor. Pellentesque auctor nisi id magna consequat sagittis. Curabitur dapibus enim sit amet elit pharetra tincidunt feugiat nisl imperdiet. Ut convallis libero in urna ultrices accumsan. Donec sed odio eros. Donec viverra mi quis quam pulvinar at malesuada arcu rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In rutrum accumsan ultricies. Mauris vitae nisi at sem facilisis semper ac in est.</p>
+<p>Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.</p>
+<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id dolor. Pellentesque auctor nisi id magna consequat sagittis. Curabitur dapibus enim sit amet elit pharetra tincidunt feugiat nisl imperdiet. Ut convallis libero in urna ultrices accumsan. Donec sed odio eros. Donec viverra mi quis quam pulvinar at malesuada arcu rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In rutrum accumsan ultricies. Mauris vitae nisi at sem facilisis semper ac in est.</p>
+<p>Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.</p>
+</div>
+</body>
+</html>
--- a/mobile/android/tests/browser/chrome/chrome.ini
+++ b/mobile/android/tests/browser/chrome/chrome.ini
@@ -1,12 +1,13 @@
[DEFAULT]
skip-if = os != 'android'
support-files =
basic_article.html
+ basic_article_mobile.html
desktopmode_user_agent.sjs
devicesearch.xml
head.js
head_search.js
session_formdata_sample.html
simpleservice.xml
video_controls.html
video_discovery.html
@@ -35,13 +36,14 @@ skip-if = debug
[test_offline_page.html]
skip-if = true # Bug 1241478
[test_reader_view.html]
[test_resource_substitutions.html]
[test_restricted_profiles.html]
[test_select_disabled.html]
[test_selectoraddtab.html]
[test_session_form_data.html]
+[test_session_scroll_position.html]
[test_session_zombification.html]
[test_shared_preferences.html]
[test_simple_discovery.html]
[test_video_discovery.html]
[test_web_channel.html]
--- a/mobile/android/tests/browser/chrome/head.js
+++ b/mobile/android/tests/browser/chrome/head.js
@@ -1,11 +1,15 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
+function fuzzyEquals(a, b) {
+ return (Math.abs(a - b) < 1e-6);
+}
+
function promiseBrowserEvent(browser, eventType) {
return new Promise((resolve) => {
function handle(event) {
// Since we'll be redirecting, don't make assumptions about the given URL and the loaded URL
if (event.target != browser.contentDocument || event.target.location.href == "about:blank") {
info("Skipping spurious '" + eventType + "' event" + " for " + event.target.location.href);
return;
}
new file mode 100644
--- /dev/null
+++ b/mobile/android/tests/browser/chrome/test_session_scroll_position.html
@@ -0,0 +1,183 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=810981
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 810981</title>
+ <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SpawnTask.js"></script>
+ <link rel="stylesheet" type="text/css" href="chrome://global/skin"/>
+ <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="head.js"></script>
+ <script type="application/javascript;version=1.7">
+
+ /** Test for Bug 810981 **/
+
+ "use strict";
+
+ const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
+
+ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+ Cu.import("resource://gre/modules/Services.jsm");
+ Cu.import("resource://gre/modules/Messaging.jsm");
+ Cu.import("resource://gre/modules/Task.jsm");
+
+ // The chrome window.
+ let chromeWin;
+
+ // Track the tabs where the tests are happening.
+ let tabScroll;
+
+ // Use something with enough content to allow for scrolling.
+ const URL = "http://example.org/chrome/mobile/android/tests/browser/chrome/basic_article_mobile.html";
+
+ function dispatchUIEvent(browser, type) {
+ let event = browser.contentDocument.createEvent("UIEvents");
+ event.initUIEvent(type, true, false, browser.contentDocument.defaultView, 0);
+ browser.dispatchEvent(event);
+ }
+
+ function setScrollPosition(browser, x, y) {
+ browser.contentWindow.scrollTo(x, y);
+ dispatchUIEvent(browser, "scroll");
+ }
+
+ function setZoomLevel(browser, zoom) {
+ browser.contentWindow.QueryInterface(
+ Ci.nsIInterfaceRequestor).getInterface(
+ Ci.nsIDOMWindowUtils).setResolutionAndScaleTo(zoom);
+ }
+
+ let ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
+
+ add_task(function* test_sessionStoreScrollPosition() {
+ const SCROLL_X = 0;
+ const SCROLL_Y = 38;
+
+ chromeWin = Services.wm.getMostRecentWindow("navigator:browser");
+ let BrowserApp = chromeWin.BrowserApp;
+
+ // Creates a tab, sets a scroll position and closes the tab.
+ function createAndRemoveTab() {
+ return Task.spawn(function () {
+ // Create a new tab.
+ tabScroll = BrowserApp.addTab(URL);
+ let browser = tabScroll.browser;
+ yield promiseBrowserEvent(browser, "pageshow");
+
+ // Modify scroll position.
+ setScrollPosition(browser, SCROLL_X, SCROLL_Y);
+ yield promiseTabEvent(browser, "SSTabScrollCaptured");
+
+ // Check that we've actually scrolled.
+ let ifreq = browser.contentWindow.QueryInterface(Ci.nsIInterfaceRequestor);
+ let utils = ifreq.getInterface(Ci.nsIDOMWindowUtils);
+ let scrollX = {}, scrollY = {};
+ utils.getScrollXY(false, scrollX, scrollY);
+ is(scrollX.value, SCROLL_X, "scrollX set correctly");
+ is(scrollY.value, SCROLL_Y, "scrollY set correctly");
+
+ // Remove the tab.
+ BrowserApp.closeTab(tabScroll);
+ yield promiseTabEvent(browser, "SSTabCloseProcessed");
+ });
+ }
+
+ yield createAndRemoveTab();
+ let state = ss.getClosedTabs(chromeWin);
+ let [{scrolldata}] = state;
+ is(scrolldata.scroll, SCROLL_X + "," + SCROLL_Y, "stored scroll position is correct");
+
+ // Restore the closed tab.
+ let closedTabData = ss.getClosedTabs(chromeWin)[0];
+ let browser = ss.undoCloseTab(chromeWin, closedTabData);
+ yield promiseBrowserEvent(browser, "pageshow");
+
+ // Check the scroll position.
+ let ifreq = browser.contentWindow.QueryInterface(Ci.nsIInterfaceRequestor);
+ let utils = ifreq.getInterface(Ci.nsIDOMWindowUtils);
+ let scrollX = {}, scrollY = {};
+ utils.getScrollXY(false, scrollX, scrollY);
+ is(scrollX.value, SCROLL_X, "scrollX restored correctly");
+ is(scrollY.value, SCROLL_Y, "scrollY restored correctly");
+
+ // Remove the tab.
+ BrowserApp.closeTab(BrowserApp.getTabForBrowser(browser));
+ });
+
+ add_task(function* test_sessionStoreZoomLevel() {
+ const ZOOM = 4.2;
+ const SCROLL_X = 42;
+ const SCROLL_Y = 42;
+
+ chromeWin = Services.wm.getMostRecentWindow("navigator:browser");
+ let BrowserApp = chromeWin.BrowserApp;
+
+ // Creates a tab, sets a scroll position and zoom level and closes the tab.
+ function createAndRemoveTab() {
+ return Task.spawn(function () {
+ // Create a new tab.
+ tabScroll = BrowserApp.addTab(URL);
+ let browser = tabScroll.browser;
+ yield promiseBrowserEvent(browser, "pageshow");
+
+ // Modify scroll position and zoom level.
+ setZoomLevel(browser, ZOOM);
+ setScrollPosition(browser, SCROLL_X, SCROLL_Y);
+ yield promiseTabEvent(browser, "SSTabScrollCaptured");
+
+ // Check that we've actually scrolled and zoomed.
+ let ifreq = browser.contentWindow.QueryInterface(Ci.nsIInterfaceRequestor);
+ let utils = ifreq.getInterface(Ci.nsIDOMWindowUtils);
+ let scrollX = {}, scrollY = {}, zoom = {};
+ utils.getResolution(zoom);
+ utils.getScrollXY(false, scrollX, scrollY);
+ ok(fuzzyEquals(zoom.value, ZOOM), "zoom set correctly");
+ is(scrollX.value, SCROLL_X, "scrollX set correctly");
+ is(scrollY.value, SCROLL_Y, "scrollY set correctly");
+
+ // Remove the tab.
+ BrowserApp.closeTab(tabScroll);
+ yield promiseTabEvent(browser, "SSTabCloseProcessed");
+ });
+ }
+
+ yield createAndRemoveTab();
+ let state = ss.getClosedTabs(chromeWin);
+ let [{scrolldata}] = state;
+ is(scrolldata.scroll, SCROLL_X + "," + SCROLL_Y, "stored scroll position is correct");
+ ok(fuzzyEquals(scrolldata.zoom.resolution, ZOOM), "stored zoom level is correct");
+
+ // Restore the closed tab.
+ let closedTabData = ss.getClosedTabs(chromeWin)[0];
+ let browser = ss.undoCloseTab(chromeWin, closedTabData);
+ yield promiseBrowserEvent(browser, "pageshow");
+
+ // Check the scroll position and zoom level.
+ let ifreq = browser.contentWindow.QueryInterface(Ci.nsIInterfaceRequestor);
+ let utils = ifreq.getInterface(Ci.nsIDOMWindowUtils);
+ let scrollX = {}, scrollY = {}, zoom = {};
+ utils.getResolution(zoom);
+ utils.getScrollXY(false, scrollX, scrollY);
+ ok(fuzzyEquals(zoom.value, ZOOM), "zoom restored correctly");
+ is(scrollX.value, SCROLL_X, "scrollX restored correctly");
+ is(scrollY.value, SCROLL_Y, "scrollY restored correctly");
+
+ // Remove the tab.
+ BrowserApp.closeTab(BrowserApp.getTabForBrowser(browser));
+ });
+
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=810981">Mozilla Bug 810981</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>