Skip to content

Commit

Permalink
test: update WPT harness and tests
Browse files Browse the repository at this point in the history
PR-URL: #33770
Reviewed-By: Daijiro Wachi <daijiro.wachi@gmail.com>
Reviewed-By: Shingo Inoue <leko.noor@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
  • Loading branch information
targos authored and nodejs-github-bot committed Sep 16, 2020
1 parent 9cf9e4a commit eb9d7a4
Show file tree
Hide file tree
Showing 133 changed files with 9,646 additions and 1,775 deletions.
15 changes: 8 additions & 7 deletions test/fixtures/wpt/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@ See [test/wpt](../../wpt/README.md) for information on how these tests are run.

Last update:

- console: https://github.com/web-platform-tests/wpt/tree/9786a4b131/console
- encoding: https://github.com/web-platform-tests/wpt/tree/5059d2c777/encoding
- url: https://github.com/web-platform-tests/wpt/tree/43feb7f612/url
- resources: https://github.com/web-platform-tests/wpt/tree/e1fddfbf80/resources
- interfaces: https://github.com/web-platform-tests/wpt/tree/8ada332aea/interfaces
- html/webappapis/microtask-queuing: https://github.com/web-platform-tests/wpt/tree/0c3bed38df/html/webappapis/microtask-queuing
- html/webappapis/timers: https://github.com/web-platform-tests/wpt/tree/ddfe9c089b/html/webappapis/timers
- console: https://github.com/web-platform-tests/wpt/tree/3b1f72e99a/console
- encoding: https://github.com/web-platform-tests/wpt/tree/11e6941923/encoding
- url: https://github.com/web-platform-tests/wpt/tree/551c9d604f/url
- resources: https://github.com/web-platform-tests/wpt/tree/55e9dc7f5e/resources
- interfaces: https://github.com/web-platform-tests/wpt/tree/4471cda31b/interfaces
- html/webappapis/microtask-queuing: https://github.com/web-platform-tests/wpt/tree/2c5c3c4c27/html/webappapis/microtask-queuing
- html/webappapis/timers: https://github.com/web-platform-tests/wpt/tree/264f12bc7b/html/webappapis/timers
- hr-time: https://github.com/web-platform-tests/wpt/tree/a5d1774ecf/hr-time
- common: https://github.com/web-platform-tests/wpt/tree/4dacb6e2ff/common

[Web Platform Tests]: https://github.com/web-platform-tests/wpt
[`git node wpt`]: https://github.com/nodejs/node-core-utils/blob/master/docs/git-node.md#git-node-wpt
3 changes: 3 additions & 0 deletions test/fixtures/wpt/common/META.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
suggested_reviewers:
- zqzhang
- deniak
116 changes: 116 additions & 0 deletions test/fixtures/wpt/common/PrefixedLocalStorage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/**
* Supports pseudo-"namespacing" localStorage for a given test
* by generating and using a unique prefix for keys. Why trounce on other
* tests' localStorage items when you can keep it "separated"?
*
* PrefixedLocalStorageTest: Instantiate in testharness.js tests to generate
* a new unique-ish prefix
* PrefixedLocalStorageResource: Instantiate in supporting test resource
* files to use/share a prefix generated by a test.
*/
var PrefixedLocalStorage = function () {
this.prefix = ''; // Prefix for localStorage keys
this.param = 'prefixedLocalStorage'; // Param to use in querystrings
};

PrefixedLocalStorage.prototype.clear = function () {
if (this.prefix === '') { return; }
Object.keys(localStorage).forEach(sKey => {
if (sKey.indexOf(this.prefix) === 0) {
localStorage.removeItem(sKey);
}
});
};

/**
* Append/replace prefix parameter and value in URI querystring
* Use to generate URLs to resource files that will share the prefix.
*/
PrefixedLocalStorage.prototype.url = function (uri) {
function updateUrlParameter (uri, key, value) {
var i = uri.indexOf('#');
var hash = (i === -1) ? '' : uri.substr(i);
uri = (i === -1) ? uri : uri.substr(0, i);
var re = new RegExp(`([?&])${key}=.*?(&|$)`, 'i');
var separator = uri.indexOf('?') !== -1 ? '&' : '?';
uri = (uri.match(re)) ? uri.replace(re, `$1${key}=${value}$2`) :
`${uri}${separator}${key}=${value}`;
return uri + hash;
}
return updateUrlParameter(uri, this.param, this.prefix);
};

