summaryrefslogtreecommitdiffstats
path: root/dom/tests/mochitest/sessionstorage
diff options
context:
space:
mode:
Diffstat (limited to 'dom/tests/mochitest/sessionstorage')
-rw-r--r--dom/tests/mochitest/sessionstorage/chrome.ini3
-rw-r--r--dom/tests/mochitest/sessionstorage/file_http.html40
-rw-r--r--dom/tests/mochitest/sessionstorage/file_https.html15
-rw-r--r--dom/tests/mochitest/sessionstorage/frameEqual.html47
-rw-r--r--dom/tests/mochitest/sessionstorage/frameNotEqual.html43
-rw-r--r--dom/tests/mochitest/sessionstorage/frameReplace.html75
-rw-r--r--dom/tests/mochitest/sessionstorage/interOriginSlave.js42
-rw-r--r--dom/tests/mochitest/sessionstorage/interOriginTest.js44
-rw-r--r--dom/tests/mochitest/sessionstorage/mochitest.ini18
-rw-r--r--dom/tests/mochitest/sessionstorage/test_cookieSession.html124
-rw-r--r--dom/tests/mochitest/sessionstorage/test_sessionStorageBase.html180
-rw-r--r--dom/tests/mochitest/sessionstorage/test_sessionStorageBaseSessionOnly.html231
-rw-r--r--dom/tests/mochitest/sessionstorage/test_sessionStorageClone.html94
-rw-r--r--dom/tests/mochitest/sessionstorage/test_sessionStorageFromChrome.xhtml34
-rw-r--r--dom/tests/mochitest/sessionstorage/test_sessionStorageHttpHttps.html59
-rw-r--r--dom/tests/mochitest/sessionstorage/test_sessionStorageReplace.html78
16 files changed, 1127 insertions, 0 deletions
diff --git a/dom/tests/mochitest/sessionstorage/chrome.ini b/dom/tests/mochitest/sessionstorage/chrome.ini
new file mode 100644
index 000000000..65112f0f8
--- /dev/null
+++ b/dom/tests/mochitest/sessionstorage/chrome.ini
@@ -0,0 +1,3 @@
+[DEFAULT]
+
+[test_sessionStorageFromChrome.xhtml]
diff --git a/dom/tests/mochitest/sessionstorage/file_http.html b/dom/tests/mochitest/sessionstorage/file_http.html
new file mode 100644
index 000000000..e8614dd54
--- /dev/null
+++ b/dom/tests/mochitest/sessionstorage/file_http.html
@@ -0,0 +1,40 @@
+<html>
+<head>
+<script>
+
+window.addEventListener("message", onMessageReceived, false);
+
+function postMsg(msg)
+{
+ parent.postMessage(msg, "http://mochi.test:8888");
+}
+
+function onMessageReceived(event)
+{
+ if (event.data == "check") {
+ postMsg(sessionStorage.getItem("foo"));
+
+ var gotValue = "threw";
+ try {
+ gotValue = sessionStorage.getItem("foo-https");
+ } catch (e) {
+ }
+
+ postMsg(gotValue);
+
+ postMsg("the end");
+ }
+}
+
+function start()
+{
+ sessionStorage.setItem("foo", "insecure");
+ postMsg(sessionStorage.getItem("foo"));
+}
+
+</script>
+</head>
+<body onload="start();">
+insecure
+</body>
+</html>
diff --git a/dom/tests/mochitest/sessionstorage/file_https.html b/dom/tests/mochitest/sessionstorage/file_https.html
new file mode 100644
index 000000000..915c54950
--- /dev/null
+++ b/dom/tests/mochitest/sessionstorage/file_https.html
@@ -0,0 +1,15 @@
+<html>
+<head>
+<script>
+function start()
+{
+ sessionStorage.setItem("foo-https", "secure");
+ parent.postMessage(sessionStorage.getItem("foo-https"),
+ "http://mochi.test:8888");
+}
+</script>
+</head>
+<body onload="start();">
+secure
+</body>
+</html>
diff --git a/dom/tests/mochitest/sessionstorage/frameEqual.html b/dom/tests/mochitest/sessionstorage/frameEqual.html
new file mode 100644
index 000000000..787f3ee3e
--- /dev/null
+++ b/dom/tests/mochitest/sessionstorage/frameEqual.html
@@ -0,0 +1,47 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>slave for sessionStorage test</title>
+
+<script type="text/javascript" src="interOriginSlave.js"></script>
+<script type="text/javascript">
+
+var currentStep = 2;
+
+function doStep()
+{
+ switch (currentStep)
+ {
+ case 2:
+ is(sessionStorage.getItem("A"), "1", "A is 1 in the slave");
+ is(sessionStorage.getItem("B"), "2", "B is 2 in the slave");
+ is(sessionStorage.length, 2, "Num of items is 2");
+
+ sessionStorage.setItem("C", "3");
+ is(sessionStorage.getItem("C"), "3", "C is 3 in the slave");
+ is(sessionStorage.length, 3, "Num of items is 3");
+ break;
+
+ case 4:
+ is(sessionStorage.getItem("A"), "1", "A is 1 in the slave");
+ is(sessionStorage.getItem("B"), "2", "B is 2 in the slave");
+ is(sessionStorage.getItem("C"), "3", "C is 3 in the slave");
+ is(sessionStorage.length, 3, "Num of items is 3");
+ break;
+
+ case 6:
+ return finishTest();
+ }
+
+ ++currentStep;
+ ++currentStep;
+
+ return true;
+}
+
+</script>
+
+</head>
+
+<body onload="postMsg('frame loaded');">
+</body>
+</html>
diff --git a/dom/tests/mochitest/sessionstorage/frameNotEqual.html b/dom/tests/mochitest/sessionstorage/frameNotEqual.html
new file mode 100644
index 000000000..221ca97e5
--- /dev/null
+++ b/dom/tests/mochitest/sessionstorage/frameNotEqual.html
@@ -0,0 +1,43 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>slave for sessionStorage test</title>
+
+<script type="text/javascript" src="interOriginSlave.js"></script>
+<script type="text/javascript">
+
+var currentStep = 2;
+
+function doStep()
+{
+ switch (currentStep)
+ {
+ case 2:
+ is(sessionStorage.length, 0, "Num of items is 0");
+
+ sessionStorage.setItem("C", "3");
+ is(sessionStorage.getItem("C"), "3", "C is 3 in the slave");
+ is(sessionStorage.length, 1, "Num of items is 1");
+ break;
+
+ case 4:
+ is(sessionStorage.getItem("C"), "3", "C is 3 in the slave");
+ is(sessionStorage.length, 1, "Num of items is 1");
+ break;
+
+ case 6:
+ return finishTest();
+ }
+
+ ++currentStep;
+ ++currentStep;
+
+ return true;
+}
+
+</script>
+
+</head>
+
+<body onload="postMsg('frame loaded');">
+</body>
+</html>
diff --git a/dom/tests/mochitest/sessionstorage/frameReplace.html b/dom/tests/mochitest/sessionstorage/frameReplace.html
new file mode 100644
index 000000000..bf5579c71
--- /dev/null
+++ b/dom/tests/mochitest/sessionstorage/frameReplace.html
@@ -0,0 +1,75 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>sessionStorage replace frame</title>
+
+<script type="text/javascript">
+
+var shell;
+
+function ok(a, message)
+{
+ if (!a)
+ shell.postMessage("FAILURE: " + message, "http://mochi.test:8888");
+ else
+ shell.postMessage(message, "http://mochi.test:8888");
+}
+
+function is(a, b, message)
+{
+ if (a != b)
+ shell.postMessage("FAILURE: " + message + ", expected "+b+" got "+a, "http://mochi.test:8888");
+ else
+ shell.postMessage(message + ", expected "+b+" got "+a, "http://mochi.test:8888");
+}
+
+function doTest()
+{
+ var query = location.search.substring(1);
+ var queries = query.split("&");
+
+ var action = queries[0];
+ shell = queries[1];
+ switch (shell)
+ {
+ case "frame":
+ shell = parent;
+ break;
+ case "window":
+ shell = opener;
+ break;
+ }
+
+ switch (action)
+ {
+ case "init":
+ sessionStorage.setItem("A", "1");
+ sessionStorage.setItem("B", "2");
+ sessionStorage.setItem("C", "3");
+ is(sessionStorage.getItem("A"), "1", "'A' is '1'");
+ is(sessionStorage.getItem("B"), "2", "'A' is '2'");
+ is(sessionStorage.getItem("C"), "3", "'A' is '3'");
+ break;
+
+ case "check":
+ is(sessionStorage.getItem("A"), null, "'A' is null");
+ is(sessionStorage.getItem("B"), null, "'A' is null");
+ is(sessionStorage.getItem("C"), null, "'A' is null");
+ break;
+
+ case "clean":
+ is(sessionStorage.getItem("A"), "1", "'A' is '1'");
+ is(sessionStorage.getItem("B"), "2", "'A' is '2'");
+ is(sessionStorage.getItem("C"), "3", "'A' is '3'");
+ sessionStorage.clear();
+ break;
+ }
+
+ shell.postMessage(action + "_done", "http://mochi.test:8888");
+}
+
+</script>
+
+</head>
+<body onload="doTest();">
+</body>
+</html>
diff --git a/dom/tests/mochitest/sessionstorage/interOriginSlave.js b/dom/tests/mochitest/sessionstorage/interOriginSlave.js
new file mode 100644
index 000000000..e3b3cdbb3
--- /dev/null
+++ b/dom/tests/mochitest/sessionstorage/interOriginSlave.js
@@ -0,0 +1,42 @@
+function postMsg(message)
+{
+ opener.postMessage(message, "http://mochi.test:8888");
+}
+
+window.addEventListener("message", onMessageReceived, false);
+
+function onMessageReceived(event)
+{
+ //alert("slave got event: "+event.data);
+ if (event.data == "step") {
+ if (doStep())
+ postMsg("perf");
+
+ return;
+ }
+
+ postMsg("Invalid message");
+}
+
+function ok(a, message)
+{
+ if (!a)
+ postMsg("FAILURE: " + message);
+ else
+ postMsg(message);
+}
+
+function is(a, b, message)
+{
+ if (a != b)
+ postMsg("FAILURE: " + message + ", expected "+b+" got "+a);
+ else
+ postMsg(message + ", expected "+b+" got "+a);
+}
+
+function finishTest()
+{
+ sessionStorage.clear();
+ postMsg("done");
+ return false;
+}
diff --git a/dom/tests/mochitest/sessionstorage/interOriginTest.js b/dom/tests/mochitest/sessionstorage/interOriginTest.js
new file mode 100644
index 000000000..adea77edb
--- /dev/null
+++ b/dom/tests/mochitest/sessionstorage/interOriginTest.js
@@ -0,0 +1,44 @@
+var slaveLoadsPending = 1;
+
+var slaveOrigin = "";
+var slave = null;
+
+var failureRegExp = new RegExp("^FAILURE");
+const slavePath = "/tests/dom/tests/mochitest/sessionstorage/";
+
+window.addEventListener("message", onMessageReceived, false);
+
+function onMessageReceived(event)
+{
+ //alert("master got event: "+event.data);
+ switch (event.data)
+ {
+ // Indication of the frame onload event
+ case "frame loaded":
+ if (--slaveLoadsPending)
+ break;
+
+ // Just fall through...
+
+ // Indication of successfully finished step of a test
+ case "perf":
+ // We called doStep before the frame was load
+ if (event.data == "perf")
+ doStep();
+
+ slave.postMessage("step", slaveOrigin);
+ break;
+
+ // Indication of all test parts finish (from any of the frames)
+ case "done":
+ sessionStorage.clear();
+ slaveLoadsPending = 1;
+ doNextTest();
+ break;
+
+ // Any other message indicates error or succes message of a test
+ default:
+ SimpleTest.ok(!event.data.match(failureRegExp), event.data);
+ break;
+ }
+}
diff --git a/dom/tests/mochitest/sessionstorage/mochitest.ini b/dom/tests/mochitest/sessionstorage/mochitest.ini
new file mode 100644
index 000000000..126216c4f
--- /dev/null
+++ b/dom/tests/mochitest/sessionstorage/mochitest.ini
@@ -0,0 +1,18 @@
+[DEFAULT]
+support-files =
+ file_http.html
+ file_https.html
+ frameEqual.html
+ frameNotEqual.html
+ frameReplace.html
+ interOriginSlave.js
+ interOriginTest.js
+
+[test_cookieSession.html]
+[test_sessionStorageBase.html]
+[test_sessionStorageBaseSessionOnly.html]
+[test_sessionStorageClone.html]
+skip-if = toolkit == 'android'
+[test_sessionStorageHttpHttps.html]
+skip-if = toolkit == 'android' #TIMED_OUT
+[test_sessionStorageReplace.html]
diff --git a/dom/tests/mochitest/sessionstorage/test_cookieSession.html b/dom/tests/mochitest/sessionstorage/test_cookieSession.html
new file mode 100644
index 000000000..01bd596ee
--- /dev/null
+++ b/dom/tests/mochitest/sessionstorage/test_cookieSession.html
@@ -0,0 +1,124 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>cookie per-session only test</title>
+
+<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+
+<script type="text/javascript">
+
+/*
+ Set cookie access to be just per session and store to the sessionStorage.
+ Content stored must prevail only for session of the browser, so it must
+ be accessible in another window we try to access that key in the same
+ storage.
+ */
+
+function pushCookie(aValue, aNext) {
+ SpecialPowers.pushPermissions([{'type': 'cookie', 'allow': aValue, 'context': document}], pushPermissionAndTest);
+}
+
+function pushPermissionAndTest() {
+ var test = tests.shift();
+ if (test) {
+ document.getElementById('testframe').onload = test;
+ /* After every permission change, an iframe has to be reloaded,
+ otherwise this test causes failures in b2g (oop) mochitest, because
+ the permission changes don't seem to be always picked up
+ by the code that excercises it */
+ document.getElementById('testframe').contentWindow.location.reload();
+ } else {
+ ok(false, 'should not be reached');
+ SimpleTest.finish();
+ }
+}
+
+function startTest() {
+ pushCookie(SpecialPowers.Ci.nsICookiePermission.ACCESS_DEFAULT);
+}
+
+var tests = [
+ function test1() {
+ sessionStorage.setItem("persistent1", "persistent value 1");
+ sessionStorage.setItem("persistent2", "persistent value 2");
+
+ pushCookie(SpecialPowers.Ci.nsICookiePermission.ACCESS_SESSION);
+ },
+
+ function test2() {
+ sessionStorage.setItem("session only", "session value");
+ is(sessionStorage.getItem("session only"), "session value", "Value present when cookies in session-only mode");
+ is(sessionStorage.getItem("persistent1"), "persistent value 1", "Persistent value present");
+ is(sessionStorage.getItem("persistent2"), "persistent value 2", "Persistent value present");
+
+ sessionStorage.setItem("persistent1", "changed persistent value 1");
+ sessionStorage.removeItem("persistent2");
+
+ is(sessionStorage.getItem("session only"), "session value", "Value present when cookies in session-only mode");
+ is(sessionStorage.getItem("persistent1"), "changed persistent value 1", "Persistent value present");
+ is(sessionStorage.getItem("persistent2"), null, "Persistent value removed");
+
+ // This clear has to delete only changes made in session only mode
+ sessionStorage.clear();
+
+ is(sessionStorage.getItem("session only"), null, "Value not present when cookies in session-only mode after delete");
+ is(sessionStorage.getItem("persistent1"), null, "Persistent value not present in session only after delete");
+ is(sessionStorage.getItem("persistent2"), null, "Persistent value not present in session only after delete");
+
+ sessionStorage.setItem("session only 2", "must be deleted on drop of session-only cookies permissions");
+
+ pushCookie(SpecialPowers.Ci.nsICookiePermission.ACCESS_DEFAULT);
+ },
+
+ function test3() {
+ is(sessionStorage.getItem("session only"), null, "No value when cookies are in default mode");
+ is(sessionStorage.getItem("session only 2"), null, "No value when cookies are in default mode");
+ is(sessionStorage.getItem("persistent1"), "persistent value 1", "Persistent value present");
+ is(sessionStorage.getItem("persistent2"), "persistent value 2", "Persistent value present");
+
+ pushCookie(SpecialPowers.Ci.nsICookiePermission.ACCESS_SESSION);
+ },
+
+ function test4() {
+ is(sessionStorage.getItem("session only"), null, "Value not present when cookies in session-only mode after delete");
+ is(sessionStorage.getItem("session only 2"), null, "Value not present when cookies in session-only mode after delete");
+ is(sessionStorage.getItem("persistent1"), "persistent value 1", "Persistent value present again");
+ is(sessionStorage.getItem("persistent2"), "persistent value 2", "Persistent value present again");
+
+ pushCookie(SpecialPowers.Ci.nsICookiePermission.ACCESS_DEFAULT);
+ },
+
+ function test5() {
+ sessionStorage.clear();
+
+ is(sessionStorage.getItem("session only"), null, "No value when cookies are in default mode");
+ is(sessionStorage.getItem("persistent1"), null, "Persistent value not present after delete");
+ is(sessionStorage.getItem("persistent2"), null, "Persistent value not present after delete");
+
+ pushCookie(SpecialPowers.Ci.nsICookiePermission.ACCESS_SESSION);
+ },
+
+ function test6() {
+ is(sessionStorage.getItem("session only"), null, "Value not present when cookies in session-only mode after delete");
+ is(sessionStorage.getItem("session only 2"), null, "No value when cookies are in default mode");
+ is(sessionStorage.getItem("persistent1"), null, "Persistent value not present in session only after delete");
+ is(sessionStorage.getItem("persistent2"), null, "Persistent value not present in session only after delete");
+
+ pushCookie(SpecialPowers.Ci.nsICookiePermission.ACCESS_DEFAULT);
+ },
+
+ function test7() {
+ SimpleTest.finish();
+ }
+];
+
+SimpleTest.waitForExplicitFinish();
+
+</script>
+
+</head>
+
+<body onload="startTest();">
+<iframe id="testframe" src="data:text/html;charset=utf-8,"></iframe>
+</body>
+</html>
diff --git a/dom/tests/mochitest/sessionstorage/test_sessionStorageBase.html b/dom/tests/mochitest/sessionstorage/test_sessionStorageBase.html
new file mode 100644
index 000000000..c1d9f712b
--- /dev/null
+++ b/dom/tests/mochitest/sessionstorage/test_sessionStorageBase.html
@@ -0,0 +1,180 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>sessionStorage basic test</title>
+
+<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+
+<script type="text/javascript">
+
+var expectedEvents = [
+ "empty,null,",
+ "empty,,null",
+ "key1,null,value1",
+ "key1,value1,null",
+ "key1,null,value1",
+ "key2,null,value2",
+ "key2,value2,value2-2",
+ "key1,value1,value1-2",
+ "key2,value2-2,null",
+ "null,null,null"
+];
+
+function setup() {
+ sessionStorage.clear();
+ SimpleTest.executeSoon(startTest);
+}
+
+function startTest()
+{
+ // Initially check the sessionStorage is empty
+ is(sessionStorage.length, 0, "The storage is empty [1]");
+ is(sessionStorage.key(0), null, "key() should return null for out-of-bounds access");
+ is(sessionStorage.key(-1), null, "key() should return null for out-of-bounds access");
+ is(sessionStorage.key(1), null, "key() should return null for out-of-bounds access");
+ is(sessionStorage.getItem("nonexisting"), null, "Nonexisting item is null (getItem())");
+ is(sessionStorage["nonexisting"], undefined, "Nonexisting item is undefined (array access)");
+ is(sessionStorage.nonexisting, undefined, "Nonexisting item is undefined (property access)");
+ sessionStorage.removeItem("nonexisting"); // Just check there is no exception
+
+ is(typeof sessionStorage.getItem("nonexisting"), "object", "getItem('nonexisting') is object");
+ is(typeof sessionStorage["nonexisting"], "undefined", "['nonexisting'] is undefined");
+ is(typeof sessionStorage.nonexisting, "undefined", "nonexisting is undefined");
+ is(typeof sessionStorage.getItem("nonexisting2"), "object", "getItem('nonexisting2') is object");
+ is(typeof sessionStorage["nonexisting2"], "undefined", "['nonexisting2'] is undefined");
+ is(typeof sessionStorage.nonexisting2, "undefined", "nonexisting2 is undefined");
+
+ var sessionStorageCopy = sessionStorage;
+
+ function onStorageChanged(e) {
+ if (e.storageArea == sessionStorageCopy) {
+ ok(expectedEvents.length > 0, "Not more then expected events encountered");
+ var receivedEvent = e.key + "," + e.oldValue + "," + e.newValue;
+ is(receivedEvent, expectedEvents.shift(), "Expected event data: " + receivedEvent);
+ }
+ }
+
+ // Listen for MozSessionStorageChanged
+ SpecialPowers.addChromeEventListener("MozSessionStorageChanged", onStorageChanged, true);
+
+ // add an empty-value key
+ sessionStorage.setItem("empty", "");
+ is(sessionStorage.getItem("empty"), "", "Empty value (getItem())");
+ is(sessionStorage["empty"], "", "Empty value (array access)");
+ is(sessionStorage.empty, "", "Empty value (property access)");
+ is(typeof sessionStorage.getItem("empty"), "string", "getItem('empty') is string");
+ is(typeof sessionStorage["empty"], "string", "['empty'] is string");
+ is(typeof sessionStorage.empty, "string", "empty is string");
+ sessionStorage.removeItem("empty");
+ is(sessionStorage.length, 0, "The storage has no keys");
+ is(sessionStorage.getItem("empty"), null, "empty item is null (getItem())");
+ is(sessionStorage["empty"], undefined, "empty item is undefined (array access)");
+ is(sessionStorage.empty, undefined, "empty item is undefined (property access)");
+ is(typeof sessionStorage.getItem("empty"), "object", "getItem('empty') is object");
+ is(typeof sessionStorage["empty"], "undefined", "['empty'] is undefined");
+ is(typeof sessionStorage.empty, "undefined", "empty is undefined");
+
+ // add one key, check it is there
+ sessionStorage.setItem("key1", "value1");
+ is(sessionStorage.length, 1, "The storage has one key-value pair");
+ is(sessionStorage.key(0), "key1");
+ is(sessionStorage.key(-1), null, "key() should return null for out-of-bounds access");
+ is(sessionStorage.key(1), null, "key() should return null for out-of-bounds access");
+
+ // check all access method give the correct result
+ // and are of the correct type
+ is(sessionStorage.getItem("key1"), "value1", "getItem('key1') == value1");
+ is(sessionStorage["key1"], "value1", "['key1'] == value1");
+ is(sessionStorage.key1, "value1", "key1 == value1");
+
+ is(typeof sessionStorage.getItem("key1"), "string", "getItem('key1') is string");
+ is(typeof sessionStorage["key1"], "string", "['key1'] is string");
+ is(typeof sessionStorage.key1, "string", "key1 is string");
+
+ // remove the previously added key and check the storage is empty
+ sessionStorage.removeItem("key1");
+ is(sessionStorage.length, 0, "The storage is empty [2]");
+ is(sessionStorage.key(0), null, "key() should return null for out-of-bounds access");
+ is(sessionStorage.getItem("key1"), null, "\'key1\' removed");
+
+ is(typeof sessionStorage.getItem("key1"), "object", "getItem('key1') is object");
+ is(typeof sessionStorage["key1"], "undefined", "['key1'] is undefined");
+ is(typeof sessionStorage.key1, "undefined", "key1 is undefined");
+
+ // add one key, check it is there
+ sessionStorage.setItem("key1", "value1");
+ is(sessionStorage.length, 1, "The storage has one key-value pair");
+ is(sessionStorage.key(0), "key1");
+ is(sessionStorage.getItem("key1"), "value1");
+
+ // add a second key
+ sessionStorage.setItem("key2", "value2");
+ is(sessionStorage.length, 2, "The storage has two key-value pairs");
+ is(sessionStorage.getItem("key1"), "value1");
+ is(sessionStorage.getItem("key2"), "value2");
+ var firstKey = sessionStorage.key(0);
+ var secondKey = sessionStorage.key(1);
+ ok((firstKey == 'key1' && secondKey == 'key2') ||
+ (firstKey == 'key2' && secondKey == 'key1'),
+ 'key() API works.');
+
+ // change the second key
+ sessionStorage.setItem("key2", "value2-2");
+ is(sessionStorage.length, 2, "The storage has two key-value pairs");
+ is(sessionStorage.key(0), firstKey); // After key value changes the order must be preserved
+ is(sessionStorage.key(1), secondKey);
+ is(sessionStorage.key(-1), null, "key() should return null for out-of-bounds access");
+ is(sessionStorage.key(2), null, "key() should return null for out-of-bounds access");
+ is(sessionStorage.getItem("key1"), "value1");
+ is(sessionStorage.getItem("key2"), "value2-2");
+
+ // change the first key
+ sessionStorage.setItem("key1", "value1-2");
+ is(sessionStorage.length, 2, "The storage has two key-value pairs");
+ is(sessionStorage.key(0), firstKey); // After key value changes the order must be preserved
+ is(sessionStorage.key(1), secondKey);
+ is(sessionStorage.key(-1), null, "key() should return null for out-of-bounds access");
+ is(sessionStorage.key(2), null, "key() should return null for out-of-bounds access");
+ is(sessionStorage.getItem("key1"), "value1-2");
+ is(sessionStorage.getItem("key2"), "value2-2");
+
+ // remove the second key
+ sessionStorage.removeItem("key2");
+ is(sessionStorage.length, 1, "The storage has one key-value pair");
+ is(sessionStorage.key(0), "key1");
+ is(sessionStorage.key(-1), null, "key() should return null for out-of-bounds access");
+ is(sessionStorage.key(1), null, "key() should return null for out-of-bounds access");
+ is(sessionStorage.getItem("key1"), "value1-2");
+
+ // Clear the storage
+ sessionStorage.clear();
+ is(sessionStorage.length, 0, "The storage is empty [3]");
+ is(sessionStorage.key(0), null, "key() should return null for out-of-bounds access");
+ is(sessionStorage.key(-1), null, "key() should return null for out-of-bounds access");
+ is(sessionStorage.key(1), null, "key() should return null for out-of-bounds access");
+ is(sessionStorage.getItem("nonexisting"), null, "Nonexisting item is null");
+ is(sessionStorage.getItem("key1"), null, "key1 removed");
+ is(sessionStorage.getItem("key2"), null, "key2 removed");
+ sessionStorage.removeItem("nonexisting"); // Just check there is no exception
+ sessionStorage.removeItem("key1"); // Just check there is no exception
+ sessionStorage.removeItem("key2"); // Just check there is no exception
+
+ SimpleTest.executeSoon(function () {
+ SpecialPowers.removeChromeEventListener("MozSessionStorageChanged", onStorageChanged, true);
+ is(expectedEvents.length, 0, "received the correct number of events");
+
+ sessionStorage.clear();
+ SimpleTest.finish();
+ });
+}
+
+SimpleTest.waitForExplicitFinish();
+
+</script>
+
+</head>
+
+<body onload="setup();">
+
+</body>
+</html>
diff --git a/dom/tests/mochitest/sessionstorage/test_sessionStorageBaseSessionOnly.html b/dom/tests/mochitest/sessionstorage/test_sessionStorageBaseSessionOnly.html
new file mode 100644
index 000000000..38db680ce
--- /dev/null
+++ b/dom/tests/mochitest/sessionstorage/test_sessionStorageBaseSessionOnly.html
@@ -0,0 +1,231 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>sessionStorage basic test, while in sesison only mode</title>
+
+<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+
+<script type="text/javascript">
+
+var testframe;
+function iframeOnload(aValue) {
+ switch (aValue) {
+ case 1:
+ testframe.onload = test1;
+ break;
+ case 2:
+ testframe.onload = test2;
+ break;
+ default:
+ of(false, 'should not be reached');
+ SimpleTest.finish();
+ return;
+ }
+ /* After every permission change, an iframe has to be reloaded,
+ otherwise this test causes failures in b2g (oop) mochitest, because
+ the permission changes don't seem to be always picked up
+ by the code that excercises it */
+ testframe.contentWindow.location.reload();
+}
+
+function startTest() {
+ testframe = document.getElementById('testframe');
+ SpecialPowers.pushPermissions([{'type': 'cookie', 'allow': SpecialPowers.Ci.nsICookiePermission.ACCESS_SESSION, 'context': document}], function() { iframeOnload(1); });
+}
+
+function test1() {
+
+ // Initially check the sessionStorage is empty
+ is(sessionStorage.length, 0, "The storage is empty [1]");
+ is(sessionStorage.key(0), null, "key() should return null for out-of-bounds access");
+ is(sessionStorage.key(-1), null, "key() should return null for out-of-bounds access");
+ is(sessionStorage.key(1), null, "key() should return null for out-of-bounds access");
+ is(sessionStorage.getItem("nonexisting"), null, "Nonexisting item is null (getItem())");
+ is(sessionStorage["nonexisting"], undefined, "Nonexisting item is undefined (array access)");
+ is(sessionStorage.nonexisting, undefined, "Nonexisting item is undefined (property access)");
+ sessionStorage.removeItem("nonexisting"); // Just check there is no exception
+
+ is(typeof sessionStorage.getItem("nonexisting"), "object", "getItem('nonexisting') is object");
+ is(typeof sessionStorage["nonexisting"], "undefined", "['nonexisting'] is undefined");
+ is(typeof sessionStorage.nonexisting, "undefined", "nonexisting is undefined");
+ is(typeof sessionStorage.getItem("nonexisting2"), "object", "getItem('nonexisting2') is object");
+ is(typeof sessionStorage["nonexisting2"], "undefined", "['nonexisting2'] is undefined");
+ is(typeof sessionStorage.nonexisting2, "undefined", "nonexisting2 is undefined");
+
+ // add an empty-value key
+ sessionStorage.setItem("empty", "");
+ is(sessionStorage.getItem("empty"), "", "Empty value (getItem())");
+ is(sessionStorage["empty"], "", "Empty value (array access)");
+ is(sessionStorage.empty, "", "Empty value (property access)");
+ is(typeof sessionStorage.getItem("empty"), "string", "getItem('empty') is string");
+ is(typeof sessionStorage["empty"], "string", "['empty'] is string");
+ is(typeof sessionStorage.empty, "string", "empty is string");
+ sessionStorage.removeItem("empty");
+ is(sessionStorage.length, 0, "The storage has no keys");
+ is(sessionStorage.getItem("empty"), null, "empty item is null (getItem())");
+ is(sessionStorage["empty"], undefined, "empty item is undefined (array access)");
+ is(sessionStorage.empty, undefined, "empty item is undefined (property access)");
+ is(typeof sessionStorage.getItem("empty"), "object", "getItem('empty') is object");
+ is(typeof sessionStorage["empty"], "undefined", "['empty'] is undefined");
+ is(typeof sessionStorage.empty, "undefined", "empty is undefined");
+
+ // add one key, check it is there
+ sessionStorage.setItem("key1", "value1");
+ is(sessionStorage.length, 1, "The storage has one key-value pair");
+ is(sessionStorage.key(0), "key1");
+ is(sessionStorage.key(-1), null, "key() should return null for out-of-bounds access");
+ is(sessionStorage.key(1), null, "key() should return null for out-of-bounds access");
+
+ // check all access method give the correct result
+ // and are of the correct type
+ is(sessionStorage.getItem("key1"), "value1", "getItem('key1') == value1");
+ is(sessionStorage["key1"], "value1", "['key1'] == value1");
+ is(sessionStorage.key1, "value1", "key1 == value1");
+
+ is(typeof sessionStorage.getItem("key1"), "string", "getItem('key1') is string");
+ is(typeof sessionStorage["key1"], "string", "['key1'] is string");
+ is(typeof sessionStorage.key1, "string", "key1 is string");
+
+ // remove the previously added key and check the storage is empty
+ sessionStorage.removeItem("key1");
+ is(sessionStorage.length, 0, "The storage is empty [2]");
+ is(sessionStorage.key(0), null, "key() should return null for out-of-bounds access");
+ is(sessionStorage.getItem("key1"), null, "\'key1\' removed");
+
+ is(typeof sessionStorage.getItem("key1"), "object", "getItem('key1') is object");
+ is(typeof sessionStorage["key1"], "undefined", "['key1'] is undefined");
+ is(typeof sessionStorage.key1, "undefined", "key1 is undefined");
+
+ // add one key, check it is there
+ sessionStorage.setItem("key1", "value1");
+ is(sessionStorage.length, 1, "The storage has one key-value pair");
+ is(sessionStorage.key(0), "key1");
+ is(sessionStorage.getItem("key1"), "value1");
+
+ // add a second key
+ sessionStorage.setItem("key2", "value2");
+ is(sessionStorage.length, 2, "The storage has two key-value pairs");
+ is(sessionStorage.getItem("key1"), "value1");
+ is(sessionStorage.getItem("key2"), "value2");
+ var firstKey = sessionStorage.key(0);
+ var secondKey = sessionStorage.key(1);
+ ok((firstKey == 'key1' && secondKey == 'key2') ||
+ (firstKey == 'key2' && secondKey == 'key1'),
+ 'key() API works.');
+
+ // change the second key
+ sessionStorage.setItem("key2", "value2-2");
+ is(sessionStorage.length, 2, "The storage has two key-value pairs");
+ is(sessionStorage.key(0), firstKey); // After key value changes the order must be preserved
+ is(sessionStorage.key(1), secondKey);
+ is(sessionStorage.key(-1), null, "key() should return null for out-of-bounds access");
+ is(sessionStorage.key(2), null, "key() should return null for out-of-bounds access");
+ is(sessionStorage.getItem("key1"), "value1");
+ is(sessionStorage.getItem("key2"), "value2-2");
+
+ // change the first key
+ sessionStorage.setItem("key1", "value1-2");
+ is(sessionStorage.length, 2, "The storage has two key-value pairs");
+ is(sessionStorage.key(0), firstKey); // After key value changes the order must be preserved
+ is(sessionStorage.key(1), secondKey);
+ is(sessionStorage.key(-1), null, "key() should return null for out-of-bounds access");
+ is(sessionStorage.key(2), null, "key() should return null for out-of-bounds access");
+ is(sessionStorage.getItem("key1"), "value1-2");
+ is(sessionStorage.getItem("key2"), "value2-2");
+
+ // remove the second key
+ sessionStorage.removeItem("key2");
+ is(sessionStorage.length, 1, "The storage has one key-value pair");
+ is(sessionStorage.key(0), "key1");
+ is(sessionStorage.key(-1), null, "key() should return null for out-of-bounds access");
+ is(sessionStorage.key(1), null, "key() should return null for out-of-bounds access");
+ is(sessionStorage.getItem("key1"), "value1-2");
+
+ // JS property test
+ sessionStorage.testA = "valueA";
+ is(sessionStorage.testA, "valueA");
+ is(sessionStorage["testA"], "valueA");
+ is(sessionStorage.getItem("testA"), "valueA");
+
+ sessionStorage.testA = "valueA2";
+ is(sessionStorage.testA, "valueA2");
+ is(sessionStorage["testA"], "valueA2");
+ is(sessionStorage.getItem("testA"), "valueA2");
+
+ sessionStorage["testB"] = "valueB";
+ is(sessionStorage.testB, "valueB");
+ is(sessionStorage["testB"], "valueB");
+ is(sessionStorage.getItem("testB"), "valueB");
+
+ sessionStorage["testB"] = "valueB2";
+ is(sessionStorage.testB, "valueB2");
+ is(sessionStorage["testB"], "valueB2");
+ is(sessionStorage.getItem("testB"), "valueB2");
+
+ sessionStorage.setItem("testC", "valueC");
+ is(sessionStorage.testC, "valueC");
+ is(sessionStorage["testC"], "valueC");
+ is(sessionStorage.getItem("testC"), "valueC");
+
+ sessionStorage.setItem("testC", "valueC2");
+ is(sessionStorage.testC, "valueC2");
+ is(sessionStorage["testC"], "valueC2");
+ is(sessionStorage.getItem("testC"), "valueC2");
+
+ sessionStorage.setItem("testC", null);
+ is("testC" in sessionStorage, true);
+ is(sessionStorage.getItem("testC"), "null");
+ is(sessionStorage["testC"], "null");
+ is(sessionStorage.testC, "null");
+
+ sessionStorage.removeItem("testC");
+ sessionStorage["testC"] = null;
+ is("testC" in sessionStorage, true);
+ is(sessionStorage.getItem("testC"), "null");
+ is(sessionStorage["testC"], "null");
+ is(sessionStorage.testC, "null");
+
+ sessionStorage.setItem(null, "test");
+ is("null" in sessionStorage, true);
+ is(sessionStorage.getItem("null"), "test");
+ is(sessionStorage.getItem(null), "test");
+ is(sessionStorage["null"], "test");
+ sessionStorage.removeItem(null, "test");
+ is("null" in sessionStorage, false);
+
+ sessionStorage.setItem(null, "test");
+ is("null" in sessionStorage, true);
+ sessionStorage.removeItem("null", "test");
+ is("null" in sessionStorage, false);
+
+ // Clear the storage
+ sessionStorage.clear();
+ is(sessionStorage.length, 0, "The storage is empty [3]");
+ is(sessionStorage.key(0), null, "key() should return null for out-of-bounds access");
+ is(sessionStorage.key(-1), null, "key() should return null for out-of-bounds access");
+ is(sessionStorage.key(1), null, "key() should return null for out-of-bounds access");
+ is(sessionStorage.getItem("nonexisting"), null, "Nonexisting item is null");
+ is(sessionStorage.getItem("key1"), null, "key1 removed");
+ is(sessionStorage.getItem("key2"), null, "key2 removed");
+ sessionStorage.removeItem("nonexisting"); // Just check there is no exception
+ sessionStorage.removeItem("key1"); // Just check there is no exception
+ sessionStorage.removeItem("key2"); // Just check there is no exception
+
+ SpecialPowers.pushPermissions([{'type': 'cookie', 'allow': SpecialPowers.Ci.nsICookiePermission.ACCESS_DEFAULT, 'context': document}], function() { iframeOnload(2); });
+}
+
+function test2() {
+ sessionStorage.clear();
+ SimpleTest.finish();
+}
+
+SimpleTest.waitForExplicitFinish();
+
+</script>
+
+</head>
+
+<body onload="startTest();">
+<iframe id="testframe" src="data:text/html;charset=utf-8,"></iframe>
+</body>
+</html>
diff --git a/dom/tests/mochitest/sessionstorage/test_sessionStorageClone.html b/dom/tests/mochitest/sessionstorage/test_sessionStorageClone.html
new file mode 100644
index 000000000..68370867e
--- /dev/null
+++ b/dom/tests/mochitest/sessionstorage/test_sessionStorageClone.html
@@ -0,0 +1,94 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>sessionStorage clone equal origins</title>
+
+<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+<script type="text/javascript" src="interOriginTest.js"></script>
+<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+
+<script type="text/javascript">
+
+var currentTest = 1;
+var currentStep = 1;
+
+/*
+window.addEventListener("storage", onStorageEvent, false);
+
+function onStorageEvent(event)
+{
+}
+*/
+
+function doNextTest()
+{
+ // We must perform the first step of the test
+ // to prepare the land.
+ currentStep = 1;
+ doStep();
+
+ switch (currentTest)
+ {
+ case 1:
+ // Open a window from the same origin and check data
+ // are copied but not further modified on our side
+ slaveOrigin = "http://mochi.test:8888";
+ slave = window.open(slaveOrigin + slavePath + "frameEqual.html");
+ break;
+
+ case 2:
+ slave.close();
+ // Open a window from a different origin and check data
+ // are NOT copied and not modified on our side
+ slaveOrigin = "http://example.com";
+ slave = window.open(slaveOrigin + slavePath + "frameNotEqual.html");
+ break;
+
+ case 3:
+ slave.close();
+ sessionStorage.clear();
+ SimpleTest.finish();
+ break;
+ }
+
+ ++currentTest;
+}
+
+function doStep()
+{
+ switch (currentStep)
+ {
+ case 1:
+ sessionStorage.setItem("A", "1");
+ sessionStorage.setItem("B", "2");
+ is(sessionStorage.getItem("A"), "1", "A is 1 in the master");
+ is(sessionStorage.getItem("B"), "2", "B is 2 in the master");
+ is(sessionStorage.length, 2, "Num of items is 2");
+ break;
+
+ case 3:
+ is(sessionStorage.getItem("A"), "1", "A is 1 in the master");
+ is(sessionStorage.getItem("B"), "2", "B is 2 in the master");
+ is(sessionStorage.getItem("C"), null, "C is null in the master");
+ is(sessionStorage.length, 2, "Num of items is 2");
+
+ sessionStorage.setItem("C", "4");
+ is(sessionStorage.getItem("C"), "4", "C is 4 in the master");
+ is(sessionStorage.length, 3, "Num of items is 3");
+ break;
+ }
+
+ ++currentStep;
+ ++currentStep;
+
+ return true;
+}
+
+SimpleTest.waitForExplicitFinish();
+
+</script>
+
+</head>
+
+<body onload="doNextTest();">
+</body>
+</html>
diff --git a/dom/tests/mochitest/sessionstorage/test_sessionStorageFromChrome.xhtml b/dom/tests/mochitest/sessionstorage/test_sessionStorageFromChrome.xhtml
new file mode 100644
index 000000000..79a5a9280
--- /dev/null
+++ b/dom/tests/mochitest/sessionstorage/test_sessionStorageFromChrome.xhtml
@@ -0,0 +1,34 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>sessionStorage basic test</title>
+
+<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+<script type="text/javascript">
+
+function startTest()
+{
+ // Check that we do not crash when we access the sessionStorage object from
+ // chrome and that we throw. See bug 404453.
+ var exceptionCaught = false;
+ try {
+ sessionStorage;
+ }
+ catch (e) {
+ is(e.result, Components.results.NS_ERROR_NOT_AVAILABLE,
+ "Testing that we get the expected exception.");
+ exceptionCaught = true;
+ }
+ is(exceptionCaught, true, "Testing that an exception was thrown.");
+
+ SimpleTest.finish();
+}
+
+</script>
+
+</head>
+
+<body onload="startTest();">
+</body>
+</html>
diff --git a/dom/tests/mochitest/sessionstorage/test_sessionStorageHttpHttps.html b/dom/tests/mochitest/sessionstorage/test_sessionStorageHttpHttps.html
new file mode 100644
index 000000000..e145ee16b
--- /dev/null
+++ b/dom/tests/mochitest/sessionstorage/test_sessionStorageHttpHttps.html
@@ -0,0 +1,59 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>sessionStorage replace test</title>
+
+<!--
+ This test checks that sessionStorage values set in an https page
+ are not readable from a non-https page from the same domain.
+-->
+
+<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+
+<script type="text/javascript">
+
+window.addEventListener("message", onMessageReceived, false);
+
+var messages = [];
+
+function onMessageReceived(event)
+{
+ if (event.data == "the end") {
+ is(messages.length, 4, "Wrong number of messages.");
+ is(messages[0], "insecure", "Wrong message from insecure page");
+ is(messages[1], "secure", "Wrong message from secure page");
+ is(messages[2], "insecure", "Wrong second message from insecure page");
+ is(messages[3], null, "Insecure page got secure message?");
+
+ SimpleTest.finish();
+
+ return;
+ }
+
+ messages.push(event.data);
+
+ if (event.data == "insecure" && messages.length == 1) {
+ window.httpsframe.location = "https://test1.example.com/tests/dom/tests/mochitest/sessionstorage/file_https.html";
+ }
+
+ if (event.data == "secure") {
+ window.httpframe.postMessage("check", "http://test1.example.com");
+ }
+}
+
+function startTest()
+{
+ window.httpframe.location = "http://test1.example.com/tests/dom/tests/mochitest/sessionstorage/file_http.html";
+}
+
+SimpleTest.waitForExplicitFinish();
+
+</script>
+
+</head>
+
+<body onload="startTest();">
+ <iframe src="" name="httpframe"></iframe>
+ <iframe src="" name="httpsframe"></iframe>
+</body>
+</html>
diff --git a/dom/tests/mochitest/sessionstorage/test_sessionStorageReplace.html b/dom/tests/mochitest/sessionstorage/test_sessionStorageReplace.html
new file mode 100644
index 000000000..007188a2e
--- /dev/null
+++ b/dom/tests/mochitest/sessionstorage/test_sessionStorageReplace.html
@@ -0,0 +1,78 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>sessionStorage replace test</title>
+
+<!--
+ This test checks that sessionStorage object doesn't leak
+ in a window that changes its location. We do this by switching
+ frame location inside of this window and then by changing location
+ of a top level window.
+-->
+
+<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+
+<script type="text/javascript">
+
+var shell;
+var shellType;
+var failureRegExp = new RegExp("^FAILURE");
+
+window.addEventListener("message", onMessageReceived, false);
+
+function onMessageReceived(event)
+{
+ //alert("onMessageReceived "+event.data);
+ switch (event.data)
+ {
+ case "init_done":
+ // This is frame with different origin in the same browsing context
+ // as the first frame adding data to sessionStorage of the first origin.
+ shell.location = "http://example.com/tests/dom/tests/mochitest/sessionstorage/frameReplace.html?check&" + shellType;
+ break;
+
+ case "check_done":
+ // Recheck and clean the sessionStorage of the first origin.
+ shell.location = "http://example.org:80/tests/dom/tests/mochitest/sessionstorage/frameReplace.html?clean&" + shellType;
+ break;
+
+ case "clean_done":
+ switch (shellType)
+ {
+ case "frame":
+ // We finished testing in a frame
+ // proceed with test in a separate window
+ shellType = "window";
+ shell = window.open("http://example.org/tests/dom/tests/mochitest/sessionstorage/frameReplace.html?init&" + shellType);
+ break;
+
+ case "window":
+ shell.close();
+ window.setTimeout(function() {SimpleTest.finish();}, 0);
+ break;
+ }
+ break;
+
+ default:
+ SimpleTest.ok(!event.data.match(failureRegExp), event.data);
+ break;
+ }
+}
+
+function startTest()
+{
+ shellType = "frame";
+ shell = frame;
+ shell.location = "http://example.org/tests/dom/tests/mochitest/sessionstorage/frameReplace.html?init&" + shellType;
+}
+
+SimpleTest.waitForExplicitFinish();
+
+</script>
+
+</head>
+
+<body onload="startTest();">
+ <iframe src="" name="frame"></iframe>
+</body>
+</html>