summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/clear-site-data/support/test_utils.sub.js
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /testing/web-platform/tests/clear-site-data/support/test_utils.sub.js
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--testing/web-platform/tests/clear-site-data/support/test_utils.sub.js261
1 files changed, 261 insertions, 0 deletions
diff --git a/testing/web-platform/tests/clear-site-data/support/test_utils.sub.js b/testing/web-platform/tests/clear-site-data/support/test_utils.sub.js
new file mode 100644
index 0000000000..71fc79c420
--- /dev/null
+++ b/testing/web-platform/tests/clear-site-data/support/test_utils.sub.js
@@ -0,0 +1,261 @@
+var TestUtils = (function() {
+ function randomString() {
+ var result = "";
+ for (var i = 0; i < 5; i++)
+ result += String.fromCharCode(97 + Math.floor(Math.random() * 26));
+ return result;
+ };
+
+ /**
+ * Representation of one datatype.
+ * @typedef Datatype
+ * @type{object}
+ * @property{string} name Name of the datatype.
+ * @property{function():boolean} supported
+ * Whether this datatype is supported by this user agent.
+ * @method{function():Void} add A function to add an instance of the datatype.
+ * @method{function():boolean} isEmpty A function that tests whether
+ * the datatype's storage backend is empty.
+ */
+ var Datatype;
+
+ var TestUtils = {};
+
+ /**
+ * Various storage backends that are part of the 'storage' datatype.
+ * @param{Array.<Datatype>}
+ */
+ TestUtils.STORAGE = [
+ {
+ "name": "local storage",
+ "supported": function() { return !!window.localStorage; },
+ "add": function() {
+ return new Promise(function(resolve, reject) {
+ localStorage.setItem(randomString(), randomString());
+ resolve();
+ });
+ },
+ "isEmpty": function() {
+ return new Promise(function(resolve, reject) {
+ resolve(!localStorage.length);
+ });
+ }
+ },
+ {
+ "name": "Indexed DB",
+ "supported": function() { return !!window.indexedDB; },
+ "add": function() {
+ return new Promise(function(resolve, reject) {
+ var request = window.indexedDB.open("database");
+ request.onupgradeneeded = function() {
+ request.result.createObjectStore("store");
+ };
+ request.onsuccess = function() {
+ request.result.close();
+ resolve();
+ }
+ });
+ },
+ "isEmpty": function() {
+ return new Promise(function(resolve, reject) {
+ var request = window.indexedDB.open("database");
+ request.onsuccess = function() {
+ var database = request.result;
+ try {
+ var transaction = database.transaction(["store"]);
+ resolve(false);
+ } catch(error) {
+ // The database is empty. However, by testing that, we have also
+ // created it, which means that |onupgradeneeded| in the "add"
+ // method will not run the next time. Delete the database before
+ // reporting that it was empty.
+ var deletion = window.indexedDB.deleteDatabase("database");
+ deletion.onsuccess = resolve.bind(this, true);
+ } finally {
+ database.close();
+ }
+ };
+ });
+ }
+ },
+ {
+ // TODO(@msramek): We should also test the PERSISTENT filesystem, however,
+ // that might require storage permissions.
+ "name": "filesystems",
+ "supported": function() {
+ return window.requestFileSystem || window.webkitRequestFileSystem;
+ },
+ "add": function() {
+ return new Promise(function(resolve, reject) {
+ var onSuccess = function(fileSystem) {
+ fileSystem.root.getFile('file', {"create": true}, resolve, resolve);
+ }
+ var onFailure = resolve;
+
+ var requestFileSystem =
+ window.requestFileSystem || window.webkitRequestFileSystem;
+ requestFileSystem(window.TEMPORARY, 1 /* 1B */,
+ onSuccess, onFailure);
+ });
+ },
+ "isEmpty": function() {
+ return new Promise(function(resolve, reject) {
+ var onSuccess = function(fileSystem) {
+ fileSystem.root.getFile(
+ 'file', {},
+ resolve.bind(this, false) /* opened successfully */,
+ resolve.bind(this, true) /* failed to open */);
+ }
+ var onFailure = resolve.bind(this, true);
+
+ var requestFileSystem =
+ window.requestFileSystem || window.webkitRequestFileSystem;
+ requestFileSystem(window.TEMPORARY, 1 /* 1B */,
+ onSuccess, onFailure);
+ });
+ }
+ },
+ {
+ "name": "service workers",
+ "supported": function() { return !!navigator.serviceWorker; },
+ "add": function() {
+ return navigator.serviceWorker.register(
+ "support/service_worker.js",
+ { scope: "support/page_using_service_worker.html"});
+ },
+ "isEmpty": function() {
+ return new Promise(function(resolve, reject) {
+ navigator.serviceWorker.getRegistrations()
+ .then(function(registrations) {
+ resolve(!registrations.length);
+ });
+ });
+ }
+ },
+ {
+ "name": "Storage Buckets",
+ "supported": function() { return !!navigator.storageBuckets; },
+ "add": function() {
+ return navigator.storageBuckets.open('inbox_bucket');
+ },
+ "isEmpty": function() {
+ return new Promise(async function(resolve, reject) {
+ var keys = await navigator.storageBuckets.keys();
+ resolve(!keys.includes('inbox_bucket'));
+ });
+ }
+ },
+ ].filter(function(backend) { return backend.supported(); });
+
+ /**
+ * All datatypes supported by Clear-Site-Data.
+ * @param{Array.<Datatype>}
+ */
+ TestUtils.DATATYPES = [
+ {
+ "name": "cookies",
+ "supported": function() { return typeof document.cookie == "string"; },
+ "add": function() {
+ return new Promise(function(resolve, reject) {
+ document.cookie = randomString() + "=" + randomString();
+ resolve();
+ });
+ },
+ "isEmpty": function() {
+ return new Promise(function(resolve, reject) {
+ resolve(!document.cookie);
+ });
+ }
+ },
+ {
+ "name": "storage",
+ "supported": TestUtils.STORAGE[0].supported,
+ "add": TestUtils.STORAGE[0].add,
+ "isEmpty": TestUtils.STORAGE[0].isEmpty,
+ }
+ ].filter(function(datatype) { return datatype.supported(); });
+
+ /**
+ * All possible combinations of datatypes.
+ * @property {Array.<Array.<Datatype>>}
+ */
+ TestUtils.COMBINATIONS = (function() {
+ var combinations = [];
+ for (var mask = 0; mask < (1 << TestUtils.DATATYPES.length); mask++) {
+ var combination = [];
+
+ for (var datatype = 0;
+ datatype < TestUtils.DATATYPES.length; datatype++) {
+ if (mask & (1 << datatype))
+ combination.push(TestUtils.DATATYPES[datatype]);
+ }
+
+ combinations.push(combination);
+ }
+ return combinations;
+ })();
+
+ /**
+ * Populates |datatypes| by calling the "add" method on each of them,
+ * and verifies that they are nonempty.
+ * @param {Array.<Datatype>} datatypes to be populated.
+ * @private
+ */
+ function populate(datatypes) {
+ return Promise.all(datatypes.map(function(datatype) {
+ return new Promise(function(resolve, reject) {
+ datatype.add().then(function() {
+ datatype.isEmpty().then(function(isEmpty) {
+ assert_false(
+ isEmpty,
+ datatype.name +
+ " has to be nonempty before the test starts.");
+ resolve();
+ });
+ });
+ });
+ }));
+ };
+
+ /**
+ * Ensures that all datatypes are nonempty. Should be called in the test
+ * setup phase.
+ */
+ TestUtils.populateDatatypes = populate.bind(this, TestUtils.DATATYPES);
+
+ /**
+ * Ensures that all backends of the "storage" datatype are nonempty. Should
+ * be called in the test setup phase.
+ */
+ TestUtils.populateStorage = populate.bind(this, TestUtils.STORAGE);
+
+ /**
+ * Get the support server URL that returns a Clear-Site-Data header
+ * to clear |datatypes|.
+ * @param{Array.<Datatype>} datatypes The list of datatypes to be deleted.
+ * @return string The URL to be queried.
+ */
+ TestUtils.getClearSiteDataUrl = function(datatypes) {
+ names = datatypes.map(function(e) { return e.name });
+ return "support/echo-clear-site-data.py?" + names.join("&");
+ }
+
+ /**
+ * @param{string} page_scheme Scheme of the page. "http" or "https".
+ * @param{string} resource_scheme Scheme of the resource. "http" or "https".
+ * @return The URL of a page that contains a resource requesting the deletion
+ * of storage.
+ */
+ TestUtils.getPageWithResourceUrl = function(page_scheme, resource_scheme) {
+ if (page_scheme != "https" && page_scheme != "http")
+ throw "Unsupported scheme: " + page_scheme;
+ if (resource_scheme != "https" && resource_scheme != "http")
+ throw "Unsupported scheme: " + resource_scheme;
+ return page_scheme + "://{{domains[]}}:" +
+ (page_scheme == "https" ? {{ports[https][0]}} : {{ports[http][0]}}) +
+ "/clear-site-data/support/page_with_resource.sub.html?scheme=" +
+ resource_scheme;
+ }
+
+ return TestUtils;
+})();