Bug 1539614 [wpt PR 16077] - HTML: move textarea tests together, a=testonly
[gecko.git] / testing / web-platform / tests / common / PrefixedLocalStorage.js
blob2f4e7b6a055caa3fdd8bfdfb383b34c496b60549
1 /**
2  * Supports pseudo-"namespacing" localStorage for a given test
3  * by generating and using a unique prefix for keys. Why trounce on other
4  * tests' localStorage items when you can keep it "separated"?
5  *
6  * PrefixedLocalStorageTest: Instantiate in testharness.js tests to generate
7  *   a new unique-ish prefix
8  * PrefixedLocalStorageResource: Instantiate in supporting test resource
9  *   files to use/share a prefix generated by a test.
10  */
11 var PrefixedLocalStorage = function () {
12   this.prefix = ''; // Prefix for localStorage keys
13   this.param = 'prefixedLocalStorage'; // Param to use in querystrings
16 PrefixedLocalStorage.prototype.clear = function () {
17   if (this.prefix === '') { return; }
18   Object.keys(localStorage).forEach(sKey => {
19     if (sKey.indexOf(this.prefix) === 0) {
20       localStorage.removeItem(sKey);
21     }
22   });
25 /**
26  * Append/replace prefix parameter and value in URI querystring
27  * Use to generate URLs to resource files that will share the prefix.
28  */
29 PrefixedLocalStorage.prototype.url = function (uri) {
30   function updateUrlParameter (uri, key, value) {
31     var i         = uri.indexOf('#');
32     var hash      = (i === -1) ? '' : uri.substr(i);
33     uri           = (i === -1) ? uri : uri.substr(0, i);
34     var re        = new RegExp(`([?&])${key}=.*?(&|$)`, 'i');
35     var separator = uri.indexOf('?') !== -1 ? '&' : '?';
36     uri = (uri.match(re)) ? uri.replace(re, `$1${key}=${value}$2`) :
37       `${uri}${separator}${key}=${value}`;
38     return uri + hash;
39   }
40   return updateUrlParameter(uri, this.param, this.prefix);
43 PrefixedLocalStorage.prototype.prefixedKey = function (baseKey) {
44   return `${this.prefix}${baseKey}`;
47 PrefixedLocalStorage.prototype.setItem = function (baseKey, value) {
48   localStorage.setItem(this.prefixedKey(baseKey), value);
51 /**
52  * Listen for `storage` events pertaining to a particular key,
53  * prefixed with this object's prefix. Ignore when value is being set to null
54  * (i.e. removeItem).
55  */
56 PrefixedLocalStorage.prototype.onSet = function (baseKey, fn) {
57   window.addEventListener('storage', e => {
58     var match = this.prefixedKey(baseKey);
59     if (e.newValue !== null && e.key.indexOf(match) === 0) {
60       fn.call(this, e);
61     }
62   });
65 /*****************************************************************************
66  * Use in a testharnessjs test to generate a new key prefix.
67  * async_test(t => {
68  *   var prefixedStorage = new PrefixedLocalStorageTest();
69  *   t.add_cleanup(() => prefixedStorage.cleanup());
70  *   /...
71  * });
72  */
73 var PrefixedLocalStorageTest = function () {
74   PrefixedLocalStorage.call(this);
75   this.prefix = `${document.location.pathname}-${Math.random()}-${Date.now()}-`;
77 PrefixedLocalStorageTest.prototype = Object.create(PrefixedLocalStorage.prototype);
78 PrefixedLocalStorageTest.prototype.constructor = PrefixedLocalStorageTest;
80 /**
81  * Use in a cleanup function to clear out prefixed entries in localStorage
82  */
83 PrefixedLocalStorageTest.prototype.cleanup = function () {
84   this.setItem('closeAll', 'true');
85   this.clear();
88 /*****************************************************************************
89  * Use in test resource files to share a prefix generated by a
90  * PrefixedLocalStorageTest. Will look in URL querystring for prefix.
91  * Setting `close_on_cleanup` opt truthy will make this script's window listen
92  * for storage `closeAll` event from controlling test and close itself.
93  *
94  * var PrefixedLocalStorageResource({ close_on_cleanup: true });
95  */
96 var PrefixedLocalStorageResource = function (options) {
97   PrefixedLocalStorage.call(this);
98   this.options = Object.assign({}, {
99     close_on_cleanup: false
100   }, options || {});
101   // Check URL querystring for prefix to use
102   var regex = new RegExp(`[?&]${this.param}(=([^&#]*)|&|#|$)`),
103     results = regex.exec(document.location.href);
104   if (results && results[2]) {
105     this.prefix = results[2];
106   }
107   // Optionally have this window close itself when the PrefixedLocalStorageTest
108   // sets a `closeAll` item.
109   if (this.options.close_on_cleanup) {
110     this.onSet('closeAll', () => {
111       window.close();
112     });
113   }
115 PrefixedLocalStorageResource.prototype = Object.create(PrefixedLocalStorage.prototype);
116 PrefixedLocalStorageResource.prototype.constructor = PrefixedLocalStorageResource;