Bug 784013: adding application cache helpers support to Marionette; r=jgriffin
authorDavid Burns <dburns@mozilla.com>
Thu, 23 Aug 2012 15:07:16 -0700
changeset 110613 1bb0cd787de743db235f7651614d99921b174b91
parent 110612 23794d765b02f6e59d459925ac6c5e7e3e3173c4
child 110614 2f52467023f2ba5cd2dbfbf3eef59b0680f4180b
push id93
push usernmatsakis@mozilla.com
push dateWed, 31 Oct 2012 21:26:57 +0000
reviewersjgriffin
bugs784013
milestone19.0a1
Bug 784013: adding application cache helpers support to Marionette; r=jgriffin
testing/marionette/client/marionette/application_cache.py
testing/marionette/client/marionette/marionette.py
testing/marionette/client/marionette/tests/unit/test_appcache.py
testing/marionette/client/marionette/tests/unit/unit-tests.ini
testing/marionette/client/marionette/www/html5/blue.jpg
testing/marionette/client/marionette/www/html5/geolocation.js
testing/marionette/client/marionette/www/html5/green.jpg
testing/marionette/client/marionette/www/html5/offline.html
testing/marionette/client/marionette/www/html5/red.jpg
testing/marionette/client/marionette/www/html5/status.html
testing/marionette/client/marionette/www/html5/test.appcache
testing/marionette/client/marionette/www/html5/yellow.jpg
testing/marionette/client/marionette/www/html5Page.html
testing/marionette/marionette-actors.js
testing/marionette/marionette-listener.js
new file mode 100644
--- /dev/null
+++ b/testing/marionette/client/marionette/application_cache.py
@@ -0,0 +1,31 @@
+"""
+Copyright 2011 Software Freedom Conservancy.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+
+class ApplicationCache(object):
+
+    UNCACHED = 0
+    IDLE = 1
+    CHECKING = 2
+    DOWNLOADING = 3
+    UPDATE_READY = 4
+    OBSOLETE = 5
+
+    def __init__(self, driver):
+        self.driver = driver
+
+    @property
+    def status(self):
+        return self.driver._send_message('getAppCacheStatus', 'value')
--- a/testing/marionette/client/marionette/marionette.py
+++ b/testing/marionette/client/marionette/marionette.py
@@ -1,15 +1,16 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 import socket
 
 from client import MarionetteClient
+from application_cache import ApplicationCache
 from keys import Keys
 from errors import *
 from emulator import Emulator
 from geckoinstance import GeckoInstance
 
 class HTMLElement(object):
 
     CLASS = "class name"
@@ -426,8 +427,12 @@ class Marionette(object):
 
     def get_perf_data(self):
         return self._send_message('getPerfData', 'value')
 
     def import_script(self, file):
         f = open(file, "r")
         js = f.read()
         return self._send_message('importScript', 'ok', script=js)
+
+    @property
+    def application_cache(self):
+        return ApplicationCache(self)
new file mode 100644
--- /dev/null
+++ b/testing/marionette/client/marionette/tests/unit/test_appcache.py
@@ -0,0 +1,31 @@
+#Copyright 2007-2009 WebDriver committers
+#Copyright 2007-2009 Google Inc.
+#
+#Licensed under the Apache License, Version 2.0 (the "License");
+#you may not use this file except in compliance with the License.
+#You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+#Unless required by applicable law or agreed to in writing, software
+#distributed under the License is distributed on an "AS IS" BASIS,
+#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#See the License for the specific language governing permissions and
+#limitations under the License.
+
+from application_cache import ApplicationCache
+from marionette_test import MarionetteTestCase
+
+
+class AppCacheTests(MarionetteTestCase):
+
+    def testWeCanGetTheStatusOfTheAppCache(self):
+        test_url = self.marionette.absolute_url('html5Page')
+        self.marionette.navigate(test_url)
+        app_cache = self.marionette.application_cache
+
+        status = app_cache.status 
+        while status == ApplicationCache.DOWNLOADING:
+            status = app_cache.status
+
+        self.assertEquals(ApplicationCache.UNCACHED, app_cache.status)
--- a/testing/marionette/client/marionette/tests/unit/unit-tests.ini
+++ b/testing/marionette/client/marionette/tests/unit/unit-tests.ini
@@ -31,8 +31,11 @@ b2g = false
 [test_simpletest_chrome.js]
 [test_simpletest_timeout.js]
 [test_specialpowers.py]
 [test_switch_frame.py]
 b2g = false
 
 [test_window_management.py]
 b2g = false
+
+[test_appcache.py]
+
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..8ea27c42faa7b5e56c43d3db317d5e4ecf1cb613
GIT binary patch
literal 92
zc${<hbhEHbG-5DfXkcJaWSGJLB!99nfPfB&0Ld^g8MpMWJpGn`@tiHUx;Nk3^P9iz
qk;k-Woy%UG+V+n7_$Qz1-+G__I`{n_KMz;?kwqUne6-YA8LR;;1tfp~
new file mode 100644
--- /dev/null
+++ b/testing/marionette/client/marionette/www/html5/geolocation.js
@@ -0,0 +1,18 @@
+function success(position) {
+  var message = document.getElementById("status");
+  message.innerHTML ="<img src='http://maps.google.com/maps/api/staticmap?center=" + position.coords.latitude + "," + position.coords.longitude + "&size=300x200&maptype=roadmap&zoom=12&&markers=size:mid|color:red|" + position.coords.latitude + "," + position.coords.longitude + "&sensor=false' />";
+  message.innerHTML += "<p>Longitude: " + position.coords.longitude + "</p>";
+  message.innerHTML += "<p>Latitude: " + position.coords.latitude + "</p>";
+  message.innerHTML += "<p>Altitude: " + position.coords.altitude + "</p>";
+}
+
+function error(msg) {
+  var message = document.getElementById("status");
+  message.innerHTML = "Failed to get geolocation.";
+}
+
+if (navigator.geolocation) {
+  navigator.geolocation.getCurrentPosition(success, error);
+} else {
+  error('Geolocation is not supported.');
+}
\ No newline at end of file
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..6a0d3bea4793a5fe3a3a36e29ba174540540513d
GIT binary patch
literal 92
zc${<hbhEHbG-5DfXkcJqT;s&Rz@Ye(g#iR~Km<sJfyua~f92`7{EO#oxz)Y--k#t5
sZI3*rJ?mWd>eRM(+{ZupT>sYl{MWhf|M+>h+K(*y*x{q4&dOj706pU*x&QzG
new file mode 100644
--- /dev/null
+++ b/testing/marionette/client/marionette/www/html5/offline.html
@@ -0,0 +1,1 @@
+<html><head><title>Offline</title></head><body></body></html>
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..f296e271956d5d4e0939b9706e86b2c2bc0d65b7
GIT binary patch
literal 92
zc${<hbhEHbG-5DfXkcLY$H2kBz@Ye(g#iR~Km<sJfyua~f92`7{EO#oxz)Y--k#t5
sZI3*rJ?mWd>eRM(+{ZupT>sYl{MWhf|M+>h+K(*y*x{q4&dOj707e`n(EtDd
new file mode 100644
--- /dev/null
+++ b/testing/marionette/client/marionette/www/html5/status.html
@@ -0,0 +1,1 @@
+<html><head><title>Online</title></head><body></body></html>
new file mode 100644
--- /dev/null
+++ b/testing/marionette/client/marionette/www/html5/test.appcache
@@ -0,0 +1,11 @@
+CACHE MANIFEST
+
+CACHE:
+# Additional items to cache.
+yellow.jpg
+red.jpg
+blue.jpg
+green.jpg
+
+FALLBACK:
+status.html offline.html
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..7c609b371291aeb672feb6bc24497d5f64d20288
GIT binary patch
literal 92
zc${<hbhEHbG-5DfXkcLYcZ>lD6o0aSC<Yx60g_>0GH&T#dHOB?;yGJxb#K16=Qn@b
rBadm%I+wjVwe21E@lQV2zx6)<b?*B=ejcv&Ba1$E_-LuKGFSrufCwdz
new file mode 100644
--- /dev/null
+++ b/testing/marionette/client/marionette/www/html5Page.html
@@ -0,0 +1,45 @@
+<html manifest="html5/test.appcache">
+<!--
+Copyright 2011 Software Freedom Conservancy.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+
+<head>
+<title>HTML5</title>
+</head>
+<body>
+
+<h3>Geolocation Test</h3>
+<div id="status">Location unknown</div>
+<script language="javascript" type="text/javascript" src="html5/geolocation.js"></script>
+
+<h3>Application Cache Test</h3>
+<div id="images">
+  <p>Current network status: <span id="state"></span></p>
+  <script>
+    var state = document.getElementById('state')
+    setInterval(function () {
+      state.className = navigator.onLine ? 'online' : 'offline';
+      state.innerHTML = navigator.onLine ? 'online' : 'offline';
+    }, 250);
+  </script>
+  <img id="red" src="html5/red.jpg">
+  <img id="blue" src="html5/blue.jpg">
+  <img id="green" src="html5/green.jpg">
+  <img id="yellow" src="html5/yellow.jpg">
+</div>
+
+</body>
+</html>
--- a/testing/marionette/marionette-actors.js
+++ b/testing/marionette/marionette-actors.js
@@ -1453,16 +1453,23 @@ MarionetteDriverActor.prototype = {
     this.curBrowser = null;
     try {
       this.importedScripts.remove(false);
     }
     catch (e) {
     }
   },
 
+  /**
+   * Returns the current status of the Application Cache
+   */
+  getAppCacheStatus: function MDA_getAppCacheStatus(aRequest) {
+    this.sendAsync("getAppCacheStatus");
+  },
+
   _emu_cb_id: 0,
   _emu_cbs: null,
   runEmulatorCmd: function runEmulatorCmd(cmd, callback) {
     if (callback) {
       if (!this._emu_cbs) {
         this._emu_cbs = {};
       }
       this._emu_cbs[this._emu_cb_id] = callback;
@@ -1676,16 +1683,17 @@ MarionetteDriverActor.prototype.requestT
   "refresh":  MarionetteDriverActor.prototype.refresh,
   "getWindow":  MarionetteDriverActor.prototype.getWindow,
   "getWindows":  MarionetteDriverActor.prototype.getWindows,
   "switchToFrame": MarionetteDriverActor.prototype.switchToFrame,
   "switchToWindow": MarionetteDriverActor.prototype.switchToWindow,
   "deleteSession": MarionetteDriverActor.prototype.deleteSession,
   "emulatorCmdResult": MarionetteDriverActor.prototype.emulatorCmdResult,
   "importScript": MarionetteDriverActor.prototype.importScript,
+  "getAppCacheStatus": MarionetteDriverActor.prototype.getAppCacheStatus,
   "closeWindow": MarionetteDriverActor.prototype.closeWindow
 };
 
 /**
  * Creates a BrowserObj. BrowserObjs handle interactions with the
  * browser, according to the current environment (desktop, b2g, etc.)
  *
  * @param nsIDOMWindow win
--- a/testing/marionette/marionette-listener.js
+++ b/testing/marionette/marionette-listener.js
@@ -109,16 +109,17 @@ function startListeners() {
   addMessageListenerId("Marionette:isElementSelected", isElementSelected);
   addMessageListenerId("Marionette:sendKeysToElement", sendKeysToElement);
   addMessageListenerId("Marionette:clearElement", clearElement);
   addMessageListenerId("Marionette:switchToFrame", switchToFrame);
   addMessageListenerId("Marionette:deleteSession", deleteSession);
   addMessageListenerId("Marionette:sleepSession", sleepSession);
   addMessageListenerId("Marionette:emulatorCmdResult", emulatorCmdResult);
   addMessageListenerId("Marionette:importScript", importScript);
+  addMessageListenerId("Marionette:getAppCacheStatus", getAppCacheStatus);
 }
 
 /**
  * Called when we start a new session. It registers the
  * current environment, and resets all values
  */
 function newSession(msg) {
   isB2G = msg.json.B2G;
@@ -170,16 +171,17 @@ function deleteSession(msg) {
   removeMessageListenerId("Marionette:isElementSelected", isElementSelected);
   removeMessageListenerId("Marionette:sendKeysToElement", sendKeysToElement);
   removeMessageListenerId("Marionette:clearElement", clearElement);
   removeMessageListenerId("Marionette:switchToFrame", switchToFrame);
   removeMessageListenerId("Marionette:deleteSession", deleteSession);
   removeMessageListenerId("Marionette:sleepSession", sleepSession);
   removeMessageListenerId("Marionette:emulatorCmdResult", emulatorCmdResult);
   removeMessageListenerId("Marionette:importScript", importScript);
+  removeMessageListenerId("Marionette:getAppCacheStatus", getAppCacheStatus);
   this.elementManager.reset();
   try {
     importedScripts.remove(false);
   }
   catch (e) {
   }
 }
 
@@ -790,16 +792,20 @@ function switchToFrame(msg) {
   }
   else {
     curWindow = curWindow.contentWindow;
     curWindow.focus();
     sendOk();
   }
 }
 
+function getAppCacheStatus() {
+  sendResponse({ value: curWindow.applicationCache.status });  
+} 
+
 // emulator callbacks
 let _emu_cb_id = 0;
 let _emu_cbs = {};
 
 function runEmulatorCmd(cmd, callback) {
   if (callback) {
     _emu_cbs[_emu_cb_id] = callback;
   }