You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by pu...@apache.org on 2012/04/10 00:40:30 UTC

[30/34] updated mobile spec tests for CordovaJS

http://git-wip-us.apache.org/repos/asf/incubator-cordova-wp7/blob/5bca3c1a/tests/MobileSpecUnitTests/www/autotest/tests/geolocation.tests.js
----------------------------------------------------------------------
diff --git a/tests/MobileSpecUnitTests/www/autotest/tests/geolocation.tests.js b/tests/MobileSpecUnitTests/www/autotest/tests/geolocation.tests.js
index eb7758c..7890b40 100644
--- a/tests/MobileSpecUnitTests/www/autotest/tests/geolocation.tests.js
+++ b/tests/MobileSpecUnitTests/www/autotest/tests/geolocation.tests.js
@@ -21,39 +21,70 @@ Tests.prototype.GeoLocationTests = function() {
 	});
 	test("getCurrentPosition success callback should be called with a Position object", function() {
 		expect(2);
-		QUnit.stop(Tests.TEST_TIMEOUT);
+		QUnit.stop(15000);
 		var win = function(p) {
 			ok(p.coords != null, "Position object returned in getCurrentPosition success callback has a 'coords' property.");
 			ok(p.timestamp != null, "Position object returned in getCurrentPosition success callback has a 'timestamp' property.");
-			start();
+			QUnit.start();
 		};
-		var fail = function() { start(); };
-		navigator.geolocation.getCurrentPosition(win, fail);
+		var fail = function() { 
+        ok(false, "Error callback fired, test failed.");
+        QUnit.start();
+    };
+		navigator.geolocation.getCurrentPosition(win, fail, {
+        maximumAge:300000 // 5 minutes maximum age of cached position
+    });
 	});
+  test("getCurrentPosition success callback should be called with a cached Position", function() {
+    expect(1);
+    QUnit.stop(Tests.TEST_TIMEOUT);
+    var win = function(p) {
+      ok(p.coords instanceof Position, "Position object returned is an instance of Position");
+      QUnit.start();
+    };
+    var fail = function(e) {
+      ok(false, "Error callback called, test failed.");
+    };
+    navigator.geolocation.getCurrentPosition(win, fail, {
+        maximumAge:300000 // 5 minutes
+    });
+  });
+  test("getCurrentPosition error callback should be called if we set timeout to 0 and maximumAge to a very small number", function() {
+    expect(1);
+    QUnit.stop(Tests.TEST_TIMEOUT);
+    var win = function(p) {
+      ok(false, "success callback called, test failed.");
+      QUnit.start();
+    };
+    var fail = function(e) {
+      ok(true, "error callback called");
+      QUnit.start();
+    };
+    navigator.geolocation.getCurrentPosition(win, fail, {
+        maximumAge: 0,
+        timeout: 0
+    });
+  });
 	// TODO: Need to test error callback... how?
 	// TODO: Need to test watchPosition success callback, test that makes sure clearPosition works (how to test that a timer is getting cleared?)
-	// TODO: Need to test options object passed in. Members that need to be tested so far include:
-	//				- options.frequency: this is also labelled differently on some implementations (internval on iPhone/BlackBerry currently). 
-	
-	
-//	module('Geolocation model');
-//	test("should be able to define a Position object with coords and timestamp properties", function() {
-//		expect(3);
-//		var pos = new Position({}, new Date());
-//		ok(pos != null, "new Position() should not be null.");
-//		ok(typeof pos.coords != 'undefined' && pos.coords != null, "new Position() should include a 'coords' property.");
-//		ok(typeof pos.timestamp != 'undefined' && pos.timestamp != null, "new Position() should include a 'timestamp' property.");
-//	});
-//	test("should be able to define a Coordinates object with latitude, longitude, accuracy, altitude, heading, speed and altitudeAccuracy properties", function() {
-//		expect(8);
-//		var coords = new Coordinates(1,2,3,4,5,6,7);
-//		ok(coords != null, "new Coordinates() should not be null.");
-//		ok(typeof coords.latitude != 'undefined' && coords.latitude != null, "new Coordinates() should include a 'latitude' property.");
-//		ok(typeof coords.longitude != 'undefined' && coords.longitude != null, "new Coordinates() should include a 'longitude' property.");
-//		ok(typeof coords.accuracy != 'undefined' && coords.accuracy != null, "new Coordinates() should include a 'accuracy' property.");
-//		ok(typeof coords.altitude != 'undefined' && coords.altitude != null, "new Coordinates() should include a 'altitude' property.");
-//		ok(typeof coords.heading != 'undefined' && coords.heading != null, "new Coordinates() should include a 'heading' property.");
-//		ok(typeof coords.speed != 'undefined' && coords.speed != null, "new Coordinates() should include a 'speed' property.");
-//		ok(typeof coords.altitudeAccuracy != 'undefined' && coords.altitudeAccuracy != null, "new Coordinates() should include a 'altitudeAccuracy' property.");
-//	});
-};
\ No newline at end of file
+	module('Geolocation model');
+	test("should be able to define a Position object with coords and timestamp properties", function() {
+		expect(3);
+		var pos = new Position({}, new Date());
+		ok(pos != null, "new Position() should not be null.");
+		ok(typeof pos.coords != 'undefined' && pos.coords != null, "new Position() should include a 'coords' property.");
+		ok(typeof pos.timestamp != 'undefined' && pos.timestamp != null, "new Position() should include a 'timestamp' property.");
+	});
+	test("should be able to define a Coordinates object with latitude, longitude, accuracy, altitude, heading, speed and altitudeAccuracy properties", function() {
+		expect(8);
+		var coords = new Coordinates(1,2,3,4,5,6,7);
+		ok(coords != null, "new Coordinates() should not be null.");
+		ok(typeof coords.latitude != 'undefined' && coords.latitude != null, "new Coordinates() should include a 'latitude' property.");
+		ok(typeof coords.longitude != 'undefined' && coords.longitude != null, "new Coordinates() should include a 'longitude' property.");
+		ok(typeof coords.accuracy != 'undefined' && coords.accuracy != null, "new Coordinates() should include a 'accuracy' property.");
+		ok(typeof coords.altitude != 'undefined' && coords.altitude != null, "new Coordinates() should include a 'altitude' property.");
+		ok(typeof coords.heading != 'undefined' && coords.heading != null, "new Coordinates() should include a 'heading' property.");
+		ok(typeof coords.speed != 'undefined' && coords.speed != null, "new Coordinates() should include a 'speed' property.");
+		ok(typeof coords.altitudeAccuracy != 'undefined' && coords.altitudeAccuracy != null, "new Coordinates() should include a 'altitudeAccuracy' property.");
+	});
+};