PrefixedLocalStorage.prototype.prefixedKey = function (baseKey) {
return `${this.prefix}${baseKey}`;
};

PrefixedLocalStorage.prototype.setItem = function (baseKey, value) {
localStorage.setItem(this.prefixedKey(baseKey), value);
};

/**
* Listen for `storage` events pertaining to a particular key,
* prefixed with this object's prefix. Ignore when value is being set to null
* (i.e. removeItem).
*/
PrefixedLocalStorage.prototype.onSet = function (baseKey, fn) {
window.addEventListener('storage', e => {
var match = this.prefixedKey(baseKey);
if (e.newValue !== null && e.key.indexOf(match) === 0) {
fn.call(this, e);
}
});
};

/*****************************************************************************
* Use in a testharnessjs test to generate a new key prefix.
* async_test(t => {
* var prefixedStorage = new PrefixedLocalStorageTest();
* t.add_cleanup(() => prefixedStorage.cleanup());
* /...
* });
*/
var PrefixedLocalStorageTest = function () {
PrefixedLocalStorage.call(this);
this.prefix = `${document.location.pathname}-${Math.random()}-${Date.now()}-`;
};
PrefixedLocalStorageTest.prototype = Object.create(PrefixedLocalStorage.prototype);
PrefixedLocalStorageTest.prototype.constructor = PrefixedLocalStorageTest;

/**
* Use in a cleanup function to clear out prefixed entries in localStorage
*/
PrefixedLocalStorageTest.prototype.cleanup = function () {
this.setItem('closeAll', 'true');
this.clear();
};

/*****************************************************************************
* Use in test resource files to share a prefix generated by a
* PrefixedLocalStorageTest. Will look in URL querystring for prefix.
* Setting `close_on_cleanup` opt truthy will make this script's window listen
* for storage `closeAll` event from controlling test and close itself.
*
* var PrefixedLocalStorageResource({ close_on_cleanup: true });
*/
var PrefixedLocalStorageResource = function (options) {
PrefixedLocalStorage.call(this);
this.options = Object.assign({}, {
close_on_cleanup: false
}, options || {});
// Check URL querystring for prefix to use
var regex = new RegExp(`[?&]${this.param}(=([^&#]*)|&|#|$)`),
results = regex.exec(document.location.href);
if (results && results[2]) {
this.prefix = results[2];
}
// Optionally have this window close itself when the PrefixedLocalStorageTest
// sets a `closeAll` item.
if (this.options.close_on_cleanup) {
this.onSet('closeAll', () => {
window.close();
});
}
};
PrefixedLocalStorageResource.prototype = Object.create(PrefixedLocalStorage.prototype);
PrefixedLocalStorageResource.prototype.constructor = PrefixedLocalStorageResource;
1 change: 1 addition & 0 deletions test/fixtures/wpt/common/PrefixedLocalStorage.js.headers
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Content-Type: text/javascript; charset=utf-8
100 changes: 100 additions & 0 deletions test/fixtures/wpt/common/PrefixedPostMessage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/**
* Supports pseudo-"namespacing" for window-posted messages for a given test
* by generating and using a unique prefix that gets wrapped into message
* objects. This makes it more feasible to have multiple tests that use
* `window.postMessage` in a single test file. Basically, make it possible
* for the each test to listen for only the messages that are pertinent to it.
*
* 'Prefix' not an elegant term to use here but this models itself after
* PrefixedLocalStorage.
*
* PrefixedMessageTest: Instantiate in testharness.js tests to generate
* a new unique-ish prefix that can be used by other test support files
* PrefixedMessageResource: Instantiate in supporting test resource
* files to use/share a prefix generated by a test.
*/
var PrefixedMessage = function () {
this.prefix = '';
this.param = 'prefixedMessage'; // Param to use in querystrings
};

/**
* Generate a URL that adds/replaces param with this object's prefix
* Use to link to test support files that make use of
* PrefixedMessageResource.
*/
PrefixedMessage.prototype.url = function (uri) {
function updateUrlParameter (uri, key, value) {
var i = uri.indexOf('#');
var hash = (i === -1) ? '' : uri.substr(i);
uri = (i === -1) ? uri : uri.substr(0, i);
var re = new RegExp(`([?&])${key}=.*?(&|$)`, 'i');
var separator = uri.indexOf('?') !== -1 ? '&' : '?';
uri = (uri.match(re)) ? uri.replace(re, `$1${key}=${value}$2`) :
`${uri}${separator}${key}=${value}`;
return uri + hash;
}
return updateUrlParameter(uri, this.param, this.prefix);
};

