You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by bo...@apache.org on 2012/03/23 23:01:17 UTC

[12/17] Adding the tests from the GitHub Prototype

http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/blob/ae8bc77e/test/assets/www/autotest/tests/geolocation.tests.js
----------------------------------------------------------------------
diff --git a/test/assets/www/autotest/tests/geolocation.tests.js b/test/assets/www/autotest/tests/geolocation.tests.js
new file mode 100644
index 0000000..17f37ce
--- /dev/null
+++ b/test/assets/www/autotest/tests/geolocation.tests.js
@@ -0,0 +1,57 @@
+Tests.prototype.GeoLocationTests = function() {	
+	module('Geolocation (navigator.geolocation)');
+	test("should exist", function() {
+  		expect(1);
+  		ok(navigator.geolocation != null, "navigator.geolocation should not be null.");
+	});
+	test("should contain a getCurrentPosition function", function() {
+		expect(2);
+		ok(typeof navigator.geolocation.getCurrentPosition != 'undefined' && navigator.geolocation.getCurrentPosition != null, "navigator.geolocation.getCurrentPosition should not be null.");
+		ok(typeof navigator.geolocation.getCurrentPosition == 'function', "navigator.geolocation.getCurrentPosition should be a function.");
+	});
+	test("should contain a watchPosition function", function() {
+		expect(2);
+		ok(typeof navigator.geolocation.watchPosition != 'undefined' && navigator.geolocation.watchPosition != null, "navigator.geolocation.watchPosition should not be null.");
+		ok(typeof navigator.geolocation.watchPosition == 'function', "navigator.geolocation.watchPosition should be a function.");
+	});
+	test("should contain a clearWatch function", function() {
+		expect(2);
+		ok(typeof navigator.geolocation.clearWatch != 'undefined' && navigator.geolocation.clearWatch != null, "navigator.geolocation.watchPosition should not be null.");
+		ok(typeof navigator.geolocation.clearWatch == 'function', "navigator.geolocation.clearWatch should be a function.");
+	});
+	test("getCurrentPosition success callback should be called with a Position object", function() {
+		expect(2);
+		QUnit.stop(Tests.TEST_TIMEOUT);
+		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();
+		};
+		var fail = function() { start(); };
+		navigator.geolocation.getCurrentPosition(win, fail);
+	});
+	// 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