http://git-wip-us.apache.org/repos/asf/incubator-cordova-wp7/blob/5bca3c1a/tests/MobileSpecUnitTests/www/autotest/tests/media.tests.js
----------------------------------------------------------------------
diff --git a/tests/MobileSpecUnitTests/www/autotest/tests/media.tests.js b/tests/MobileSpecUnitTests/www/autotest/tests/media.tests.js
index dc47d19..cf6ded4 100644
--- a/tests/MobileSpecUnitTests/www/autotest/tests/media.tests.js
+++ b/tests/MobileSpecUnitTests/www/autotest/tests/media.tests.js
@@ -1,185 +1,152 @@
-//
-// @TODO Update to Latest HTML5 Audio Element Spec
-// @see http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html#audio
-//
-Tests.prototype.MediaTests = function () {
-    module('Media (Audio)');
-
-    var srcLocalMediaFile = "test.wav";
-    var srcNetworkMediaFile = "http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3";
-
-    var srcDummyFile = "some link to media file";
-    var media = new Media(srcDummyFile, null, null);
-
-    test("should exist", function () {
-        expect(1);
-        ok(typeof Audio === "function" || typeof Audio === "object", "'Audio' should be defined as a function in global scope.");
-    });
-    test("should define constants for Media errors", function () {
-        expect(9);
-        ok(MediaError != null && typeof MediaError != 'undefined', "MediaError object exists in global scope.");
-        equals(MediaError.MEDIA_ERR_PLAY_MODE_SET, 1, "MediaError.MEDIA_ERR_PLAY_MODE_SET is equal to 1.");
-        equals(MediaError.MEDIA_ERR_ALREADY_RECORDING, 2, "MediaError.MEDIA_ERR_ALREADY_RECORDING is equal to 2.");
-        equals(MediaError.MEDIA_ERR_STARTING_RECORDING, 3, "MediaError.MEDIA_ERR_STARTING_RECORDING is equal to 3.");
-        equals(MediaError.MEDIA_ERR_RECORD_MODE_SET, 4, "MediaError.MEDIA_ERR_RECORD_MODE_SET is equal to 4.");
-        equals(MediaError.MEDIA_ERR_STARTING_PLAYBACK, 5, "MediaError.MEDIA_ERR_STARTING_PLAYBACK is equal to 5.");
-        equals(MediaError.MEDIA_ERR_RESUME_STATE, 6, "MediaError.MEDIA_ERR_DECODE is equal to 6.");
-        equals(MediaError.MEDIA_ERR_PAUSE_STATE, 7, "MediaError.MEDIA_ERR_PAUSE_STATE is equal to 7.");
-        equals(MediaError.MEDIA_ERR_STOP_STATE, 8, "MediaError.MEDIA_ERR_STOP_STATE is equal to 8.");
-    });
-
-    test("should contain 'src', 'loop' and 'error' properties", function () {
-        expect(7);
-        var audioSrc = '/test.mp3';
-        var audio = new Audio(audioSrc);
-        ok(typeof audio == "object", "Instantiated 'Audio' object instance should be of type 'object.'");
-        ok(audio.src != null && typeof audio.src != 'undefined', "Instantiated 'Audio' object's 'src' property should not be null or undefined.");
-        ok(audio.src.indexOf(audioSrc) >= 0, "Instantiated 'Audio' object's 'src' property should match constructor parameter.");
-        ok(audio.loop != null && typeof audio.loop != 'undefined', "Instantiated 'Audio' object's 'loop' property should not be null or undefined.");
-        ok(audio.loop == false, "Instantiated 'Audio' object's 'loop' property should initially be false.");
-        ok(typeof audio.error != 'undefined', "Instantiated 'Audio' object's 'error' property should not undefined.");
-        ok(audio.error == null, "Instantiated 'Audio' object's 'error' should initially be null.");
-    });
-
-    test("Media constructor should exist", function () {
-        expect(1);
-        ok(media != null, "media1 should not be null.");
-    });
-
-    test("should contain an play function", function () {
+Tests.prototype.MediaTests = function() {	
+	module('Media');
+	test("should exist", function() {
+  		expect(1);
+		ok(typeof Media === "function" || typeof Media === "object", "'Media' should be defined as a function in global scope.");
+	});
+    test("should have the following properties", function() {
+        var media1 = new Media("dummy");
+        expect(4);
+        ok(typeof media1.id != 'undefined' && media1.id != null, "'Media' should have an id property.");
+        ok(typeof media1.src != 'undefined', "'Media' should have an src property.");
+        ok(typeof media1._duration != 'undefined' && media1._duration != null, "'Media' should have an _duration property.");
+        ok(typeof media1._position != 'undefined' && media1._position != null, "'Media' should have an _position property.");
+        media1.release();
+    });
+	test("should define constants for Media errors", function() {
+		expect(6);
+		ok(MediaError != null && typeof MediaError != 'undefined', "MediaError object exists in global scope.");
+        equals(MediaError.MEDIA_ERR_NONE_ACTIVE, 0, "MediaError.MEDIA_ERR_NONE_ACTIVE is equal to 0.");
+        equals(MediaError.MEDIA_ERR_ABORTED, 1, "MediaError.MEDIA_ERR_ABORTED is equal to 1.");
+		equals(MediaError.MEDIA_ERR_NETWORK, 2, "MediaError.MEDIA_ERR_NETWORK is equal to 2.");
+		equals(MediaError.MEDIA_ERR_DECODE, 3, "MediaError.MEDIA_ERR_DECODE is equal to 3.");
+		equals(MediaError.MEDIA_ERR_NONE_SUPPORTED, 4, "MediaError.MEDIA_ERR_NONE_SUPPORTED is equal to 4.");
+	});
+    test("should contain a play function", function() {
+        var media1 = new Media();
         expect(2);
-        ok(typeof media.play != 'undefined' && media.play != null, "media.play should not be null.");
-        ok(typeof media.play == 'function', "media.play should be a function.");
+        ok(typeof media1.play != 'undefined' && media1.play != null, "Media.play should not be null.");
+        ok(typeof media1.play == 'function', "Media.play should be a function.");
+        media1.release();
     });
-
-    test("should contain an pause function", function () {
+    test("should contain a stop function", function() {
+        var media1 = new Media();
         expect(2);
-        ok(typeof media.pause != 'undefined' && media.pause != null, "media.pause should not be null.");
-        ok(typeof media.pause == 'function', "media.pause should be a function.");
+        ok(typeof media1.stop != 'undefined' && media1.stop != null, "Media.stop should not be null.");
+        ok(typeof media1.stop == 'function', "Media.stop should be a function.");
+        media1.release();
     });
-
-    test("should contain an stop function", function () {
+    test("should contain a seekTo function", function() {
+        var media1 = new Media();
         expect(2);
-        ok(typeof media.stop != 'undefined' && media.stop != null, "media.stop should not be null.");
-        ok(typeof media.stop == 'function', "media.stop should be a function.");
+        ok(typeof media1.seekTo != 'undefined' && media1.seekTo != null, "Media.seekTo should not be null.");
+        ok(typeof media1.seekTo == 'function', "Media.seekTo should be a function.");
+        media1.release();
     });
-
-    test("should contain an seekTo function", function () {
+    test("should contain a pause function", function() {
+        var media1 = new Media();
         expect(2);
-        ok(typeof media.seekTo != 'undefined' && media.seekTo != null, "media.seekTo should not be null.");
-        ok(typeof media.seekTo == 'function', "media.seekTo should be a function.");
+        ok(typeof media1.pause != 'undefined' && media1.pause != null, "Media.pause should not be null.");
+        ok(typeof media1.pause == 'function', "Media.pause should be a function.");
+        media1.release();
     });
-
-    test("should contain an getDuration function", function () {
+    test("should contain a getDuration function", function() {
+        var media1 = new Media();
         expect(2);
-        ok(typeof media.getDuration != 'undefined' && media.getDuration != null, "media.getDuration should not be null.");
-        ok(typeof media.getDuration == 'function', "media.getDuration should be a function.");
+        ok(typeof media1.getDuration != 'undefined' && media1.getDuration != null, "Media.getDuration should not be null.");
+        ok(typeof media1.getDuration == 'function', "Media.getDuration should be a function.");
+        media1.release();
     });
-
-    test("should contain an getCurrentPosition function", function () {
+    test("should contain a getCurrentPosition function", function() {
+        var media1 = new Media();
         expect(2);
-        ok(typeof media.getCurrentPosition != 'undefined' && media.getCurrentPosition != null, "media.getCurrentPosition should not be null.");
-        ok(typeof media.getCurrentPosition == 'function', "media.getCurrentPosition should be a function.");
+        ok(typeof media1.getCurrentPosition != 'undefined' && media1.getCurrentPosition != null, "Media.getCurrentPosition should not be null.");
+        ok(typeof media1.getCurrentPosition == 'function', "Media.getCurrentPosition should be a function.");
+        media1.release();
     });
-
-    test("should contain an release function", function () {
+    test("should contain a startRecord function", function() {
+        var media1 = new Media();
         expect(2);
-        ok(typeof media.release != 'undefined' && media.release != null, "media.release should not be null.");
-        ok(typeof media.release == 'function', "media.release should be a function.");
+        ok(typeof media1.startRecord != 'undefined' && media1.startRecord != null, "Media.startRecord should not be null.");
+        ok(typeof media1.startRecord == 'function', "Media.startRecord should be a function.");
+        media1.release();
     });
-
-    test("should contain an startRecord function", function () {
+    test("should contain a stopRecord function", function() {
+        var media1 = new Media();
         expect(2);
-        ok(typeof media.startRecord != 'undefined' && media.startRecord != null, "media.startRecord should not be null.");
-        ok(typeof media.startRecord == 'function', "media.startRecord should be a function.");
+        ok(typeof media1.stopRecord != 'undefined' && media1.stopRecord != null, "Media.stopRecord should not be null.");
+        ok(typeof media1.stopRecord == 'function', "Media.stopRecord should be a function.");
+        media1.release();
     });
-
-    test("should contain an stopRecord function", function () {
+    test("should contain a release function", function() {
+        var media1 = new Media();
         expect(2);
-        ok(typeof media.stopRecord != 'undefined' && media.stopRecord != null, "media.stopRecord should not be null.");
-        ok(typeof media.stopRecord == 'function', "media.stopRecord should be a function.");
+        ok(typeof media1.release != 'undefined' && media1.release != null, "Media.release should not be null.");
+        ok(typeof media1.release == 'function', "Media.release should be a function.");
+        media1.release();
     });
-
-    test("should Cordova.Media.onStatus exist", function () {
-        expect(1);
-        ok(typeof Cordova.Media.onStatus === "function" || typeof Cordova.Media.onStatus === "object", "'Audio' should be defined as a function in global scope.");
-    });
-    
-    test("record audio", function () {
-        var media2 = new Media(srcLocalMediaFile,
-                null,
-                function (err) {
-                    QUnit.start();
-                },
-                function (status) {
-                    ok(status !== null, "status should not be null.");
-
-                    if (typeof (media2.statusFlag) == 'undefined') {
-                        equal(status, 2, "Should receive status MEDIA_RUNNING");
-                        media2.statusFlag = true;
-
-                        var recInterval = setInterval(function () {
-                            clearInterval(recInterval);
-                            media2.stopRecord();
-                        }, 1000);
-
-                    }
-                    else {
-                        equal(status, 4, "Should receive status MEDIA_STOPPED");
-                        QUnit.start();
-                    }
-                });
-
-        QUnit.stop(Tests.TEST_TIMEOUT);
-        expect(4);
-        media2.startRecord();
-
-    });
-   
-    test("play file that doesn't exist", function () {
-
-        var src = "wrongSrc";
-
-        var media3 = new Media(src,
-            null,
-            function (err) {
-                ok(err !== null, "error should not be null.");
-                equal(err, MediaError.MEDIA_ERR_STARTING_PLAYBACK, "Should receive error code MEDIA_ERR_STARTING_PLAYBACK");
-                QUnit.start();
-            });
-
-        QUnit.stop(Tests.TEST_TIMEOUT);
+    test("should contain a setVolume function", function() {
+        var media1 = new Media();
         expect(2);
-        media3.play();
-    });
-
-    test("play internet audio", function () {
-        var media2a = new Media(srcNetworkMediaFile,
-                null,
-                function (err) {
-                    console.log("playAudio():Audio Error: " + err);
+        ok(typeof media1.setVolume != 'undefined' && media1.setVolume != null, "Media.setVolume should not be null.");
+        ok(typeof media1.setVolume == 'function', "Media.setVolume should be a function.");
+        media1.release();
+    });
+	test("should return MediaError for bad filename", function() {
+		expect(2);
+		QUnit.stop(10000);
+		var badMedia = null;
+		var releaseMedia = function() {
+			badMedia.release();
+		};
+		var win = function() {
+			ok(0, "should NOT succeed with bad media file name");
+			releaseMedia();
+			QUnit.start();
+		};
+		var fail = function(result){
+			ok(typeof result == 'object', "Object returned in media.play failure callback is of type 'object' (actually MediaError).");
+			ok(result.code == MediaError.MEDIA_ERR_ABORTED, "Object returned in media.find failure callback has a code property which equal to MediaError.MEDIA_ERR_ABORTED");
+			releaseMedia();
+			QUnit.start(); 
+		};
+		badMedia = new Media("invalid.file.name", win,fail);
+		badMedia.play();
+	});
+    test("position should be set properly", function() {
+        var media1 = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3");
+        media1.play();
+        expect(1);
+        QUnit.stop(15000);
+        setTimeout(
+                function() {
+                    media1.getCurrentPosition(
+                        function(position) {
+                            console.log("position = " + position);
+                            ok(position >= 0.0, "position should not be -1");
+                            QUnit.start();
+                            media1.stop()
+                            media1.release();
+                        },
+                        function(e) {
+                            QUnit.start();
+                        }
+                    );
+                }
+           , 5000);
+    });
+    test("duration should be set properly", function() {
+        var media1 = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3");
+        media1.play();
+        expect(1);
+        QUnit.stop(15000);
+        setTimeout(
+                function() {
+                    ok(media1.getDuration() >= 0.0, "duration should not be -1");
                     QUnit.start();
-                },
-                function (status) {
-                    ok(status !== null, "status should not be null.");
-
-                    if (typeof (media2a.statusFlag) == 'undefined') {
-                        equal(status, 1, "Should receive status MEDIA_STARTING");
-                        media2a.statusFlag = 1;
-
-                    } else if (media2a.statusFlag === 1) {
-                        equal(status, 2, "Should receive status MEDIA_RUNNING");
-                        media2a.statusFlag = 2;
-                        media2a.stop();
-                    } else {
-                        equal(status, 4, "Should receive status MEDIA_STOPPED");
-                        QUnit.start();
-                    }
-                });
-
-        QUnit.stop(10000);
-        expect(6);
-        media2a.play();
-
+                    media1.stop()
+                    media1.release();
+                }
+           , 5000);
     });
 };
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-cordova-wp7/blob/5bca3c1a/tests/MobileSpecUnitTests/www/autotest/tests/platform.tests.js
----------------------------------------------------------------------
diff --git a/tests/MobileSpecUnitTests/www/autotest/tests/platform.tests.js b/tests/MobileSpecUnitTests/www/autotest/tests/platform.tests.js
new file mode 100644
index 0000000..67fb28c
--- /dev/null
+++ b/tests/MobileSpecUnitTests/www/autotest/tests/platform.tests.js
@@ -0,0 +1,37 @@
+Tests.prototype.PlatformTests = function() {	
+    module('Platform (cordova)');
+    test("should exist", function() {
+        expect(1);
+        ok(typeof cordova != 'undefined' && cordova != null, "cordova should not be null.");
+    });
+    module('Platform (Cordova)');
+    test("should not exist", function() {
+        expect(1);
+        ok(typeof Cordova == 'undefined', "Cordova should be null.");
+    });
+    module('Platform (PhoneGap)');
+    test("should exist", function() {
+        expect(1);
+        ok(typeof PhoneGap != 'undefined' && PhoneGap != null, "PhoneGap should not be null.");
+    });
+    test("exec method should exist", function() {
+        expect(2);
+        ok(typeof PhoneGap.exec != 'undefined' && PhoneGap.exec != null, "PhoneGap.exec should not be null.");
+        ok(typeof PhoneGap.exec == 'function', "PhoneGap.exec should be a function.");
+    });
+    test("addPlugin method should exist", function() {
+        expect(2);
+        ok(typeof PhoneGap.addPlugin != 'undefined' && PhoneGap.addPlugin != null, "PhoneGap.addPlugin should not be null.");
+        ok(typeof PhoneGap.addPlugin == 'function', "PhoneGap.addPlugin should be a function.");
+    });
+    test("addConstructor method should exist", function() {
+        expect(2);
+        ok(typeof PhoneGap.addConstructor != 'undefined' && PhoneGap.addConstructor != null, "PhoneGap.addConstructor should not be null.");
+        ok(typeof PhoneGap.addConstructor == 'function', "PhoneGap.addConstructor should be a function.");
+    });
+    module('Platform (window.plugins)');
+    test("should exist", function() {
+        expect(1);
+        ok(typeof window.plugins != 'undefined' && window.plugins != null, "window.plugins should not be null.");
+    });
+};
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-cordova-wp7/blob/5bca3c1a/tests/MobileSpecUnitTests/www/autotest/tests/storage.tests.js
----------------------------------------------------------------------
diff --git a/tests/MobileSpecUnitTests/www/autotest/tests/storage.tests.js b/tests/MobileSpecUnitTests/www/autotest/tests/storage.tests.js
index e5dd028..41476d8 100644
--- a/tests/MobileSpecUnitTests/www/autotest/tests/storage.tests.js
+++ b/tests/MobileSpecUnitTests/www/autotest/tests/storage.tests.js
@@ -1,7 +1,6 @@
 Tests.prototype.StorageTests = function() 
 {
   module("Session Storage");
-
   test("should exist", function() {
 	expect(7);
 	ok(window.sessionStorage != null, "sessionStorage is defined");
@@ -12,7 +11,6 @@ Tests.prototype.StorageTests = function()
     ok(typeof(window.sessionStorage.removeItem) == "function", "sessionStorage.removeItem is defined");
     ok(typeof(window.sessionStorage.clear) == "function", "sessionStorage.clear is defined");
   });
-
   test("check length", function() {
     expect(3);
     ok(window.sessionStorage.length == 0, "length should be 0");
@@ -21,9 +19,6 @@ Tests.prototype.StorageTests = function()
     window.sessionStorage.removeItem("key");   
     ok(window.sessionStorage.length == 0, "length should be 0");
   });
-
-
-
   test("check key", function() {
 	expect(3);
 	ok(window.sessionStorage.key(0) == null, "key should be null");
@@ -32,7 +27,6 @@ Tests.prototype.StorageTests = function()
 	window.sessionStorage.removeItem("test");   
 	ok(window.sessionStorage.key(0) == null, "key should be null");
   });
-
   test("check getItem", function() {
 	expect(3);
     ok(window.sessionStorage.getItem("item") == null, "item should be null");
@@ -41,7 +35,6 @@ Tests.prototype.StorageTests = function()
     window.sessionStorage.removeItem("item");   
     ok(window.sessionStorage.getItem("item") == null, "item should be null");
   });
-
   test("check setItem", function() {
     expect(4);
     ok(window.sessionStorage.getItem("item") == null, "item should be null");
@@ -52,7 +45,6 @@ Tests.prototype.StorageTests = function()
     window.sessionStorage.removeItem("item");   
     ok(window.sessionStorage.getItem("item") == null, "item should be null");
   });
-
   test("check removeItem", function() {
     expect(3);
     ok(window.sessionStorage.getItem("item") == null, "item should be null");
@@ -61,7 +53,6 @@ Tests.prototype.StorageTests = function()
     window.sessionStorage.removeItem("item");   
     ok(window.sessionStorage.getItem("item") == null, "item should be null");
   });
-  
   test("check clear", function() {
     expect(11);
     ok(window.sessionStorage.getItem("item1") == null, "item1 should be null");
@@ -80,7 +71,6 @@ Tests.prototype.StorageTests = function()
     ok(window.sessionStorage.getItem("item2") == null, "item2 should be null");
     ok(window.sessionStorage.getItem("item3") == null, "item3 should be null");	    
   });
-
   test("check dot notation", function() {
     expect(3);
     ok(window.sessionStorage.item == null, "item should be null");
@@ -89,9 +79,7 @@ Tests.prototype.StorageTests = function()
     window.sessionStorage.removeItem("item");   
     ok(window.sessionStorage.item == null, "item should be null");
   });
-
   module("Local Storage");
-
   test("should exist", function() {
 	expect(7);
 	ok(window.localStorage != null, "localStorage is defined");
@@ -102,7 +90,6 @@ Tests.prototype.StorageTests = function()
     ok(typeof(window.localStorage.removeItem) == "function", "localStorage.removeItem is defined");
     ok(typeof(window.localStorage.clear) == "function", "localStorage.clear is defined");
   });  
-
   test("check length", function() {
     expect(3);
     ok(window.localStorage.length == 0, "length should be 0");
@@ -111,7 +98,6 @@ Tests.prototype.StorageTests = function()
     window.localStorage.removeItem("key");   
     ok(window.localStorage.length == 0, "length should be 0");
   });
-
   test("check key", function() {
     expect(3);
     ok(window.localStorage.key(0) == null, "key should be null");
@@ -120,7 +106,6 @@ Tests.prototype.StorageTests = function()
     window.localStorage.removeItem("test");   
     ok(window.localStorage.key(0) == null, "key should be null");
   });
-
   test("check getItem", function() {
     expect(3);
     ok(window.localStorage.getItem("item") == null, "item should be null");
@@ -129,7 +114,6 @@ Tests.prototype.StorageTests = function()
     window.localStorage.removeItem("item");   
     ok(window.localStorage.getItem("item") == null, "item should be null");
   });
-
   test("check setItem", function() {
     expect(4);
     ok(window.localStorage.getItem("item") == null, "item should be null");
@@ -140,7 +124,6 @@ Tests.prototype.StorageTests = function()
     window.localStorage.removeItem("item");   
     ok(window.localStorage.getItem("item") == null, "item should be null");
   });
-
   test("check removeItem", function() {
     expect(3);
     ok(window.localStorage.getItem("item") == null, "item should be null");
@@ -149,7 +132,6 @@ Tests.prototype.StorageTests = function()
     window.localStorage.removeItem("item");   
     ok(window.localStorage.getItem("item") == null, "item should be null");
   });
-
   test("check clear", function() {
     expect(11);
     ok(window.localStorage.getItem("item1") == null, "item1 should be null");
@@ -168,7 +150,6 @@ Tests.prototype.StorageTests = function()
     ok(window.localStorage.getItem("item2") == null, "item2 should be null");
     ok(window.localStorage.getItem("item3") == null, "item3 should be null");	    
   });
-
   test("check dot notation", function() {
     expect(3);
     ok(window.localStorage.item == null, "item should be null");
@@ -177,12 +158,7 @@ Tests.prototype.StorageTests = function()
     window.localStorage.removeItem("item");   
     ok(window.localStorage.item == null, "item should be null");
   });
-
-  
-
-  /*
   module("HTML 5 Storage");
-
   test("should exist", function() {
     expect(1);
     ok(typeof(window.openDatabase) == "function", "Database is defined");
@@ -191,5 +167,4 @@ Tests.prototype.StorageTests = function()
     var db = openDatabase("Database", "1.0", "HTML5 Database API example", 200000);
     ok(db != null, "Database should be opened");
   });
-  */
 }

http://git-wip-us.apache.org/repos/asf/incubator-cordova-wp7/blob/5bca3c1a/tests/MobileSpecUnitTests/www/battery/index.html
----------------------------------------------------------------------
diff --git a/tests/MobileSpecUnitTests/www/battery/index.html b/tests/MobileSpecUnitTests/www/battery/index.html
new file mode 100644
index 0000000..593104a
--- /dev/null
+++ b/tests/MobileSpecUnitTests/www/battery/index.html
@@ -0,0 +1,96 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
+    <title>Cordova Mobile Spec</title>
+    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
+    <script type="text/javascript" charset="utf-8" src="../phonegap.js"></script>      
+
+      
+<script type="text/javascript" charset="utf-8">
+
+    var deviceReady = false;
+    
+    /**
+     * Function called when page has finished loading.
+     */
+    function init() {
+        document.addEventListener("deviceready", function() {
+                deviceReady = true;
+                console.log("Device="+device.platform+" "+device.version);
+            }, false);
+        window.setTimeout(function() {
+            if (!deviceReady) {
+                alert("Error: PhoneGap did not initialize.  Demo will not run correctly.");
+            }
+        },1000);
+    }
+
+    /* Battery */
+    function updateInfo(info) {
+        document.getElementById('level').innerText = info.level;
+        document.getElementById('isPlugged').innerText = info.isPlugged;
+        if (info.level > 5) {
+            document.getElementById('crit').innerText = "false";
+        }
+        if (info.level > 20) {
+            document.getElementById('low').innerText = "false";
+        }
+    }
+    
+    function batteryLow(info) {
+        document.getElementById('low').innerText = "true";
+    }
+    
+    function batteryCritical(info) {
+        document.getElementById('crit').innerText = "true";
+    }
+    
+    function addBattery() {
+        window.addEventListener("batterystatus", updateInfo, false);
+    }
+    
+    function removeBattery() {
+        window.removeEventListener("batterystatus", updateInfo, false);
+    }
+    
+    function addLow() {
+        window.addEventListener("batterylow", batteryLow, false);
+    }
+    
+    function removeLow() {
+        window.removeEventListener("batterylow", batteryLow, false);
+    }
+    
+    function addCritical() {
+        window.addEventListener("batterycritical", batteryCritical, false);
+    }
+    
+    function removeCritical() {
+        window.removeEventListener("batterycritical", batteryCritical, false);
+    }
+
+</script>
+
+  </head>
+  <body onload="init();" id="stage" class="theme">
+  
+    <h1>Battery</h1>
+    <div id="info">
+        <b>Status:</b> <span id="battery_status"></span><br>
+        Level: <span id="level"></span><br/>
+        Plugged: <span id="isPlugged"></span><br/>
+        Low: <span id="low"></span><br/>
+        Critical: <span id="crit"></span><br/>
+    </div>
+    <h2>Action</h2>
+    <div class="btn large" onclick="addBattery();">Add "batterystatus" listener</div>
+    <div class="btn large" onclick="removeBattery();">Remove "batterystatus" listener</div>
+    <div class="btn large" onclick="addLow();">Add "batterylow" listener</div>
+    <div class="btn large" onclick="removeLow();">Remove "batterylow" listener</div>
+    <div class="btn large" onclick="addCritical();">Add "batterycritical" listener</div>
+    <div class="btn large" onclick="removeCritical();">Remove "batterycritical" listener</div>
+    <h2> </h2><div class="backBtn" onclick="backHome();">Back</div>
+  </body>
+</html>      

http://git-wip-us.apache.org/repos/asf/incubator-cordova-wp7/blob/5bca3c1a/tests/MobileSpecUnitTests/www/camera/index.html
----------------------------------------------------------------------
diff --git a/tests/MobileSpecUnitTests/www/camera/index.html b/tests/MobileSpecUnitTests/www/camera/index.html
new file mode 100644
index 0000000..2e27da5
--- /dev/null
+++ b/tests/MobileSpecUnitTests/www/camera/index.html
@@ -0,0 +1,96 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
+    <title>Cordova Mobile Spec</title>
+    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
+    <script type="text/javascript" charset="utf-8" src="../phonegap.js"></script>      
+
+      
+<script type="text/javascript" charset="utf-8">
+
+    var deviceReady = false;
+
+    //-------------------------------------------------------------------------
+    // Camera 
+    //-------------------------------------------------------------------------
+
+    /**
+     * Capture picture
+     */
+    function getPicture() {
+        
+        //navigator.camera.getPicture(onPhotoDataSuccess, onFail, { quality: 50, 
+        //    destinationType: Camera.DestinationType.FILE_URI, sourceType : Camera.PictureSourceType.CAMERA });
+        
+        navigator.camera.getPicture(
+            function(data) {
+                var img = document.getElementById('camera_image');
+                img.style.visibility = "visible";
+                img.style.display = "block";
+                //img.src = "data:image/jpeg;base64," + data;
+                img.src = data;
+                document.getElementById('camera_status').innerHTML = "Success";
+            },
+            function(e) {
+                console.log("Error getting picture: " + e);
+                document.getElementById('camera_status').innerHTML = "Error getting picture.";
+            },
+            { quality: 50, destinationType:
+            Camera.DestinationType.FILE_URI, sourceType : Camera.PictureSourceType.CAMERA});
+    };
+
+    /**
+     * Select image from library
+     */
+    function getImage() {
+        navigator.camera.getPicture(
+            function(data) {
+                var img = document.getElementById('camera_image');
+                img.style.visibility = "visible";
+                img.style.display = "block";
+                //img.src = "data:image/jpeg;base64," + data;
+                img.src = data;
+                document.getElementById('camera_status').innerHTML = "Success";
+            },
+            function(e) {
+                console.log("Error getting picture: " + e);
+                document.getElementById('camera_status').innerHTML = "Error getting picture.";
+            },
+            { quality: 50, destinationType:
+            Camera.DestinationType.FILE_URI, sourceType: Camera.PictureSourceType.PHOTOLIBRARY});
+    };
+
+    
+    /**
+     * Function called when page has finished loading.
+     */
+    function init() {
+        document.addEventListener("deviceready", function() {
+                deviceReady = true;
+                console.log("Device="+device.platform+" "+device.version);
+            }, false);
+        window.setTimeout(function() {
+        	if (!deviceReady) {
+        		alert("Error: PhoneGap did not initialize.  Demo will not run correctly.");
+        	}
+        },1000);
+    }
+
+</script>
+
+  </head>
+  <body onload="init();" id="stage" class="theme">
+  
+    <h1>Camera</h1>
+    <div id="info">
+        <b>Status:</b> <span id="camera_status"></span><br>
+        <img style="width:120px;height:120px;visibility:hidden;display:none;" id="camera_image" src="" />
+    </div>
+    <h2>Action</h2>
+    <div class="btn large" onclick="getPicture();">Take Picture</div>
+    <div class="btn large" onclick="getImage();">Select Image from Library</div>
+    <h2> </h2><div class="backBtn" onclick="backHome();">Back</div>
+  </body>
+</html>      

http://git-wip-us.apache.org/repos/asf/incubator-cordova-wp7/blob/5bca3c1a/tests/MobileSpecUnitTests/www/compass/index.html
----------------------------------------------------------------------
diff --git a/tests/MobileSpecUnitTests/www/compass/index.html b/tests/MobileSpecUnitTests/www/compass/index.html
new file mode 100644
index 0000000..3bc4d9b
--- /dev/null
+++ b/tests/MobileSpecUnitTests/www/compass/index.html
@@ -0,0 +1,128 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
+    <title>Cordova Mobile Spec</title>
+    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
+    <script type="text/javascript" charset="utf-8" src="../phonegap.js"></script>      
+
+      
+<script type="text/javascript" charset="utf-8">
+
+    var deviceReady = false;
+
+    function roundNumber(num) {
+        var dec = 3;
+        var result = Math.round(num*Math.pow(10,dec))/Math.pow(10,dec);
+        return result;
+    }
+
+    //-------------------------------------------------------------------------
+    // Compass
+    //-------------------------------------------------------------------------
+    var watchCompassId = null;
+
+    /**
+     * Start watching compass
+     */
+    var watchCompass = function() {
+        console.log("watchCompass()");
+
+        // Success callback
+        var success = function(a){
+            document.getElementById('compassHeading').innerHTML = roundNumber(a.magneticHeading);
+        };
+
+        // Fail callback
+        var fail = function(e){
+            console.log("watchCompass fail callback with error code "+e);
+            stopCompass();
+            setCompassStatus(e);
+        };
+
+        // Update heading every 1 sec
+        var opt = {};
+        opt.frequency = 1000;
+        watchCompassId = navigator.compass.watchHeading(success, fail, opt);
+
+        setCompassStatus("Running");
+    };
+
+    /**
+     * Stop watching the acceleration
+     */
+    var stopCompass = function() {
+        setCompassStatus("Stopped");
+        if (watchCompassId) {
+            navigator.compass.clearWatch(watchCompassId);
+            watchCompassId = null;
+        }
+    };
+
+    /**
+     * Get current compass
+     */
+    var getCompass = function() {
+        console.log("getCompass()");
+
+        // Stop compass if running
+        stopCompass();
+
+        // Success callback
+        var success = function(a){
+            document.getElementById('compassHeading').innerHTML = roundNumber(a.magneticHeading);
+        };
+
+        // Fail callback
+        var fail = function(e){
+            console.log("getCompass fail callback with error code "+e);
+            setCompassStatus(e);
+        };
+
+        // Make call
+        var opt = {};
+        navigator.compass.getCurrentHeading(success, fail, opt);
+    };
+
+    /**
+     * Set compass status
+     */
+    var setCompassStatus = function(status) {
+        document.getElementById('compass_status').innerHTML = status;
+    };
+    
+    /**
+     * Function called when page has finished loading.
+     */
+    function init() {
+        document.addEventListener("deviceready", function() {
+                deviceReady = true;
+                console.log("Device="+device.platform+" "+device.version);
+            }, false);
+        window.setTimeout(function() {
+        	if (!deviceReady) {
+        		alert("Error: PhoneGap did not initialize.  Demo will not run correctly.");
+        	}
+        },1000);
+    }
+
+</script>
+
+  </head>
+  <body onload="init();" id="stage" class="theme">
+  
+    <h1>Compass</h1>
+    <div id="info">
+        <b>Status:</b> <span id="compass_status">Stopped</span>
+        <table width="100%"><tr>
+            <td width="33%">Heading: <span id="compassHeading"> </span></td>
+        </tr></table>
+    </div>
+    <h2>Action</h2>
+    <div class="btn large" onclick="getCompass();">Get Compass</div>
+    <div class="btn large" onclick="watchCompass();">Start Watching Compass</div>
+    <div class="btn large" onclick="stopCompass();">Stop Watching Compass</div>
+    <h2> </h2><div class="backBtn" onclick="backHome();">Back</div>
+  </body>
+</html>      

http://git-wip-us.apache.org/repos/asf/incubator-cordova-wp7/blob/5bca3c1a/tests/MobileSpecUnitTests/www/contacts/index.html
----------------------------------------------------------------------
diff --git a/tests/MobileSpecUnitTests/www/contacts/index.html b/tests/MobileSpecUnitTests/www/contacts/index.html
new file mode 100644
index 0000000..c646db1
--- /dev/null
+++ b/tests/MobileSpecUnitTests/www/contacts/index.html
@@ -0,0 +1,112 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
+    <title>Cordova Mobile Spec</title>
+    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
+    <script type="text/javascript" charset="utf-8" src="../phonegap.js"></script>      
+
+      
+<script type="text/javascript" charset="utf-8">
+
+    var deviceReady = false;
+
+    //-------------------------------------------------------------------------
+    // Contacts
+    //-------------------------------------------------------------------------
+    function getContacts() {
+        obj = new ContactFindOptions();
+        obj.filter = "D"; //Brooks";
+        obj.multiple = true;
+        navigator.contacts.find(
+            ["displayName", "name", "phoneNumbers", "emails", "urls", "note"],
+            function(contacts) {
+                var s = "";
+                if (contacts.length == 0) {
+                    s = "No contacts found";
+                }
+                else {
+                    s = "Number of contacts: "+contacts.length+"<br><table width='100%'><tr><th>Name</th><td>Phone</td><td>Email</td></tr>";
+                    for (var i=0; i<contacts.length; i++) {
+                        var contact = contacts[i];
+                        s = s + "<tr><td>" + contact.name.formatted + "</td><td>";
+                        if (contact.phoneNumbers && contact.phoneNumbers.length > 0) {
+                            s = s + contact.phoneNumbers[0].value;
+                        }
+                        s = s + "</td><td>"
+                        if (contact.emails && contact.emails.length > 0) {
+                            s = s + contact.emails[0].value;
+                        }
+                        s = s + "</td></tr>";
+                    }
+                    s = s + "</table>";
+                }
+                document.getElementById('contacts_results').innerHTML = s;
+            },
+            function(e) {
+                document.getElementById('contacts_results').innerHTML = "Error: "+e.code;
+            },
+            obj);
+    };
+
+    function addContact(){
+        console.log("addContact()");
+        try{
+            var contact = navigator.contacts.create({"displayName": "Dooney Evans"});
+            var contactName = {
+                formatted: "Dooney Evans",
+                familyName: "Evans",
+                givenName: "Dooney",
+                middleName: ""
+            };
+
+            contact.name = contactName;
+
+            var phoneNumbers = [1];
+            phoneNumbers[0] = new ContactField('work', '512-555-1234', true);
+            contact.phoneNumbers = phoneNumbers;
+
+            contact.save(
+                function() { alert("Contact saved.");},
+                function(e) { alert("Contact save failed: " + e.code); }
+            );
+            console.log("you have saved the contact");
+        }
+        catch (e){
+            alert(e);
+        }
+
+    };
+    
+    /**
+     * Function called when page has finished loading.
+     */
+    function init() {
+        document.addEventListener("deviceready", function() {
+                deviceReady = true;
+                console.log("Device="+device.platform+" "+device.version);
+            }, false);
+        window.setTimeout(function() {
+        	if (!deviceReady) {
+        		alert("Error: PhoneGap did not initialize.  Demo will not run correctly.");
+        	}
+        },1000);
+    }
+
+</script>
+
+  </head>
+  <body onload="init();" id="stage" class="theme">
+  
+    <h1>Contacts</h1>    
+    <div id="info">
+        <b>Results:</b><br>
+        <span id="contacts_results"> </span>
+    </div>
+    <h2>Action</h2>
+    <div class="btn large" onclick="getContacts();">Get phone's contacts</div>
+    <div class="btn large" onclick="addContact();">Add a new contact 'Dooney Evans'</div>
+    <h2> </h2><div class="backBtn" onclick="backHome();">Back</div>
+  </body>
+</html>      

http://git-wip-us.apache.org/repos/asf/incubator-cordova-wp7/blob/5bca3c1a/tests/MobileSpecUnitTests/www/events/index.html
----------------------------------------------------------------------
diff --git a/tests/MobileSpecUnitTests/www/events/index.html b/tests/MobileSpecUnitTests/www/events/index.html
new file mode 100644
index 0000000..6ce3ae6
--- /dev/null
+++ b/tests/MobileSpecUnitTests/www/events/index.html
@@ -0,0 +1,72 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
+    <title>Cordova Mobile Spec</title>
+    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
+    <script type="text/javascript" charset="utf-8" src="../phonegap.js"></script>      
+
+      
+<script type="text/javascript" charset="utf-8">
+
+    var deviceReady = false;
+
+    function interceptBackbutton() {
+    	eventOutput("Back button intercepted");
+    }
+    function interceptMenubutton() {
+    	eventOutput("Menu button intercepted");
+    }
+    function interceptSearchbutton() {
+    	eventOutput("Search button intercepted");
+    }
+    
+    var eventOutput = function(s) {
+        var el = document.getElementById("results");
+        el.innerHTML = el.innerHTML + s + "<br>";
+    };
+
+    
+    /**
+     * Function called when page has finished loading.
+     */
+    function init() {
+        document.addEventListener("deviceready", function() {
+                deviceReady = true;
+                console.log("Device="+device.platform+" "+device.version);
+                eventOutput("deviceready event: "+device.platform+" "+device.version);
+            }, false);
+        window.setTimeout(function() {
+        	if (!deviceReady) {
+        		alert("Error: PhoneGap did not initialize.  Demo will not run correctly.");
+        	}
+        },1000);
+        document.addEventListener("resume", function() {eventOutput("resume event");}, false);
+        document.addEventListener("pause", function() {eventOutput("pause event");}, false);
+        window.addEventListener("online", function() {eventOutput("online event");});  
+        window.addEventListener("offline", function() {eventOutput("offline event");});  
+
+    }
+
+</script>
+
+  </head>
+  <body onload="init();" id="stage" class="theme">
+  
+    <h1>Events</h1>
+    <div id="info">
+        <b>Results:</b><br>
+        <span id="results"></span>
+    </div>
+
+    <h2>Action</h2>
+    <div class="btn large" onclick="document.addEventListener('backbutton', interceptBackbutton, false);">Intercept backbutton</div>
+    <div class="btn large" onclick="document.removeEventListener('backbutton', interceptBackbutton, false);">Stop intercept of backbutton</div>
+    <div class="btn large" onclick="document.addEventListener('menubutton', interceptMenubutton, false);">Intercept menubutton</div>
+    <div class="btn large" onclick="document.removeEventListener('menubutton', interceptMenubutton, false);">Stop intercept of menubutton</div>
+    <div class="btn large" onclick="document.addEventListener('searchbutton', interceptSearchbutton, false);">Intercept searchbutton</div>
+    <div class="btn large" onclick="document.removeEventListener('searchbutton', interceptSearchbutton, false);">Stop intercept of searchbutton</div>
+    <h2> </h2><div class="backBtn" onclick="backHome();">Back</div>
+  </body>
+</html>      

http://git-wip-us.apache.org/repos/asf/incubator-cordova-wp7/blob/5bca3c1a/tests/MobileSpecUnitTests/www/index.html
----------------------------------------------------------------------
diff --git a/tests/MobileSpecUnitTests/www/index.html b/tests/MobileSpecUnitTests/www/index.html
index 22b4230..9bc5b52 100644
--- a/tests/MobileSpecUnitTests/www/index.html
+++ b/tests/MobileSpecUnitTests/www/index.html
@@ -1,73 +1,36 @@
-<!DOCTYPE html>
+<!DOCTYPE html>
 <html>
   <head>
-    <meta name="viewport" content="width=320; user-scalable=no" />
-    <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
-
-    <title>Cordova Tests</title>
-	  <link rel="stylesheet" href="master.css" type="text/css" media="screen" title="no title" charset="utf-8"/>
-
-      
-      <script type="text/javascript" charset="utf-8" src="cordova-1.6.0.js"></script>
-       
-      <script type="text/javascript">
-
-
-      function init()
-      {
-      document.addEventListener("deviceready",onDeviceReady,false);
-      document.addEventListener("backbutton",onBackButton,false);
-
-      }
-
-
-      function onBackButton()
-      {
-      console.log("onBackButton");
-      }
-
-      function onDeviceReady(e)
-      {
-      updateDeviceInfo();
-      console.log("deviceready event fired!");
-      }
-
-      function updateDeviceInfo()
-      {
-      document.getElementById("platform").innerHTML = device.platform;
-      document.getElementById("version").innerHTML = device.version;
-      document.getElementById("uuid").innerHTML = device.uuid;
-      document.getElementById("name").innerHTML = device.name;
-      document.getElementById("width").innerHTML = screen.width;
-      document.getElementById("height").innerHTML = screen.height;
-      document.getElementById("colorDepth").innerHTML = screen.colorDepth;
-      document.getElementById("cordovaVersion").innerHTML = device.cordova;
-
-      };
-
-
-
-
-
-  </script>
-
+    <meta name="viewport" content="width=device-width,height=device-height,user-scalable=no,initial-scale=1.0" />
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
+    <title>Cordova Mobile Spec</title>
+	  <link rel="stylesheet" href="master.css" type="text/css" media="screen" title="no title" charset="utf-8">
+	  <script type="text/javascript" charset="utf-8" src="phonegap.js"></script>
+	  <script type="text/javascript" charset="utf-8" src="main.js"></script>
 
   </head>
-  <body onLoad="init();" id="stage" class="theme">
+  <body onload="init();" id="stage" class="theme">
     <h1>PhoneGap Tests</h1>
     <div id="info">
-        <h4>Platform: <span id="platform"></span></h4>
-        <h4>Version: <span id="version"></span></h4>
-        <h4>UUID: <span id="uuid"></span></h4>
-        <h4>Name: <span id="name"></span></h4>
-        <h4>Width: <span id="width"></span>
-        ,   Height: <span id="height"></span>
-        , Color Depth: <span id="colorDepth"></span>
-        </h4>
-        <h4>CordovaVersion:<span id="cordovaVersion"></span></h4>
+        <h4>Platform: <span id="platform">  </span></h4>
+        <h4>Version: <span id="version"> </span></h4>
+        <h4>UUID: <span id="uuid">  </span></h4>
+        <h4>Name: <span id="name"> </span></h4>
+        <h4>Width: <span id="width">  </span>,   Height: <span id="height"> 
+                   </span>, Color Depth: <span id="colorDepth"></span></h4>
      </div>
-     
-     
     <a href="autotest/index.html" class="btn large">Automatic Test</a>
+    <a href="accelerometer/index.html" class="btn large">Accelerometer</a>
+    <a href="audio/index.html" class="btn large">Audio Play/Record</a>
+    <a href="battery/index.html" class="btn large">Battery</a>
+    <a href="camera/index.html" class="btn large">Camera</a>
+    <a href="compass/index.html" class="btn large">Compass</a>
+    <a href="contacts/index.html" class="btn large">Contacts</a>
+    <a href="events/index.html" class="btn large">Events</a>
+    <a href="location/index.html" class="btn large">Location</a>
+    <a href="misc/index.html" class="btn large">Misc Content</a>
+    <a href="notification/index.html" class="btn large">Notification</a>
+    <a href="sql/index.html" class="btn large">Web SQL</a>
+    <a href="storage/index.html" class="btn large">Local Storage</a>
   </body>
 </html>

http://git-wip-us.apache.org/repos/asf/incubator-cordova-wp7/blob/5bca3c1a/tests/MobileSpecUnitTests/www/location/index.html
----------------------------------------------------------------------
diff --git a/tests/MobileSpecUnitTests/www/location/index.html b/tests/MobileSpecUnitTests/www/location/index.html
new file mode 100644
index 0000000..438bfbb
--- /dev/null
+++ b/tests/MobileSpecUnitTests/www/location/index.html
@@ -0,0 +1,123 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
+    <title>Cordova Mobile Spec</title>
+    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
+    <script type="text/javascript" charset="utf-8" src="../phonegap.js"></script>      
+
+      
+<script type="text/javascript" charset="utf-8">
+
+    var deviceReady = false;
+
+    //-------------------------------------------------------------------------
+    // Location
+    //-------------------------------------------------------------------------
+    var watchLocationId = null;
+
+    /**
+     * Start watching location
+     */
+    var watchLocation = function() {
+        console.log("watchLocation()");
+
+        // Success callback
+        var success = function(p){
+            document.getElementById('latitude').innerHTML = p.coords.latitude;
+            document.getElementById('longitude').innerHTML = p.coords.longitude;
+        };
+
+        // Fail callback
+        var fail = function(e){
+            console.log("watchLocation fail callback with error code "+e);
+            stopLocation();
+        };
+
+        // Get location
+        watchLocationId = navigator.geolocation.watchPosition(success, fail, {enableHighAccuracy: true});
+        setLocationStatus("Running");
+    };
+
+    /**
+     * Stop watching the location
+     */
+    var stopLocation = function() {
+        setLocationStatus("Stopped");
+        if (watchLocationId) {
+            navigator.geolocation.clearWatch(watchLocationId);
+            watchLocationId = null;
+        }
+    };
+
+    /**
+     * Get current location
+     */
+    var getLocation = function() {
+        console.log("getLocation()");
+
+        // Stop location if running
+        stopLocation();
+
+        // Success callback
+        var success = function(p){
+            document.getElementById('latitude').innerHTML = p.coords.latitude;
+            document.getElementById('longitude').innerHTML = p.coords.longitude;
+            setLocationStatus("Done");
+        };
+
+        // Fail callback
+        var fail = function(e){
+            console.log("getLocation fail callback with error code "+e.code);
+            setLocationStatus("Error: "+e.code);
+        };
+
+        // Get location
+        navigator.geolocation.getCurrentPosition(success, fail, {enableHighAccuracy: true}); //, {timeout: 10000});
+        setLocationStatus("Retrieving location...");
+
+    };
+
+    /**
+     * Set location status
+     */
+    var setLocationStatus = function(status) {
+        document.getElementById('location_status').innerHTML = status;
+    };
+    
+    /**
+     * Function called when page has finished loading.
+     */
+    function init() {
+        document.addEventListener("deviceready", function() {
+                deviceReady = true;
+                console.log("Device="+device.platform+" "+device.version);
+            }, false);
+        window.setTimeout(function() {
+        	if (!deviceReady) {
+        		alert("Error: PhoneGap did not initialize.  Demo will not run correctly.");
+        	}
+        },1000);
+    }
+
+</script>
+
+  </head>
+  <body onload="init();" id="stage" class="theme">
+  
+    <h1>Location</h1>
+    <div id="info">
+        <b>Status:</b> <span id="location_status">Stopped</span>
+        <table width="100%">
+            <tr><td><b>Latitude:</b></td><td id="latitude"> </td></tr>
+            <tr><td><b>Longitude:</b></td><td id="longitude"> </td></tr>
+        </table>
+    </div>
+    <h2>Action</h2>
+    <div class="btn large" onclick="getLocation();">Get Location</div>
+    <div class="btn large" onclick="watchLocation();">Start Watching Location</div>
+    <div class="btn large" onclick="stopLocation();">Stop Watching Location</div>
+    <h2> </h2><div class="backBtn" onclick="backHome();">Back</div>    
+  </body>
+</html>      

http://git-wip-us.apache.org/repos/asf/incubator-cordova-wp7/blob/5bca3c1a/tests/MobileSpecUnitTests/www/main.js
----------------------------------------------------------------------
diff --git a/tests/MobileSpecUnitTests/www/main.js b/tests/MobileSpecUnitTests/www/main.js
new file mode 100644
index 0000000..ae447aa
--- /dev/null
+++ b/tests/MobileSpecUnitTests/www/main.js
@@ -0,0 +1,140 @@
+var deviceInfo = function() {
+    document.getElementById("platform").innerHTML = device.platform;
+    document.getElementById("version").innerHTML = device.version;
+    document.getElementById("uuid").innerHTML = device.uuid;
+    document.getElementById("name").innerHTML = device.name;
+    document.getElementById("width").innerHTML = screen.width;
+    document.getElementById("height").innerHTML = screen.height;
+    document.getElementById("colorDepth").innerHTML = screen.colorDepth;
+};
+
+var getLocation = function() {
+    var suc = function(p) {
+        alert(p.coords.latitude + " " + p.coords.longitude);
+    };
+    var locFail = function() {
+    };
+    navigator.geolocation.getCurrentPosition(suc, locFail);
+};
+
+var beep = function() {
+    navigator.notification.beep(2);
+};
+
+var vibrate = function() {
+    navigator.notification.vibrate(0);
+};
+
+function roundNumber(num) {
+    var dec = 3;
+    var result = Math.round(num * Math.pow(10, dec)) / Math.pow(10, dec);
+    return result;
+}
+
+var accelerationWatch = null;
+
+function updateAcceleration(a) {
+    document.getElementById('x').innerHTML = roundNumber(a.x);
+    document.getElementById('y').innerHTML = roundNumber(a.y);
+    document.getElementById('z').innerHTML = roundNumber(a.z);
+}
+
+var toggleAccel = function() {
+    if (accelerationWatch !== null) {
+        navigator.accelerometer.clearWatch(accelerationWatch);
+        updateAcceleration({
+            x : "",
+            y : "",
+            z : ""
+        });
+        accelerationWatch = null;
+    } else {
+        var options = {};
+        options.frequency = 1000;
+        accelerationWatch = navigator.accelerometer.watchAcceleration(
+                updateAcceleration, function(ex) {
+                    alert("accel fail (" + ex.name + ": " + ex.message + ")");
+                }, options);
+    }
+};
+
+var preventBehavior = function(e) {
+    e.preventDefault();
+};
+
+function dump_pic(data) {
+    var viewport = document.getElementById('viewport');
+    console.log(data);
+    viewport.style.display = "";
+    viewport.style.position = "absolute";
+    viewport.style.top = "10px";
+    viewport.style.left = "10px";
+    document.getElementById("test_img").src = "data:image/jpeg;base64," + data;
+}
+
+function fail(msg) {
+    alert(msg);
+}
+
+function show_pic() {
+    navigator.camera.getPicture(dump_pic, fail, {
+        quality : 50
+    });
+}
+
+function close() {
+    var viewport = document.getElementById('viewport');
+    viewport.style.position = "relative";
+    viewport.style.display = "none";
+}
+
+// This is just to do this.
+function readFile() {
+    navigator.file.read('/sdcard/phonegap.txt', fail, fail);
+}
+
+function writeFile() {
+    navigator.file.write('foo.txt', "This is a test of writing to a file",
+            fail, fail);
+}
+
+function contacts_success(contacts) {
+    alert(contacts.length
+            + ' contacts returned.'
+            + (contacts[2] && contacts[2].name ? (' Third contact is ' + contacts[2].name.formatted)
+                    : ''));
+}
+
+function get_contacts() {
+    var obj = new ContactFindOptions();
+    obj.filter = "";
+    obj.multiple = true;
+    obj.limit = 5;
+    navigator.service.contacts.find(
+            [ "displayName", "name" ], contacts_success,
+            fail, obj);
+}
+
+var networkReachableCallback = function(reachability) {
+    // There is no consistency on the format of reachability
+    var networkState = reachability.code || reachability;
+
+    var currentState = {};
+    currentState[NetworkStatus.NOT_REACHABLE] = 'No network connection';
+    currentState[NetworkStatus.REACHABLE_VIA_CARRIER_DATA_NETWORK] = 'Carrier data connection';
+    currentState[NetworkStatus.REACHABLE_VIA_WIFI_NETWORK] = 'WiFi connection';
+
+    confirm("Connection type:\n" + currentState[networkState]);
+};
+
+function check_network() {
+    navigator.network.isReachable("www.mobiledevelopersolutions.com",
+            networkReachableCallback, {});
+}
+
+function init() {
+    // the next line makes it impossible to see Contacts on the HTC Evo since it
+    // doesn't have a scroll button
+    // document.addEventListener("touchmove", preventBehavior, false);
+    document.addEventListener("deviceready", deviceInfo, true);
+}

http://git-wip-us.apache.org/repos/asf/incubator-cordova-wp7/blob/5bca3c1a/tests/MobileSpecUnitTests/www/master.css
----------------------------------------------------------------------
diff --git a/tests/MobileSpecUnitTests/www/master.css b/tests/MobileSpecUnitTests/www/master.css
index f3f3717..2d427f3 100644
--- a/tests/MobileSpecUnitTests/www/master.css
+++ b/tests/MobileSpecUnitTests/www/master.css
@@ -1,12 +1,11 @@
-  
   body {
-	background:#222 none repeat scroll 0 0;
-	color:#FFC312;
-	font-family:Helvetica, Verdana, Geneva, sans-serif;
-	font-size:72%;
-	line-height:1.5em;
-	margin:0;
-	border-top:1px solid #393939;
+    background:#222 none repeat scroll 0 0;
+    color:#666;
+    font-family:Helvetica;
+    font-size:72%;
+    line-height:1.5em;
+    margin:0;
+    border-top:1px solid #393939;
   }
 
   #info{
@@ -18,7 +17,6 @@
     margin:15px 6px 0;
     width:295px;
     padding:4px 0px 2px 10px;
-	color:#666;
   }
   
   #info > h4{
@@ -91,10 +89,12 @@
   	padding:1.2em 0;
   	margin:3px 0px 3px 5px;
   }
-  #stage.theme .btn.large{
+  
+  #stage.theme .large{
   	width:308px;
   	padding:1.2em 0;
   }
+  
   #stage.theme .backBtn{
    border: 1px solid #555;
    -webkit-border-radius: 5px;

http://git-wip-us.apache.org/repos/asf/incubator-cordova-wp7/blob/5bca3c1a/tests/MobileSpecUnitTests/www/misc/index.html
----------------------------------------------------------------------
diff --git a/tests/MobileSpecUnitTests/www/misc/index.html b/tests/MobileSpecUnitTests/www/misc/index.html
new file mode 100644
index 0000000..023678d
--- /dev/null
+++ b/tests/MobileSpecUnitTests/www/misc/index.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
+    <title>Cordova Mobile Spec</title>
+    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
+    <script type="text/javascript" charset="utf-8" src="../phonegap.js"></script>      
+
+      
+<script type="text/javascript" charset="utf-8">
+
+    var deviceReady = false;
+
+    function roundNumber(num) {
+        var dec = 3;
+        var result = Math.round(num*Math.pow(10,dec))/Math.pow(10,dec);
+        return result;
+    }
+    
+    /**
+     * Function called when page has finished loading.
+     */
+    function init() {
+        document.addEventListener("deviceready", function() {
+                deviceReady = true;
+                console.log("Device="+device.platform+" "+device.version);
+            }, false);
+        window.setTimeout(function() {
+        	if (!deviceReady) {
+        		alert("Error: PhoneGap did not initialize.  Demo will not run correctly.");
+        	}
+        },1000);
+    }
+
+</script>
+
+  </head>
+  <body onload="init();" id="stage" class="theme">
+  
+    <h1>Display Other Content</h1>
+    <div id="info">
+    </div>
+    <h2>Action</h2>
+    <div class="btn large" onclick="document.location='tel:5551212';" >Call 411</div>
+    <a href="mailto:bob@abc.org?subject=My Subject&body=This is the body.%0D%0ANew line." class="btn large">Send Mail</div>
+    <a href="sms:5125551234?body=The SMS message." class="btn large">Send SMS</div>
+    <a href="http://www.google.com" class="btn large">Load Web Site</div>
+    <!--  Need new URL -->
+    <!-- a href="http://handle.library.cornell.edu/control/authBasic/authTest/" class="btn large">Basic Auth: test/this</a -->
+    <a href="page2.html?me=test" class="btn large">Load another PhoneGap page</a>
+    <h2>Android Only</h2>
+    <a href="geo:0,0?q=11400 Burnet Rd, Austin, TX" class="btn large">Map IBM</a>
+    <a href="market://search?q=google" class="btn large">Search Android market</a>
+    <a href="content://media/external/images/media" class="btn large">View image app</a>
+
+    <h2> </h2><div class="backBtn" onclick="backHome();">Back</div>
+  </body>
+</html>      

http://git-wip-us.apache.org/repos/asf/incubator-cordova-wp7/blob/5bca3c1a/tests/MobileSpecUnitTests/www/misc/page2.html
----------------------------------------------------------------------
diff --git a/tests/MobileSpecUnitTests/www/misc/page2.html b/tests/MobileSpecUnitTests/www/misc/page2.html
new file mode 100644
index 0000000..ee6c398
--- /dev/null
+++ b/tests/MobileSpecUnitTests/www/misc/page2.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
+    <title>Cordova Mobile Spec</title>
+      <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
+      <script type="text/javascript" charset="utf-8" src="../phonegap.js"></script>
+      <script type="text/javascript" charset="utf-8" src="../main.js"></script>
+
+  </head>
+  <body onload="init();" id="stage" class="theme">
+    <h1>Page2 App</h1>
+    <h2>This is page 2 of a PhoneGap app</h2>
+    <div id="info">
+        <h4>Platform: <span id="platform">  </span></h4>
+        <h4>Version: <span id="version"> </span></h4>
+        <h4>UUID: <span id="uuid">  </span></h4>
+        <h4>Name: <span id="name"> </span></h4>
+        <h4>Width: <span id="width">  </span>,   Height: <span id="height"> 
+                   </span>, Color Depth: <span id="colorDepth"></span></h4>
+     </div>
+      <div ><button onclick="history.back();">Back</button></div>
+  </body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-cordova-wp7/blob/5bca3c1a/tests/MobileSpecUnitTests/www/notification/index.html
----------------------------------------------------------------------
diff --git a/tests/MobileSpecUnitTests/www/notification/index.html b/tests/MobileSpecUnitTests/www/notification/index.html
new file mode 100644
index 0000000..ac8be10
--- /dev/null
+++ b/tests/MobileSpecUnitTests/www/notification/index.html
@@ -0,0 +1,81 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
+    <title>Cordova Mobile Spec</title>
+    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
+    <script type="text/javascript" charset="utf-8" src="../phonegap.js"></script>      
+
+      
+<script type="text/javascript" charset="utf-8">
+
+    var deviceReady = false;
+
+    //-------------------------------------------------------------------------
+    // Notifications
+    //-------------------------------------------------------------------------
+
+    var beep = function(){
+        navigator.notification.beep(3);
+    };
+
+    var vibrate = function(){
+      navigator.notification.vibrate(0);
+    };
+
+    var alertDialog = function(message, title, button) {
+        console.log("alertDialog()");
+        navigator.notification.alert(message,
+            function(){
+                console.log("Alert dismissed.");
+            },
+            title, button);
+        console.log("After alert");
+    };
+
+    var confirmDialog = function(message, title, buttons) {
+        navigator.notification.confirm(message,
+            function(r) {
+                console.log("You selected " + r);
+                alert("You selected " + (buttons.split(","))[r-1]);
+            },
+            title,
+            buttons);
+    };
+    
+    /**
+     * Function called when page has finished loading.
+     */
+    function init() {
+        document.addEventListener("deviceready", function() {
+                deviceReady = true;
+                console.log("Device="+device.platform+" "+device.version);
+            }, false);
+        window.setTimeout(function() {
+        	if (!deviceReady) {
+        		alert("Error: PhoneGap did not initialize.  Demo will not run correctly.");
+        	}
+        },1000);
+    }
+
+</script>
+
+  </head>
+  <body onload="init();" id="stage" class="theme">
+  
+    <h1>Notifications and Dialogs</h1>
+    <div id="info">
+    </div>
+    
+    <h2>Action</h2>
+    <div class="btn large" onclick="beep();">Beep</div>
+    <div class="btn large" onclick="vibrate();">Vibrate</div>
+    <div class="btn large" onclick="alertDialog('You pressed alert.', 'Alert Dialog', 'Continue');">Alert Dialog</div>
+    <div class="btn large" onclick="confirmDialog('You pressed confirm.', 'Confirm Dialog', 'Yes,No,Maybe');">Confirm Dialog</div>
+    <div class="btn large" onclick="alert('You pressed alert.');">Built-in Alert Dialog</div>
+    <div class="btn large" onclick="confirm('You selected confirm');">Built-in Confirm Dialog</div>
+    <div class="btn large" onclick="prompt('This is a prompt.', 'Default value');">Built-in Prompt Dialog</div>
+    <h2> </h2><div class="backBtn" onclick="backHome();">Back</div>
+  </body>
+</html>      

http://git-wip-us.apache.org/repos/asf/incubator-cordova-wp7/blob/5bca3c1a/tests/MobileSpecUnitTests/www/phonegap.js
----------------------------------------------------------------------
diff --git a/tests/MobileSpecUnitTests/www/phonegap.js b/tests/MobileSpecUnitTests/www/phonegap.js
new file mode 100644
index 0000000..044a06b
--- /dev/null
+++ b/tests/MobileSpecUnitTests/www/phonegap.js
@@ -0,0 +1,13 @@
+document.write('<script type="text/javascript" charset="utf-8" src="../../cordova.wp7.js"></script>');
+document.write('<script type="text/javascript" charset="utf-8" src="../cordova.wp7.js"></script>');
+document.write('<script type="text/javascript" charset="utf-8" src="cordova.wp7.js"></script>');
+
+function backHome() {
+	
+	if (window.device && device.platform && device.platform.toLowerCase() == 'android') {
+            navigator.app.backHistory();
+	}
+	else {
+	    window.history.go(-1);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-cordova-wp7/blob/5bca3c1a/tests/MobileSpecUnitTests/www/sql/index.html
----------------------------------------------------------------------
diff --git a/tests/MobileSpecUnitTests/www/sql/index.html b/tests/MobileSpecUnitTests/www/sql/index.html
new file mode 100644
index 0000000..cae19ce
--- /dev/null
+++ b/tests/MobileSpecUnitTests/www/sql/index.html
@@ -0,0 +1,132 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
+    <title>Cordova Mobile Spec</title>
+    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
+    <script type="text/javascript" charset="utf-8" src="../phonegap.js"></script>      
+
+      
+<script type="text/javascript" charset="utf-8">
+
+    var deviceReady = false;
+
+    //-------------------------------------------------------------------------
+    // HTML5 Database
+    //-------------------------------------------------------------------------
+    var db;
+    var callDatabase = function() {
+        db = openDatabase("mydb", "1.0", "PhoneGap Demo", 20000);
+        if (db === null) {
+            databaseOutput("Database could not be opened.");
+            return;
+        }
+        databaseOutput("Database opened.");
+        db.transaction(function (tx) {
+            tx.executeSql('DROP TABLE IF EXISTS DEMO');
+            tx.executeSql('CREATE TABLE IF NOT EXISTS DEMO (id unique, data)', [],
+                 function(tx,results) { console.log("Created table"); },
+                 function(tx,err) { alert("Error creating table: "+err.message); });
+            tx.executeSql('INSERT INTO DEMO (id, data) VALUES (1, "First row")', [],
+                 function(tx,results) { console.log("Insert row1 success"); },
+                 function(tx,err) { alert("Error adding 1st row: "+err.message); });
+            tx.executeSql('INSERT INTO DEMO (id, data) VALUES (2, "Second row")', [],
+                 function(tx,results) { console.log("Insert row2 success"); },
+                 function(tx,err) { alert("Error adding 2nd row: "+err.message); });
+            databaseOutput("Data written to DEMO table.");
+            console.log("Data written to DEMO table.");
+
+            tx.executeSql('SELECT * FROM DEMO', [], function (tx, results) {
+                var len = results.rows.length;
+                var text = "DEMO table: " + len + " rows found.<br>";
+                text = text + "<table border='1'><tr><td>Row</td><td>Data</td></tr>";
+                for (var i=0; i<len; i++){
+                    text = text + "<tr><td>" + i + "</td><td>" + results.rows.item(i).id + ", " + results.rows.item(i).data + "</td></tr>";
+                }
+                text = text + "</table>";
+                databaseOutput(text);
+            }, function(tx, err) {
+                alert("Error processing SELECT * SQL: "+err.message);
+            });
+            tx.executeSql('SELECT ID FROM DEMO', [], function (tx, results) {
+                var len = results.rows.length;
+                var text = "DEMO table: " + len + " rows found.<br>";
+                text = text + "<table border='1'><tr><td>Row</td><td>Data</td></tr>";
+                for (var i=0; i<len; i++){
+                    text = text + "<tr><td>" + i + "</td><td>" + results.rows.item(i).id + "</td></tr>";
+                }
+                text = text + "</table>";
+                databaseOutput(text);
+            }, function(tx, err) {
+                alert("Error processing SELECT ID SQL: "+err.message);
+            });
+            
+        },
+        function(err) {
+            console.log("Transaction failed: " + err.message);
+        });
+
+
+    };
+
+    var readDatabase = function() {
+    	if (!db) {
+    	    db = openDatabase("mydb", "1.0", "PhoneGap Demo", 20000);
+    	    if (db === null) {
+                databaseOutput("Database could not be opened.");
+                return;
+    	    }
+        }
+        db.transaction(function (tx) {
+            tx.executeSql('SELECT * FROM DEMO WHERE id=2', [], function (tx, results) {
+                var len = results.rows.length;
+                var text = "DEMO table: " + len + " rows found.<br>";
+                text = text + "<table border='1'><tr><td>Row</td><td>Data</td></tr>";
+                for (var i=0; i<len; i++){
+                    text = text + "<tr><td>" + i + "</td><td>" + results.rows.item(i).id + ", " + results.rows.item(i).data + "</td></tr>";
+                }
+                text = text + "</table>";
+                databaseOutput(text);
+            }, function(tx, err) {
+                alert("Error processing SELECT * WHERE id=2 SQL: "+err.message);
+            });
+        });
+    }
+
+    var databaseOutput = function(s) {
+        var el = document.getElementById("database_results");
+        el.innerHTML = el.innerHTML + s + "<br>";
+    };
+    
+    /**
+     * Function called when page has finished loading.
+     */
+    function init() {
+        document.addEventListener("deviceready", function() {
+                deviceReady = true;
+                console.log("Device="+device.platform+" "+device.version);
+            }, false);
+        window.setTimeout(function() {
+        	if (!deviceReady) {
+        		alert("Error: PhoneGap did not initialize.  Demo will not run correctly.");
+        	}
+        },1000);
+    }
+
+</script>
+
+  </head>
+  <body onload="init();" id="stage" class="theme">
+  
+    <h1>HTML5 Database</h1>   
+    <div id="info">
+        <b>Results:</b><br>
+        <span id="database_results"></span>
+    </div>
+    <h2>Action</h2>
+    <div class="btn large" onclick="callDatabase();">Create, Add, Read Database</div>
+    <div class="btn large" onclick="readDatabase();">Read Database</div>
+    <h2> </h2><div class="backBtn" onclick="backHome();">Back</div>    
+  </body>
+</html>      

http://git-wip-us.apache.org/repos/asf/incubator-cordova-wp7/blob/5bca3c1a/tests/MobileSpecUnitTests/www/storage/index.html
----------------------------------------------------------------------
diff --git a/tests/MobileSpecUnitTests/www/storage/index.html b/tests/MobileSpecUnitTests/www/storage/index.html
new file mode 100644
index 0000000..d638a29
--- /dev/null
+++ b/tests/MobileSpecUnitTests/www/storage/index.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
+    <title>Cordova Mobile Spec</title>
+    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
+    <script type="text/javascript" charset="utf-8" src="../phonegap.js"></script>      
+
+      
+<script type="text/javascript" charset="utf-8">
+
+    var deviceReady = false;
+    
+    /**
+     * Function called when page has finished loading.
+     */
+    function init() {
+        document.addEventListener("deviceready", function() {
+                deviceReady = true;
+                console.log("Device="+device.platform+" "+device.version);
+            }, false);
+        window.setTimeout(function() {
+        	if (!deviceReady) {
+        		alert("Error: PhoneGap did not initialize.  Demo will not run correctly.");
+        	}
+        },1000);
+    }
+
+</script>
+
+  </head>
+  <body onload="init();" id="stage" class="theme">
+  
+    <h1>Local Storage</h1>
+    <div id="info">
+        You have run this app <span id="count">an untold number of</span> time(s).
+    </div>
+
+    <script>
+    if (!localStorage.pageLoadCount) {
+        localStorage.pageLoadCount = 0;
+    }
+    localStorage.pageLoadCount = parseInt(localStorage.pageLoadCount) + 1;
+    document.getElementById('count').textContent = localStorage.pageLoadCount;
+    </script>
+
+    <h2> </h2><div class="backBtn" onclick="backHome();">Back</div>
+  </body>
+</html>