/**
* Add an eventListener on `message` but only invoke the given callback
* for messages whose object contains this object's prefix. Remove the
* event listener once the anticipated message has been received.
*/
PrefixedMessage.prototype.onMessage = function (fn) {
window.addEventListener('message', e => {
if (typeof e.data === 'object' && e.data.hasOwnProperty('prefix')) {
if (e.data.prefix === this.prefix) {
// Only invoke callback when `data` is an object containing
// a `prefix` key with this object's prefix value
// Note fn is invoked with "unwrapped" data first, then the event `e`
// (which contains the full, wrapped e.data should it be needed)
fn.call(this, e.data.data, e);
window.removeEventListener('message', fn);
}
}
});
};

/**
* Instantiate in a test file (e.g. during `setup`) to create a unique-ish
* prefix that can be shared by support files
*/
var PrefixedMessageTest = function () {
PrefixedMessage.call(this);
this.prefix = `${document.location.pathname}-${Math.random()}-${Date.now()}-`;
};
PrefixedMessageTest.prototype = Object.create(PrefixedMessage.prototype);
PrefixedMessageTest.prototype.constructor = PrefixedMessageTest;

/**
* Instantiate in a test support script to use a "prefix" generated by a
* PrefixedMessageTest in a controlling test file. It will look for
* the prefix in a URL param (see also PrefixedMessage#url)
*/
var PrefixedMessageResource = function () {
PrefixedMessage.call(this);
// Check URL querystring for prefix to use
var regex = new RegExp(`[?&]${this.param}(=([^&#]*)|&|#|$)`),
results = regex.exec(document.location.href);
if (results && results[2]) {
this.prefix = results[2];
}
};
PrefixedMessageResource.prototype = Object.create(PrefixedMessage.prototype);
PrefixedMessageResource.prototype.constructor = PrefixedMessageResource;

/**
* This is how a test resource document can "send info" to its
* opener context. It will whatever message is being sent (`data`) in
* an object that injects the prefix.
*/
PrefixedMessageResource.prototype.postToOpener = function (data) {
if (window.opener) {
window.opener.postMessage({
prefix: this.prefix,
data: data
}, '*');
}
};
1 change: 1 addition & 0 deletions test/fixtures/wpt/common/PrefixedPostMessage.js.headers
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Content-Type: text/javascript; charset=utf-8
10 changes: 10 additions & 0 deletions test/fixtures/wpt/common/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
The files in this directory are non-infrastructure support files that can be used by tests.

