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.toml3
-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.html49
-rw-r--r--dom/tests/mochitest/sessionstorage/frameReplace.html75
-rw-r--r--dom/tests/mochitest/sessionstorage/interOriginSlave.js40
-rw-r--r--dom/tests/mochitest/sessionstorage/interOriginTest.js43
-rw-r--r--dom/tests/mochitest/sessionstorage/mochitest.toml47
-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.html112
-rw-r--r--dom/tests/mochitest/sessionstorage/test_sessionStorageClone_alwaysPartitioned.html110
-rw-r--r--dom/tests/mochitest/sessionstorage/test_sessionStorageClone_alwaysPartitioned_exempted.html110
-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
-rw-r--r--dom/tests/mochitest/sessionstorage/test_sessionStorageUsage.html53
18 files changed, 1326 insertions, 0 deletions
diff --git a/dom/tests/mochitest/sessionstorage/chrome.toml b/dom/tests/mochitest/sessionstorage/chrome.toml
new file mode 100644
index 0000000000..d08aa43973
--- /dev/null
+++ b/dom/tests/mochitest/sessionstorage/chrome.toml
@@ -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 0000000000..7825f60c51
--- /dev/null
+++ b/dom/tests/mochitest/sessionstorage/file_http.html
@@ -0,0 +1,40 @@
+<html>
+<head>
+<script>
+
+window.addEventListener("message", onMessageReceived);
+
+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 0000000000..915c54950e
--- /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 0000000000..787f3ee3eb
--- /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 0000000000..bdda1baf70
--- /dev/null
+++ b/dom/tests/mochitest/sessionstorage/frameNotEqual.html
@@ -0,0 +1,49 @@
+<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 aps = document.location.hash.includes("aps");
+var xorigin = document.location.hash.includes("xorigin");
+var sameOrigin = document.location.origin === "http://mochi.test:8888";
+
+var currentStep = 2;
+
+function doStep()
+{
+ var expect = (!xorigin && aps && sameOrigin) ? 2 : 0;
+ switch (currentStep)
+ {
+ case 2:
+ is(sessionStorage.length, expect, `Num of items is ${expect}`);
+
+ sessionStorage.setItem("C", "3");
+
+ is(sessionStorage.getItem("C"), "3", "C is 3 in the slave");
+ is(sessionStorage.length, expect + 1, `Num of items is ${expect + 1}`);
+ break;
+
+ case 4:
+ is(sessionStorage.getItem("C"), "3", "C is 3 in the slave");
+ is(sessionStorage.length, expect + 1, `Num of items is ${expect + 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 0000000000..bf5579c718
--- /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 0000000000..c4d4231542
--- /dev/null
+++ b/dom/tests/mochitest/sessionstorage/interOriginSlave.js
@@ -0,0 +1,40 @@
+function postMsg(message) {
+ opener.postMessage(message, "http://mochi.test:8888");
+}
+
+window.addEventListener("message", onMessageReceived);
+
+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 0000000000..4d2654e5dc
--- /dev/null
+++ b/dom/tests/mochitest/sessionstorage/interOriginTest.js
@@ -0,0 +1,43 @@
+var slaveLoadsPending = 1;
+
+var slaveOrigin = "";
+var slave = null;
+
+var failureRegExp = new RegExp("^FAILURE");
+const slavePath = "/tests/dom/tests/mochitest/sessionstorage/";
+
+window.addEventListener("message", onMessageReceived);
+
+function onMessageReceived(event) {
+ //alert("master got event: "+event.data);
+ switch (event.data) {
+ // Indication of the frame onload event
+ case "frame loaded":
+ if (--slaveLoadsPending) {
+ break;
+ }
+
+ // Indication of successfully finished step of a test
+ // Just fall through...
+ 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.toml b/dom/tests/mochitest/sessionstorage/mochitest.toml
new file mode 100644
index 0000000000..b30ef73aa7
--- /dev/null
+++ b/dom/tests/mochitest/sessionstorage/mochitest.toml
@@ -0,0 +1,47 @@
+[DEFAULT]
+support-files = [
+ "file_http.html",
+ "file_https.html",
+ "frameEqual.html",
+ "frameNotEqual.html",
+ "frameReplace.html",
+ "interOriginSlave.js",
+ "interOriginTest.js",
+]
+
+["test_sessionStorageBase.html"]
+
+["test_sessionStorageBaseSessionOnly.html"]
+
+["test_sessionStorageClone.html"]
+skip-if = [
+ "http3",
+ "http2",
+]
+
+["test_sessionStorageClone_alwaysPartitioned.html"]
+skip-if = [
+ "http3",
+ "http2",
+ "os == 'android' && xorigin", # bug 1855525
+]
+
+["test_sessionStorageClone_alwaysPartitioned_exempted.html"]
+skip-if = [
+ "http3",
+ "http2",
+]
+
+["test_sessionStorageHttpHttps.html"]
+skip-if = [
+ "http3",
+ "http2",
+]
+
+["test_sessionStorageReplace.html"]
+skip-if = [
+ "http3",
+ "http2",
+]
+
+["test_sessionStorageUsage.html"]
diff --git a/dom/tests/mochitest/sessionstorage/test_sessionStorageBase.html b/dom/tests/mochitest/sessionstorage/test_sessionStorageBase.html
new file mode 100644
index 0000000000..e7538127fe
--- /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 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, "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 0000000000..34169decc4
--- /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 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" srcdoc="<meta 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 0000000000..e0045480b2
--- /dev/null
+++ b/dom/tests/mochitest/sessionstorage/test_sessionStorageClone.html
@@ -0,0 +1,112 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>sessionStorage clone equal origins</title>
+
+<script 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)
+{
+}
+*/
+
+async function doNextTest()
+{
+ // Bug 1746646: Make mochitests work with TCP enabled (cookieBehavior = 5)
+ // Acquire storage access permission here so that the sessionStorage object is
+ // shared between this window and the slave in xorigin tests. Without this,
+ // our storage would be isolated as a xorigin iframe.
+ if (isXOrigin) {
+ SpecialPowers.wrap(document).notifyUserGestureActivation();
+ await SpecialPowers.addPermission(
+ "storageAccessAPI",
+ true,
+ window.location.href
+ );
+ await SpecialPowers.wrap(document).requestStorageAccess();
+ }
+
+ await SpecialPowers.pushPrefEnv({
+ set: [["privacy.partition.always_partition_third_party_non_cookie_storage", false]],
+ });
+
+ // 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 = "https://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_sessionStorageClone_alwaysPartitioned.html b/dom/tests/mochitest/sessionstorage/test_sessionStorageClone_alwaysPartitioned.html
new file mode 100644
index 0000000000..384faf2044
--- /dev/null
+++ b/dom/tests/mochitest/sessionstorage/test_sessionStorageClone_alwaysPartitioned.html
@@ -0,0 +1,110 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>sessionStorage clone equal origins</title>
+
+<script 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;
+
+async function doNextTest()
+{
+ // Bug 1746646: Make mochitests work with TCP enabled (cookieBehavior = 5)
+ // Acquire storage access permission here so that the sessionStorage object is
+ // shared between this window and the slave in xorigin tests. Without this,
+ // our storage would be isolated as a xorigin iframe.
+ if (isXOrigin) {
+ SpecialPowers.wrap(document).notifyUserGestureActivation();
+ await SpecialPowers.addPermission(
+ "storageAccessAPI",
+ true,
+ window.location.href
+ );
+ await SpecialPowers.wrap(document).requestStorageAccess();
+ }
+
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ ["privacy.partition.always_partition_third_party_non_cookie_storage", true],
+ ["privacy.partition.always_partition_third_party_non_cookie_storage.exempt_sessionstorage", false]
+ ],
+ });
+
+ // We must perform the first step of the test
+ // to prepare the land.
+ currentStep = 1;
+ doStep();
+
+ let hash = "#aps";
+ if (isXOrigin) hash += "xorigin";
+
+ 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 + "frameNotEqual.html" + hash);
+ 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 = "https://example.com";
+ slave = window.open(slaveOrigin + slavePath + "frameNotEqual.html" + hash);
+ 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_sessionStorageClone_alwaysPartitioned_exempted.html b/dom/tests/mochitest/sessionstorage/test_sessionStorageClone_alwaysPartitioned_exempted.html
new file mode 100644
index 0000000000..3f9e3b331f
--- /dev/null
+++ b/dom/tests/mochitest/sessionstorage/test_sessionStorageClone_alwaysPartitioned_exempted.html
@@ -0,0 +1,110 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>sessionStorage clone equal origins</title>
+
+<script 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;
+
+async function doNextTest()
+{
+ // Bug 1746646: Make mochitests work with TCP enabled (cookieBehavior = 5)
+ // Acquire storage access permission here so that the sessionStorage object is
+ // shared between this window and the slave in xorigin tests. Without this,
+ // our storage would be isolated as a xorigin iframe.
+ if (isXOrigin) {
+ SpecialPowers.wrap(document).notifyUserGestureActivation();
+ await SpecialPowers.addPermission(
+ "storageAccessAPI",
+ true,
+ window.location.href
+ );
+ await SpecialPowers.wrap(document).requestStorageAccess();
+ }
+
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ ["privacy.partition.always_partition_third_party_non_cookie_storage", true],
+ ["privacy.partition.always_partition_third_party_non_cookie_storage.exempt_sessionstorage", true]
+ ],
+ });
+
+ // We must perform the first step of the test
+ // to prepare the land.
+ currentStep = 1;
+ doStep();
+
+ let hash = "#";
+ if (isXOrigin) hash += "xorigin";
+
+ 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" + hash);
+ 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 = "https://example.com";
+ slave = window.open(slaveOrigin + slavePath + "frameNotEqual.html" + hash);
+ 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 0000000000..1a95a8c91f
--- /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 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, Cr.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 0000000000..e8fbfcca03
--- /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 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);
+
+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 0000000000..9993d8f789
--- /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 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);
+
+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>
diff --git a/dom/tests/mochitest/sessionstorage/test_sessionStorageUsage.html b/dom/tests/mochitest/sessionstorage/test_sessionStorageUsage.html
new file mode 100644
index 0000000000..db894c9780
--- /dev/null
+++ b/dom/tests/mochitest/sessionstorage/test_sessionStorageUsage.html
@@ -0,0 +1,53 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>sessionStorage basic test</title>
+
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+
+<script type="text/javascript">
+
+function setup() {
+ sessionStorage.clear();
+ SimpleTest.executeSoon(startTest);
+}
+
+function startTest()
+{
+ var util = SpecialPowers.getDOMWindowUtils(window);
+
+ // Check initial state.
+ is(sessionStorage.length, 0, "storage is empty");
+ is(util.getStorageUsage(sessionStorage), 0, "usage is zero");
+
+ // Add some data.
+ sessionStorage.setItem("one", "data");
+ var usage = util.getStorageUsage(sessionStorage);
+ ok(usage > 0, "storage contains data");
+
+ // Add some more data.
+ sessionStorage.setItem("two", "data");
+ ok(usage < util.getStorageUsage(sessionStorage), "storage size grew");
+
+ // Remove data.
+ sessionStorage.removeItem("two");
+ is(util.getStorageUsage(sessionStorage), usage, "storage size shrunk");
+
+ // Cleanup.
+ sessionStorage.clear();
+ is(sessionStorage.length, 0, "storage is empty");
+ is(util.getStorageUsage(sessionStorage), 0, "usage is zero");
+
+ SimpleTest.finish();
+}
+
+SimpleTest.waitForExplicitFinish();
+
+</script>
+
+</head>
+
+<body onload="setup();">
+
+</body>
+</html>