diff options
Diffstat (limited to 'dom/tests/mochitest/localstorage')
47 files changed, 3377 insertions, 0 deletions
diff --git a/dom/tests/mochitest/localstorage/chrome.ini b/dom/tests/mochitest/localstorage/chrome.ini new file mode 100644 index 000000000..6cc5562c0 --- /dev/null +++ b/dom/tests/mochitest/localstorage/chrome.ini @@ -0,0 +1,11 @@ +[DEFAULT] +skip-if = os == 'android' +support-files = + page_blank.html + frameQuota.html + interOriginFrame.js + +[test_localStorageBasePrivateBrowsing_perwindowpb.html] +skip-if = true # bug 1156725 +[test_localStorageFromChrome.xhtml] +[test_localStorageQuotaPrivateBrowsing_perwindowpb.html] diff --git a/dom/tests/mochitest/localstorage/frameChromeSlave.html b/dom/tests/mochitest/localstorage/frameChromeSlave.html new file mode 100644 index 000000000..fd87702e9 --- /dev/null +++ b/dom/tests/mochitest/localstorage/frameChromeSlave.html @@ -0,0 +1,9 @@ +<html> +<head> +<body> + <span id="data"></span> + <script> + var span = document.getElementById("data"); + span.innerHTML = localStorage.chromekey + </script> +</body> diff --git a/dom/tests/mochitest/localstorage/frameKeySync.html b/dom/tests/mochitest/localstorage/frameKeySync.html new file mode 100644 index 000000000..4bc4794e6 --- /dev/null +++ b/dom/tests/mochitest/localstorage/frameKeySync.html @@ -0,0 +1,51 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>frame for localStorage test</title> + +<script type="text/javascript" src="interOriginFrame.js"></script> +<script type="text/javascript"> + +var currentStep = parseInt(location.search.substring(1)); + +function doStep() +{ + switch (currentStep) + { + case 1: + localStorage.clear(); + break; + + case 2: + localStorage.setItem("a", "1"); + is(localStorage["a"], "1", "Value a=1 set"); + break; + + case 3: + try { + is(localStorage.key(0), "a", "Key 'a' present in 'key' array") + } + catch (exc) { + ok(false, "Shouldn't throw when accessing key(0) " + exc); + } + is(localStorage["a"], "1", "Value a=1 set"); + break; + + default: + return finishTest(); + } + + // Increase by two to as odd number are executed in a window separate from + // where even step are. + ++currentStep; + ++currentStep; + + return true; +} + +</script> + +</head> + +<body onload="postMsg('frame loaded');"> +</body> +</html> diff --git a/dom/tests/mochitest/localstorage/frameLocalStorageCookieSettings.html b/dom/tests/mochitest/localstorage/frameLocalStorageCookieSettings.html new file mode 100644 index 000000000..de42e6bb9 --- /dev/null +++ b/dom/tests/mochitest/localstorage/frameLocalStorageCookieSettings.html @@ -0,0 +1,20 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>localStorage cookies settings test</title> + +<script type="text/javascript" src="interOriginFrame.js"></script> + +</head> +<body> +<script type="text/javascript"> + try { + localStorage.setItem("contentkey", "test-value"); + ok(false, "Setting localStorageItem should throw a security exception"); + } catch(ex) { + is(ex.name, "SecurityError"); + } + + finishTest(); +</script> +</body> +</html> diff --git a/dom/tests/mochitest/localstorage/frameLocalStorageSessionOnly.html b/dom/tests/mochitest/localstorage/frameLocalStorageSessionOnly.html new file mode 100644 index 000000000..f6c7f0291 --- /dev/null +++ b/dom/tests/mochitest/localstorage/frameLocalStorageSessionOnly.html @@ -0,0 +1,8 @@ +<!doctype html> +<html> + <body> + <script> + parent.postMessage(SpecialPowers.wrap(localStorage).isSessionOnly, "*"); + </script> + </body> +</html> diff --git a/dom/tests/mochitest/localstorage/frameMasterEqual.html b/dom/tests/mochitest/localstorage/frameMasterEqual.html new file mode 100644 index 000000000..4d83c4fef --- /dev/null +++ b/dom/tests/mochitest/localstorage/frameMasterEqual.html @@ -0,0 +1,56 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>frame for localStorage test</title> + +<script type="text/javascript" src="interOriginFrame.js"></script> +<script type="text/javascript"> + +var currentStep = 1; + +function doStep() +{ + switch (currentStep) + { + case 1: + localStorage.setItem("X", "1"); + is(localStorage.getItem("X"), "1", "X is 1 in the master"); + break; + + case 3: + is(localStorage.getItem("X"), "2", "X set to 2 in the master"); + localStorage.removeItem("X"); + is(localStorage.getItem("X"), null, "X was removed from the master"); + break; + + case 5: + is(localStorage.getItem("Y"), "3", "Y is 3 in the master"); + localStorage.setItem("Z", "4"); + is(localStorage.getItem("Z"), "4", "Z is 4 in the master"); + + localStorage.clear(); + is(localStorage.length, 0, "Master is empty"); + break; + + case 7: + is(localStorage.length, 0, "Master is empty"); + break; + + case 9: + return finishTest(); + } + + // Increase by two to distinguish each test step order + // in both master doStep and slave doStep functions. + ++currentStep; + ++currentStep; + + return true; +} + +</script> + +</head> + +<body onload="postMsg('frame loaded');"> +</body> +</html> diff --git a/dom/tests/mochitest/localstorage/frameMasterNotEqual.html b/dom/tests/mochitest/localstorage/frameMasterNotEqual.html new file mode 100644 index 000000000..fef476bed --- /dev/null +++ b/dom/tests/mochitest/localstorage/frameMasterNotEqual.html @@ -0,0 +1,47 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>frame for localStorage test</title> + +<script type="text/javascript" src="interOriginFrame.js"></script> +<script type="text/javascript"> + +var currentStep = 1; + +function doStep() +{ + switch (currentStep) + { + case 1: + localStorage.setItem("X", "1"); + is(localStorage.getItem("X"), "1", "X is 1 in the master"); + break; + + case 3: + is(localStorage.getItem("X"), "1", "X remains 1 in the master"); + localStorage.removeItem("X"); + is(localStorage.getItem("X"), null, "X was removed from the master"); + break; + + case 5: + is(localStorage.getItem("Y"), null, "Y null in the master"); + break; + + case 7: + return finishTest(); + } + + // Increase by two to distinguish each test step order + // in both master doStep and slave doStep functions. + ++currentStep; + ++currentStep; + + return true; +} + +</script> + +</head> + +<body onload="postMsg('frame loaded');"> +</body> +</html> diff --git a/dom/tests/mochitest/localstorage/frameOrder.html b/dom/tests/mochitest/localstorage/frameOrder.html new file mode 100644 index 000000000..3b3f0ebef --- /dev/null +++ b/dom/tests/mochitest/localstorage/frameOrder.html @@ -0,0 +1,27 @@ +<html> +<head> +</head> +<script type="text/javascript"> +function doTest() +{ + var query = location.search.substring(1); + query = unescape(query); + var keyNames = eval(query); + + parent.is(localStorage.a, "10", "a = 10"); + parent.is(localStorage.b, "20", "b = 20"); + parent.is(localStorage.c, "30", "c = 30"); + parent.is(localStorage.d, "40", "d = 40"); + parent.is(localStorage.e, "50", "e = 50"); + parent.is(localStorage.length, 5, "length = 5"); + + for (var i = 0; i < localStorage.length; ++i) + parent.is(keyNames[i], localStorage.key(i), "key "+keyNames[i]+" on same index"); + + parent.SimpleTest.finish(); + localStorage.clear(); +} +</script> +<body onload="doTest();"> +</body> +</html> diff --git a/dom/tests/mochitest/localstorage/frameQuota.html b/dom/tests/mochitest/localstorage/frameQuota.html new file mode 100644 index 000000000..d3e32ad71 --- /dev/null +++ b/dom/tests/mochitest/localstorage/frameQuota.html @@ -0,0 +1,105 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>slave for sessionStorage test</title> + +<script type="text/javascript" src="interOriginFrame.js"></script> +<script type="text/javascript"> + +const DOM_QUOTA_REACHED = 2152924150; + +function checkException(func, exc) +{ + var exceptionThrew = false; + try { + func(); + } + catch (ex) { + exceptionThrew = true; + is(ex.result, exc, "Expected "+exc+" exception"); + } + ok(exceptionThrew, "Exception "+exc+" threw at "+location); +} + +function doStep() +{ + var query = location.search.substring(1); + var queries = query.split("&"); + + var operation = queries[0]; + var keyName = queries[1]; + var result = queries[2]; + + switch (result) + { + case "success": + switch (operation) + { + case "add": + // Store 500 bytes long string must succeed + localStorage.setItem(keyName, "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"); + is(localStorage.getItem(keyName), "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", "500 bytes key "+keyName+" stored"); + break; + + case "remove": + localStorage.removeItem(keyName); + is(localStorage.getItem(keyName), null, "Key "+keyName+" removed"); + break; + + case "checkclean": + is(localStorage.getItem(keyName), null, "Key "+keyName+" not present"); + break; + + case "checknotclean": + is(localStorage.getItem(keyName), "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", "Key "+keyName+" is present"); + break; + } + + break; + + case "failure": + switch (operation) + { + case "add": + // Attempt to store 500 bytes long string that doens't + // fit the quota, have to throw DOM_QUOTA_REACHED exception + checkException(function() { + localStorage.setItem(keyName, "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"); + }, DOM_QUOTA_REACHED); + is(localStorage.getItem(keyName), null, "500 bytes key "+keyName+" is NOT stored"); + break; + + case "add2": + // Attempt to change a key value to reach the DOM quota and + // check it fails and the old key value is still present. + checkException(function() { + localStorage.setItem(keyName, "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"); + }, DOM_QUOTA_REACHED); + is(localStorage.getItem(keyName), "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", "Key "+keyName+" left unchanged"); + break; + } + + break; + + default: + switch (operation) + { + case "clear": + localStorage.clear(); + break; + } + + break; + } + + // Just inform the master we are finished now + postMsg("done"); + return false; +} + +</script> + +</head> + +<body onload="postMsg('frame loaded');"> +</body> +</html> diff --git a/dom/tests/mochitest/localstorage/frameQuotaSessionOnly.html b/dom/tests/mochitest/localstorage/frameQuotaSessionOnly.html new file mode 100644 index 000000000..a6f69b176 --- /dev/null +++ b/dom/tests/mochitest/localstorage/frameQuotaSessionOnly.html @@ -0,0 +1,111 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>slave for sessionStorage test</title> + +<script type="text/javascript" src="interOriginFrame.js"></script> +<script type="text/javascript"> + +const DOM_QUOTA_REACHED = 2152924150; + +function checkException(func, exc) +{ + var exceptionThrew = false; + try { + func(); + } + catch (ex) { + exceptionThrew = true; + is(ex.result, exc, "Expected "+exc+" exception"); + } + ok(exceptionThrew, "Exception "+exc+" threw at "+location); +} + +function doStep() +{ + var query = location.search.substring(1); + var queries = query.split("&"); + + var operation = queries[0]; + var keyName = queries[1]; + var result = queries[2]; + + switch (result) + { + case "success": + switch (operation) + { + case "add": + // Store 500 bytes long string must succeed + localStorage.setItem(keyName, "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"); + is(localStorage.getItem(keyName), "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", "500 bytes key "+keyName+" stored"); + break; + + case "remove": + localStorage.removeItem(keyName); + is(localStorage.getItem(keyName), null, "Key "+keyName+" removed"); + break; + + case "checkclean": + is(localStorage.getItem(keyName), null, "Key "+keyName+" not present"); + break; + + case "checknotclean": + is(localStorage.getItem(keyName), "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", "Key "+keyName+" is present"); + break; + } + + break; + + case "failure": + switch (operation) + { + case "add": + // Attempt to store 500 bytes long string that doens't + // fit the quota, have to throw DOM_QUOTA_REACHED exception + checkException(function() { + localStorage.setItem(keyName, "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"); + }, DOM_QUOTA_REACHED); + is(localStorage.getItem(keyName), null, "500 bytes key "+keyName+" is NOT stored"); + break; + + case "add2": + // Attempt to change a key value to reach the DOM quota and + // check it fails and the old key value is still present. + checkException(function() { + localStorage.setItem(keyName, "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"); + }, DOM_QUOTA_REACHED); + is(localStorage.getItem(keyName), "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", "Key "+keyName+" left unchanged"); + break; + } + + break; + + case "": + default: + switch (operation) + { + case "clear": + localStorage.clear(); + break; + } + + break; + } + + // Just inform the master we are finished now + postMsg("done"); + return false; +} + +function startTest() { + SpecialPowers.pushPermissions([{'type': 'cookie', 'allow': SpecialPowers.Ci.nsICookiePermission.ACCESS_SESSION, 'context': document}], function() { + postMsg('frame loaded'); + }); +} +</script> + +</head> + +<body onload="startTest();"> +</body> +</html> diff --git a/dom/tests/mochitest/localstorage/frameReplace.html b/dom/tests/mochitest/localstorage/frameReplace.html new file mode 100644 index 000000000..145bfe8fc --- /dev/null +++ b/dom/tests/mochitest/localstorage/frameReplace.html @@ -0,0 +1,72 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>localStorage 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": + localStorage.setItem("A", "1"); + localStorage.setItem("B", "2"); + localStorage.setItem("C", "3"); + is(localStorage.getItem("A"), "1", "'A' is '1'"); + is(localStorage.getItem("B"), "2", "'A' is '2'"); + is(localStorage.getItem("C"), "3", "'A' is '3'"); + break; + + case "check": + is(localStorage.getItem("A"), null, "'A' is null"); + is(localStorage.getItem("B"), null, "'A' is null"); + is(localStorage.getItem("C"), null, "'A' is null"); + break; + + case "clean": + localStorage.clear(); + break; + } + + shell.postMessage(action + "_done", "http://mochi.test:8888"); +} + +</script> + +</head> +<body onload="doTest();"> +</body> +</html> diff --git a/dom/tests/mochitest/localstorage/frameSlaveEqual.html b/dom/tests/mochitest/localstorage/frameSlaveEqual.html new file mode 100644 index 000000000..b64b8de10 --- /dev/null +++ b/dom/tests/mochitest/localstorage/frameSlaveEqual.html @@ -0,0 +1,51 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>frame for localStorage test</title> + +<script type="text/javascript" src="interOriginFrame.js"></script> +<script type="text/javascript"> + +var currentStep = 2; + +function doStep() +{ + switch (currentStep) + { + case 2: + is(localStorage.getItem("X"), "1", "X is 1 in the slave"); + localStorage.setItem("X", "2"); + is(localStorage.getItem("X"), "2", "X set to 2 in the slave"); + break; + + case 4: + is(localStorage.getItem("X"), null, "X was removed from the slave"); + localStorage.setItem("Y", "3"); + is(localStorage.getItem("Y"), "3", "Y set to 3 in the slave"); + break; + + case 6: + is(localStorage.length, 0, "Slave is empty"); + is(localStorage.getItem("X"), null, "X is null in the slave"); + is(localStorage.getItem("Y"), null, "Y is null in the slave"); + is(localStorage.getItem("Z"), null, "Z is null in the slave"); + break; + + case 8: + return finishTest(); + } + + // Increase by two to distinguish each test step order + // in both master doStep and slave doStep functions. + ++currentStep; + ++currentStep; + + return true; +} + +</script> + +</head> + +<body onload="postMsg('frame loaded');"> +</body> +</html> diff --git a/dom/tests/mochitest/localstorage/frameSlaveNotEqual.html b/dom/tests/mochitest/localstorage/frameSlaveNotEqual.html new file mode 100644 index 000000000..9daf9e9f7 --- /dev/null +++ b/dom/tests/mochitest/localstorage/frameSlaveNotEqual.html @@ -0,0 +1,44 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>frame for localStorage test</title> + +<script type="text/javascript" src="interOriginFrame.js"></script> +<script type="text/javascript"> + +var currentStep = 2; + +function doStep() +{ + switch (currentStep) + { + case 2: + is(localStorage.getItem("X"), null, "X not set in the slave"); + localStorage.setItem("X", "2"); + is(localStorage.getItem("X"), "2", "X set to 2 in the slave"); + break; + + case 4: + is(localStorage.getItem("X"), "2", "X still set to 2 in the slave"); + localStorage.setItem("Y", "3"); + is(localStorage.getItem("Y"), "3", "Y set to 4 (MUST FAIL!) in the slave"); + break; + + case 6: + return finishTest(); + } + + // Increase by two to distinguish each test step order + // in both master doStep and slave doStep functions. + ++currentStep; + ++currentStep; + + return true; +} + +</script> + +</head> + +<body onload="postMsg('frame loaded');"> +</body> +</html> diff --git a/dom/tests/mochitest/localstorage/interOriginFrame.js b/dom/tests/mochitest/localstorage/interOriginFrame.js new file mode 100644 index 000000000..185ef8858 --- /dev/null +++ b/dom/tests/mochitest/localstorage/interOriginFrame.js @@ -0,0 +1,57 @@ +function postMsg(message) +{ + parent.postMessage(message, "http://mochi.test:8888"); +} + +window.addEventListener("message", onMessageReceived, false); + +function onMessageReceived(event) +{ + if (event.data == "step") { + var performed = false; + try { + performed = doStep(); + } + catch (ex) { + postMsg("FAILURE: exception threw at "+ location +":\n" + ex); + finishTest(); + } + + if (performed) + 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 todo(a, b, message) +{ + postMsg("TODO: " + message + ", expected "+b+" got "+a); +} + +function finishTest() +{ + try { + localStorage.clear(); + } catch (e) {} + postMsg("done"); + return false; +} diff --git a/dom/tests/mochitest/localstorage/interOriginTest.js b/dom/tests/mochitest/localstorage/interOriginTest.js new file mode 100644 index 000000000..dcfac783a --- /dev/null +++ b/dom/tests/mochitest/localstorage/interOriginTest.js @@ -0,0 +1,42 @@ +var slaveLoadsPending = 1; + +var slaveOrigin = ""; +var slave = null; + +var failureRegExp = new RegExp("^FAILURE"); +const slavePath = "/tests/dom/tests/mochitest/localstorage/"; + +window.addEventListener("message", onMessageReceived, false); + +function onMessageReceived(event) +{ + 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": + if (event.data == "perf") + doStep(); + + slave.postMessage("step", slaveOrigin); + break; + + // Indication of all test parts finish (from any of the frames) + case "done": + localStorage.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/localstorage/interOriginTest2.js b/dom/tests/mochitest/localstorage/interOriginTest2.js new file mode 100644 index 000000000..e3f3c8771 --- /dev/null +++ b/dom/tests/mochitest/localstorage/interOriginTest2.js @@ -0,0 +1,53 @@ +var t = async_test(document.title); + +var frameLoadsPending = 2; + +var callMasterFrame = true; +var testDone = false; + +var masterFrameOrigin = ""; +var slaveFrameOrigin = ""; + +var failureRegExp = new RegExp("^FAILURE"); + +const framePath = "/tests/dom/tests/mochitest/localstorage/"; + +window.addEventListener("message", onMessageReceived, false); + +function onMessageReceived(event) +{ + switch (event.data) + { + // Indication of the frame onload event + case "frame loaded": + if (--frameLoadsPending) + break; + + // Just fall through... + + // Indication of successfully finished step of a test + case "perf": + if (callMasterFrame) + masterFrame.postMessage("step", masterFrameOrigin); + else + slaveFrame.postMessage("step", slaveFrameOrigin); + callMasterFrame = !callMasterFrame; + break; + + // Indication of all test parts finish (from any of the frames) + case "done": + if (testDone) + break; + + testDone = true; + t.done(); + break; + + // Any other message indicates error, succes or todo message of a test + default: + t.step(function() { + assert_true(!event.data.match(failureRegExp), event.data); + }); + break; + } +} diff --git a/dom/tests/mochitest/localstorage/localStorageCommon.js b/dom/tests/mochitest/localstorage/localStorageCommon.js new file mode 100644 index 000000000..5ca414067 --- /dev/null +++ b/dom/tests/mochitest/localstorage/localStorageCommon.js @@ -0,0 +1,45 @@ +function localStorageFlush(cb) +{ + var ob = { + observe : function(sub, top, dat) + { + os().removeObserver(ob, "domstorage-test-flushed"); + cb(); + } + }; + os().addObserver(ob, "domstorage-test-flushed", false); + notify("domstorage-test-flush-force"); +} + +function localStorageReload() +{ + notify("domstorage-test-reload"); +} + +function localStorageFlushAndReload(cb) +{ + localStorageFlush(function() { + localStorageReload(); + cb(); + }); +} + +function localStorageClearAll() +{ + os().notifyObservers(null, "cookie-changed", "cleared"); +} + +function localStorageClearDomain(domain) +{ + os().notifyObservers(null, "browser:purge-domain-data", domain); +} + +function os() +{ + return SpecialPowers.Services.obs; +} + +function notify(top) +{ + os().notifyObservers(null, top, null); +} diff --git a/dom/tests/mochitest/localstorage/mochitest.ini b/dom/tests/mochitest/localstorage/mochitest.ini new file mode 100644 index 000000000..5242bf9b1 --- /dev/null +++ b/dom/tests/mochitest/localstorage/mochitest.ini @@ -0,0 +1,52 @@ +[DEFAULT] +support-files = + frameChromeSlave.html + frameLocalStorageCookieSettings.html + frameKeySync.html + frameMasterEqual.html + frameMasterNotEqual.html + frameOrder.html + frameQuota.html + frameQuotaSessionOnly.html + frameReplace.html + frameSlaveEqual.html + frameSlaveNotEqual.html + interOriginFrame.js + interOriginTest.js + interOriginTest2.js + localStorageCommon.js + frameLocalStorageSessionOnly.html + +[test_brokenUTF-16.html] +[test_bug600307-DBOps.html] +[test_bug746272-1.html] +[test_bug746272-2.html] +skip-if = os == "android" # bug 962029 +[test_cookieBlock.html] +[test_cookieSession.html] +[test_embededNulls.html] +[test_keySync.html] +[test_localStorageBase.html] +skip-if = e10s +[test_localStorageBaseSessionOnly.html] +[test_localStorageCookieSettings.html] +[test_localStorageEnablePref.html] +[test_localStorageKeyOrder.html] +[test_localStorageOriginsDiff.html] +[test_localStorageOriginsDomainDiffs.html] +[test_localStorageOriginsEquals.html] +skip-if = toolkit == 'android' +[test_localStorageOriginsPortDiffs.html] +[test_localStorageOriginsSchemaDiffs.html] +skip-if = toolkit == 'android' #TIMED_OUT +[test_localStorageQuota.html] +skip-if = toolkit == 'android' #TIMED_OUT +[test_localStorageQuotaSessionOnly.html] +skip-if = toolkit == 'android' #TIMED_OUT +[test_localStorageQuotaSessionOnly2.html] +skip-if = toolkit == 'android' #TIMED_OUT +[test_localStorageReplace.html] +skip-if = toolkit == 'android' +[test_lowDeviceStorage.html] +[test_storageConstructor.html] +[test_localStorageSessionPrefOverride.html] diff --git a/dom/tests/mochitest/localstorage/page_blank.html b/dom/tests/mochitest/localstorage/page_blank.html new file mode 100644 index 000000000..157317d64 --- /dev/null +++ b/dom/tests/mochitest/localstorage/page_blank.html @@ -0,0 +1,6 @@ +<!DOCTYPE html> +<html> +<body> + +</body> +</html> diff --git a/dom/tests/mochitest/localstorage/test_brokenUTF-16.html b/dom/tests/mochitest/localstorage/test_brokenUTF-16.html new file mode 100644 index 000000000..d9648b271 --- /dev/null +++ b/dom/tests/mochitest/localstorage/test_brokenUTF-16.html @@ -0,0 +1,100 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>incomplete UTF-16 test</title> +<meta http-equiv="Content-type" content="text/html; charset=UTF-8" /> + +<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"> + +function startTest() +{ + // Check this works for a diacritics + var k = "valid UTF-16 key"; + var v = "ěščřžýáíéúůĚŠČŘŽÝÁÍÉÚŮ"; + + localStorage.setItem(k, v); + is(localStorage.getItem(k), v, "UTF-16 value results from getItem"); + + localStorage.setItem(v, "a value"); + is(localStorage.getItem(v), "a value", "value result using UTF-16 key from getItem"); + + localStorage.clear(); + + localStorage[k] = v; + is(localStorage[k], v, "UTF-16 value results from []"); + + localStorage[v] = "a value"; + is(localStorage[v], "a value", "value result using UTF-16 key from []"); + + localStorage.clear(); + + localStorage.aKey = v; + is(localStorage.aKey, v, "UTF-16 value results from a dynamic property"); + + localStorage.clear(); + + // Broken UTF-16 + k = "broken UTF-16 key"; + v = "\uD800"; // broken UTF-16 + + localStorage.setItem(k, v); + is(localStorage.getItem(k), v, "broken value results from getItem"); + + localStorage.setItem(v, "a value"); + is(localStorage.getItem(v), "a value", "value result using broken key from getItem"); + + localStorage.clear(); + + localStorage[k] = v; + is(localStorage[k], v, "broken value results from []"); + + localStorage[v] = "a value"; + is(localStorage[v], "a value", "value result using broken key from []"); + + localStorage.clear(); + + localStorage.aKey = v; + is(localStorage.aKey, v, "broken value results from a dynamic property"); + + localStorage.clear(); + + // Another variant + v = "FcK" + + String.fromCharCode(0x8a) + + ".jp"; + + localStorage.setItem(k, v); + is(localStorage.getItem(k), v); + + localStorage.setItem(v, "a value"); + is(localStorage.getItem(v), "a value"); + + localStorage.clear(); + + // And yet another variant + v = "something" + + String.fromCharCode(355, 277, 349, 357, 533, 537, 101, 345); + + localStorage.setItem(k, v); + is(localStorage.getItem(k), v); + + localStorage.setItem(v, "a value"); + is(localStorage.getItem(v), "a value"); + + localStorage.clear(); + + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); + +</script> + +</head> + +<body onload="startTest();"> + +</body> +</html> diff --git a/dom/tests/mochitest/localstorage/test_bug600307-DBOps.html b/dom/tests/mochitest/localstorage/test_bug600307-DBOps.html new file mode 100644 index 000000000..8d539288b --- /dev/null +++ b/dom/tests/mochitest/localstorage/test_bug600307-DBOps.html @@ -0,0 +1,166 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>bug 600307</title> + +<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> +<script type="text/javascript" src="localStorageCommon.js"></script> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + +<script type="text/javascript"> + +/* +This is strictly implementation specific test for dom storage code from bug 600307. +It exercises code for asynchronous data flushing with regard to cache life time and its preload. + +"flush + reload" means to tell the database to store all pending data then wipe the cached content and reload it from the db + +"reload" only means to simulate situation when there is a pending flush for an origin but a new cache is about to preload +which is a corner case happening rarely ; this helps check the next preload operation will load correct data from the database anyway + +Case 1: set | flush + reload | remove | set | remove | flush + reload | get ?= null + checks coalescing optimization for single key changes does work correctly for repeated removals of a key + +Case 2: set | set | clear | flush + reload | count ?= 0 + checks whether clear operation superseeds setting keys, the database must be empty for the origin + +Case 3: set | set | clear | reload | count ?= 0 + check the corner case when a data clear flush is pending but a new cache is about to preload +*/ + +function startTest() +{ + // Have an untouched land + localStorage.clear(); + + // Initial flush + localStorageFlush(function() { + is(localStorage.length, 0, "localStorage empty at the test start"); + + // Basic test 1 (set a key, check presence after reload): + localStorage.setItem("item", "value"); + localStorageFlushAndReload(function() { + is(localStorage.getItem("item"), "value", "Basic persistance works"); + is(localStorage.length, 1, "1 item in localStorage"); + + // Basic test 2 (set a key twice, check presence of the last value): + localStorage.setItem("item", "value2"); + localStorage.setItem("item", "value3"); + localStorageFlushAndReload(function() { + is(localStorage.getItem("item"), "value3", "Basic persistance 2 works"); + + // Basic test 3 (remove a key, check it has been deleted): + localStorage.removeItem("item"); + localStorageFlushAndReload(function() { + is(localStorage.getItem("item"), null, "Basic delete works"); + + // Basic test 4 (set and remove a key, check it is not present): + localStorage.setItem("item", "value4"); + localStorage.removeItem("item"); + localStorageFlushAndReload(function() { + is(localStorage.getItem("item"), null, "Basic delete 2 works"); + + + // Case 1: + localStorage.setItem("item", "value"); + localStorageFlushAndReload(function() { + localStorage.removeItem("item"); + localStorage.setItem("item", "value2"); + localStorage.removeItem("item"); + localStorageFlushAndReload(function() { + is(localStorage.getItem("item"), null, "Item deleted in case 1"); + + // Case 2: + localStorage.setItem("item", "value"); + localStorage.setItem("item2", "value2"); + localStorage.clear(); + localStorageFlushAndReload(function() { + is(localStorage.length, 0, "localStorage clean in case 2"); + + // Case 3: + localStorageFlush(function() { + localStorage.setItem("item", "value"); + localStorage.setItem("item2", "value2"); + localStorage.clear(); + localStorageReload(); + is(localStorage.length, 0, "localStorage clean in case 4"); + + if (SpecialPowers.Cc["@mozilla.org/xre/app-info;1"].getService( + SpecialPowers.Ci.nsIXULRuntime).processType != SpecialPowers.Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT) { + // Following tests cannot be run in a child/plugin process type + SimpleTest.finish(); + return; + } + + // Cookies clean 1 + localStorageFlush(function() { + localStorage.setItem("item", "value"); + localStorageClearAll(); + is(localStorage.length, 0, "localStorage clean after cookies deletion"); + localStorage.setItem("item2", "value2"); + is(localStorage.getItem("item"), null, "Unexpected key 1, cookies delete"); + is(localStorage.getItem("item2"), "value2", "Expected key 2, cookies delete"); + localStorageFlushAndReload(function() { + is(localStorage.getItem("item"), null, "Unexpected key 1, cookies delete"); + is(localStorage.getItem("item2"), "value2", "Expected key 2, cookies delete"); + + // Cookies clean 2 + localStorage.clear(); + localStorageFlush(function() { + localStorage.setItem("item", "value"); + localStorageClearAll(); + is(localStorage.length, 0, "localStorage clean after cookies deletion 2"); + localStorageFlushAndReload(function() { + is(localStorage.length, 0, "localStorage clean after cookies deletion 2"); + + + // Domain clean 1 + localStorageFlush(function() { + localStorage.setItem("item", "value"); + localStorageClearDomain("test"); + is(localStorage.length, 0, "localStorage clean after domain deletion"); + localStorage.setItem("item2", "value2"); + is(localStorage.getItem("item"), null, "Unexpected key 1, domain delete"); + is(localStorage.getItem("item2"), "value2", "Expected key 2, domain delete"); + localStorageFlushAndReload(function() { + is(localStorage.getItem("item"), null, "Unexpected key 1, domain delete"); + is(localStorage.getItem("item2"), "value2", "Expected key 2, domain delete"); + + // Domain clean 2 + localStorage.clear(); + localStorageFlush(function() { + localStorage.setItem("item", "value"); + localStorageClearDomain("test"); + is(localStorage.length, 0, "localStorage clean after domain deletion 2"); + localStorageFlushAndReload(function() { + is(localStorage.length, 0, "localStorage clean after domain deletion 2"); + + SimpleTest.finish(); + + }); + }); + }); + }); + }); + }); + }); + }); + }); + }); + }); + }); + }); + }); + }); + }); + }); +} + +SimpleTest.waitForExplicitFinish(); + +</script> + +</head> + +<body onload="startTest();"> +</body> +</html> diff --git a/dom/tests/mochitest/localstorage/test_bug746272-1.html b/dom/tests/mochitest/localstorage/test_bug746272-1.html new file mode 100644 index 000000000..d080fbf75 --- /dev/null +++ b/dom/tests/mochitest/localstorage/test_bug746272-1.html @@ -0,0 +1,32 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>incomplete UTF-16 test</title> +<meta http-equiv="Content-type" content="text/html; charset=UTF-8" /> + +<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"> + +function startTest() +{ + localStorage.clear(); + localStorage.setItem("test1", "value1"); + localStorage.setItem("test2", "value2"); + localStorage.setItem("test3", "value3"); + + is(localStorage.length, 3, "expected number of items"); + + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); + +</script> + +</head> + +<body onload="startTest();"> + +</body> +</html> diff --git a/dom/tests/mochitest/localstorage/test_bug746272-2.html b/dom/tests/mochitest/localstorage/test_bug746272-2.html new file mode 100644 index 000000000..bb19b90c0 --- /dev/null +++ b/dom/tests/mochitest/localstorage/test_bug746272-2.html @@ -0,0 +1,31 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>incomplete UTF-16 test</title> +<meta http-equiv="Content-type" content="text/html; charset=UTF-8" /> + +<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"> + +function startTest() +{ + var test2 = localStorage.getItem("test2"); + is(test2, "value2", "expected item"); + + localStorage.removeItem("test2"); + is(localStorage.length, 2, "expected number of items"); + + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); + +</script> + +</head> + +<body onload="startTest();"> + +</body> +</html> diff --git a/dom/tests/mochitest/localstorage/test_cookieBlock.html b/dom/tests/mochitest/localstorage/test_cookieBlock.html new file mode 100644 index 000000000..c95cbca49 --- /dev/null +++ b/dom/tests/mochitest/localstorage/test_cookieBlock.html @@ -0,0 +1,42 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>cookie blocking 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"> + +function startTest() +{ + try { + localStorage.setItem("blocked", "blockedvalue"); + ok(false, "Exception for localStorage.setItem, ACCESS_DENY"); + } + catch (ex) { + ok(true, "Exception for localStorage.setItem, ACCESS_DENY"); + } + + try { + localStorage.getItem("blocked"); + ok(false, "Exception for localStorage.getItem, ACCESS_DENY"); + } + catch (ex) { + ok(true, "Exception for localStorage.getItem, ACCESS_DENY"); + } + + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); + +SpecialPowers.pushPermissions([{'type': 'cookie', 'allow': false, 'context': document}], startTest); + +</script> + +</head> + +<body> + +</body> +</html> diff --git a/dom/tests/mochitest/localstorage/test_cookieSession.html b/dom/tests/mochitest/localstorage/test_cookieSession.html new file mode 100644 index 000000000..1fdd6f4d5 --- /dev/null +++ b/dom/tests/mochitest/localstorage/test_cookieSession.html @@ -0,0 +1,132 @@ +<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 localStorage. + 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(aPermission, aNext) { + SpecialPowers.pushPermissions([{'type': 'cookie', 'allow': aPermission, 'context': document}], aNext); +} + +function test1() { + localStorage.setItem("persistent1", "persistent value 1"); + localStorage.setItem("persistent2", "persistent value 2"); + + pushCookie(SpecialPowers.Ci.nsICookiePermission.ACCESS_SESSION, test1_b); +} + +function test1_b() { + localStorage.setItem("session only", "session value"); + parent.is(localStorage.getItem("session only"), "session value"); + parent.is(localStorage.getItem("persistent1"), "persistent value 1"); + parent.is(localStorage.getItem("persistent2"), "persistent value 2"); + + window.location.search = '?2'; +} + +function test2() +{ + parent.is(localStorage.getItem("session only"), "session value", "Value present when cookies in session-only mode"); + parent.is(localStorage.getItem("persistent1"), "persistent value 1", "Persistent value present"); + parent.is(localStorage.getItem("persistent2"), "persistent value 2", "Persistent value present"); + + localStorage.setItem("persistent1", "changed persistent value 1"); + localStorage.removeItem("persistent2"); + + parent.is(localStorage.getItem("session only"), "session value", "Value present when cookies in session-only mode"); + parent.is(localStorage.getItem("persistent1"), "changed persistent value 1", "Persistent value present"); + parent.is(localStorage.getItem("persistent2"), null, "Persistent value removed"); + + // This clear has to delete only changes made in session only mode + localStorage.clear(); + + parent.is(localStorage.getItem("session only"), null, "Value not present when cookies in session-only mode after delete"); + parent.is(localStorage.getItem("persistent1"), null, "Persistent value not present in session only after delete"); + parent.is(localStorage.getItem("persistent2"), null, "Persistent value not present in session only after delete"); + + localStorage.setItem("session only 2", "must be deleted on drop of session-only cookies permissions"); + + pushCookie(SpecialPowers.Ci.nsICookiePermission.ACCESS_DEFAULT, function() { window.location.search = '?3'; }); +} + +function test3() { + parent.is(localStorage.getItem("session only"), null, "No value when cookies are in default mode"); + parent.is(localStorage.getItem("session only 2"), null, "No value when cookies are in default mode"); + parent.is(localStorage.getItem("persistent1"), "persistent value 1", "Persistent value present"); + parent.is(localStorage.getItem("persistent2"), "persistent value 2", "Persistent value present"); + + pushCookie(SpecialPowers.Ci.nsICookiePermission.ACCESS_SESSION, function() { window.location.search = '?4'; }); +} + +function test4() { + parent.is(localStorage.getItem("session only"), null, "Value not present when cookies in session-only mode after delete"); + parent.is(localStorage.getItem("session only 2"), null, "Value not present when cookies in session-only mode after delete"); + parent.is(localStorage.getItem("persistent1"), "persistent value 1", "Persistent value present again"); + parent.is(localStorage.getItem("persistent2"), "persistent value 2", "Persistent value present again"); + + pushCookie(SpecialPowers.Ci.nsICookiePermission.ACCESS_DEFAULT, function() { window.location.search = '?5'; }); +} + +function test5() { + localStorage.clear(); + + parent.is(localStorage.getItem("session only"), null, "No value when cookies are in default mode"); + parent.is(localStorage.getItem("persistent1"), null, "Persistent value not present after delete"); + parent.is(localStorage.getItem("persistent2"), null, "Persistent value not present after delete"); + + pushCookie(SpecialPowers.Ci.nsICookiePermission.ACCESS_SESSION, function() { window.location.search = '?6'; }); +} + +function test6() { + parent.is(localStorage.getItem("session only"), null, "Value not present when cookies in session-only mode after delete"); + parent.is(localStorage.getItem("session only 2"), null, "No value when cookies are in default mode"); + parent.is(localStorage.getItem("persistent1"), null, "Persistent value not present in session only after delete"); + parent.is(localStorage.getItem("persistent2"), null, "Persistent value not present in session only after delete"); + + parent.SimpleTest.finish(); +} + +function startTest() { + switch (location.search) { + case '?1': + test1(); + break; + case '?2': + test2(); + break; + case '?3': + test3(); + break; + case '?4': + test4(); + break; + case '?5': + test5(); + break; + case '?6': + test6(); + break; + default: + SimpleTest.waitForExplicitFinish(); + var iframe = document.createElement('iframe'); + iframe.src = 'test_cookieSession.html?1'; + document.body.appendChild(iframe); + } +} +</script> + +</head> + +<body onload="startTest()"> +</body> +</html> diff --git a/dom/tests/mochitest/localstorage/test_embededNulls.html b/dom/tests/mochitest/localstorage/test_embededNulls.html new file mode 100644 index 000000000..04b88cfba --- /dev/null +++ b/dom/tests/mochitest/localstorage/test_embededNulls.html @@ -0,0 +1,40 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>embeded nulls 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"> + +function startTest() +{ + var k = "key with\x00null"; + var v = "value with\x00null"; + + localStorage.setItem(k, v); + + is(localStorage.getItem("key with"), null, + "not accessible by truncated key"); + + is(localStorage.getItem(k), "value with\x00null", + "value is identical to what has been stored"); + + isnot(localStorage.getItem(k), "value with", + "value is not truncated"); + + localStorage.clear(); + + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); + +</script> + +</head> + +<body onload="startTest();"> + +</body> +</html> diff --git a/dom/tests/mochitest/localstorage/test_keySync.html b/dom/tests/mochitest/localstorage/test_keySync.html new file mode 100644 index 000000000..3f23945e2 --- /dev/null +++ b/dom/tests/mochitest/localstorage/test_keySync.html @@ -0,0 +1,33 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>localStorage equal origins</title> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="interOriginTest2.js"></script> + +<!-- + This test loads two frames from the same origin, clears in one frame, + sets a single key in another and then checks key(0) in the first frame. +--> + +<script type="text/javascript"> + +function startTest() +{ + masterFrameOrigin = "http://example.org:80"; + slaveFrameOrigin = "http://example.org:80"; + + masterFrame.location = masterFrameOrigin + framePath + "frameKeySync.html?1"; + slaveFrame.location = slaveFrameOrigin + framePath + "frameKeySync.html?2"; +} + +</script> + +</head> + +<body onload="startTest();"> + <iframe src="" name="masterFrame"></iframe> + <iframe src="" name="slaveFrame"></iframe> +</body> +</html> diff --git a/dom/tests/mochitest/localstorage/test_localStorageBase.html b/dom/tests/mochitest/localstorage/test_localStorageBase.html new file mode 100644 index 000000000..767a7d50c --- /dev/null +++ b/dom/tests/mochitest/localstorage/test_localStorageBase.html @@ -0,0 +1,247 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>localStorage 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", + "testA,null,valueA", + "testA,valueA,valueA2", + "testB,null,valueB", + "testB,valueB,valueB2", + "testC,null,valueC", + "testC,valueC,valueC2", + "testC,valueC2,null", + "testC,null,null", + "testC,null,null", + "null,null,test", + "null,test,null", + "null,null,test", + "null,test,null", + "null,null,null" +]; + +function startTest() +{ + // Initially check the localStorage is empty + is(localStorage.length, 0, "The storage is empty [1]"); + is(localStorage.key(0), null, "key() should return null for out-of-bounds access"); + is(localStorage.key(-1), null, "key() should return null for out-of-bounds access"); + is(localStorage.key(1), null, "key() should return null for out-of-bounds access"); + is(localStorage.getItem("nonexisting"), null, "Nonexisting item is null (getItem())"); + is(localStorage["nonexisting"], undefined, "Nonexisting item is undefined (array access)"); + is(localStorage.nonexisting, undefined, "Nonexisting item is undefined (property access)"); + localStorage.removeItem("nonexisting"); // Just check there is no exception + + is(typeof localStorage.getItem("nonexisting"), "object", "getItem('nonexisting') is object"); + is(typeof localStorage["nonexisting"], "undefined", "['nonexisting'] is undefined"); + is(typeof localStorage.nonexisting, "undefined", "nonexisting is undefined"); + is(typeof localStorage.getItem("nonexisting2"), "object", "getItem('nonexisting2') is object"); + is(typeof localStorage["nonexisting2"], "undefined", "['nonexisting2'] is undefined"); + is(typeof localStorage.nonexisting2, "undefined", "nonexisting2 is undefined"); + + var localStorageCopy = localStorage; + + function onStorageChanged(e) { + if (e.storageArea == localStorageCopy) { + 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 MozLocalStorageChanged + SpecialPowers.addChromeEventListener("MozLocalStorageChanged", onStorageChanged, true); + + // add an empty-value key + localStorage.setItem("empty", ""); + is(localStorage.getItem("empty"), "", "Empty value (getItem())"); + is(localStorage["empty"], "", "Empty value (array access)"); + is(localStorage.empty, "", "Empty value (property access)"); + is(typeof localStorage.getItem("empty"), "string", "getItem('empty') is string"); + is(typeof localStorage["empty"], "string", "['empty'] is string"); + is(typeof localStorage.empty, "string", "empty is string"); + localStorage.removeItem("empty"); + is(localStorage.length, 0, "The storage has no keys"); + is(localStorage.getItem("empty"), null, "empty item is null (getItem())"); + is(localStorage["empty"], undefined, "empty item is undefined (array access)"); + is(localStorage.empty, undefined, "empty item is undefined (property access)"); + is(typeof localStorage.getItem("empty"), "object", "getItem('empty') is object"); + is(typeof localStorage["empty"], "undefined", "['empty'] is undefined"); + is(typeof localStorage.empty, "undefined", "empty is undefined"); + + // add one key, check it is there + localStorage.setItem("key1", "value1"); + is(localStorage.length, 1, "The storage has one key-value pair"); + is(localStorage.key(0), "key1"); + is(localStorage.key(-1), null, "key() should return null for out-of-bounds access"); + is(localStorage.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(localStorage.getItem("key1"), "value1", "getItem('key1') == value1"); + is(localStorage["key1"], "value1", "['key1'] == value1"); + is(localStorage.key1, "value1", "key1 == value1"); + + is(typeof localStorage.getItem("key1"), "string", "getItem('key1') is string"); + is(typeof localStorage["key1"], "string", "['key1'] is string"); + is(typeof localStorage.key1, "string", "key1 is string"); + + // remove the previously added key and check the storage is empty + localStorage.removeItem("key1"); + is(localStorage.length, 0, "The storage is empty [2]"); + is(localStorage.key(0), null, "key() should return null for out-of-bounds access"); + is(localStorage.getItem("key1"), null, "\'key1\' removed"); + + is(typeof localStorage.getItem("key1"), "object", "getItem('key1') is object"); + is(typeof localStorage["key1"], "undefined", "['key1'] is object"); + is(typeof localStorage.key1, "undefined", "key1 is object"); + + // add one key, check it is there + localStorage.setItem("key1", "value1"); + is(localStorage.length, 1, "The storage has one key-value pair"); + is(localStorage.key(0), "key1"); + is(localStorage.getItem("key1"), "value1"); + + // add a second key + localStorage.setItem("key2", "value2"); + is(localStorage.length, 2, "The storage has two key-value pairs"); + is(localStorage.getItem("key1"), "value1"); + is(localStorage.getItem("key2"), "value2"); + var firstKey = localStorage.key(0); + var secondKey = localStorage.key(1); + ok((firstKey == 'key1' && secondKey == 'key2') || + (firstKey == 'key2' && secondKey == 'key1'), + 'key() API works.'); + + // change the second key + localStorage.setItem("key2", "value2-2"); + is(localStorage.length, 2, "The storage has two key-value pairs"); + is(localStorage.key(0), firstKey); // After key value changes the order must be preserved + is(localStorage.key(1), secondKey); + is(localStorage.key(-1), null, "key() should return null for out-of-bounds access"); + is(localStorage.key(2), null, "key() should return null for out-of-bounds access"); + is(localStorage.getItem("key1"), "value1"); + is(localStorage.getItem("key2"), "value2-2"); + + // change the first key + localStorage.setItem("key1", "value1-2"); + is(localStorage.length, 2, "The storage has two key-value pairs"); + is(localStorage.key(0), firstKey); // After key value changes the order must be preserved + is(localStorage.key(1), secondKey); + is(localStorage.key(-1), null, "key() should return null for out-of-bounds access"); + is(localStorage.key(2), null, "key() should return null for out-of-bounds access"); + is(localStorage.getItem("key1"), "value1-2"); + is(localStorage.getItem("key2"), "value2-2"); + + // remove the second key + localStorage.removeItem("key2"); + is(localStorage.length, 1, "The storage has one key-value pair"); + is(localStorage.key(0), "key1"); + is(localStorage.key(-1), null, "key() should return null for out-of-bounds access"); + is(localStorage.key(1), null, "key() should return null for out-of-bounds access"); + is(localStorage.getItem("key1"), "value1-2"); + + // JS property test + localStorage.testA = "valueA"; + is(localStorage.testA, "valueA"); + is(localStorage["testA"], "valueA"); + is(localStorage.getItem("testA"), "valueA"); + + localStorage.testA = "valueA2"; + is(localStorage.testA, "valueA2"); + is(localStorage["testA"], "valueA2"); + is(localStorage.getItem("testA"), "valueA2"); + + localStorage["testB"] = "valueB"; + is(localStorage.testB, "valueB"); + is(localStorage["testB"], "valueB"); + is(localStorage.getItem("testB"), "valueB"); + + localStorage["testB"] = "valueB2"; + is(localStorage.testB, "valueB2"); + is(localStorage["testB"], "valueB2"); + is(localStorage.getItem("testB"), "valueB2"); + + localStorage.setItem("testC", "valueC"); + is(localStorage.testC, "valueC"); + is(localStorage["testC"], "valueC"); + is(localStorage.getItem("testC"), "valueC"); + + localStorage.setItem("testC", "valueC2"); + is(localStorage.testC, "valueC2"); + is(localStorage["testC"], "valueC2"); + is(localStorage.getItem("testC"), "valueC2"); + + localStorage.setItem("testC", null); + is("testC" in localStorage, true); + is(localStorage.getItem("testC"), "null"); + is(localStorage["testC"], "null"); + is(localStorage.testC, "null"); + + localStorage.removeItem("testC"); + localStorage["testC"] = null; + is("testC" in localStorage, true); + is(localStorage.getItem("testC"), "null"); + is(localStorage["testC"], "null"); + is(localStorage.testC, "null"); + + localStorage.setItem(null, "test"); + is("null" in localStorage, true); + is(localStorage.getItem("null"), "test"); + is(localStorage.getItem(null), "test"); + is(localStorage["null"], "test"); + localStorage.removeItem(null, "test"); + is("null" in localStorage, false); + + localStorage.setItem(null, "test"); + is("null" in localStorage, true); + localStorage.removeItem("null", "test"); + is("null" in localStorage, false); + + // Clear the storage + localStorage.clear(); + is("testB" in localStorage, false, "Keys are not in the JS scope of the storage"); + is("testC" in localStorage, false, "Keys are not in the JS scope of the storage"); + is(localStorage.length, 0, "The storage is empty [3]"); + is(localStorage.key(0), null, "key() should return null for out-of-bounds access"); + is(localStorage.key(-1), null, "key() should return null for out-of-bounds access"); + is(localStorage.key(1), null, "key() should return null for out-of-bounds access"); + is(localStorage.getItem("nonexisting"), null, "Nonexisting item is null"); + is(localStorage.getItem("key1"), null, "key1 removed"); + is(localStorage.getItem("key2"), null, "key2 removed"); + localStorage.removeItem("nonexisting"); // Just check there is no exception + localStorage.removeItem("key1"); // Just check there is no exception + localStorage.removeItem("key2"); // Just check there is no exception + + SimpleTest.executeSoon(function () { + SpecialPowers.removeChromeEventListener("MozLocalStorageChanged", onStorageChanged, true); + is(expectedEvents.length, 0, "received the correct number of events"); + + localStorage.clear(); + SimpleTest.finish(); + }); +} + +SimpleTest.waitForExplicitFinish(); + +</script> + +</head> + +<body onload="startTest();"> + +</body> +</html> diff --git a/dom/tests/mochitest/localstorage/test_localStorageBasePrivateBrowsing_perwindowpb.html b/dom/tests/mochitest/localstorage/test_localStorageBasePrivateBrowsing_perwindowpb.html new file mode 100644 index 000000000..dbcf01fc2 --- /dev/null +++ b/dom/tests/mochitest/localstorage/test_localStorageBasePrivateBrowsing_perwindowpb.html @@ -0,0 +1,263 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>localStorage basic test, while in sesison only mode</title> + +<script type="application/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"> + +const Ci = Components.interfaces; +var mainWindow; + +var prefBranch = Components.classes["@mozilla.org/preferences-service;1"] + .getService(Components.interfaces.nsIPrefBranch); +prefBranch.setIntPref("browser.startup.page", 0); +prefBranch.setCharPref("browser.startup.homepage_override.mstone", "ignore"); + +function startTest() { + mainWindow = window.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIWebNavigation) + .QueryInterface(Ci.nsIDocShellTreeItem) + .rootTreeItem + .QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDOMWindow); + + doTest(); +} + +var contentPage = "http://mochi.test:8888/chrome/dom/tests/mochitest/localstorage/page_blank.html"; + +function testOnWindow(aIsPrivate, aCallback) { + var win = mainWindow.OpenBrowserWindow({private: aIsPrivate}); + win.addEventListener("load", function onLoad() { + win.removeEventListener("load", onLoad, false); + win.addEventListener("DOMContentLoaded", function onInnerLoad() { + if (win.content.location.href == "about:privatebrowsing") { + win.gBrowser.loadURI(contentPage); + return; + } + win.removeEventListener("DOMContentLoaded", onInnerLoad, true); + SimpleTest.executeSoon(function() { aCallback(win); }); + }, true); + win.gBrowser.loadURI(contentPage); + }, true); +} + +function doTest() { + testOnWindow(false, function(aWin) { + aWin.content.localStorage.setItem("persistent", "persistent1"); + + testOnWindow(true, function(privateWin) { + is(privateWin.content.localStorage.getItem("persistent"), null, "previous values are inaccessible"); + + // Initially check the privateWin.content.localStorage is empty + is(privateWin.content.localStorage.length, 0, "The storage is empty [1]"); + is(privateWin.content.localStorage.key(0), null, "key() should return null for out-of-bounds access"); + is(privateWin.content.localStorage.key(-1), null, "key() should return null for out-of-bounds access"); + is(privateWin.content.localStorage.key(1), null, "key() should return null for out-of-bounds access"); + is(privateWin.content.localStorage.getItem("nonexisting"), null, "Nonexisting item is null (getItem())"); + is(privateWin.content.localStorage["nonexisting"], undefined, "Nonexisting item is null (array access)"); + is(privateWin.content.localStorage.nonexisting, undefined, "Nonexisting item is null (property access)"); + privateWin.content.localStorage.removeItem("nonexisting"); // Just check there is no exception + + is(typeof privateWin.content.localStorage.getItem("nonexisting"), "object", "getItem('nonexisting') is object"); + is(typeof privateWin.content.localStorage["nonexisting"], "undefined", "['nonexisting'] is undefined"); + is(typeof privateWin.content.localStorage.nonexisting, "undefined", "nonexisting is undefined"); + is(typeof privateWin.content.localStorage.getItem("nonexisting2"), "object", "getItem('nonexisting2') is object"); + is(typeof privateWin.content.localStorage["nonexisting2"], "undefined", "['nonexisting2'] is undefined"); + is(typeof privateWin.content.localStorage.nonexisting2, "undefined", "nonexisting2 is undefined"); + + // add an empty-value key + privateWin.content.localStorage.setItem("empty", ""); + is(privateWin.content.localStorage.getItem("empty"), "", "Empty value (getItem())"); + is(privateWin.content.localStorage["empty"], "", "Empty value (array access)"); + is(privateWin.content.localStorage.empty, "", "Empty value (property access)"); + is(typeof privateWin.content.localStorage.getItem("empty"), "string", "getItem('empty') is string"); + is(typeof privateWin.content.localStorage["empty"], "string", "['empty'] is string"); + is(typeof privateWin.content.localStorage.empty, "string", "empty is string"); + privateWin.content.localStorage.removeItem("empty"); + is(privateWin.content.localStorage.length, 0, "The storage has no keys"); + is(privateWin.content.localStorage.getItem("empty"), null, "empty item is null (getItem())"); + is(privateWin.content.localStorage["empty"], undefined, "empty item is undefined (array access)"); + is(privateWin.content.localStorage.empty, undefined, "empty item is undefined (property access)"); + is(typeof privateWin.content.localStorage.getItem("empty"), "object", "getItem('empty') is object"); + is(typeof privateWin.content.localStorage["empty"], "undefined", "['empty'] is undefined"); + is(typeof privateWin.content.localStorage.empty, "undefined", "empty is undefined"); + + // add one key, check it is there + privateWin.content.localStorage.setItem("key1", "value1"); + is(privateWin.content.localStorage.length, 1, "The storage has one key-value pair"); + is(privateWin.content.localStorage.key(0), "key1"); + is(privateWin.content.localStorage.key(-1), null, "key() should return null for out-of-bounds access"); + is(privateWin.content.localStorage.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(privateWin.content.localStorage.getItem("key1"), "value1", "getItem('key1') == value1"); + is(privateWin.content.localStorage["key1"], "value1", "['key1'] == value1"); + is(privateWin.content.localStorage.key1, "value1", "key1 == value1"); + + is(typeof privateWin.content.localStorage.getItem("key1"), "string", "getItem('key1') is string"); + is(typeof privateWin.content.localStorage["key1"], "string", "['key1'] is string"); + is(typeof privateWin.content.localStorage.key1, "string", "key1 is string"); + + // remove the previously added key and check the storage is empty + privateWin.content.localStorage.removeItem("key1"); + is(privateWin.content.localStorage.length, 0, "The storage is empty [2]"); + is(privateWin.content.localStorage.key(0), null, "key() should return null for out-of-bounds access"); + is(privateWin.content.localStorage.getItem("key1"), null, "\'key1\' removed"); + + is(typeof privateWin.content.localStorage.getItem("key1"), "object", "getItem('key1') is object"); + is(typeof privateWin.content.localStorage["key1"], "undefined", "['key1'] is undefined"); + is(typeof privateWin.content.localStorage.key1, "undefined", "key1 is undefined"); + + // add one key, check it is there + privateWin.content.localStorage.setItem("key1", "value1"); + is(privateWin.content.localStorage.length, 1, "The storage has one key-value pair"); + is(privateWin.content.localStorage.key(0), "key1"); + is(privateWin.content.localStorage.getItem("key1"), "value1"); + + // add a second key + privateWin.content.localStorage.setItem("key2", "value2"); + is(privateWin.content.localStorage.length, 2, "The storage has two key-value pairs"); + is(privateWin.content.localStorage.getItem("key1"), "value1"); + is(privateWin.content.localStorage.getItem("key2"), "value2"); + var firstKey = privateWin.content.localStorage.key(0); + var secondKey = privateWin.content.localStorage.key(1); + ok((firstKey == 'key1' && secondKey == 'key2') || + (firstKey == 'key2' && secondKey == 'key1'), + 'key() API works.'); + + // change the second key + privateWin.content.localStorage.setItem("key2", "value2-2"); + is(privateWin.content.localStorage.length, 2, "The storage has two key-value pairs"); + is(privateWin.content.localStorage.key(0), firstKey); // After key value changes the order must be preserved + is(privateWin.content.localStorage.key(1), secondKey); + is(privateWin.content.localStorage.key(-1), null, "key() should return null for out-of-bounds access"); + is(privateWin.content.localStorage.key(2), null, "key() should return null for out-of-bounds access"); + is(privateWin.content.localStorage.getItem("key1"), "value1"); + is(privateWin.content.localStorage.getItem("key2"), "value2-2"); + + // change the first key + privateWin.content.localStorage.setItem("key1", "value1-2"); + is(privateWin.content.localStorage.length, 2, "The storage has two key-value pairs"); + is(privateWin.content.localStorage.key(0), firstKey); // After key value changes the order must be preserved + is(privateWin.content.localStorage.key(1), secondKey); + is(privateWin.content.localStorage.key(-1), null, "key() should return null for out-of-bounds access"); + is(privateWin.content.localStorage.key(2), null, "key() should return null for out-of-bounds access"); + is(privateWin.content.localStorage.getItem("key1"), "value1-2"); + is(privateWin.content.localStorage.getItem("key2"), "value2-2"); + + // remove the second key + privateWin.content.localStorage.removeItem("key2"); + is(privateWin.content.localStorage.length, 1, "The storage has one key-value pair"); + is(privateWin.content.localStorage.key(0), "key1"); + is(privateWin.content.localStorage.key(-1), null, "key() should return null for out-of-bounds access"); + is(privateWin.content.localStorage.key(1), null, "key() should return null for out-of-bounds access"); + is(privateWin.content.localStorage.getItem("key1"), "value1-2"); + + // JS property test + privateWin.content.localStorage.testA = "valueA"; + is(privateWin.content.localStorage.testA, "valueA"); + is(privateWin.content.localStorage["testA"], "valueA"); + is(privateWin.content.localStorage.getItem("testA"), "valueA"); + + privateWin.content.localStorage.testA = "valueA2"; + is(privateWin.content.localStorage.testA, "valueA2"); + is(privateWin.content.localStorage["testA"], "valueA2"); + is(privateWin.content.localStorage.getItem("testA"), "valueA2"); + + privateWin.content.localStorage["testB"] = "valueB"; + is(privateWin.content.localStorage.testB, "valueB"); + is(privateWin.content.localStorage["testB"], "valueB"); + is(privateWin.content.localStorage.getItem("testB"), "valueB"); + + privateWin.content.localStorage["testB"] = "valueB2"; + is(privateWin.content.localStorage.testB, "valueB2"); + is(privateWin.content.localStorage["testB"], "valueB2"); + is(privateWin.content.localStorage.getItem("testB"), "valueB2"); + + privateWin.content.localStorage.setItem("testC", "valueC"); + is(privateWin.content.localStorage.testC, "valueC"); + is(privateWin.content.localStorage["testC"], "valueC"); + is(privateWin.content.localStorage.getItem("testC"), "valueC"); + + privateWin.content.localStorage.setItem("testC", "valueC2"); + is(privateWin.content.localStorage.testC, "valueC2"); + is(privateWin.content.localStorage["testC"], "valueC2"); + is(privateWin.content.localStorage.getItem("testC"), "valueC2"); + + privateWin.content.localStorage.setItem("testC", null); + is("testC" in privateWin.content.localStorage, true); + is(privateWin.content.localStorage.getItem("testC"), "null"); + is(privateWin.content.localStorage["testC"], "null"); + is(privateWin.content.localStorage.testC, "null"); + + privateWin.content.localStorage.removeItem("testC"); + privateWin.content.localStorage["testC"] = null; + is("testC" in privateWin.content.localStorage, true); + is(privateWin.content.localStorage.getItem("testC"), "null"); + is(privateWin.content.localStorage["testC"], "null"); + is(privateWin.content.localStorage.testC, "null"); + + privateWin.content.localStorage.setItem(null, "test"); + is("null" in privateWin.content.localStorage, true); + is(privateWin.content.localStorage.getItem("null"), "test"); + is(privateWin.content.localStorage.getItem(null), "test"); + is(privateWin.content.localStorage["null"], "test"); + privateWin.content.localStorage.removeItem(null, "test"); + is("null" in privateWin.content.localStorage, false); + + privateWin.content.localStorage.setItem(null, "test"); + is("null" in privateWin.content.localStorage, true); + privateWin.content.localStorage.removeItem("null", "test"); + is("null" in privateWin.content.localStorage, false); + + // Clear the storage + privateWin.content.localStorage.clear(); + is(privateWin.content.localStorage.length, 0, "The storage is empty [3]"); + is(privateWin.content.localStorage.key(0), null, "key() should return null for out-of-bounds access"); + is(privateWin.content.localStorage.key(-1), null, "key() should return null for out-of-bounds access"); + is(privateWin.content.localStorage.key(1), null, "key() should return null for out-of-bounds access"); + is(privateWin.content.localStorage.getItem("nonexisting"), null, "Nonexisting item is null"); + is(privateWin.content.localStorage.getItem("key1"), null, "key1 removed"); + is(privateWin.content.localStorage.getItem("key2"), null, "key2 removed"); + privateWin.content.localStorage.removeItem("nonexisting"); // Just check there is no exception + privateWin.content.localStorage.removeItem("key1"); // Just check there is no exception + privateWin.content.localStorage.removeItem("key2"); // Just check there is no exception + + privateWin.content.localStorage.setItem("must disappear", "private browsing value"); + + privateWin.close(); + + // The .close() call above will operate asynchronously, so execute the + // code below asynchronously as well. + function callback(newPrivateWin) { + is(newPrivateWin.content.localStorage.getItem("must disappear"), null, "private browsing values threw away"); + is(newPrivateWin.content.localStorage.length, 0, "No items"); + + newPrivateWin.close(); + is(aWin.content.localStorage.getItem("persistent"), "persistent1", "back in normal mode"); + aWin.content.localStorage.clear(); + aWin.close(); + + prefBranch.clearUserPref("browser.startup.page") + prefBranch.clearUserPref("browser.startup.homepage_override.mstone"); + SimpleTest.finish(); + }; + SimpleTest.executeSoon(() => testOnWindow(true, callback)); + }); + }); +} + +SimpleTest.waitForExplicitFinish(); + +</script> + +</head> + +<body onload="startTest();"> + +</body> +</html> diff --git a/dom/tests/mochitest/localstorage/test_localStorageBaseSessionOnly.html b/dom/tests/mochitest/localstorage/test_localStorageBaseSessionOnly.html new file mode 100644 index 000000000..c55a8e48d --- /dev/null +++ b/dom/tests/mochitest/localstorage/test_localStorageBaseSessionOnly.html @@ -0,0 +1,205 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>localStorage 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"> + +function startTest() +{ + SpecialPowers.pushPermissions([{'type': 'cookie', 'allow': SpecialPowers.Ci.nsICookiePermission.ACCESS_SESSION, 'context': document}], test1); +} + +function test1() { + // Initially check the localStorage is empty + is(localStorage.length, 0, "The storage is empty [1]"); + is(localStorage.key(0), null, "key() should return null for out-of-bounds access"); + is(localStorage.key(-1), null, "key() should return null for out-of-bounds access"); + is(localStorage.key(1), null, "key() should return null for out-of-bounds access"); + is(localStorage.getItem("nonexisting"), null, "Nonexisting item is null (getItem())"); + is(localStorage["nonexisting"], undefined, "Nonexisting item is undefined (array access)"); + is(localStorage.nonexisting, undefined, "Nonexisting item is undefined (property access)"); + localStorage.removeItem("nonexisting"); // Just check there is no exception + + is(typeof localStorage.getItem("nonexisting"), "object", "getItem('nonexisting') is object"); + is(typeof localStorage["nonexisting"], "undefined", "['nonexisting'] is undefined"); + is(typeof localStorage.nonexisting, "undefined", "nonexisting is undefined"); + is(typeof localStorage.getItem("nonexisting2"), "object", "getItem('nonexisting2') is object"); + is(typeof localStorage["nonexisting2"], "undefined", "['nonexisting2'] is undefined"); + is(typeof localStorage.nonexisting2, "undefined", "nonexisting2 is undefined"); + + // add an empty-value key + localStorage.setItem("empty", ""); + is(localStorage.getItem("empty"), "", "Empty value (getItem())"); + is(localStorage["empty"], "", "Empty value (array access)"); + is(localStorage.empty, "", "Empty value (property access)"); + is(typeof localStorage.getItem("empty"), "string", "getItem('empty') is string"); + is(typeof localStorage["empty"], "string", "['empty'] is string"); + is(typeof localStorage.empty, "string", "empty is string"); + localStorage.removeItem("empty"); + is(localStorage.length, 0, "The storage has no keys"); + is(localStorage.getItem("empty"), null, "empty item is null (getItem())"); + is(localStorage["empty"], undefined, "empty item is undefined (array access)"); + is(localStorage.empty, undefined, "empty item is undefined (property access)"); + is(typeof localStorage.getItem("empty"), "object", "getItem('empty') is object"); + is(typeof localStorage["empty"], "undefined", "['empty'] is undefined"); + is(typeof localStorage.empty, "undefined", "empty is undefined"); + + // add one key, check it is there + localStorage.setItem("key1", "value1"); + is(localStorage.length, 1, "The storage has one key-value pair"); + is(localStorage.key(0), "key1"); + is(localStorage.key(-1), null, "key() should return null for out-of-bounds access"); + is(localStorage.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(localStorage.getItem("key1"), "value1", "getItem('key1') == value1"); + is(localStorage["key1"], "value1", "['key1'] == value1"); + is(localStorage.key1, "value1", "key1 == value1"); + + is(typeof localStorage.getItem("key1"), "string", "getItem('key1') is string"); + is(typeof localStorage["key1"], "string", "['key1'] is string"); + is(typeof localStorage.key1, "string", "key1 is string"); + + // remove the previously added key and check the storage is empty + localStorage.removeItem("key1"); + is(localStorage.length, 0, "The storage is empty [2]"); + is(localStorage.key(0), null, "key() should return null for out-of-bounds access"); + is(localStorage.getItem("key1"), null, "\'key1\' removed"); + + is(typeof localStorage.getItem("key1"), "object", "getItem('key1') is object"); + is(typeof localStorage["key1"], "undefined", "['key1'] is undefined"); + is(typeof localStorage.key1, "undefined", "key1 is undefined"); + + // add one key, check it is there + localStorage.setItem("key1", "value1"); + is(localStorage.length, 1, "The storage has one key-value pair"); + is(localStorage.key(0), "key1"); + is(localStorage.getItem("key1"), "value1"); + + // add a second key + localStorage.setItem("key2", "value2"); + is(localStorage.length, 2, "The storage has two key-value pairs"); + is(localStorage.getItem("key1"), "value1"); + is(localStorage.getItem("key2"), "value2"); + var firstKey = localStorage.key(0); + var secondKey = localStorage.key(1); + ok((firstKey == 'key1' && secondKey == 'key2') || + (firstKey == 'key2' && secondKey == 'key1'), + 'key() API works.'); + + // change the second key + localStorage.setItem("key2", "value2-2"); + is(localStorage.length, 2, "The storage has two key-value pairs"); + is(localStorage.key(0), firstKey); // After key value changes the order must be preserved + is(localStorage.key(1), secondKey); + is(localStorage.key(-1), null, "key() should return null for out-of-bounds access"); + is(localStorage.key(2), null, "key() should return null for out-of-bounds access"); + is(localStorage.getItem("key1"), "value1"); + is(localStorage.getItem("key2"), "value2-2"); + + // change the first key + localStorage.setItem("key1", "value1-2"); + is(localStorage.length, 2, "The storage has two key-value pairs"); + is(localStorage.key(0), firstKey); // After key value changes the order must be preserved + is(localStorage.key(1), secondKey); + is(localStorage.key(-1), null, "key() should return null for out-of-bounds access"); + is(localStorage.key(2), null, "key() should return null for out-of-bounds access"); + is(localStorage.getItem("key1"), "value1-2"); + is(localStorage.getItem("key2"), "value2-2"); + + // remove the second key + localStorage.removeItem("key2"); + is(localStorage.length, 1, "The storage has one key-value pair"); + is(localStorage.key(0), "key1"); + is(localStorage.key(-1), null, "key() should return null for out-of-bounds access"); + is(localStorage.key(1), null, "key() should return null for out-of-bounds access"); + is(localStorage.getItem("key1"), "value1-2"); + + // JS property test + localStorage.testA = "valueA"; + is(localStorage.testA, "valueA"); + is(localStorage["testA"], "valueA"); + is(localStorage.getItem("testA"), "valueA"); + + localStorage.testA = "valueA2"; + is(localStorage.testA, "valueA2"); + is(localStorage["testA"], "valueA2"); + is(localStorage.getItem("testA"), "valueA2"); + + localStorage["testB"] = "valueB"; + is(localStorage.testB, "valueB"); + is(localStorage["testB"], "valueB"); + is(localStorage.getItem("testB"), "valueB"); + + localStorage["testB"] = "valueB2"; + is(localStorage.testB, "valueB2"); + is(localStorage["testB"], "valueB2"); + is(localStorage.getItem("testB"), "valueB2"); + + localStorage.setItem("testC", "valueC"); + is(localStorage.testC, "valueC"); + is(localStorage["testC"], "valueC"); + is(localStorage.getItem("testC"), "valueC"); + + localStorage.setItem("testC", "valueC2"); + is(localStorage.testC, "valueC2"); + is(localStorage["testC"], "valueC2"); + is(localStorage.getItem("testC"), "valueC2"); + + localStorage.setItem("testC", null); + is("testC" in localStorage, true); + is(localStorage.getItem("testC"), "null"); + is(localStorage["testC"], "null"); + is(localStorage.testC, "null"); + + localStorage.removeItem("testC"); + localStorage["testC"] = null; + is("testC" in localStorage, true); + is(localStorage.getItem("testC"), "null"); + is(localStorage["testC"], "null"); + is(localStorage.testC, "null"); + + localStorage.setItem(null, "test"); + is("null" in localStorage, true); + is(localStorage.getItem("null"), "test"); + is(localStorage.getItem(null), "test"); + is(localStorage["null"], "test"); + localStorage.removeItem(null, "test"); + is("null" in localStorage, false); + + localStorage.setItem(null, "test"); + is("null" in localStorage, true); + localStorage.removeItem("null", "test"); + is("null" in localStorage, false); + + // Clear the storage + localStorage.clear(); + is(localStorage.length, 0, "The storage is empty [3]"); + is(localStorage.key(0), null, "key() should return null for out-of-bounds access"); + is(localStorage.key(-1), null, "key() should return null for out-of-bounds access"); + is(localStorage.key(1), null, "key() should return null for out-of-bounds access"); + is(localStorage.getItem("nonexisting"), null, "Nonexisting item is null"); + is(localStorage.getItem("key1"), null, "key1 removed"); + is(localStorage.getItem("key2"), null, "key2 removed"); + localStorage.removeItem("nonexisting"); // Just check there is no exception + localStorage.removeItem("key1"); // Just check there is no exception + localStorage.removeItem("key2"); // Just check there is no exception + + localStorage.clear(); + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); + +</script> + +</head> + +<body onload="startTest();"> + +</body> +</html> diff --git a/dom/tests/mochitest/localstorage/test_localStorageCookieSettings.html b/dom/tests/mochitest/localstorage/test_localStorageCookieSettings.html new file mode 100644 index 000000000..99f3b1ace --- /dev/null +++ b/dom/tests/mochitest/localstorage/test_localStorageCookieSettings.html @@ -0,0 +1,59 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>localStorage cookies settings test</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" /> + +</head> +<body> +<iframe></iframe> + +<script type="text/javascript"> + +SimpleTest.waitForExplicitFinish(); + +// Set cookies behavior to "always reject". +SpecialPowers.pushPrefEnv({"set": [["network.cookie.cookieBehavior", 2]]}, + test1); + +function test1() { + try { + localStorage.setItem("contentkey", "test-value"); + ok(false, "Setting localStorageItem should throw a security exception"); + } + catch(ex) { + is(ex.name, "SecurityError"); + } + + // Set cookies behavior to "reject 3rd party" + SpecialPowers.pushPrefEnv({"set": [["network.cookie.cookieBehavior", 1]], + "clear": [["network.cookie.lifetimePolicy"]]}, + test3); +} + +function test3() { + try { + localStorage.setItem("contentkey", "test-value"); + ok(true, "Setting localStorageItem should not throw a security exception"); + } + catch(ex) { + ok(false, "Setting localStorageItem should not throw a security exception"); + } + + var fileTest = (location.protocol + "//example.com" + location.pathname) + .replace("test_l", "frameL"); + + var myframe = document.querySelector("iframe"); + myframe.src = fileTest; +} + +// Called by interOriginTest.js +function doNextTest() { + SimpleTest.finish(); +} + +</script> +</body> +</html> diff --git a/dom/tests/mochitest/localstorage/test_localStorageEnablePref.html b/dom/tests/mochitest/localstorage/test_localStorageEnablePref.html new file mode 100644 index 000000000..88fd81e0b --- /dev/null +++ b/dom/tests/mochitest/localstorage/test_localStorageEnablePref.html @@ -0,0 +1,65 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>localStorage enable preference 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"> + +SimpleTest.requestCompleteLog(); + +function checkException(func, exc) +{ + var exceptionThrew = false; + try { + func(); + } + catch (ex) { + exceptionThrew = true; + is(ex.name, exc, "Expected "+exc+" exception"); + if (ex.name != exc) { + info("The exception which was thrown is: " + ex); + } + } + ok(exceptionThrew, "Exception "+exc+" threw"); +} + +var storage; +function test1() { + is(typeof(window.localStorage), "object", "Storage is present"); + storage = window.localStorage; + + SpecialPowers.pushPrefEnv({"set": [["dom.storage.enabled", false]]}, test2); +} + +function test2() { + is(window.localStorage, null, "Storage is null"); + + checkException(function() {storage.setItem("test", "value");}, "SecurityError"); + + SpecialPowers.pushPrefEnv({"set": [["dom.storage.enabled", true]]}, test3); +} + +function test3() { + is(typeof(window.localStorage), "object", "Storage is present again"); + storage.setItem("test", "value"); + ok(storage.getItem("test"), "value", "value can be set"); + window.localStorage.clear(); + SimpleTest.finish(); +} + +function doTest() { + SpecialPowers.pushPrefEnv({"set": [["dom.storage.enabled", true]]}, test1); +} + +SimpleTest.waitForExplicitFinish(); + +</script> + +</head> + +<body onload="doTest();"> + +</body> +</html> diff --git a/dom/tests/mochitest/localstorage/test_localStorageFromChrome.xhtml b/dom/tests/mochitest/localstorage/test_localStorageFromChrome.xhtml new file mode 100644 index 000000000..22665b008 --- /dev/null +++ b/dom/tests/mochitest/localstorage/test_localStorageFromChrome.xhtml @@ -0,0 +1,58 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>localStorage 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() +{ + var url = "http://example.com/tests/dom/tests/mochitest/localstorage/frameChromeSlave.html"; + var ios = Components.classes["@mozilla.org/network/io-service;1"] + .getService(Components.interfaces.nsIIOService); + var ssm = Components.classes["@mozilla.org/scriptsecuritymanager;1"] + .getService(Components.interfaces.nsIScriptSecurityManager); + var dsm = Components.classes["@mozilla.org/dom/localStorage-manager;1"] + .getService(Components.interfaces.nsIDOMStorageManager); + + var uri = ios.newURI(url, "", null); + var principal = ssm.createCodebasePrincipal(uri, {}); + var storage = dsm.createStorage(window, principal, ""); + + storage.setItem("chromekey", "chromevalue"); + + var aframe = document.getElementById("aframe"); + aframe.onload = function() + { + is(storage.getItem("chromekey"), "chromevalue"); + is(aframe.contentDocument.getElementById("data").innerHTML, "chromevalue"); + SimpleTest.finish(); + } + aframe.src = "http://example.com/tests/dom/tests/mochitest/localstorage/frameChromeSlave.html"; + + // Additionally check that we do not crash when we access the localStorage + // object in the owning chrome window (but we should throw). See bug 485396. + var exceptionCaught = false; + try { + localStorage; + } + 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.waitForExplicitFinish(); + +</script> + +</head> + +<body onload="startTest();"> + <iframe src="" id="aframe"></iframe> +</body> +</html> diff --git a/dom/tests/mochitest/localstorage/test_localStorageKeyOrder.html b/dom/tests/mochitest/localstorage/test_localStorageKeyOrder.html new file mode 100644 index 000000000..ecc0af8ee --- /dev/null +++ b/dom/tests/mochitest/localstorage/test_localStorageKeyOrder.html @@ -0,0 +1,73 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>localStorage key order test</title> + +<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + +<!-- + Check we preserve order of keys in localStorage when + keys are just modified. When a new key is added or + a key is removed order is again unspecified. +--> + +<script type="text/javascript"> + +function startTest() +{ + try + { + var keyNames = new Array; + localStorage.a = "1"; + localStorage.b = "2"; + localStorage.c = "3"; + localStorage.d = "4"; + localStorage.e = "5"; + + is(localStorage.a, "1", "a = 1"); + is(localStorage.b, "2", "b = 2"); + is(localStorage.c, "3", "c = 3"); + is(localStorage.d, "4", "d = 4"); + is(localStorage.e, "5", "e = 5"); + is(localStorage.length, 5, "length = 5"); + + for (var i = 0; i < localStorage.length; ++i) + keyNames[i] = localStorage.key(i); + + localStorage.a = "10"; + localStorage.b = "20"; + localStorage.c = "30"; + localStorage.d = "40"; + localStorage.e = "50"; + + is(localStorage.a, "10", "a = 10"); + is(localStorage.b, "20", "b = 20"); + is(localStorage.c, "30", "c = 30"); + is(localStorage.d, "40", "d = 40"); + is(localStorage.e, "50", "e = 50"); + is(localStorage.length, 5, "length = 5"); + + for (var i = 0; i < localStorage.length; ++i) + is(keyNames[i], localStorage.key(i), "key "+keyNames[i]+" on same index"); + + keyNamesStringify = "[\"" + keyNames.join("\",\"") + "\"]"; + frame.location = "http://mochi.test:8888/tests/dom/tests/mochitest/localstorage/frameOrder.html?" + + keyNamesStringify; + } + catch (ex) + { + localStorage.clear(); + throw ex; + } +} + +SimpleTest.waitForExplicitFinish(); + +</script> + +</head> + +<body onload="startTest();"> + <iframe src="" name="frame"></frame> +</body> +</html> diff --git a/dom/tests/mochitest/localstorage/test_localStorageOriginsDiff.html b/dom/tests/mochitest/localstorage/test_localStorageOriginsDiff.html new file mode 100644 index 000000000..96a93171c --- /dev/null +++ b/dom/tests/mochitest/localstorage/test_localStorageOriginsDiff.html @@ -0,0 +1,41 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>localStorage different origins</title> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="interOriginTest2.js"></script> + +<!-- + This test loads two frames from different + origins and checks that entries of localStorage + objects don't leak each between other. + + The subsystem is based on postMessage and addEventListener + to send messages among different origins. The subsystem waits + for both frames be loaded and then alternately calls each frames' + doStep() function that on each call proceeds with a single step + of the test on its side. This way the subsystem alternate between + both frames until both sequences completely finish. +--> + +<script type="text/javascript"> + +function startTest() +{ + masterFrameOrigin = "http://example.org:80"; + slaveFrameOrigin = "http://example.com:80"; + + masterFrame.location = masterFrameOrigin + framePath + "frameMasterNotEqual.html"; + slaveFrame.location = slaveFrameOrigin + framePath + "frameSlaveNotEqual.html"; +} + +</script> + +</head> + +<body onload="startTest();"> + <iframe src="" name="masterFrame"></iframe> + <iframe src="" name="slaveFrame"></iframe> +</body> +</html> diff --git a/dom/tests/mochitest/localstorage/test_localStorageOriginsDomainDiffs.html b/dom/tests/mochitest/localstorage/test_localStorageOriginsDomainDiffs.html new file mode 100644 index 000000000..c1a441772 --- /dev/null +++ b/dom/tests/mochitest/localstorage/test_localStorageOriginsDomainDiffs.html @@ -0,0 +1,41 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>localStorage different domains</title> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="interOriginTest2.js"></script> + +<!-- + This test loads two frames from different + origins and checks that entries of localStorage + objects don't leak each between other. + + The subsystem is based on postMessage and addEventListener + to send messages among different origins. The subsystem waits + for both frames be loaded and then alternately calls each frames' + doStep() function that on each call proceeds with a single step + of the test on its side. This way the subsystem alternate between + both frames until both sequences completely finish. +--> + +<script type="text/javascript"> + +function startTest() +{ + masterFrameOrigin = "http://example.org:80"; + slaveFrameOrigin = "http://test1.example.org:80"; + + masterFrame.location = masterFrameOrigin + framePath + "frameMasterNotEqual.html"; + slaveFrame.location = slaveFrameOrigin + framePath + "frameSlaveNotEqual.html"; +} + +</script> + +</head> + +<body onload="startTest();"> + <iframe src="" name="masterFrame"></iframe> + <iframe src="" name="slaveFrame"></iframe> +</body> +</html> diff --git a/dom/tests/mochitest/localstorage/test_localStorageOriginsEquals.html b/dom/tests/mochitest/localstorage/test_localStorageOriginsEquals.html new file mode 100644 index 000000000..35cdd86b3 --- /dev/null +++ b/dom/tests/mochitest/localstorage/test_localStorageOriginsEquals.html @@ -0,0 +1,42 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>localStorage equal origins</title> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="interOriginTest2.js"></script> + +<!-- + This test loads two frames from equal + origins and checks that entries of localStorage + objects are kept up-to-date and synchronized + between both frames. + + The subsystem is based on postMessage and addEventListener + to send messages among different origins. The subsystem waits + for both frames be loaded and then alternately calls each frames' + doStep() function that on each call proceeds with a single step + of the test on its side. This way the subsystem alternate between + both frames until both sequences completely finish. +--> + +<script type="text/javascript"> + +function startTest() +{ + masterFrameOrigin = "http://example.org:80"; + slaveFrameOrigin = "http://example.org:80"; + + masterFrame.location = masterFrameOrigin + framePath + "frameMasterEqual.html"; + slaveFrame.location = slaveFrameOrigin + framePath + "frameSlaveEqual.html"; +} + +</script> + +</head> + +<body onload="startTest();"> + <iframe src="" name="masterFrame"></iframe> + <iframe src="" name="slaveFrame"></iframe> +</body> +</html> diff --git a/dom/tests/mochitest/localstorage/test_localStorageOriginsPortDiffs.html b/dom/tests/mochitest/localstorage/test_localStorageOriginsPortDiffs.html new file mode 100644 index 000000000..d34e0dbcd --- /dev/null +++ b/dom/tests/mochitest/localstorage/test_localStorageOriginsPortDiffs.html @@ -0,0 +1,41 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>localStorage different port numbers</title> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="interOriginTest2.js"></script> + +<!-- + This test loads two frames from different + origins and checks that entries of localStorage + objects don't leak each between other. + + The subsystem is based on postMessage and addEventListener + to send messages among different origins. The subsystem waits + for both frames be loaded and then alternately calls each frames' + doStep() function that on each call proceeds with a single step + of the test on its side. This way the subsystem alternate between + both frames until both sequences completely finish. +--> + +<script type="text/javascript"> + +function startTest() +{ + masterFrameOrigin = "http://example.org:80"; + slaveFrameOrigin = "http://example.org:8000"; + + masterFrame.location = masterFrameOrigin + framePath + "frameMasterNotEqual.html"; + slaveFrame.location = slaveFrameOrigin + framePath + "frameSlaveNotEqual.html"; +} + +</script> + +</head> + +<body onload="startTest();"> + <iframe src="" name="masterFrame"></iframe> + <iframe src="" name="slaveFrame"></iframe> +</body> +</html> diff --git a/dom/tests/mochitest/localstorage/test_localStorageOriginsSchemaDiffs.html b/dom/tests/mochitest/localstorage/test_localStorageOriginsSchemaDiffs.html new file mode 100644 index 000000000..57e4fb5ab --- /dev/null +++ b/dom/tests/mochitest/localstorage/test_localStorageOriginsSchemaDiffs.html @@ -0,0 +1,41 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>localStorage different domains</title> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="interOriginTest2.js"></script> + +<!-- + This test loads two frames from different + origins and checks that entries of localStorage + objects don't leak each between other. + + The subsystem is based on postMessage and addEventListener + to send messages among different origins. The subsystem waits + for both frames be loaded and then alternately calls each frames' + doStep() function that on each call proceeds with a single step + of the test on its side. This way the subsystem alternate between + both frames until both sequences completely finish. +--> + +<script type="text/javascript"> + +function startTest() +{ + masterFrameOrigin = "http://example.com"; + slaveFrameOrigin = "https://example.com"; + + masterFrame.location = masterFrameOrigin + framePath + "frameMasterNotEqual.html"; + slaveFrame.location = slaveFrameOrigin + framePath + "frameSlaveNotEqual.html"; +} + +</script> + +</head> + +<body onload="startTest();"> + <iframe src="" name="masterFrame"></iframe> + <iframe src="" name="slaveFrame"></iframe> +</body> +</html> diff --git a/dom/tests/mochitest/localstorage/test_localStorageQuota.html b/dom/tests/mochitest/localstorage/test_localStorageQuota.html new file mode 100644 index 000000000..6aeefe6bc --- /dev/null +++ b/dom/tests/mochitest/localstorage/test_localStorageQuota.html @@ -0,0 +1,111 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>localStorage and DOM quota test</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"> +//Note: this test is currently giving failures when running standalone, see bug 914865 + +var currentTest = 1; + +function doNextTest() +{ + slave = frame; + + switch (currentTest) + { + case 1: + slaveOrigin = "http://example.com"; + slave.location = slaveOrigin + slavePath + "frameQuota.html?add&A&success"; + break; + + // In subdomain now set another key with length 500 bytes, i.e. + // allocate 501 bytes + case 2: + slaveOrigin = "http://test1.example.com"; + slave.location = slaveOrigin + slavePath + "frameQuota.html?add&B&success"; + break; + + // Try to set the same key value again to check we don't fail + // even 1002 bytes has already been exhausted from the quota + // We just change the value of an existing key. + case 3: + slaveOrigin = "http://test1.example.com"; + slave.location = slaveOrigin + slavePath + "frameQuota.html?add&B&success"; + break; + + // Try to set the same key to a larger value that would lead to + // quota reach and check that the value is still the old one + case 4: + slaveOrigin = "http://test1.example.com"; + slave.location = slaveOrigin + slavePath + "frameQuota.html?add2&B&failure"; + break; + + // In a different subdomain try to set a new 500 bytes key + // and check we fail because we are over the quota + case 5: + slaveOrigin = "https://test2.example.com"; + slave.location = slaveOrigin + slavePath + "frameQuota.html?add&C&failure"; + break; + + // Remove from the second subdomain the second key, it must not fail + // This should release the allocated space of the quota assigned to + // example.com. + case 6: + slaveOrigin = "http://test1.example.com"; + slave.location = slaveOrigin + slavePath + "frameQuota.html?remove&B&success"; + break; + + // Now try again to set 500 bytes key, it must succeed. + case 7: + slaveOrigin = "https://test2.example.com"; + slave.location = slaveOrigin + slavePath + "frameQuota.html?add&C&success"; + break; + + case 8: + // Do a clean up... + slaveOrigin = "http://example.com"; + slave.location = slaveOrigin + slavePath + "frameQuota.html?clear"; + break; + + case 9: + // Do a clean up... + slaveOrigin = "http://test1.example.com"; + slave.location = slaveOrigin + slavePath + "frameQuota.html?clear"; + break; + + case 10: + // Do a clean up... + slaveOrigin = "https://test2.example.com"; + slave.location = slaveOrigin + slavePath + "frameQuota.html?clear"; + break; + + default: // end + SimpleTest.finish(); + } + + ++currentTest; +} + +function doStep() +{ +} + +SimpleTest.waitForExplicitFinish(); + +function startTest() { + // Initialy setup the quota to testing value of 1024B and + // set a 500 bytes key with name length 1 (allocate 501 bytes) + SpecialPowers.pushPrefEnv({"set": [["dom.storage.default_quota", 1], ["security.mixed_content.block_display_content", false], ["security.mixed_content.block_active_content", false]]}, doNextTest); +} +</script> + +</head> + +<body onload="startTest();"> + <iframe src="" name="frame"></iframe> +</body> +</html> diff --git a/dom/tests/mochitest/localstorage/test_localStorageQuotaPrivateBrowsing_perwindowpb.html b/dom/tests/mochitest/localstorage/test_localStorageQuotaPrivateBrowsing_perwindowpb.html new file mode 100644 index 000000000..24d3e4ba3 --- /dev/null +++ b/dom/tests/mochitest/localstorage/test_localStorageQuotaPrivateBrowsing_perwindowpb.html @@ -0,0 +1,192 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>localStorage and DOM quota 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"> +SimpleTest.waitForExplicitFinish(); + +Components.utils.import("resource://gre/modules/Services.jsm"); + +const Ci = Components.interfaces; +const CONTENT_PAGE = "http://mochi.test:8888/chrome/dom/tests/mochitest/localstorage/page_blank.html"; +const slavePath = "/chrome/dom/tests/mochitest/localstorage/"; +var currentTest = 1; +var quota; + +try { + quota = Services.prefs.getIntPref("dom.storage.default_quota"); +} catch (ex) { + quota = 5 * 1024; +} +Services.prefs.setIntPref("browser.startup.page", 0); +Services.prefs.setIntPref("dom.storage.default_quota", 1); + +var slaveLoadsPending = 1; +var slaveOrigin = ""; +var slave = null; +var failureRegExp = new RegExp("^FAILURE"); + +function startTest() { + testOnWindow(true, function(aWindow) { + info("Private window loaded"); + var frame = aWindow.content.document.createElement("iframe"); + aWindow.content.document.body.appendChild(frame); + aWindow.content.addEventListener("message", function(aEvent) { + onMessageReceived(aEvent, aWindow) + }, false); + slave = aWindow.content.frames[0]; + + SimpleTest.waitForFocus(() => doNextTest(aWindow), aWindow); + }); +} + +function doNextTest(aWindow) { + info("Running test: " + currentTest); + switch (currentTest) { + // Initialy setup the quota to testing value of 1024B and + // set a 500 bytes key with name length 1 (allocate 501 bytes) + case 1: + slaveOrigin = "http://example.com"; + slave.location = slaveOrigin + slavePath + "frameQuota.html?add&A&success"; + break; + + // In subdomain now set another key with length 500 bytes, i.e. + // allocate 501 bytes + case 2: + slaveOrigin = "http://test1.example.com"; + slave.location = slaveOrigin + slavePath + "frameQuota.html?add&B&success"; + break; + + // Try to set the same key value again to check we don't fail + // even 1002 bytes has already been exhausted from the quota + // We just change the value of an existing key. + case 3: + slaveOrigin = "http://test1.example.com"; + slave.location = slaveOrigin + slavePath + "frameQuota.html?add&B&success"; + break; + + // Try to set the same key to a larger value that would lead to + // quota reach and check that the value is still the old one + case 4: + slaveOrigin = "http://test1.example.com"; + slave.location = slaveOrigin + slavePath + "frameQuota.html?add2&B&failure"; + break; + + // In a different subdomain try to set a new 500 bytes key + // and check we fail because we are over the quota + case 5: + slaveOrigin = "https://test2.example.com"; + slave.location = slaveOrigin + slavePath + "frameQuota.html?add&C&failure"; + break; + + // Remove from the second subdomain the second key, it must not fail + // This should release the allocated space of the quota assigned to + // example.com. + case 6: + slaveOrigin = "http://test1.example.com"; + slave.location = slaveOrigin + slavePath + "frameQuota.html?remove&B&success"; + break; + + // Now try again to set 500 bytes key, it must succeed. + case 7: + slaveOrigin = "https://test2.example.com"; + slave.location = slaveOrigin + slavePath + "frameQuota.html?add&C&success"; + break; + + case 8: + // Do a clean up... + // TODO Bug 455070, use just ?clear what invokes call + // of clear() in the target frame. W/o clear method we must + // call clear implemented as removeItem for each item in + // the localStorage. + slaveOrigin = "http://example.com"; + slave.location = slaveOrigin + slavePath + "frameQuota.html?clear&A&"; + break; + + case 9: + // Do a clean up... + slaveOrigin = "http://test1.example.com"; + slave.location = slaveOrigin + slavePath + "frameQuota.html?clear&B&"; + break; + + case 10: + // Do a clean up... + slaveOrigin = "https://test2.example.com"; + slave.location = slaveOrigin + slavePath + "frameQuota.html?clear&C&"; + break; + + default: + Services.prefs.clearUserPref("browser.startup.page") + Services.prefs.setIntPref("dom.storage.default_quota", quota); + aWindow.close(); + SimpleTest.finish(); + } + + ++currentTest; +} + +function onMessageReceived(event, aWindow) { + info("Message received: " + 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": + // postMessage should send to the slaveOrigin. However with the addition of private + // browsing flags in origin attributes this will cause postMessage to fail. The origin of this + // window has false privatebrowsing, while the recipient is in a private window. + // To fix this issue and preserve the integrity of the test a * is passed to get around origin equality. + slave.postMessage("step", "*"); + break; + // Indication of all test parts finish (from any of the frames) + case "done": + aWindow.content.localStorage.clear(); + slaveLoadsPending = 1; + doNextTest(aWindow); + break; + // Any other message indicates error or succes message of a test + default: + SimpleTest.ok(!event.data.match(failureRegExp), event.data); + break; + } +} + +function whenDelayedStartupFinished(aWindow, aCallback) { + Services.obs.addObserver(function observer(aSubject, aTopic) { + if (aWindow == aSubject) { + Services.obs.removeObserver(observer, aTopic); + } + + if (aWindow.content == null || aWindow.content.location.href != CONTENT_PAGE ) { + aWindow.addEventListener("DOMContentLoaded", function onInnerLoad() { + aWindow.removeEventListener("DOMContentLoaded", onInnerLoad, true); + SimpleTest.executeSoon(function() { aCallback(aWindow); }); + }, true); + + aWindow.gBrowser.loadURI(CONTENT_PAGE); + } + }, "browser-delayed-startup-finished", false); +} + +function testOnWindow(aIsPrivate, callback) { + var mainWindow = window.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIWebNavigation) + .QueryInterface(Ci.nsIDocShellTreeItem) + .rootTreeItem + .QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDOMWindow); + + var win = mainWindow.OpenBrowserWindow({private: aIsPrivate}); + whenDelayedStartupFinished(win, function() { callback(win); }); +}; +</script> +</head> +<body onload="startTest();"> +</body> +</html> diff --git a/dom/tests/mochitest/localstorage/test_localStorageQuotaSessionOnly.html b/dom/tests/mochitest/localstorage/test_localStorageQuotaSessionOnly.html new file mode 100644 index 000000000..585da7ceb --- /dev/null +++ b/dom/tests/mochitest/localstorage/test_localStorageQuotaSessionOnly.html @@ -0,0 +1,112 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>localStorage and DOM quota test</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; + +function doNextTest() +{ + slave = frame; + + switch (currentTest) + { + case 1: + slaveOrigin = "http://example.com"; + slave.location = slaveOrigin + slavePath + "frameQuotaSessionOnly.html?add&A&success"; + break; + + // In subdomain now set another key with length 500 bytes, i.e. + // allocate 501 bytes + case 2: + slaveOrigin = "http://test1.example.com"; + slave.location = slaveOrigin + slavePath + "frameQuotaSessionOnly.html?add&B&success"; + break; + + // Try to set the same key value again to check we don't fail + // even 1002 bytes has already been exhausted from the quota + // We just change the value of an existing key. + case 3: + slaveOrigin = "http://test1.example.com"; + slave.location = slaveOrigin + slavePath + "frameQuotaSessionOnly.html?add&B&success"; + break; + + // Try to set the same key to a larger value that would lead to + // quota reach and check that the value is still the old one + case 4: + slaveOrigin = "http://test1.example.com"; + slave.location = slaveOrigin + slavePath + "frameQuotaSessionOnly.html?add2&B&failure"; + break; + + // In a different subdomain try to set a new 500 bytes key + // and check we fail because we are over the quota + case 5: + slaveOrigin = "https://test2.example.com"; + slave.location = slaveOrigin + slavePath + "frameQuotaSessionOnly.html?add&C&failure"; + break; + + // Remove from the second subdomain the second key, it must not fail + // This should release the allocated space of the quota assigned to + // example.com. + case 6: + slaveOrigin = "http://test1.example.com"; + slave.location = slaveOrigin + slavePath + "frameQuotaSessionOnly.html?remove&B&success"; + break; + + // Now try again to set 500 bytes key, it must succeed. + case 7: + slaveOrigin = "https://test2.example.com"; + slave.location = slaveOrigin + slavePath + "frameQuotaSessionOnly.html?add&C&success"; + break; + + case 8: + // Do a clean up... + slaveOrigin = "http://example.com"; + slave.location = slaveOrigin + slavePath + "frameQuotaSessionOnly.html?clear"; + break; + + case 9: + // Do a clean up... + slaveOrigin = "http://test1.example.com"; + slave.location = slaveOrigin + slavePath + "frameQuotaSessionOnly.html?clear"; + break; + + case 10: + // Do a clean up... + slaveOrigin = "https://test2.example.com"; + slave.location = slaveOrigin + slavePath + "frameQuotaSessionOnly.html?clear"; + break; + + default: + SimpleTest.finish(); + } + + ++currentTest; +} + +function doStep() +{ +} + +SimpleTest.waitForExplicitFinish(); + +function startTest() { + SpecialPowers.pushPermissions([{'type': 'cookie', 'allow': SpecialPowers.Ci.nsICookiePermission.ACCESS_SESSION, 'context': document}], function() { + // Initialy setup the quota to testing value of 1024B and + // set a 500 bytes key with name length 1 (allocate 501 bytes) + SpecialPowers.pushPrefEnv({"set": [["dom.storage.default_quota", 1], ["security.mixed_content.block_display_content", false], ["security.mixed_content.block_active_content", false]]}, doNextTest); + }); +} +</script> + +</head> + +<body onload="startTest();"> + <iframe src="" name="frame"></iframe> +</body> +</html> diff --git a/dom/tests/mochitest/localstorage/test_localStorageQuotaSessionOnly2.html b/dom/tests/mochitest/localstorage/test_localStorageQuotaSessionOnly2.html new file mode 100644 index 000000000..1c1a70537 --- /dev/null +++ b/dom/tests/mochitest/localstorage/test_localStorageQuotaSessionOnly2.html @@ -0,0 +1,98 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>localStorage and DOM quota test</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; + +function doNextTest() +{ + slave = frame; + + switch (currentTest) + { + case 1: + slaveOrigin = "http://example.com"; + slave.location = slaveOrigin + slavePath + "frameQuotaSessionOnly.html?add&A&success"; + break; + + // In subdomain now set another key with length 500 bytes, i.e. + // allocate 501 bytes + case 2: + slaveOrigin = "http://example.com"; + slave.location = slaveOrigin + slavePath + "frameQuotaSessionOnly.html?add&B&success"; + break; + + // Try to set the same key value again to check we don't fail + // even 1002 bytes has already been exhausted from the quota + // We just change the value of an existing key. + case 3: + slaveOrigin = "http://example.com"; + slave.location = slaveOrigin + slavePath + "frameQuotaSessionOnly.html?add&B&success"; + break; + + // Try to set the same key to a larger value that would lead to + // quota reach and check that the value is still the old one + case 4: + slaveOrigin = "http://example.com"; + slave.location = slaveOrigin + slavePath + "frameQuotaSessionOnly.html?add2&B&failure"; + break; + + // Try to set a new 500 bytes key + // and check we fail because we are over the quota + case 5: + slaveOrigin = "https://example.com"; + slave.location = slaveOrigin + slavePath + "frameQuotaSessionOnly.html?add&C&failure"; + break; + + // Remove the key inherited from the non-session-only database + case 6: + slaveOrigin = "http://example.com"; + slave.location = slaveOrigin + slavePath + "frameQuotaSessionOnly.html?remove&A&success"; + break; + + // Now try again to set 500 bytes key, it must succeed. + case 7: + slaveOrigin = "https://example.com"; + slave.location = slaveOrigin + slavePath + "frameQuotaSessionOnly.html?add&C&success"; + break; + + case 8: + // Do a clean up... + slaveOrigin = "http://example.com"; + slave.location = slaveOrigin + slavePath + "frameQuotaSessionOnly.html?clear"; + break; + + default: + SimpleTest.finish(); + } + + ++currentTest; +} + +function doStep() +{ +} + +SimpleTest.waitForExplicitFinish(); + +function startTest() { + // Initialy setup the quota to testing value of 1024B and + // set a 500 bytes key with name length 1 (allocate 501 bytes) + SpecialPowers.pushPrefEnv({"set": [["dom.storage.default_quota", 1], ["security.mixed_content.block_display_content", false], ["security.mixed_content.block_active_content", false]]}, function() { + SpecialPowers.pushPermissions([{'type': 'cookie', 'allow': SpecialPowers.Ci.nsICookiePermission.ACCESS_SESSION, 'context': document}], doNextTest); + }); +} +</script> + +</head> + +<body onload="startTest();"> + <iframe src="" name="frame"></iframe> +</body> +</html> diff --git a/dom/tests/mochitest/localstorage/test_localStorageReplace.html b/dom/tests/mochitest/localstorage/test_localStorageReplace.html new file mode 100644 index 000000000..e1412eaef --- /dev/null +++ b/dom/tests/mochitest/localstorage/test_localStorageReplace.html @@ -0,0 +1,80 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>localStorage replace test</title> + +<!-- + This test checks that localStorage 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) +{ + switch (event.data) + { + case "init_done": + // This is frame with different origin in the same browsing context + // as the first frame adding data to localStorage of the first origin. + shell.location = "http://example.com:80/tests/dom/tests/mochitest/localstorage/frameReplace.html?check&" + shellType; + break; + + case "check_done": + // Clean the localStorage of the first origin. + shell.location = "http://example.org:80/tests/dom/tests/mochitest/localstorage/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:80/tests/dom/tests/mochitest/localstorage/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() { + SpecialPowers.pushPrefEnv({"set": [["security.mixed_content.block_display_content", false], ["security.mixed_content.block_active_content", false]]}, test1); +} + +function test1() { + shellType = "frame"; + shell = frame; + shell.location = "http://example.org:80/tests/dom/tests/mochitest/localstorage/frameReplace.html?init&" + shellType; +} + +SimpleTest.waitForExplicitFinish(); + +</script> + +</head> + +<body onload="startTest();"> + <iframe src="" name="frame"></iframe> +</body> +</html> diff --git a/dom/tests/mochitest/localstorage/test_localStorageSessionPrefOverride.html b/dom/tests/mochitest/localstorage/test_localStorageSessionPrefOverride.html new file mode 100644 index 000000000..9fe6a48ec --- /dev/null +++ b/dom/tests/mochitest/localstorage/test_localStorageSessionPrefOverride.html @@ -0,0 +1,54 @@ +<html> + <head> + <title>Local Storage Session Pref Override</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script> + const ACCEPT_SESSION = 2; + + add_task(function*() { + yield new Promise((resolve, reject) => { + SpecialPowers.pushPrefEnv({"set": [["network.cookie.lifetimePolicy", + ACCEPT_SESSION]]}, + resolve); + }); + + // Before setting permission + yield new Promise((resolve) => { + var frame = document.createElement('iframe'); + frame.src = "frameLocalStorageSessionOnly.html"; + + var listener = (e) => { + is(e.data, true, "Before adding permission should be session only"); + window.removeEventListener('message', listener); + resolve(); + }; + window.addEventListener('message', listener); + document.body.appendChild(frame); + }); + + // After setting permission + yield new Promise((resolve) => { + SpecialPowers.pushPermissions([{"type": "cookie", "allow": 1, "context": document}], + resolve); + }); + + yield new Promise((resolve) => { + var frame = document.createElement('iframe'); + frame.src = "frameLocalStorageSessionOnly.html"; + + var listener = (e) => { + is(e.data, false, "After adding permission should not be session only"); + window.removeEventListener('message', listener); + resolve(); + }; + window.addEventListener('message', listener); + document.body.appendChild(frame); + }); + }); + </script> + </head> + <body> + </body> +</html> diff --git a/dom/tests/mochitest/localstorage/test_lowDeviceStorage.html b/dom/tests/mochitest/localstorage/test_lowDeviceStorage.html new file mode 100644 index 000000000..046587150 --- /dev/null +++ b/dom/tests/mochitest/localstorage/test_lowDeviceStorage.html @@ -0,0 +1,76 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>Test localStorage usage while in a low device storage situation</title> + +<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> +<script type="text/javascript" src="localStorageCommon.js"></script> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + +<script type="text/javascript"> + +/* +This test does the following: +- Stores an item in localStorage. +- Checks the stored value. +- Emulates a low device storage situation. +- Gets the stored item again. +- Removes the stored item. +- Fails storing a new value. +- Emulates recovering from a low device storage situation. +- Stores a new value. +- Checks the stored value. +*/ + +function lowDeviceStorage(lowStorage) { + var data = lowStorage ? "full" : "free"; + os().notifyObservers(null, "disk-space-watcher", data); +} + +function startTest() { + // Add a test item. + localStorage.setItem("item", "value"); + is(localStorage.getItem("item"), "value", "getItem()"); + + // Emulates a low device storage situation. + lowDeviceStorage(true); + + // Checks that we can still access to the stored item. + is(localStorage.getItem("item"), "value", + "getItem() during a device storage situation"); + + // Removes the stored item. + localStorage.removeItem("item"); + is(localStorage.getItem("item"), null, + "getItem() after removing the item"); + + // Fails storing a new item. + try { + localStorage.setItem("newItem", "value"); + ok(false, "Storing a new item is expected to fail"); + } catch(e) { + ok(true, "Got an expected exception " + e); + } finally { + is(localStorage.getItem("newItem"), null, + "setItem while device storage is low"); + } + + // Emulates recovering from a low device storage situation. + lowDeviceStorage(false); + + // Add a test item after recovering from the low device storage situation. + localStorage.setItem("newItem", "value"); + is(localStorage.getItem("newItem"), "value", + "getItem() with available storage"); + + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); + +</script> + +</head> + +<body onload="startTest();"> +</body> +</html> diff --git a/dom/tests/mochitest/localstorage/test_storageConstructor.html b/dom/tests/mochitest/localstorage/test_storageConstructor.html new file mode 100644 index 000000000..f77c80ae2 --- /dev/null +++ b/dom/tests/mochitest/localstorage/test_storageConstructor.html @@ -0,0 +1,35 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>Storage interface</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"> + +function startTest() +{ + var functionCalled = false; + is(localStorage instanceof Storage, true, "localStorage is instance of Storage"); + Storage.prototype.exists = function(key) { + functionCalled = true; + return this.getItem(key) != null; + } + localStorage.setItem("test_prototype", "value"); + is(functionCalled, false, "Overridden function not called"); + is(localStorage.exists("test_prototype"), true, "Prototype overridden"); + is(functionCalled, true, "Overridden function called"); + localStorage.clear(); + + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); + +</script> + +</head> + +<body onload="startTest();"> +</body> +</html> |