* `blank.html` - An empty HTML document.
* `domain-setter.sub.html` - An HTML document that sets `document.domain`.
* `dummy.xhtml` - An XHTML document.
* `dummy.xml` - An XML document.
* `text-plain.txt` - A text/plain document.
* `*.js` - Utility scripts. These are documented in the source.
* `*.py` - wptserve [Python Handlers](https://web-platform-tests.org/writing-tests/python-handlers/). These are documented in the source.
* `security-features` - Documented in `security-features/README.md`.
31 changes: 31 additions & 0 deletions test/fixtures/wpt/common/arrays.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* Callback for checking equality of c and d.
*
* @callback equalityCallback
* @param {*} c
* @param {*} d
* @returns {boolean}
*/

/**
* Returns true if the given arrays are equal. Optionally can pass an equality function.
* @param {Array} a
* @param {Array} b
* @param {equalityCallback} callbackFunction - defaults to `c === d`
* @returns {boolean}
*/
export function areArraysEqual(a, b, equalityFunction = (c, d) => { return c === d; }) {
try {
if (a.length !== b.length)
return false;

for (let i = 0; i < a.length; i++) {
if (!equalityFunction(a[i], b[i]))
return false;
}
} catch (ex) {
return false;
}

return true;
}
Empty file.
8 changes: 8 additions & 0 deletions test/fixtures/wpt/common/domain-setter.sub.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>A page that will likely be same-origin-domain but not same-origin</title>

<script>
"use strict";
document.domain = "{{host}}";
</script>
2 changes: 2 additions & 0 deletions test/fixtures/wpt/common/dummy.xhtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>Dummy XHTML document</title></head><body /></html>
1 change: 1 addition & 0 deletions test/fixtures/wpt/common/dummy.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<foo>Dummy XML document</foo>
58 changes: 58 additions & 0 deletions test/fixtures/wpt/common/get-host-info.sub.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/**
* Host information for cross-origin tests.
* @returns {Object} with properties for different host information.
*/
function get_host_info() {

var HTTP_PORT = '{{ports[http][0]}}';
var HTTP_PORT2 = '{{ports[http][1]}}';
var HTTPS_PORT = '{{ports[https][0]}}';
var HTTPS_PORT2 = '{{ports[https][1]}}';
var PROTOCOL = self.location.protocol;
var IS_HTTPS = (PROTOCOL == "https:");
var HTTP_PORT_ELIDED = HTTP_PORT == "80" ? "" : (":" + HTTP_PORT);
var HTTP_PORT2_ELIDED = HTTP_PORT2 == "80" ? "" : (":" + HTTP_PORT2);
var HTTPS_PORT_ELIDED = HTTPS_PORT == "443" ? "" : (":" + HTTPS_PORT);
var PORT_ELIDED = IS_HTTPS ? HTTPS_PORT_ELIDED : HTTP_PORT_ELIDED;
var ORIGINAL_HOST = '{{host}}';
var REMOTE_HOST = (ORIGINAL_HOST === 'localhost') ? '127.0.0.1' : ('www1.' + ORIGINAL_HOST);
var OTHER_HOST = '{{domains[www2]}}';
var NOTSAMESITE_HOST = (ORIGINAL_HOST === 'localhost') ? '127.0.0.1' : ('{{hosts[alt][]}}');

return {
HTTP_PORT: HTTP_PORT,
HTTP_PORT2: HTTP_PORT2,
HTTPS_PORT: HTTPS_PORT,
HTTPS_PORT2: HTTPS_PORT2,
ORIGINAL_HOST: ORIGINAL_HOST,
REMOTE_HOST: REMOTE_HOST,

ORIGIN: PROTOCOL + "//" + ORIGINAL_HOST + PORT_ELIDED,
HTTP_ORIGIN: 'http://' + ORIGINAL_HOST + HTTP_PORT_ELIDED,
HTTPS_ORIGIN: 'https://' + ORIGINAL_HOST + HTTPS_PORT_ELIDED,
HTTPS_ORIGIN_WITH_CREDS: 'https://foo:bar@' + ORIGINAL_HOST + HTTPS_PORT_ELIDED,
HTTP_ORIGIN_WITH_DIFFERENT_PORT: 'http://' + ORIGINAL_HOST + HTTP_PORT2_ELIDED,
REMOTE_ORIGIN: PROTOCOL + "//" + REMOTE_HOST + PORT_ELIDED,
HTTP_REMOTE_ORIGIN: 'http://' + REMOTE_HOST + HTTP_PORT_ELIDED,
HTTP_NOTSAMESITE_ORIGIN: 'http://' + NOTSAMESITE_HOST + HTTP_PORT_ELIDED,
HTTP_REMOTE_ORIGIN_WITH_DIFFERENT_PORT: 'http://' + REMOTE_HOST + HTTP_PORT2_ELIDED,
HTTPS_REMOTE_ORIGIN: 'https://' + REMOTE_HOST + HTTPS_PORT_ELIDED,
HTTPS_REMOTE_ORIGIN_WITH_CREDS: 'https://foo:bar@' + REMOTE_HOST + HTTPS_PORT_ELIDED,
HTTPS_NOTSAMESITE_ORIGIN: 'https://' + NOTSAMESITE_HOST + HTTPS_PORT_ELIDED,
UNAUTHENTICATED_ORIGIN: 'http://' + OTHER_HOST + HTTP_PORT_ELIDED,
AUTHENTICATED_ORIGIN: 'https://' + OTHER_HOST + HTTPS_PORT_ELIDED
};
}

/**
* When a default port is used, location.port returns the empty string.
* This function attempts to provide an exact port, assuming we are running under wptserve.
* @param {*} loc - can be Location/<a>/<area>/URL, but assumes http/https only.
* @returns {string} The port number.
*/
function get_port(loc) {
if (loc.port) {
return loc.port;
}
return loc.protocol === 'https:' ? '443' : '80';
}
1 change: 1 addition & 0 deletions test/fixtures/wpt/common/get-host-info.sub.js.headers
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Content-Type: text/javascript; charset=utf-8
Loading

0 comments on commit eb9d7a4

Please sign in to comment.