http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/blob/ae8bc77e/test/assets/www/autotest/tests/media.tests.js
----------------------------------------------------------------------
diff --git a/test/assets/www/autotest/tests/media.tests.js b/test/assets/www/autotest/tests/media.tests.js
new file mode 100644
index 0000000..43f9b1c
--- /dev/null
+++ b/test/assets/www/autotest/tests/media.tests.js
@@ -0,0 +1,31 @@
+//
+// @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)');
+	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(5);
+		ok(MediaError != null && typeof MediaError != 'undefined', "MediaError object exists in global scope.");
+		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_SRC_NOT_SUPPORTED, 4, "MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED is equal to 4.");
+	});
+	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.");
+	});
+};
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/blob/ae8bc77e/test/assets/www/autotest/tests/network.tests.js
----------------------------------------------------------------------
diff --git a/test/assets/www/autotest/tests/network.tests.js b/test/assets/www/autotest/tests/network.tests.js
new file mode 100644
index 0000000..af87d73
--- /dev/null
+++ b/test/assets/www/autotest/tests/network.tests.js
@@ -0,0 +1,26 @@
+Tests.prototype.NetworkTests = function() {
+	module('Network (navigator.network)');
+	test("should exist", function() {
+  		expect(1);
+  		ok(navigator.network != null, "navigator.network should not be null.");
+	});
+    module('Network Information API');
+    test("connection should exist", function() {
+        expect(1);
+        ok(navigator.network.connection != null, "navigator.network.connection should not be null.");
+    });
+    test("should contain connection properties", function() {
+        expect(1);
+        ok(typeof navigator.network.connection.type != 'undefined', "navigator.network.connection.type is defined.");
+    });
+    test("should define constants for connection status", function() {
+        expect(7);
+        equals(Connection.UNKNOWN, "unknown", "Connection.UNKNOWN is equal to 'unknown'.");
+        equals(Connection.ETHERNET, "ethernet", "Connection.ETHERNET is equal to 'ethernet'.");
+        equals(Connection.WIFI, "wifi", "Connection.WIFI is equal to 'wifi'.");
+        equals(Connection.CELL_2G, "2g", "Connection.CELL_2G is equal to '2g'.");
+        equals(Connection.CELL_3G, "3g", "Connection.CELL_3G is equal to '3g'.");
+        equals(Connection.CELL_4G, "4g", "Connection.CELL_4G is equal to '4g'.");
+        equals(Connection.NONE, "none", "Connection.NONE is equal to 'none'.");
+    });
+};
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/blob/ae8bc77e/test/assets/www/autotest/tests/notification.tests.js
----------------------------------------------------------------------
diff --git a/test/assets/www/autotest/tests/notification.tests.js b/test/assets/www/autotest/tests/notification.tests.js
new file mode 100644
index 0000000..03e3885
--- /dev/null
+++ b/test/assets/www/autotest/tests/notification.tests.js
@@ -0,0 +1,22 @@
+Tests.prototype.NotificationTests = function() {	
+	module('Notification (navigator.notification)');
+	test("should exist", function() {
+  		expect(1);
+  		ok(navigator.notification != null, "navigator.notification should not be null.");
+	});
+	test("should contain a vibrate function", function() {
+		expect(2);
+		ok(typeof navigator.notification.vibrate != 'undefined' && navigator.notification.vibrate != null, "navigator.notification.vibrate should not be null.");
+		ok(typeof navigator.notification.vibrate == 'function', "navigator.notification.vibrate should be a function.");
+	});
+	test("should contain a beep function", function() {
+		expect(2);
+		ok(typeof navigator.notification.beep != 'undefined' && navigator.notification.beep != null, "navigator.notification.beep should not be null.");
+		ok(typeof navigator.notification.beep == 'function', "navigator.notification.beep should be a function.");
+	});
+	test("should contain a alert function", function() {
+		expect(2);
+		ok(typeof navigator.notification.alert != 'undefined' && navigator.notification.alert != null, "navigator.notification.alert should not be null.");
+		ok(typeof navigator.notification.alert == 'function', "navigator.notification.alert should be a function.");
+	});
+};
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/blob/ae8bc77e/test/assets/www/autotest/tests/orientation.tests.js
----------------------------------------------------------------------
diff --git a/test/assets/www/autotest/tests/orientation.tests.js b/test/assets/www/autotest/tests/orientation.tests.js
new file mode 100644
index 0000000..5dcfcf1
--- /dev/null
+++ b/test/assets/www/autotest/tests/orientation.tests.js
@@ -0,0 +1,34 @@
+Tests.prototype.OrientationTests = function() {	
+	module('Orientation (navigator.orientation)');
+	test("should exist", function() {
+  		expect(1);
+  		ok(navigator.orientation != null, "navigator.orientation should not be null.");
+	});
+	test("should have an initially null lastPosition property", function() {
+  		expect(1);
+  		ok(typeof navigator.orientation.currentOrientation != 'undefined' && navigator.orientation.currentOrientation == null, "navigator.orientation.currentOrientation should be initially null.");
+	});
+	test("should contain a getCurrentOrientation function", function() {
+		expect(2);
+		ok(typeof navigator.orientation.getCurrentOrientation != 'undefined' && navigator.orientation.getCurrentOrientation != null, "navigator.orientation.getCurrentOrientation should not be null.");
+		ok(typeof navigator.orientation.getCurrentOrientation == 'function', "navigator.orientation.getCurrentOrientation should be a function.");
+	});
+	test("should contain a watchOrientation function", function() {
+		expect(2);
+		ok(typeof navigator.orientation.watchOrientation != 'undefined' && navigator.orientation.watchOrientation != null, "navigator.orientation.watchOrientation should not be null.");
+		ok(typeof navigator.orientation.watchOrientation == 'function', "navigator.orientation.watchOrientation should be a function.");
+	});
+	// TODO: add tests for DisplayOrientation constants?
+	test("getCurrentOrientation success callback should be called with an Orientation enumeration", function() {
+		expect(2);
+		QUnit.stop(Tests.TEST_TIMEOUT);
+		var win = function(orient) {
+			ok(0 <= orient <= 6, "Position object returned in getCurrentPosition success callback is a valid DisplayOrientation value.");
+			equals(orient, navigator.orientation.currentOrientation, "Orientation value returned in getCurrentOrientation success callback equals navigator.orientation.currentOrientation.");
+			start();
+		};
+		var fail = function() { start(); };
+		navigator.orientation.getCurrentOrientation(win, fail);
+	});
+	// TODO: Need to test watchPosition success callback, test that makes sure clearPosition works (how to test that a timer is getting cleared?)
+};
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/blob/ae8bc77e/test/assets/www/autotest/tests/storage.tests.js
----------------------------------------------------------------------
diff --git a/test/assets/www/autotest/tests/storage.tests.js b/test/assets/www/autotest/tests/storage.tests.js
new file mode 100644
index 0000000..41476d8
--- /dev/null
+++ b/test/assets/www/autotest/tests/storage.tests.js
@@ -0,0 +1,170 @@
+Tests.prototype.StorageTests = function() 
+{
+  module("Session Storage");
+  test("should exist", function() {
+	expect(7);
+	ok(window.sessionStorage != null, "sessionStorage is defined");
+    ok(typeof window.sessionStorage.length != 'undefined', "sessionStorage.length is defined");
+    ok(typeof(window.sessionStorage.key) == "function", "sessionStorage.key is defined");
+    ok(typeof(window.sessionStorage.getItem) == "function", "sessionStorage.getItem is defined");
+    ok(typeof(window.sessionStorage.setItem) == "function", "sessionStorage.setItem is defined");
+    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");
+    window.sessionStorage.setItem("key","value");
+    ok(window.sessionStorage.length == 1, "length should be 1");
+    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");
+	window.sessionStorage.setItem("test","value");
+	ok(window.sessionStorage.key(0) == "test", "key should be 'test'");
+	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");
+    window.sessionStorage.setItem("item","value");
+    ok(window.sessionStorage.getItem("item") == "value", "The value of the item should be 'value'");
+    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");
+    window.sessionStorage.setItem("item","value");
+    ok(window.sessionStorage.getItem("item") == "value", "The value of the item should be 'value'");
+    window.sessionStorage.setItem("item","newval");
+    ok(window.sessionStorage.getItem("item") == "newval", "The value of the item should be 'newval'");
+    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");
+    window.sessionStorage.setItem("item","value");
+    ok(window.sessionStorage.getItem("item") == "value", "The value of the item should be 'value'");
+    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");
+    ok(window.sessionStorage.getItem("item2") == null, "item2 should be null");
+    ok(window.sessionStorage.getItem("item3") == null, "item3 should be null");
+    window.sessionStorage.setItem("item1","value");
+    window.sessionStorage.setItem("item2","value");
+    window.sessionStorage.setItem("item3","value");
+    ok(window.sessionStorage.getItem("item1") == "value", "item1 should be null");
+    ok(window.sessionStorage.getItem("item2") == "value", "item2 should be null");
+    ok(window.sessionStorage.getItem("item3") == "value", "item3 should be null");	    
+    ok(window.sessionStorage.length == 3, "length should be 3");
+    window.sessionStorage.clear();
+    ok(window.sessionStorage.length == 0, "length should be 0");
+    ok(window.sessionStorage.getItem("item1") == null, "item1 should be null");
+    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");
+    window.sessionStorage.item = "value";
+    ok(window.sessionStorage.item == "value", "The value of the item should be 'value'");
+    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");
+    ok(typeof window.localStorage.length != 'undefined', "localStorage.length is defined");
+    ok(typeof(window.localStorage.key) == "function", "localStorage.key is defined");
+    ok(typeof(window.localStorage.getItem) == "function", "localStorage.getItem is defined");
+    ok(typeof(window.localStorage.setItem) == "function", "localStorage.setItem is defined");
+    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");
+    window.localStorage.setItem("key","value");
+    ok(window.localStorage.length == 1, "length should be 1");
+    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");
+    window.localStorage.setItem("test","value");
+    ok(window.localStorage.key(0) == "test", "key should be 'test'");
+    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");
+    window.localStorage.setItem("item","value");
+    ok(window.localStorage.getItem("item") == "value", "The value of the item should be 'value'");
+    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");
+    window.localStorage.setItem("item","value");
+    ok(window.localStorage.getItem("item") == "value", "The value of the item should be 'value'");
+    window.localStorage.setItem("item","newval");
+    ok(window.localStorage.getItem("item") == "newval", "The value of the item should be 'newval'");
+    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");
+    window.localStorage.setItem("item","value");
+    ok(window.localStorage.getItem("item") == "value", "The value of the item should be 'value'");
+    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");
+    ok(window.localStorage.getItem("item2") == null, "item2 should be null");
+    ok(window.localStorage.getItem("item3") == null, "item3 should be null");
+    window.localStorage.setItem("item1","value");
+    window.localStorage.setItem("item2","value");
+    window.localStorage.setItem("item3","value");
+    ok(window.localStorage.getItem("item1") == "value", "item1 should be null");
+    ok(window.localStorage.getItem("item2") == "value", "item2 should be null");
+    ok(window.localStorage.getItem("item3") == "value", "item3 should be null");	    
+    ok(window.localStorage.length == 3, "length should be 3");
+    window.localStorage.clear();
+    ok(window.localStorage.length == 0, "length should be 0");
+    ok(window.localStorage.getItem("item1") == null, "item1 should be null");
+    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");
+    window.localStorage.item = "value";
+    ok(window.localStorage.item == "value", "The value of the item should be 'value'");
+    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");
+  });
+  test("Should open a database", 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-android/blob/ae8bc77e/test/assets/www/autotest/tests/system.tests.js
----------------------------------------------------------------------
diff --git a/test/assets/www/autotest/tests/system.tests.js b/test/assets/www/autotest/tests/system.tests.js
new file mode 100644
index 0000000..c76fdb5
--- /dev/null
+++ b/test/assets/www/autotest/tests/system.tests.js
@@ -0,0 +1,261 @@
+Tests.prototype.SystemTests = function() {
+	module('System Information (navigator.system)');
+	test("should exist", function() {
+  		expect(1);
+  		ok(navigator.system != null, "navigator.system should not be null.");
+	});
+	test("should contain a get function", function() {
+		expect(2);
+		ok(typeof navigator.system.get != 'undefined' && navigator.system.get != null, "navigator.system.get should not be null.");
+		ok(typeof navigator.system.get == 'function', "navigator.system.get should be a function.");
+	});
+	test("should contain a has function", function() {
+		expect(2);
+		ok(typeof navigator.system.has != 'undefined' && navigator.system.has != null, "navigator.system.has should not be null.");
+		ok(typeof navigator.system.has == 'function', "navigator.system.has should be a function.");
+	});
+	test("should contain a monitor function", function() {
+		expect(2);
+		ok(typeof navigator.system.monitor != 'undefined' && navigator.system.monitor != null, "navigator.system.monitor should not be null.");
+		ok(typeof navigator.system.monitor == 'function', "navigator.system.monitor should be a function.");
+	});
+	module('System Information Options');
+	test("should be able to define a SystemInfoOptions object", function() {
+		expect(6);
+		var systemInfoOptions = new SystemInfoOptions(0.0, 0.0, "a", 0, "b");
+		ok(systemInfoOptions != null, "new SystemInfoOptions() should not be null.");
+		ok(typeof systemInfoOptions.highThreshold != 'undefined' && systemInfoOptions.highThreshold != null && systemInfoOptions.highThreshold == 0.0, "new SystemInfoOptions() should include a 'highThreshold' property.");
+		ok(typeof systemInfoOptions.lowThreshold != 'undefined' && systemInfoOptions.lowThreshold != null && systemInfoOptions.lowThreshold == 0.0, "new SystemInfoOptions() should include a 'lowThreshold' property.");
+		ok(typeof systemInfoOptions.thresholdTarget != 'undefined' && systemInfoOptions.thresholdTarget != null && systemInfoOptions.thresholdTarget == "a", "new SystemInfoOptions() should include a 'thresholdTarget' property.");
+		ok(typeof systemInfoOptions.timeout != 'undefined' && systemInfoOptions.timeout != null && systemInfoOptions.timeout == 0, "new SystemInfoOptions() should include a 'timeout' property.");
+		ok(typeof systemInfoOptions.id != 'undefined' && systemInfoOptions.id != null && systemInfoOptions.id == "b", "new SystemInfoOptions() should include a 'id' property.");
+	});	
+	module('Power Property');
+	test("should be able to define a Power Property object", function() {
+		expect(7);
+		var power = new PowerAttributes("a","b",0.0,0,true,false);
+		ok(power != null, "new PowerAttributes() should not be null.");
+		ok(typeof power.info != 'undefined' && power.info != null && power.info == "a", "new PowerAttributes() should include a 'info' property.");
+		ok(typeof power.id != 'undefined' && power.id != null && power.id == "b", "new PowerAttributes() should include a 'id' property.");
+		ok(typeof power.level != 'undefined' && power.level != null && power.level == 0.0, "new PowerAttributes() should include a 'level' property.");
+		ok(typeof power.timeRemaining != 'undefined' && power.timeRemaining != null && power.timeRemaining == 0, "new PowerAttributes() should include a 'timeRemaining' property.");
+		ok(typeof power.isBattery != 'undefined' && power.isBattery != null && power.isBattery == true, "new PowerAttributes() should include a 'isBattery' property.");
+		ok(typeof power.isCharging != 'undefined' && power.isCharging != null && power.isCharging == false, "new PowerAttributes() should include a 'isCharging' property.");
+	});	
+	module('CPU Property');
+	test("should be able to define a CPU Property object", function() {
+		expect(4);
+		var cpu = new CPUAttributes("a", "b", 0.0);
+		ok(cpu  != null, "new CPUAttributes() should not be null.");
+		ok(typeof cpu.info != 'undefined' && cpu.info != null && cpu.info == "a", "new CPUAttributes() should include a 'info' property.");
+		ok(typeof cpu.id != 'undefined' && cpu.id != null && cpu.id == "b", "new CPUAttributes() should include a 'id' property.");
+		ok(typeof cpu.usage != 'undefined' && cpu.usage != null && cpu.usage == 0.0, "new CPUAttributes() should include a 'usage' property.");
+	});	
+	module('Thermal Property');
+	test("should be able to define a Thermal Property object", function() {
+		expect(4);
+		var thermal = new ThermalAttributes("a", "b", 0.0);
+		ok(thermal  != null, "new ThermalAttributes() should not be null.");
+		ok(typeof thermal.info != 'undefined' && thermal.info != null && thermal.info == "a", "new ThermalAttributes() should include a 'info' property.");
+		ok(typeof thermal.id != 'undefined' && thermal.id != null && thermal.id == "b", "new ThermalAttributes() should include a 'id' property.");
+		ok(typeof thermal.state != 'undefined' && thermal.state != null && thermal.state == 0.0, "new ThermalAttributes() should include a 'state' property.");
+	});	
+	module('Network Property');
+	test("should be able to define a Network Property object", function() {
+		expect(4);
+		var network = new NetworkAttributes("a", "b", []);
+		ok(network  != null, "new NetworkAttributes() should not be null.");
+		ok(typeof network.info != 'undefined' && network.info != null && network.info == "a", "new NetworkAttributes() should include a 'info' property.");
+		ok(typeof network.id != 'undefined' && network.id != null && network.id == "b", "new NetworkAttributes() should include a 'id' property.");
+		ok(typeof network.activeConnections != 'undefined' && network.activeConnections != null, "new NetworkAttributes() should include a 'activeConnections' property.");
+	});	
+	module('Connection Type Property');
+	test("should be able to define a display Type Property object", function() {
+		expect(10);
+		var connection = new ConnectionAttributes('a', 'b', ConnectionType.UNKNOWN, 0, 0, 0, 0, 0.0, false);
+		ok(connection  != null, "new displayAttributes() should not be null.");
+		ok(typeof connection.info != 'undefined' && connection.info != null && connection.info == "a", "new ConnectionAttributes() should include a 'info' property.");
+		ok(typeof connection.id != 'undefined' && connection.id != null && connection.id == "b", "new ConnectionAttributes() should include a 'id' property.");
+		ok(typeof connection.type != 'undefined' && connection.type != null && connection.type == 'unknown', "new ConnectionAttributes() should include a 'type' property.");
+		ok(typeof connection.currentDownloadBandwidth != 'undefined' && connection.currentDownloadBandwidth != null && connection.currentDownloadBandwidth == 0, "new ConnectionAttributes() should include a 'currentDownloadBandwidth' property.");
+		ok(typeof connection.currentUploadBandwidth != 'undefined' && connection.currentUploadBandwidth != null && connection.currentUploadBandwidth == 0, "new ConnectionAttributes() should include a 'currentUploadBandwidth' property.");
+		ok(typeof connection.maxDownloadBandwidth != 'undefined' && connection.maxDownloadBandwidth != null && connection.maxDownloadBandwidth == 0, "new ConnectionAttributes() should include a 'maxDownloadBandwidth' property.");
+		ok(typeof connection.maxUploadBandwidth != 'undefined' && connection.maxUploadBandwidth != null && connection.maxUploadBandwidth == 0, "new ConnectionAttributes() should include a 'maxUploadBandwidth' property.");
+		ok(typeof connection.currentSignalStrength != 'undefined' && connection.currentSignalStrength != null && connection.currentSignalStrength == 0.0, "new ConnectionAttributes() should include a 'currentSignalStrength' property.");
+		ok(typeof connection.roaming != 'undefined' && connection.roaming != null && connection.roaming == false, "new ConnectionAttributes() should include a 'roaming' property.");
+	});	
+	module('Sensor Property');
+	test("should be able to define a Sensor Property object", function() {
+		expect(5);
+		var sensor = new SensorAttributes(0.0,0.0,0.0,0.0);
+		ok(sensor  != null, "new SensorAttributes() should not be null.");
+		ok(typeof sensor.value != 'undefined' && sensor.value != null && sensor.value == 0.0, "new SensorAttributes() should include a 'value' property.");
+		ok(typeof sensor.min != 'undefined' && sensor.min != null && sensor.min == 0.0, "new SensorAttributes() should include a 'min' property.");
+		ok(typeof sensor.max != 'undefined' && sensor.max != null && sensor.max == 0.0, "new SensorAttributes() should include a 'max' property.");
+		ok(typeof sensor.normalizedValue != 'undefined' && sensor.normalizedValue != null && sensor.normalizedValue == 0.0, "new SensorAttributes() should include a 'normalizedValue' property.");
+	});	
+	module('AVCodecs Property');
+	test("should be able to define a AVCodecs Property object", function() {
+		expect(5);
+		var avcodecs = new AVCodecsAttributes("a", "b", [], []);
+		ok(avcodecs  != null, "new AVCodecsAttributes() should not be null.");
+		ok(typeof avcodecs.info != 'undefined' && avcodecs.info != null && avcodecs.info == "a", "new AVCodecsAttributes() should include a 'info' property.");
+		ok(typeof avcodecs.id != 'undefined' && avcodecs.id != null && avcodecs.id == "b", "new AVCodecsAttributes() should include a 'id' property.");
+		ok(typeof avcodecs.audioCodecs != 'undefined' && avcodecs.audioCodecs != null, "new AVCodecsAttributes() should include a 'audioCodecs' property.");
+		ok(typeof avcodecs.videoCodecs != 'undefined' && avcodecs.videoCodecs != null, "new AVCodecsAttributes() should include a 'videoCodecs' property.");
+	});	
+	module('Audio Codec Property');
+	test("should be able to define a Audio Codec Property object", function() {
+		expect(6);
+		var codec = new AudioCodecAttributes("a", "b", 'a',true,true);
+		ok(codec != null, "new AudioCodecAttributes() should not be null.");
+		ok(typeof codec.info != 'undefined' && codec.info != null && codec.info == "a", "new AudioCodecAttributes() should include a 'info' property.");
+		ok(typeof codec.id != 'undefined' && codec.id != null && codec.id == "b", "new AudioCodecAttributes() should include a 'id' property.");
+		ok(typeof codec.compFormats != 'undefined' && codec.compFormats != null && codec.compFormats == 'a', "new AudioCodecAttributes() should include a 'compFormats' property.");
+		ok(typeof codec.encode != 'undefined' && codec.encode != null && codec.encode == true, "new AudioCodecAttributes() should include a 'encode' property.");
+		ok(typeof codec.decode != 'undefined' && codec.decode != null && codec.decode == true, "new AudioCodecAttributes() should include a 'decode' property.");
+	});	
+	module('Video Codec Property');
+	test("should be able to define a Video Codec Property object", function() {
+		expect(9);
+		var codec = new VideoCodecAttributes("a", "b", [],[],[],[],[],[]);
+		ok(codec != null, "new VideoCodecAttributes() should not be null.");
+		ok(typeof codec.info != 'undefined' && codec.info != null && codec.info == "a", "new VideoCodecAttributes() should include a 'info' property.");
+		ok(typeof codec.id != 'undefined' && codec.id != null && codec.id == "b", "new VideoCodecAttributes() should include a 'id' property.");
+		ok(typeof codec.compFormats != 'undefined' && codec.compFormats != null, "new VideoCodecAttributes() should include a 'compFormats' property.");
+		ok(typeof codec.containerFormats != 'undefined' && codec.containerFormats != null, "new VideoCodecAttributes() should include a 'containerFormats' property.");
+		ok(typeof codec.hwAccel != 'undefined' && codec.hwAccel != null, "new VideoCodecAttributes() should include a 'hwAccel' property.");
+		ok(typeof codec.profiles != 'undefined' && codec.profiles != null, "new VideoCodecAttributes() should include a 'profiles' property.");
+		ok(typeof codec.frameTypes != 'undefined' && codec.frameTypes != null, "new VideoCodecAttributes() should include a 'frameTypes' property.");
+		ok(typeof codec.rateTypes != 'undefined' && codec.rateTypes != null, "new VideoCodecAttributes() should include a 'rateTypes' property.");
+	});	
+	module('Storage Unit Property');
+	test("should be able to define a Storage Property object", function() {
+		expect(8);
+		var storage = new StorageUnitAttributes('a','b',0,true,0,0,true);
+		ok(storage != null, "new StorageUnitAttributes() should not be null.");
+		ok(typeof storage.info != 'undefined' && storage.info != null && storage.info == "a", "new StorageUnitAttributes() should include a 'info' property.");
+		ok(typeof storage.id != 'undefined' && storage.id != null && storage.id == "b", "new StorageUnitAttributes() should include a 'id' property.");
+		ok(typeof storage.type != 'undefined' && storage.type != null && storage.type == 0, "new StorageUnitAttributes() should include a 'type' property.");
+		ok(typeof storage.isWritable != 'undefined' && storage.isWritable != null && storage.isWritable == true, "new StorageUnitAttributes() should include a 'isWritable' property.");
+		ok(typeof storage.capacity != 'undefined' && storage.capacity != null && storage.capacity == 0, "new StorageUnitAttributes() should include a 'capacity' property.");
+		ok(typeof storage.availableCapacity != 'undefined' && storage.availableCapacity != null && storage.availableCapacity == 0, "new StorageUnitAttributes() should include a 'availableCapacity' property.");
+		ok(typeof storage.isRemoveable != 'undefined' && storage.isRemoveable != null && storage.isRemoveable == true, "new StorageUnitAttributes() should include a 'isRemoveable' property.");
+	});	
+	module('Output Devices Property');
+	test("should be able to define a Input Devices Property object", function() {
+		expect(11);
+		var output = new OutputDevicesAttributes('a','b',[],[],[],"a",[],"a",[],[]);
+		ok(output != null, "new OutputDevicesAttributes() should not be null.");
+		ok(typeof output.info != 'undefined' && output.info != null && output.info == "a", "new OutputDevicesAttributes() should include a 'info' property.");
+		ok(typeof output.id != 'undefined' && output.id != null && output.id == "b", "new OutputDevicesAttributes() should include a 'id' property.");
+		ok(typeof output.displayDevices != 'undefined' && output.displayDevices != null, "new OutputDevicesAttributes() should include a 'displayDevices' property.");
+		ok(typeof output.activeDisplayDevices != 'undefined' && output.activeDisplayDevices != null, "new OutputDevicesAttributes() should include a 'activeDisplayDevices' property.");
+		ok(typeof output.printingDevices != 'undefined' && output.printingDevices != null, "new OutputDevicesAttributes() should include a 'printingDevices' property.");
+		ok(typeof output.activePrintingDevice != 'undefined' && output.activePrintingDevice != null && output.activePrintingDevice == "a", "new OutputDevicesAttributes() should include a 'activePrintingDevice' property.");
+		ok(typeof output.brailleDevices != 'undefined' && output.brailleDevices != null, "new OutputDevicesAttributes() should include a 'brailleDevices' property.");
+		ok(typeof output.activeBrailleDevice != 'undefined' && output.activeBrailleDevice != null && output.activeBrailleDevice == "a", "new OutputDevicesAttributes() should include a 'activeBrailleDevice' property.");
+		ok(typeof output.audioDevices != 'undefined' && output.audioDevices != null, "new OutputDevicesAttributes() should include a 'audioDevices' property.");
+		ok(typeof output.activeAudioDevices != 'undefined' && output.activeAudioDevices != null, "new OutputDevicesAttributes() should include a 'activeAudioDevices' property.");
+	});	
+	module('Display Device Type Property');
+	test("should be able to define a Display Device Property object", function() {
+		expect(10);
+		var display = new DisplayDeviceAttributes(0,0.0,0.0,true,0,0,0.0,0.0,"a");
+		ok(display  != null, "new DisplayDeviceAttributes() should not be null.");
+		ok(typeof display.orientation != 'undefined' && display.orientation != null && display.orientation == 0, "new DisplayDeviceAttributes() should include a 'orientation' property.");
+		ok(typeof display.brightness != 'undefined' && display.brightness != null && display.brightness == 0.0, "new DisplayDeviceAttributes() should include a 'brightness' property.");
+		ok(typeof display.contrast != 'undefined' && display.contrast != null && display.contrast == 0.0, "new DisplayDeviceAttributes() should include a 'contrast' property.");
+		ok(typeof display.blanked != 'undefined' && display.blanked != null && display.blanked == true, "new DisplayDeviceAttributes() should include a 'blanked' property.");
+		ok(typeof display.dotsPerInchW != 'undefined' && display.dotsPerInchW != null && display.dotsPerInchW == 0, "new DisplayDeviceAttributes() should include a 'dotsPerInchW' property.");
+		ok(typeof display.dotsPerInchH != 'undefined' && display.dotsPerInchH != null && display.dotsPerInchH == 0, "new DisplayDeviceAttributes() should include a 'dotsPerInchH' property.");
+		ok(typeof display.physicalWidth != 'undefined' && display.physicalWidth != null && display.physicalWidth == 0.0, "new DisplayDeviceAttributes() should include a 'physicalWidth' property.");
+		ok(typeof display.physicalHeight != 'undefined' && display.physicalHeight != null && display.physicalHeight == 0.0, "new DisplayDeviceAttributes() should include a 'physicalHeight' property.");
+		ok(typeof display.info != 'undefined' && display.info != null && display.info == 'a', "new DisplayDeviceAttributes() should include a 'info' property.");
+	});	
+	module('Audio Device Type Property');
+	test("should be able to define a Audio Device Property object", function() {
+		expect(6);
+		var audio = new AudioDeviceAttributes(0,0,0,0,"a");
+		ok(audio  != null, "new AudioDeviceAttributes() should not be null.");
+		ok(typeof audio.type != 'undefined' && audio.type != null && audio.type == 0, "new AudioDeviceAttributes() should include a 'type' property.");
+		ok(typeof audio.freqRangeLow != 'undefined' && audio.freqRangeLow != null && audio.freqRangeLow == 0, "new AudioDeviceAttributes() should include a 'freqRangeLow' property.");
+		ok(typeof audio.freqRangeHigh != 'undefined' && audio.freqRangeHigh != null && audio.freqRangeHigh == 0, "new AudioDeviceAttributes() should include a 'freqRangeHigh' property.");
+		ok(typeof audio.volumeLevel != 'undefined' && audio.volumeLevel != null && audio.volumeLevel == 0, "new AudioDeviceAttributes() should include a 'volumeLevel' property.");
+		ok(typeof audio.info != 'undefined' && audio.info != null && audio.info == "a", "new AudioDeviceAttributes() should include a 'info' property.");
+	});	
+	module('Printing Device Type Property');
+	test("should be able to define a Printing Device Property object", function() {
+		expect(5);
+		var printer = new PrintingDeviceAttributes(0,0,0,"a");
+		ok(printer  != null, "new PrintingDeviceAttributes() should not be null.");
+		ok(typeof printer.type != 'undefined' && printer.type != null && printer.type == 0, "new PrintingDeviceAttributes() should include a 'type' property.");
+		ok(typeof printer.resolution != 'undefined' && printer.resolution != null && printer.resolution == 0, "new PrintingDeviceAttributes() should include a 'resolution' property.");
+		ok(typeof printer.color != 'undefined' && printer.color != null && printer.color == 0, "new PrintingDeviceAttributes() should include a 'color' property.");
+		ok(typeof printer.info != 'undefined' && printer.info != null && printer.info == "a", "new PrintingDeviceAttributes() should include a 'info' property.");
+	});	
+	module('Braille Device Type Property');
+	test("should be able to define a Printing Device Property object", function() {
+		expect(3);
+		var braille = new BrailleDeviceAttributes(0,"a");
+		ok(braille  != null, "new BrailleDeviceAttributes() should not be null.");
+		ok(typeof braille.nbCells != 'undefined' && braille.nbCells != null && braille.nbCells == 0, "new BrailleDeviceAttributes() should include a 'nbCells' property.");
+		ok(typeof braille.info != 'undefined' && braille.info != null && braille.info == "a", "new BrailleDeviceAttributes() should include a 'info' property.");
+	});	
+	module('Input Devices Property');
+	test("should be able to define a Input Devices Property object", function() {
+		expect(11);
+		var input = new InputDevicesAttributes('a','b',[],[],[],[],[],[],[],[]);
+		ok(input != null, "new InputDevicesAttributes() should not be null.");
+		ok(typeof input.info != 'undefined' && input.info != null && input.info == "a", "new InputDevicesAttributes() should include a 'info' property.");
+		ok(typeof input.id != 'undefined' && input.id != null && input.id == "b", "new InputDevicesAttributes() should include a 'id' property.");
+		ok(typeof input.pointingDevices != 'undefined' && input.pointingDevices != null, "new InputDevicesAttributes() should include a 'pointingDevices' property.");
+		ok(typeof input.activePointingDevices != 'undefined' && input.activePointingDevices != null, "new InputDevicesAttributes() should include a 'activePointingDevices' property.");
+		ok(typeof input.keyboards != 'undefined' && input.keyboards != null, "new InputDevicesAttributes() should include a 'keyboards' property.");
+		ok(typeof input.activeKeyboards != 'undefined' && input.activeKeyboards != null, "new InputDevicesAttributes() should include a 'activeKeyboards' property.");
+		ok(typeof input.cameras != 'undefined' && input.cameras != null, "new InputDevicesAttributes() should include a 'cameras' property.");
+		ok(typeof input.activeCameras != 'undefined' && input.activeCameras != null, "new InputDevicesAttributes() should include a 'activeCameras' property.");
+		ok(typeof input.microphones != 'undefined' && input.microphones != null, "new InputDevicesAttributes() should include a 'microphones' property.");
+		ok(typeof input.activeMicrophones != 'undefined' && input.activeMicrophones != null, "new InputDevicesAttributes() should include a 'activeMicrophones' property.");
+	});	
+	module('Pointer Property');
+	test("should be able to define a Pointer Property object", function() {
+		expect(4);
+		var pointer = new PointerAttributes(0,true,"a");
+		ok(pointer  != null, "new PointerAttributes() should not be null.");
+		ok(typeof pointer.type != 'undefined' && pointer.type != null && pointer.type == 0, "new PointerAttributes() should include a 'type' property.");
+		ok(typeof pointer.supportsMultiTouch != 'undefined' && pointer.supportsMultiTouch != null && pointer.supportsMultiTouch == true, "new PointerAttributes() should include a 'supportsMultiTouch' property.");
+		ok(typeof pointer.info != 'undefined' && pointer.info != null && pointer.info == "a", "new PointerAttributes() should include a 'info' property.");
+	});	
+	module('Keyboard Property');
+	test("should be able to define a Keyboard Property object", function() {
+		expect(4);
+		var keyboard = new KeyboardAttributes(0,true,"a");
+		ok(keyboard  != null, "new KeyboardAttributes() should not be null.");
+		ok(typeof keyboard.type != 'undefined' && keyboard.type != null && keyboard.type == 0, "new KeyboardAttributes() should include a 'type' property.");
+		ok(typeof keyboard.isHardware != 'undefined' && keyboard.isHardware != null && keyboard.isHardware == true, "new KeyboardAttributes() should include a 'isHardware' property.");
+		ok(typeof keyboard.info != 'undefined' && keyboard.info != null && keyboard.info == "a", "new KeyboardAttributes() should include a 'info' property.");
+	});	
+	module('Camera Property');
+	test("should be able to define a Camera Property object", function() {
+		expect(5);
+		var camera = new CameraAttributes(true,true,0,0.0);
+		ok(camera  != null, "new CameraAttributes() should not be null.");
+		ok(typeof camera.supportsVideo != 'undefined' && camera.supportsVideo != null && camera.supportsVideo == true, "new CameraAttributes() should include a 'supportsVideo' property.");
+		ok(typeof camera.hasFlash != 'undefined' && camera.hasFlash != null && camera.hasFlash == true, "new CameraAttributes() should include a 'hasFlash' property.");
+		ok(typeof camera.sensorPixels != 'undefined' && camera.sensorPixels != null && camera.sensorPixels == 0, "new CameraAttributes() should include a 'sensorPixels' property.");
+		ok(typeof camera.maxZoomFactor != 'undefined' && camera.maxZoomFactor != null && camera.maxZoomFactor == 0.0, "new CameraAttributes() should include a 'maxZoomFactor' property.");
+	});	
+	module('Microphone Property');
+	test("should be able to define a Microphone Property object", function() {
+		expect(7);
+		var mic = new MicrophoneAttributes(0,0,0,"a","b",[]);
+		ok(mic  != null, "new MicrophoneAttributes() should not be null.");
+		ok(typeof mic.type != 'undefined' && mic.type != null && mic.type == 0, "new MicrophoneAttributes() should include a 'type' property.");
+		ok(typeof mic.freqRangeLow != 'undefined' && mic.freqRangeLow != null && mic.freqRangeLow == 0, "new MicrophoneAttributes() should include a 'freqRangeLow' property.");
+		ok(typeof mic.freqRangeHigh != 'undefined' && mic.freqRangeHigh != null && mic.freqRangeHigh == 0, "new MicrophoneAttributes() should include a 'freqRangeHigh' property.");
+		ok(typeof mic.info != 'undefined' && mic.info != null && mic.info == "a", "new MicrophoneAttributes() should include a 'info' property.");
+		ok(typeof mic.name != 'undefined' && mic.name != null && mic.name == "b", "new MicrophoneAttributes() should include a 'name' property.");
+		ok(typeof mic.types != 'undefined' && mic.types != null, "new MicrophoneAttributes() should include a 'types' property.");
+	});	
+};

http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/blob/ae8bc77e/test/assets/www/battery/index.html
----------------------------------------------------------------------
diff --git a/test/assets/www/battery/index.html b/test/assets/www/battery/index.html
new file mode 100644
index 0000000..298bf19
--- /dev/null
+++ b/test/assets/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>PhoneGap</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>
+    <a href="javascript:" class="btn large" onclick="addBattery();">Add "batterystatus" listener</a>
+    <a href="javascript:" class="btn large" onclick="removeBattery();">Remove "batterystatus" listener</a>
+    <a href="javascript:" class="btn large" onclick="addLow();">Add "batterylow" listener</a>
+    <a href="javascript:" class="btn large" onclick="removeLow();">Remove "batterylow" listener</a>
+    <a href="javascript:" class="btn large" onclick="addCritical();">Add "batterycritical" listener</a>
+    <a href="javascript:" class="btn large" onclick="removeCritical();">Remove "batterycritical" listener</a>
+    <h2>&nbsp</h2><a href="javascript:" class="backBtn" onclick="backHome();">Back</a>
+  </body>
+</html>      

http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/blob/ae8bc77e/test/assets/www/camera/index.html
----------------------------------------------------------------------
diff --git a/test/assets/www/camera/index.html b/test/assets/www/camera/index.html
new file mode 100755
index 0000000..1c8fd07
--- /dev/null
+++ b/test/assets/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>PhoneGap</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>
+    <a href="javascript:" class="btn large" onclick="getPicture();">Take Picture</a>
+    <a href="javascript:" class="btn large" onclick="getImage();">Select Image from Library</a>
+    <h2>&nbsp;</h2><a href="javascript:" class="backBtn" onclick="backHome();">Back</a>
+  </body>
+</html>      

http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/blob/ae8bc77e/test/assets/www/compass/index.html
----------------------------------------------------------------------
diff --git a/test/assets/www/compass/index.html b/test/assets/www/compass/index.html
new file mode 100755
index 0000000..74b817a
--- /dev/null
+++ b/test/assets/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>PhoneGap</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">&nbsp;</span></td>
+        </tr></table>
+    </div>
+    <h2>Action</h2>
+    <a href="javascript:" class="btn large" onclick="getCompass();">Get Compass</a>
+    <a href="javascript:" class="btn large" onclick="watchCompass();">Start Watching Compass</a>
+    <a href="javascript:" class="btn large" onclick="stopCompass();">Stop Watching Compass</a>
+    <h2>&nbsp;</h2><a href="javascript:" class="backBtn" onclick="backHome();">Back</a>
+  </body>
+</html>      

http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/blob/ae8bc77e/test/assets/www/contacts/index.html
----------------------------------------------------------------------
diff --git a/test/assets/www/contacts/index.html b/test/assets/www/contacts/index.html
new file mode 100755
index 0000000..e6ce44b
--- /dev/null
+++ b/test/assets/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>PhoneGap</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">&nbsp;</span>
+    </div>
+    <h2>Action</h2>
+    <a href="javascript:" class="btn large" onclick="getContacts();">Get phone's contacts</a>
+    <a href="javascript:" class="btn large" onclick="addContact();">Add a new contact 'Dooney Evans'</a>
+    <h2>&nbsp</h2><a href="javascript:" class="backBtn" onclick="backHome();">Back</a>
+  </body>
+</html>