test: update wpt url and resource

Refs: https://github.com/web-platform-tests/wpt/pull/26317

PR-URL: https://github.com/nodejs/node/pull/36032
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
This commit is contained in:
Daijiro Wachi committed 2020-11-19 10:54:53 +09:00
1 parent 73ea670152
commit d6d4721f3b
12 files changed
+437 -222

No files matched your search

+3 -3
View File
@@ -12,9 +12,9 @@ Last update:
- console: https://github.com/web-platform-tests/wpt/tree/3b1f72e99a/console
- encoding: https://github.com/web-platform-tests/wpt/tree/1821fb5f77/encoding
- url: https://github.com/web-platform-tests/wpt/tree/54c6d64be0/url
- resources: https://github.com/web-platform-tests/wpt/tree/1d14e821b9/resources
- interfaces: https://github.com/web-platform-tests/wpt/tree/15e47f779c/interfaces
- url: https://github.com/web-platform-tests/wpt/tree/09d8830be1/url
- resources: https://github.com/web-platform-tests/wpt/tree/001e50de41/resources
- interfaces: https://github.com/web-platform-tests/wpt/tree/8719553b2d/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
+21 -5
View File
@@ -436,7 +436,6 @@ interface HTMLIFrameElement : HTMLElement {
[SameObject, PutForwards=value] readonly attribute DOMTokenList sandbox;
[CEReactions] attribute DOMString allow;
[CEReactions] attribute boolean allowFullscreen;
[CEReactions] attribute boolean allowPaymentRequest;
[CEReactions] attribute DOMString width;
[CEReactions] attribute DOMString height;
[CEReactions] attribute DOMString referrerPolicy;
@@ -1564,16 +1563,18 @@ dictionary ElementDefinitionOptions {
[Exposed=Window]
interface ElementInternals {
// Form-associated custom elements
// Shadow root access
readonly attribute ShadowRoot? shadowRoot;
// Form-associated custom elements
undefined setFormValue((File or USVString or FormData)? value,
optional (File or USVString or FormData)? state);
optional (File or USVString or FormData)? state);
readonly attribute HTMLFormElement? form;
undefined setValidity(optional ValidityStateFlags flags = {},
optional DOMString message,
optional HTMLElement anchor);
optional DOMString message,
optional HTMLElement anchor);
readonly attribute boolean willValidate;
readonly attribute ValidityState validity;
readonly attribute DOMString validationMessage;
@@ -1583,6 +1584,9 @@ interface ElementInternals {
readonly attribute NodeList labels;
};
// Accessibility semantics
ElementInternals includes ARIAMixin;
dictionary ValidityStateFlags {
boolean valueMissing = false;
boolean typeMismatch = false;
@@ -2353,6 +2357,18 @@ interface WorkerLocation {
readonly attribute USVString hash;
};
[Exposed=Worklet, SecureContext]
interface WorkletGlobalScope {};
[Exposed=Window, SecureContext]
interface Worklet {
[NewObject] Promise<undefined> addModule(USVString moduleURL, optional WorkletOptions options = {});
};
dictionary WorkletOptions {
RequestCredentials credentials = "same-origin";
};
[Exposed=Window]
interface Storage {
readonly attribute unsigned long length;
+5
View File
@@ -0,0 +1,5 @@
/* Whether the browser is Chromium-based with MojoJS enabled */
export const isChromiumBased = 'MojoInterfaceInterceptor' in self;
/* Whether the browser is WebKit-based with internal test-only API enabled */
export const isWebKitBased = !isChromiumBased && 'internals' in self;
@@ -0,0 +1,2 @@
Content-Type: text/javascript; charset=utf-8
Cache-Control: max-age=3600
+105 -4
View File
@@ -9,6 +9,7 @@
function Actions(defaultTickDuration=16) {
this.sourceTypes = new Map([["key", KeySource],
["pointer", PointerSource],
["wheel", WheelSource],
["none", GeneralSource]]);
this.sources = new Map();
this.sourceOrder = [];
@@ -22,6 +23,7 @@
this.createSource("none");
this.tickIdx = 0;
this.defaultTickDuration = defaultTickDuration;
this.context = null;
}
Actions.prototype = {
@@ -65,7 +67,17 @@
} catch(e) {
return Promise.reject(e);
}
return test_driver.action_sequence(actions);
return test_driver.action_sequence(actions, this.context);
},
/**
* Set the context for the actions
*
* @param {WindowProxy} context - Context in which to run the action sequence
*/
setContext: function(context) {
this.context = context;
return this;
},
/**
@@ -73,7 +85,7 @@
* If no name is passed, a new source with the given type is
* created.
*
* @param {String} type - Source type ('none', 'key', or 'pointer')
* @param {String} type - Source type ('none', 'key', 'pointer', or 'wheel')
* @param {String?} name - Name of the source
* @returns {Source} Source object for that source.
*/
@@ -154,6 +166,32 @@
return this;
},
/**
* Add a new wheel input source with the given name
*
* @param {String} type - Name of the wheel source
* @param {Bool} set - Set source as the default wheel source
* @returns {Actions}
*/
addWheel: function(name, set=true) {
this.createSource("wheel", name);
if (set) {
this.setWheel(name);
}
return this;
},
/**
* Set the current default wheel source
*
* @param {String} name - Name of the wheel source
* @returns {Actions}
*/
setWheel: function(name) {
this.setSource("wheel", name);
return this;
},
createSource: function(type, name, parameters={}) {
if (!this.sources.has(type)) {
throw new Error(`${type} is not a valid action type`);
@@ -196,8 +234,9 @@
*
* @param {Number?} duration - Minimum length of the tick in ms.
* @param {String} sourceType - source type
* @param {String?} sourceName - Named key or pointer source to use or null for the default
* key or pointer source
* @param {String?} sourceName - Named key, pointer or wheel source to use
* or null for the default key, pointer or
* wheel source
* @returns {Actions}
*/
pause: function(duration=0, sourceType="none", {sourceName=null}={}) {
@@ -280,6 +319,27 @@
source.pointerMove(this, x, y, duration, origin);
return this;
},
/**
* Create a scroll event for the current default wheel source
*
* @param {Number} x - mouse cursor x coordinate
* @param {Number} y - mouse cursor y coordinate
* @param {Number} deltaX - scroll delta value along the x-axis in pixels
* @param {Number} deltaY - scroll delta value along the y-axis in pixels
* @param {String|Element} origin - Origin of the coordinate system.
* Either "viewport" or an Element
* @param {Number?} duration - Time in ms for the scroll
* @param {String?} sourceName - Named wheel source to use or null for the
* default wheel source
* @returns {Actions}
*/
scroll: function(x, y, deltaX, deltaY,
{origin="viewport", duration, sourceName=null}={}) {
let source = this.getSource("wheel", sourceName);
source.scroll(this, x, y, deltaX, deltaY, duration, origin);
return this;
},
};
function GeneralSource() {
@@ -417,5 +477,46 @@
},
};
function WheelSource() {
this.actions = new Map();
}
WheelSource.prototype = {
serialize: function(tickCount) {
if (!this.actions.size) {
return undefined;
}
let actions = [];
let data = {"type": "wheel", "actions": actions};
for (let i=0; i<tickCount; i++) {
if (this.actions.has(i)) {
actions.push(this.actions.get(i));
} else {
actions.push({"type": "pause"});
}
}
return data;
},
scroll: function(actions, x, y, deltaX, deltaY, duration, origin) {
let tick = actions.tickIdx;
if (this.actions.has(tick)) {
tick = actions.addTick().tickIdx;
}
this.actions.set(tick, {type: "scroll", x, y, deltaX, deltaY, origin});
if (duration) {
this.actions.get(tick).duration = duration;
}
},
addPause: function(actions, duration) {
let tick = actions.tickIdx;
if (this.actions.has(tick)) {
tick = actions.addTick().tickIdx;
}
this.actions.set(tick, {type: "pause", duration: duration});
},
};
test_driver.Actions = Actions;
})();
+128 -193
View File
@@ -1,6 +1,7 @@
(function() {
"use strict";
var idCounter = 0;
let testharness_context = null;
function getInViewCenterPoint(rect) {
var left = Math.max(0, rect.left);
@@ -15,7 +16,8 @@
}
function getPointerInteractablePaintTree(element) {
if (!window.document.contains(element)) {
let elementDocument = element.ownerDocument;
if (!elementDocument.contains(element)) {
return [];
}
@@ -27,10 +29,10 @@
var centerPoint = getInViewCenterPoint(rectangles[0]);
if ("elementsFromPoint" in document) {
return document.elementsFromPoint(centerPoint[0], centerPoint[1]);
} else if ("msElementsFromPoint" in document) {
var rv = document.msElementsFromPoint(centerPoint[0], centerPoint[1]);
if ("elementsFromPoint" in elementDocument) {
return elementDocument.elementsFromPoint(centerPoint[0], centerPoint[1]);
} else if ("msElementsFromPoint" in elementDocument) {
var rv = elementDocument.msElementsFromPoint(centerPoint[0], centerPoint[1]);
return Array.prototype.slice.call(rv ? rv : []);
} else {
throw new Error("document.elementsFromPoint unsupported");
@@ -47,6 +49,31 @@
* @namespace
*/
window.test_driver = {
/**
* Set the context in which testharness.js is loaded
*
* @param {WindowProxy} context - the window containing testharness.js
**/
set_test_context: function(context) {
if (window.test_driver_internal.set_test_context) {
window.test_driver_internal.set_test_context(context);
}
testharness_context = context;
},
/**
* postMessage to the context containing testharness.js
*
* @param {Object} msg - the data to POST
**/
message_test: function(msg) {
let target = testharness_context;
if (testharness_context === null) {
target = window;
}
target.postMessage(msg, "*");
},
/**
* Trigger user interaction in order to grant additional privileges to
* a provided function.
@@ -56,30 +83,35 @@
* @param {String} intent - a description of the action which much be
* triggered by user interaction
* @param {Function} action - code requiring escalated privileges
* @param {WindowProxy} context - Browsing context in which
* to run the call, or null for the current
* browsing context.
*
* @returns {Promise} fulfilled following user interaction and
* execution of the provided `action` function;
* rejected if interaction fails or the provided
* function throws an error
*/
bless: function(intent, action) {
var button = document.createElement("button");
bless: function(intent, action, context=null) {
let contextDocument = context ? context.document : document;
var button = contextDocument.createElement("button");
button.innerHTML = "This test requires user interaction.<br />" +
"Please click here to allow " + intent + ".";
button.id = "wpt-test-driver-bless-" + (idCounter += 1);
const elem = document.body || document.documentElement;
const elem = contextDocument.body || contextDocument.documentElement;
elem.appendChild(button);
return new Promise(function(resolve, reject) {
button.addEventListener("click", resolve);
let wait_click = new Promise(resolve => button.addEventListener("click", resolve));
test_driver.click(button).catch(reject);
}).then(function() {
return test_driver.click(button)
.then(wait_click)
.then(function() {
button.remove();
if (typeof action === "function") {
return action();
}
return null;
});
},
@@ -95,14 +127,6 @@
* the cases the WebDriver command errors
*/
click: function(element) {
if (window.top !== window) {
return Promise.reject(new Error("can only click in top-level window"));
}
if (!window.document.contains(element)) {
return Promise.reject(new Error("element in different document or shadow tree"));
}
if (!inView(element)) {
element.scrollIntoView({behavior: "instant",
block: "end",
@@ -135,14 +159,6 @@
* the cases the WebDriver command errors
*/
send_keys: function(element, keys) {
if (window.top !== window) {
return Promise.reject(new Error("can only send keys in top-level window"));
}
if (!window.document.contains(element)) {
return Promise.reject(new Error("element in different document or shadow tree"));
}
if (!inView(element)) {
element.scrollIntoView({behavior: "instant",
block: "end",
@@ -166,34 +182,42 @@
* https://github.com/WICG/page-lifecycle/blob/master/README.md|Lifecycle API
* for Web Pages}
*
* @param {WindowProxy} context - Browsing context in which
* to run the call, or null for the current
* browsing context.
*
* @returns {Promise} fulfilled after the freeze request is sent, or rejected
* in case the WebDriver command errors
*/
freeze: function() {
freeze: function(context=null) {
return window.test_driver_internal.freeze();
},
/**
* Send a sequence of actions
*
* This function sends a sequence of actions to the top level window
* This function sends a sequence of actions
* to perform. It is modeled after the behaviour of {@link
* https://w3c.github.io/webdriver/#actions|WebDriver Actions Command}
*
* @param {Array} actions - an array of actions. The format is the same as the actions
property of the WebDriver command {@link
https://w3c.github.io/webdriver/#perform-actions|Perform
Actions} command. Each element is an object representing an
input source and each input source itself has an actions
property detailing the behaviour of that source at each timestep
(or tick). Authors are not expected to construct the actions
sequence by hand, but to use the builder api provided in
testdriver-actions.js
* property of the WebDriver command {@link
* https://w3c.github.io/webdriver/#perform-actions|Perform
* Actions} command. Each element is an object representing an
* input source and each input source itself has an actions
* property detailing the behaviour of that source at each timestep
* (or tick). Authors are not expected to construct the actions
* sequence by hand, but to use the builder api provided in
* testdriver-actions.js
* @param {WindowProxy} context - Browsing context in which
* to run the call, or null for the current
* browsing context.
*
* @returns {Promise} fufiled after the actions are performed, or rejected in
* the cases the WebDriver command errors
*/
action_sequence: function(actions) {
return window.test_driver_internal.action_sequence(actions);
action_sequence: function(actions, context=null) {
return window.test_driver_internal.action_sequence(actions, context);
},
/**
@@ -203,11 +227,15 @@
* by ReportingObserver) for testing purposes, as described in
* {@link https://w3c.github.io/reporting/#generate-test-report-command}
*
* @param {WindowProxy} context - Browsing context in which
* to run the call, or null for the current
* browsing context.
*
* @returns {Promise} fulfilled after the report is generated, or
* rejected if the report generation fails
*/
generate_test_report: function(message) {
return window.test_driver_internal.generate_test_report(message);
generate_test_report: function(message, context=null) {
return window.test_driver_internal.generate_test_report(message, context);
},
/**
@@ -221,6 +249,9 @@
* object
* @param {String} state - the state of the permission
* @param {boolean} one_realm - Optional. Whether the permission applies to only one realm
* @param {WindowProxy} context - Browsing context in which
* to run the call, or null for the current
* browsing context.
*
* The above params are used to create a [PermissionSetParameters]{@link
* https://w3c.github.io/permissions/#dictdef-permissionsetparameters} object
@@ -228,13 +259,13 @@
* @returns {Promise} fulfilled after the permission is set, or rejected if setting the
* permission fails
*/
set_permission: function(descriptor, state, one_realm) {
set_permission: function(descriptor, state, one_realm, context=null) {
let permission_params = {
descriptor,
state,
oneRealm: one_realm,
};
return window.test_driver_internal.set_permission(permission_params);
return window.test_driver_internal.set_permission(permission_params, context);
},
/**
@@ -247,12 +278,16 @@
* @param {Object} config - an [Authenticator Configuration]{@link
* https://w3c.github.io/webauthn/#authenticator-configuration}
* object
* @param {WindowProxy} context - Browsing context in which
* to run the call, or null for the current
* browsing context.
*
* @returns {Promise} fulfilled after the authenticator is added, or
* rejected in the cases the WebDriver command
* errors. Returns the ID of the authenticator
*/
add_virtual_authenticator: function(config) {
return window.test_driver_internal.add_virtual_authenticator(config);
add_virtual_authenticator: function(config, context=null) {
return window.test_driver_internal.add_virtual_authenticator(config, context);
},
/**
@@ -264,13 +299,16 @@
*
* @param {String} authenticator_id - the ID of the authenticator to be
* removed.
* @param {WindowProxy} context - Browsing context in which
* to run the call, or null for the current
* browsing context.
*
* @returns {Promise} fulfilled after the authenticator is removed, or
* rejected in the cases the WebDriver command
* errors
*/
remove_virtual_authenticator: function(authenticator_id) {
return window.test_driver_internal.remove_virtual_authenticator(authenticator_id);
remove_virtual_authenticator: function(authenticator_id, context=null) {
return window.test_driver_internal.remove_virtual_authenticator(authenticator_id, context);
},
/**
@@ -282,13 +320,16 @@
* @param {Object} credential - A [Credential Parameters]{@link
* https://w3c.github.io/webauthn/#credential-parameters}
* object
* @param {WindowProxy} context - Browsing context in which
* to run the call, or null for the current
* browsing context.
*
* @returns {Promise} fulfilled after the credential is added, or
* rejected in the cases the WebDriver command
* errors
*/
add_credential: function(authenticator_id, credential) {
return window.test_driver_internal.add_credential(authenticator_id, credential);
add_credential: function(authenticator_id, credential, context=null) {
return window.test_driver_internal.add_credential(authenticator_id, credential, context);
},
/**
@@ -300,6 +341,9 @@
* https://w3c.github.io/webauthn/#sctn-automation-get-credentials
*
* @param {String} authenticator_id - the ID of the authenticator
* @param {WindowProxy} context - Browsing context in which
* to run the call, or null for the current
* browsing context.
*
* @returns {Promise} fulfilled after the credentials are returned, or
* rejected in the cases the WebDriver command
@@ -307,8 +351,8 @@
* Parameters]{@link
* https://w3c.github.io/webauthn/#credential-parameters}
*/
get_credentials: function(authenticator_id) {
return window.test_driver_internal.get_credentials(authenticator_id);
get_credentials: function(authenticator_id, context=null) {
return window.test_driver_internal.get_credentials(authenticator_id, context=null);
},
/**
@@ -318,13 +362,16 @@
*
* @param {String} authenticator_id - the ID of the authenticator
* @param {String} credential_id - the ID of the credential
* @param {WindowProxy} context - Browsing context in which
* to run the call, or null for the current
* browsing context.
*
* @returns {Promise} fulfilled after the credential is removed, or
* rejected in the cases the WebDriver command
* errors.
*/
remove_credential: function(authenticator_id, credential_id) {
return window.test_driver_internal.remove_credential(authenticator_id, credential_id);
remove_credential: function(authenticator_id, credential_id, context=null) {
return window.test_driver_internal.remove_credential(authenticator_id, credential_id, context);
},
/**
@@ -333,13 +380,16 @@
* https://w3c.github.io/webauthn/#sctn-automation-remove-all-credentials
*
* @param {String} authenticator_id - the ID of the authenticator
* @param {WindowProxy} context - Browsing context in which
* to run the call, or null for the current
* browsing context.
*
* @returns {Promise} fulfilled after the credentials are removed, or
* rejected in the cases the WebDriver command
* errors.
*/
remove_all_credentials: function(authenticator_id) {
return window.test_driver_internal.remove_all_credentials(authenticator_id);
remove_all_credentials: function(authenticator_id, context=null) {
return window.test_driver_internal.remove_all_credentials(authenticator_id, context);
},
/**
@@ -351,9 +401,12 @@
*
* @param {String} authenticator_id - the ID of the authenticator
* @param {boolean} uv - the User Verified flag
* @param {WindowProxy} context - Browsing context in which
* to run the call, or null for the current
* browsing context.
*/
set_user_verified: function(authenticator_id, uv) {
return window.test_driver_internal.set_user_verified(authenticator_id, uv);
set_user_verified: function(authenticator_id, uv, context=null) {
return window.test_driver_internal.set_user_verified(authenticator_id, uv, context);
},
/**
@@ -370,16 +423,19 @@
* May be "*" to indicate all origins.
* @param {String} state - The storage access setting.
* Must be either "allowed" or "blocked".
* @param {WindowProxy} context - Browsing context in which
* to run the call, or null for the current
* browsing context.
*
* @returns {Promise} Fulfilled after the storage access rule has been
* set, or rejected if setting the rule fails.
*/
set_storage_access: function(origin, embedding_origin, state) {
set_storage_access: function(origin, embedding_origin, state, context=null) {
if (state !== "allowed" && state !== "blocked") {
throw new Error("storage access status must be 'allowed' or 'blocked'");
}
const blocked = state === "blocked";
return window.test_driver_internal.set_storage_access(origin, embedding_origin, blocked);
return window.test_driver_internal.set_storage_access(origin, embedding_origin, blocked, context);
},
};
@@ -392,13 +448,6 @@
*/
in_automation: false,
/**
* Waits for a user-initiated click
*
* @param {Element} element - element to be clicked
* @param {{x: number, y: number} coords - viewport coordinates to click at
* @returns {Promise} fulfilled after click occurs
*/
click: function(element, coords) {
if (this.in_automation) {
return Promise.reject(new Error('Not implemented'));
@@ -409,14 +458,6 @@
});
},
/**
* Waits for an element to receive a series of key presses
*
* @param {Element} element - element which should receve key presses
* @param {String} keys - keys to expect
* @returns {Promise} fulfilled after keys are received or rejected if
* an incorrect key sequence is received
*/
send_keys: function(element, keys) {
if (this.in_automation) {
return Promise.reject(new Error('Not implemented'));
@@ -449,158 +490,52 @@
});
},
/**
* Freeze the current page
*
* @returns {Promise} fulfilled after freeze request is sent, otherwise
* it gets rejected
*/
freeze: function() {
freeze: function(context=null) {
return Promise.reject(new Error("unimplemented"));
},
/**
* Send a sequence of pointer actions
*
* @returns {Promise} fufilled after actions are sent, rejected if any actions
* fail
*/
action_sequence: function(actions) {
action_sequence: function(actions, context=null) {
return Promise.reject(new Error("unimplemented"));
},
/**
* Generates a test report on the current page
*
* @param {String} message - the message to be contained in the report
* @returns {Promise} fulfilled after the report is generated, or
* rejected if the report generation fails
*/
generate_test_report: function(message) {
generate_test_report: function(message, context=null) {
return Promise.reject(new Error("unimplemented"));
},
/**
* Sets the state of a permission
*
* This function simulates a user setting a permission into a particular state as described
* in {@link https://w3c.github.io/permissions/#set-permission-command}
*
* @param {Object} permission_params - a [PermissionSetParameters]{@lint
* https://w3c.github.io/permissions/#dictdef-permissionsetparameters}
* object
* @returns {Promise} fulfilled after the permission is set, or rejected if setting the
* permission fails
*/
set_permission: function(permission_params) {
set_permission: function(permission_params, context=null) {
return Promise.reject(new Error("unimplemented"));
},
/**
* Creates a virtual authenticator
*
* @param {Object} config - the authenticator configuration
* @returns {Promise} fulfilled after the authenticator is added, or
* rejected in the cases the WebDriver command
* errors.
*/
add_virtual_authenticator: function(config) {
add_virtual_authenticator: function(config, context=null) {
return Promise.reject(new Error("unimplemented"));
},
/**
* Removes a virtual authenticator
*
* @param {String} authenticator_id - the ID of the authenticator to be
* removed.
*
* @returns {Promise} fulfilled after the authenticator is removed, or
* rejected in the cases the WebDriver command
* errors
*/
remove_virtual_authenticator: function(authenticator_id) {
remove_virtual_authenticator: function(authenticator_id, context=null) {
return Promise.reject(new Error("unimplemented"));
},
/**
* Adds a credential to a virtual authenticator
*
* @param {String} authenticator_id - the ID of the authenticator
* @param {Object} credential - A [Credential Parameters]{@link
* https://w3c.github.io/webauthn/#credential-parameters}
* object
*
* @returns {Promise} fulfilled after the credential is added, or
* rejected in the cases the WebDriver command
* errors
*
*/
add_credential: function(authenticator_id, credential) {
add_credential: function(authenticator_id, credential, context=null) {
return Promise.reject(new Error("unimplemented"));
},
/**
* Gets all the credentials stored in an authenticator
*
* @param {String} authenticator_id - the ID of the authenticator
*
* @returns {Promise} fulfilled after the credentials are returned, or
* rejected in the cases the WebDriver command
* errors. Returns an array of [Credential
* Parameters]{@link
* https://w3c.github.io/webauthn/#credential-parameters}
*
*/
get_credentials: function(authenticator_id) {
get_credentials: function(authenticator_id, context=null) {
return Promise.reject(new Error("unimplemented"));
},
/**
* Remove a credential stored in an authenticator
*
* @param {String} authenticator_id - the ID of the authenticator
* @param {String} credential_id - the ID of the credential
*
* @returns {Promise} fulfilled after the credential is removed, or
* rejected in the cases the WebDriver command
* errors.
*
*/
remove_credential: function(authenticator_id, credential_id) {
remove_credential: function(authenticator_id, credential_id, context=null) {
return Promise.reject(new Error("unimplemented"));
},
/**
* Removes all the credentials stored in a virtual authenticator
*
* @param {String} authenticator_id - the ID of the authenticator
*
* @returns {Promise} fulfilled after the credentials are removed, or
* rejected in the cases the WebDriver command
* errors.
*
*/
remove_all_credentials: function(authenticator_id) {
remove_all_credentials: function(authenticator_id, context=null) {
return Promise.reject(new Error("unimplemented"));
},
/**
* Sets the User Verified flag on an authenticator
*
* @param {String} authenticator_id - the ID of the authenticator
* @param {boolean} uv - the User Verified flag
*
*/
set_user_verified: function(authenticator_id, uv) {
set_user_verified: function(authenticator_id, uv, context=null) {
return Promise.reject(new Error("unimplemented"));
},
/**
* Sets the storage access policy for a third-party origin when loaded
* in the current first party context
*/
set_storage_access: function(origin, embedding_origin, blocked) {
set_storage_access: function(origin, embedding_origin, blocked, context=null) {
return Promise.reject(new Error("unimplemented"));
},
};
+80 -13
View File
@@ -520,6 +520,43 @@ policies and contribution forms [3].
Object.prototype.toString.call(worker) == '[object ServiceWorker]';
}
var seen_func_name = Object.create(null);
function get_test_name(func, name)
{
if (name) {
return name;
}
if (func) {
var func_code = func.toString();
// Try and match with brackets, but fallback to matching without
var arrow = func_code.match(/^\(\)\s*=>\s*(?:{(.*)}\s*|(.*))$/);
// Check for JS line separators
if (arrow !== null && !/[\u000A\u000D\u2028\u2029]/.test(func_code)) {
var trimmed = (arrow[1] !== undefined ? arrow[1] : arrow[2]).trim();
// drop trailing ; if there's no earlier ones
trimmed = trimmed.replace(/^([^;]*)(;\s*)+$/, "$1");
if (trimmed) {
let name = trimmed;
if (seen_func_name[trimmed]) {
// This subtest name already exists, so add a suffix.
name += " " + seen_func_name[trimmed];
} else {
seen_func_name[trimmed] = 0;
}
seen_func_name[trimmed] += 1;
return name;
}
}
}
return test_environment.next_default_test_name();
}
/*
* API functions
*/
@@ -530,17 +567,18 @@ policies and contribution forms [3].
tests.status.message = '`test` invoked after `promise_setup`';
tests.complete();
}
var test_name = name ? name : test_environment.next_default_test_name();
var test_name = get_test_name(func, name);
var test_obj = new Test(test_name, properties);
var value = test_obj.step(func, test_obj, test_obj);
if (value !== undefined) {
var msg = "Test named \"" + test_name +
"\" inappropriately returned a value";
var msg = 'Test named "' + test_name +
'" passed a function to `test` that returned a value.';
try {
if (value && value.hasOwnProperty("then")) {
msg += ", consider using `promise_test` instead";
if (value && typeof value.then === 'function') {
msg += ' Consider using `promise_test` instead when ' +
'using Promises or async/await.';
}
} catch (err) {}
@@ -565,10 +603,33 @@ policies and contribution forms [3].
name = func;
func = null;
}
var test_name = name ? name : test_environment.next_default_test_name();
var test_name = get_test_name(func, name);
var test_obj = new Test(test_name, properties);
if (func) {
test_obj.step(func, test_obj, test_obj);
var value = test_obj.step(func, test_obj, test_obj);
// Test authors sometimes return values to async_test, expecting us
// to handle the value somehow. Make doing so a harness error to be
// clear this is invalid, and point authors to promise_test if it
// may be appropriate.
//
// Note that we only perform this check on the initial function
// passed to async_test, not on any later steps - we haven't seen a
// consistent problem with those (and it's harder to check).
if (value !== undefined) {
var msg = 'Test named "' + test_name +
'" passed a function to `async_test` that returned a value.';
try {
if (value && typeof value.then === 'function') {
msg += ' Consider using `promise_test` instead when ' +
'using Promises or async/await.';
}
} catch (err) {}
tests.set_status(tests.status.ERROR, msg);
tests.complete();
}
}
return test_obj;
}
@@ -579,7 +640,7 @@ policies and contribution forms [3].
name = func;
func = null;
}
var test_name = name ? name : test_environment.next_default_test_name();
var test_name = get_test_name(func, name);
var test = new Test(test_name, properties);
test._is_promise_test = true;
@@ -1323,10 +1384,16 @@ policies and contribution forms [3].
"expected a number but got a ${type_actual}",
{type_actual:typeof actual});
assert(Math.abs(actual - expected) <= epsilon,
"assert_approx_equals", description,
"expected ${expected} +/- ${epsilon} but got ${actual}",
{expected:expected, actual:actual, epsilon:epsilon});
// The epsilon math below does not place nice with NaN and Infinity
// But in this case Infinity = Infinity and NaN = NaN
if (isFinite(actual) || isFinite(expected)) {
assert(Math.abs(actual - expected) <= epsilon,
"assert_approx_equals", description,
"expected ${expected} +/- ${epsilon} but got ${actual}",
{expected:expected, actual:actual, epsilon:epsilon});
} else {
assert_equals(actual, expected);
}
}
expose(assert_approx_equals, "assert_approx_equals");
@@ -3773,7 +3840,7 @@ policies and contribution forms [3].
function get_title()
{
if ('document' in global_scope) {
//Don't use document.title to work around an Opera bug in XHTML documents
//Don't use document.title to work around an Opera/Presto bug in XHTML documents
var title = document.getElementsByTagName("title")[0];
if (title && title.firstChild && title.firstChild.data) {
return title.firstChild.data;
+4
View File
@@ -44,6 +44,10 @@ expected to fail.
Tests in `/encoding` and `/html/infrastructure/urls/resolving-urls/query-encoding/` cover the
encoding argument to the URL parser.
There's also limited coverage in `resources/percent-encoding.json` for percent-encode after encoding
with _percentEncodeSet_ set to special-query percent-encode set and _spaceAsPlus_ set to false.
(Improvements to expand coverage here are welcome.)
## Specification
The tests in this directory assert conformance with [the URL Standard][URL].
+33
View File
@@ -0,0 +1,33 @@
promise_test(() => fetch("resources/percent-encoding.json").then(res => res.json()).then(runTests), "Loading data…");
function runTests(testUnits) {
for (const testUnit of testUnits) {
// Ignore comments
if (typeof testUnit === "string") {
continue;
}
for (const encoding of Object.keys(testUnit.output)) {
async_test(t => {
const frame = document.body.appendChild(document.createElement("iframe"));
t.add_cleanup(() => frame.remove());
frame.onload = t.step_func_done(() => {
const output = frame.contentDocument.querySelector("a");
// Test that the fragment is always UTF-8 encoded
assert_equals(output.hash, `#${testUnit.output["utf-8"]}`, "fragment");
assert_equals(output.search, `?${testUnit.output[encoding]}`, "query");
});
frame.src = `resources/percent-encoding.py?encoding=${encoding}&value=${toBase64(testUnit.input)}`;
}, `Input ${testUnit.input} with encoding ${encoding}`);
}
}
}
// Use base64 to avoid relying on the URL parser to get UTF-8 percent-encoding correctly. This does
// not use btoa directly as that only works with code points in the range U+0000 to U+00FF,
// inclusive.
function toBase64(input) {
const bytes = new TextEncoder().encode(input);
const byteString = Array.from(bytes, byte => String.fromCharCode(byte)).join("");
const encoded = self.btoa(byteString);
return encoded;
}
+48
View File
@@ -0,0 +1,48 @@
[
"Tests for percent-encoding.",
{
"input": "\u2020",
"output": {
"big5": "%26%238224%3B",
"euc-kr": "%A2%D3",
"utf-8": "%E2%80%A0",
"windows-1252": "%86"
}
},
"This uses a trailing A to prevent the URL parser from trimming the C0 control.",
{
"input": "\u000EA",
"output": {
"big5": "%0EA",
"iso-2022-jp": "%26%2365533%3BA",
"utf-8": "%0EA"
}
},
{
"input": "\u203E\u005C",
"output": {
"iso-2022-jp": "%1B(J~%1B(B\\",
"utf-8": "%E2%80%BE\\"
}
},
{
"input": "\uE5E5",
"output": {
"gb18030": "%26%2358853%3B",
"utf-8": "%EE%97%A5"
}
},
{
"input": "\u2212",
"output": {
"shift_jis": "%81|",
"utf-8": "%E2%88%92"
}
},
{
"input": "á|",
"output": {
"utf-8": "%C3%A1|"
}
}
]
+4 -4
View File
@@ -8,15 +8,15 @@
"path": "encoding"
},
"url": {
"commit": "54c6d64be071c60baaad8c4da0365b962ffbe77c",
"commit": "09d8830be15da7e3a44f32a934609c25357d6ef3",
"path": "url"
},
"resources": {
"commit": "1d14e821b9586f250e6a31d550504e3d16a05ae7",
"commit": "001e50de41dc35820774b27e31f77a165f4c0b9b",
"path": "resources"
},
"interfaces": {
"commit": "15e47f779cf61555669b0f67e2c49b9c830b9019",
"commit": "8719553b2dd8f0f39d38253ccac2ee9ab4d6c87b",
"path": "interfaces"
},
"html/webappapis/microtask-queuing": {
@@ -39,4 +39,4 @@
"commit": "7caa3de7471cf19b78ee9efa313c7341a462b5e3",
"path": "dom/abort"
}
}
}
+4
View File
@@ -3,6 +3,10 @@
"requires": ["small-icu"],
"skip": "TODO: port from .window.js"
},
"percent-encoding.window.js": {
"requires": ["small-icu"],
"skip": "TODO: port from .window.js"
},
"historical.any.js": {
"requires": ["small-icu"]
},