mirror of
https://github.com/servo/servo.git
synced 2025-08-12 08:55:32 +01:00
Update web-platform-tests to revision ac3d096a5972dea5ecca1c43e324086895db7c6f
This commit is contained in:
parent
1c74a80e28
commit
db54f176d0
47 changed files with 860 additions and 246 deletions
|
@ -0,0 +1,17 @@
|
|||
<!DOCTYPE html>
|
||||
<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-break/">
|
||||
<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=966369">
|
||||
<div id="container" style="height:100px";>
|
||||
<div style="height:100%;">
|
||||
<div style="break-before:page;"></div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script>
|
||||
test(()=> {
|
||||
document.body.offsetTop;
|
||||
container.style.height = "101px";
|
||||
}, "no crash");
|
||||
</script>
|
|
@ -13,6 +13,7 @@
|
|||
contain: layout;
|
||||
background: cyan;
|
||||
font-size: 20px;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
.wrapper > :nth-child(1) {
|
||||
background: magenta;
|
||||
|
@ -49,7 +50,7 @@ fieldset, details {
|
|||
</div>
|
||||
<div class="wrapper">
|
||||
<canvas></canvas>
|
||||
<input value="foo"></input>
|
||||
<input value="foo" size="3"></input>
|
||||
<input type="file"></input>
|
||||
</div>
|
||||
<div class="wrapper">
|
||||
|
|
|
@ -3,12 +3,16 @@
|
|||
<title>CSS Containment Test: Layout containment on button</title>
|
||||
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-contain-1/#containment-layout">
|
||||
<link rel="help" href="https://drafts.csswg.org/css2/visudet.html#propdef-vertical-align">
|
||||
<link rel="match" href="reference/contain-layout-button-001-ref.html">
|
||||
<meta name=assert content="Layout containment does apply to buttons, thus their baseline is the same than if they don't have contents.">
|
||||
<meta name=assert content="Layout containment does apply to buttons, thus their baseline is their margin-bottom edge.">
|
||||
<style>
|
||||
button {
|
||||
border: 5px solid green;
|
||||
padding: 0;
|
||||
/* We use a nonzero margin-bottom to be sure we're synthesizing a baseline
|
||||
from the margin-box rather than from the border-box: */
|
||||
margin-bottom: 2px;
|
||||
contain: layout;
|
||||
color: transparent;
|
||||
width: 0;
|
||||
|
@ -16,5 +20,5 @@ button {
|
|||
}
|
||||
</style>
|
||||
|
||||
<p>This test passes if it has the same output as the reference. You see the word "before", a 10px green square at the bottom, and then the word "after".</p>
|
||||
<p>This test passes if it has the same output as the reference. You see the word "before", a 10px green square aligned 2px above the text's baseline, and then the word "after".</p>
|
||||
before<button>b</button>after
|
||||
|
|
|
@ -46,7 +46,7 @@ fieldset, details {
|
|||
</div>
|
||||
<div class="wrapper">
|
||||
<canvas></canvas>
|
||||
<input value="foo"></input>
|
||||
<input value="foo" size="3"></input>
|
||||
<input type="file"></input>
|
||||
</div>
|
||||
<div class="wrapper">
|
||||
|
|
|
@ -3,9 +3,11 @@
|
|||
<title>CSS Containment Test: Reference file</title>
|
||||
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
|
||||
<style>
|
||||
button {
|
||||
div.fakeButton {
|
||||
display: inline-block;
|
||||
border: 5px solid green;
|
||||
padding: 0;
|
||||
margin-bottom: 2px;
|
||||
color: transparent;
|
||||
width: 0;
|
||||
height: 0px;
|
||||
|
@ -15,5 +17,5 @@ button {
|
|||
}
|
||||
</style>
|
||||
|
||||
<p>This test passes if it has the same output as the reference. You see the word "before", a 10px green square at the bottom, and then the word "after".</p>
|
||||
before<button></button>after
|
||||
<p>This test passes if it has the same output as the reference. You see the word "before", a 10px green square aligned 2px above the text's baseline, and then the word "after".</p>
|
||||
before<div class="fakeButton"></div>after
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<title>flexbox | flexcontainer versus stf :: fixed</title>
|
||||
<link rel="author" href="http://opera.com" title="Opera Software">
|
||||
<link rel="help" href="http://www.w3.org/TR/css-flexbox-1/#flex-items">
|
||||
<link rel="match" href="about:blank">
|
||||
<link rel="match" href="../reference/blank.html">
|
||||
<style>
|
||||
#test {
|
||||
background: red;
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
<!doctype html>
|
||||
<title>::marker pseudo-elements generated by ::before and ::after are not addressable by selectors</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/css-lists/#list-item">
|
||||
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1539171">
|
||||
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1543758">
|
||||
<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
|
||||
<link rel="author" href="https://mozilla.org" title="Mozilla">
|
||||
<link rel="match" href="nested-marker-ref.html">
|
||||
<style>
|
||||
li, ::marker {
|
||||
color: red;
|
||||
}
|
||||
li::before, li::after {
|
||||
display: list-item;
|
||||
content: "Before";
|
||||
}
|
||||
li::after {
|
||||
content: "After";
|
||||
}
|
||||
.tweak::marker {
|
||||
color: blue;
|
||||
}
|
||||
.tweak, .tweak::before, .tweak::after {
|
||||
color: initial;
|
||||
}
|
||||
</style>
|
||||
<ol>
|
||||
<li>Foo
|
||||
<li>Bar
|
||||
<script>
|
||||
window.onload = function() {
|
||||
document.body.offsetTop;
|
||||
for (let li of document.querySelectorAll("li"))
|
||||
li.classList.add("tweak");
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,15 @@
|
|||
<!doctype html>
|
||||
<title>CSS test reference</title>
|
||||
<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
|
||||
<link rel="author" href="https://mozilla.org" title="Mozilla">
|
||||
<style>
|
||||
li::marker {
|
||||
color: blue;
|
||||
}
|
||||
div {
|
||||
display: list-item;
|
||||
}
|
||||
</style>
|
||||
<ol>
|
||||
<li><div>Before</div>Foo<div>After</div>
|
||||
<li><div>Before</div>Bar<div>After</div>
|
|
@ -0,0 +1,26 @@
|
|||
<!doctype html>
|
||||
<title>::marker pseudo-elements generated by ::before and ::after are not addressable by global selectors</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/css-lists/#list-item">
|
||||
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1539171">
|
||||
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1543758">
|
||||
<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
|
||||
<link rel="author" href="https://mozilla.org" title="Mozilla">
|
||||
<link rel="match" href="nested-marker-ref.html">
|
||||
<style>
|
||||
::marker {
|
||||
color: red;
|
||||
}
|
||||
li::marker {
|
||||
color: blue;
|
||||
}
|
||||
li::before, li::after {
|
||||
display: list-item;
|
||||
content: "Before";
|
||||
}
|
||||
li::after {
|
||||
content: "After";
|
||||
}
|
||||
</style>
|
||||
<ol>
|
||||
<li>Foo
|
||||
<li>Bar
|
|
@ -0,0 +1,16 @@
|
|||
<!doctype html>
|
||||
<title>CSS Test: ::slotted() should not match via the matches() API, since it's in the wrong scope</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-scoping/#slotted-pseudo">
|
||||
<link rel="help" href="https://dom.spec.whatwg.org/#dom-element-matches">
|
||||
<link rel="help" href="https://bugzil.la/1544242">
|
||||
<div id="host"><div id="slotted"></div></div>
|
||||
<script>
|
||||
test(function() {
|
||||
let slotted = document.getElementById("slotted");
|
||||
host.attachShadow({ mode: "open" }).innerHTML = `<slot></slot>`;
|
||||
assert_false(slotted.matches("::slotted(div)"), "Shouldn't match ::slotted from the outer tree")
|
||||
}, "::slotted() doesn't reveal the presence of shadow DOM via matches()");
|
||||
</script>
|
|
@ -19,7 +19,8 @@ assert_not_inherited('offset-anchor', 'auto', '2px 3px');
|
|||
assert_not_inherited('offset-distance', '0px', '4px');
|
||||
assert_not_inherited('offset-path', 'none', 'path("M 5 6 H 7")');
|
||||
assert_not_inherited('offset-position', 'auto', '8px 9px');
|
||||
assert_not_inherited('offset-rotate', 'auto 0deg', '90deg');
|
||||
// https://github.com/w3c/fxtf-drafts/issues/340
|
||||
assert_not_inherited('offset-rotate', ['auto 0deg', 'auto'], '90deg');
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>CSS Motion Path: offset-rotate</title>
|
||||
<link rel="help" href="https://drafts.fxtf.org/motion-1/#offset-rotate-property">
|
||||
<link rel="match" href="offset-rotate-ref.html">
|
||||
<meta name="assert" content="This tests offset-rotate <angle>">
|
||||
<style>
|
||||
#target {
|
||||
position: absolute;
|
||||
left: 300px;
|
||||
top: 100px;
|
||||
width: 300px;
|
||||
height: 200px;
|
||||
background-color: lime;
|
||||
transform-origin: 0px 0px;
|
||||
offset-path: path('m 0 0 v -200 -200') ;
|
||||
offset-rotate: 30deg;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="target"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,37 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<head>
|
||||
<title>CSS Motion Path: offset-rotate</title>
|
||||
<link rel="help" href="https://drafts.fxtf.org/motion-1/#offset-rotate-property">
|
||||
<link rel="match" href="offset-rotate-ref.html">
|
||||
<meta name="assert" content="This tests offset-rotate auto with path()">
|
||||
<style>
|
||||
#target {
|
||||
position: absolute;
|
||||
left: 300px;
|
||||
top: 100px;
|
||||
width: 300px;
|
||||
height: 200px;
|
||||
background-color: lime;
|
||||
transform-origin: 0px 0px;
|
||||
offset-rotate: auto;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
function test() {
|
||||
let target = document.getElementById('target');
|
||||
// Get a path which has the same direction as "ray(120deg ...)"
|
||||
let verticalMove = 100 * Math.tan(30 * Math.PI / 180);
|
||||
target.style.offsetPath = `path("m 0 0 l 100 ${verticalMove}")`;
|
||||
window.getComputedStyle(target).offsetPath;
|
||||
|
||||
window.requestAnimationFrame(function() {
|
||||
document.documentElement.removeAttribute('class');
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload='test()'>
|
||||
<div id="target"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,37 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<head>
|
||||
<title>CSS Motion Path: offset-rotate</title>
|
||||
<link rel="help" href="https://drafts.fxtf.org/motion-1/#offset-rotate-property">
|
||||
<link rel="match" href="offset-rotate-ref.html">
|
||||
<meta name="assert" content="This tests offset-rotate reverse <angle> with path()">
|
||||
<style>
|
||||
#target {
|
||||
position: absolute;
|
||||
left: 300px;
|
||||
top: 100px;
|
||||
width: 300px;
|
||||
height: 200px;
|
||||
background-color: lime;
|
||||
transform-origin: 0px 0px;
|
||||
offset-rotate: reverse 60deg;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
function test() {
|
||||
let target = document.getElementById('target');
|
||||
// Get a path which has the same direction as "ray(-120deg ...)"
|
||||
let verticalMove = 100 * Math.tan(30 * Math.PI / 180);
|
||||
target.style.offsetPath = `path("m 0 0 l -100 ${verticalMove}")`;
|
||||
window.getComputedStyle(target).offsetPath;
|
||||
|
||||
window.requestAnimationFrame(function() {
|
||||
document.documentElement.removeAttribute('class');
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload='test()'>
|
||||
<div id="target"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -13,7 +13,8 @@
|
|||
<body>
|
||||
<div id="target"></div>
|
||||
<script>
|
||||
test_computed_value("offset-rotate", "auto", "auto 0deg");
|
||||
// https://github.com/w3c/fxtf-drafts/issues/340
|
||||
test_computed_value("offset-rotate", "auto", ["auto 0deg", "auto"]);
|
||||
test_computed_value("offset-rotate", "reverse", "auto 180deg");
|
||||
test_computed_value("offset-rotate", "calc(90deg - 0.5turn - 300grad + 0rad)", "-360deg");
|
||||
test_computed_value("offset-rotate", "auto 5turn", "auto 1800deg");
|
||||
|
|
|
@ -16,9 +16,11 @@ test_valid_value("offset-rotate", "auto");
|
|||
test_valid_value("offset-rotate", "reverse");
|
||||
test_valid_value("offset-rotate", "-400deg");
|
||||
test_valid_value("offset-rotate", "auto 5turn");
|
||||
test_valid_value("offset-rotate", "reverse 0rad");
|
||||
// https://github.com/w3c/fxtf-drafts/issues/340
|
||||
test_valid_value("offset-rotate", "reverse 0rad", ["reverse 0rad", "reverse"]);
|
||||
test_valid_value("offset-rotate", "5turn auto", "auto 5turn");
|
||||
test_valid_value("offset-rotate", "0rad reverse", "reverse 0rad");
|
||||
// https://github.com/w3c/fxtf-drafts/issues/340
|
||||
test_valid_value("offset-rotate", "0rad reverse", ["reverse 0rad", "reverse"]);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -6,22 +6,36 @@
|
|||
*
|
||||
* @param {string} property The name of the CSS property being tested.
|
||||
* @param {string} specified A specified value for the property.
|
||||
* @param {string} computed The expected computed value. If omitted,
|
||||
defaults to specified.
|
||||
* @param {string|array} computed The expected computed value,
|
||||
* or an array of permitted computed value.
|
||||
* If omitted, defaults to specified.
|
||||
*/
|
||||
function test_computed_value(property, specified, computed) {
|
||||
if (!computed)
|
||||
computed = specified;
|
||||
|
||||
let computedDesc = "'" + computed + "'";
|
||||
if (Array.isArray(computed))
|
||||
computedDesc = '[' + computed.map(e => "'" + e + "'").join(' or ') + ']';
|
||||
|
||||
test(() => {
|
||||
const target = document.getElementById('target');
|
||||
assert_true(property in getComputedStyle(target), property + " doesn't seem to be supported in the computed style");
|
||||
target.style[property] = '';
|
||||
target.style[property] = specified;
|
||||
assert_equals(getComputedStyle(target)[property], computed);
|
||||
if (computed !== specified) {
|
||||
target.style[property] = '';
|
||||
target.style[property] = computed;
|
||||
assert_equals(getComputedStyle(target)[property], computed, 'computed value should round-trip');
|
||||
|
||||
let readValue = getComputedStyle(target)[property];
|
||||
if (Array.isArray(computed)) {
|
||||
assert_in_array(readValue, computed);
|
||||
} else {
|
||||
assert_equals(readValue, computed);
|
||||
}
|
||||
}, "Property " + property + " value '" + specified + "' computes to '" + computed + "'");
|
||||
if (readValue !== specified) {
|
||||
target.style[property] = '';
|
||||
target.style[property] = readValue;
|
||||
assert_equals(getComputedStyle(target)[property], readValue,
|
||||
'computed value should round-trip');
|
||||
}
|
||||
}, "Property " + property + " value '" + specified + "' computes to " +
|
||||
computedDesc);
|
||||
}
|
||||
|
|
|
@ -3,13 +3,21 @@
|
|||
(function() {
|
||||
|
||||
function assert_initial(property, initial) {
|
||||
let initialDesc = initial;
|
||||
if (Array.isArray(initial))
|
||||
initialDesc = '[' + initial.map(e => "'" + e + "'").join(' or ') + ']';
|
||||
|
||||
test(() => {
|
||||
const target = document.getElementById('target');
|
||||
assert_true(property in getComputedStyle(target), property + " doesn't seem to be supported in the computed style");
|
||||
target.style[property] = 'initial';
|
||||
assert_equals(getComputedStyle(target)[property], initial);
|
||||
if (Array.isArray(initial)) {
|
||||
assert_in_array(getComputedStyle(target)[property], initial);
|
||||
} else {
|
||||
assert_equals(getComputedStyle(target)[property], initial);
|
||||
}
|
||||
target.style[property] = '';
|
||||
}, 'Property ' + property + ' has initial value ' + initial);
|
||||
}, 'Property ' + property + ' has initial value ' + initialDesc);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -17,10 +25,12 @@ function assert_initial(property, initial) {
|
|||
*
|
||||
* The current document must have an element #target within element #container.
|
||||
*
|
||||
* @param {string} property The name of the CSS property being tested.
|
||||
* @param {string} initial The computed value for 'initial'.
|
||||
* @param {string} other An arbitrary value for the property that round
|
||||
* trips and is distinct from the initial value.
|
||||
* @param {string} property The name of the CSS property being tested.
|
||||
* @param {string|array} initial The computed value for 'initial' or a list
|
||||
* of acceptable computed value serializations.
|
||||
* @param {string} other An arbitrary value for the property that
|
||||
* round trips and is distinct from the initial
|
||||
* value.
|
||||
*/
|
||||
function assert_inherited(property, initial, other) {
|
||||
assert_initial(property, initial);
|
||||
|
@ -52,10 +62,12 @@ function assert_inherited(property, initial, other) {
|
|||
*
|
||||
* The current document must have an element #target within element #container.
|
||||
*
|
||||
* @param {string} property The name of the CSS property being tested.
|
||||
* @param {string} initial The computed value for 'initial'.
|
||||
* @param {string} other An arbitrary value for the property that round
|
||||
* trips and is distinct from the initial value.
|
||||
* @param {string} property The name of the CSS property being tested.
|
||||
* @param {string|array} initial The computed value for 'initial' or a list
|
||||
* of acceptable computed value serializations.
|
||||
* @param {string} other An arbitrary value for the property that
|
||||
* round trips and is distinct from the initial
|
||||
* value.
|
||||
*/
|
||||
function assert_not_inherited(property, initial, other) {
|
||||
assert_initial(property, initial);
|
||||
|
|
|
@ -1,12 +1,25 @@
|
|||
<script>
|
||||
"use strict";
|
||||
|
||||
Promise.resolve().then(() => {
|
||||
try {
|
||||
const wakeLock = new WakeLock("screen");
|
||||
window.parent.postMessage({ enabled: true }, "*");
|
||||
} catch (e) {
|
||||
window.parent.postMessage({ enabled: false }, "*");
|
||||
}
|
||||
Promise.resolve().then(async () => {
|
||||
// On success, WakeLock.request() returns a promise that never resolves. To
|
||||
// prevent a timeout, abort it with an AbortController and use the different
|
||||
// DOMExceptions we get to determine if this worked or not.
|
||||
const controller = new AbortController();
|
||||
const wakeLock = WakeLock.request("screen", { signal: controller.signal });
|
||||
wakeLock.catch(e => {
|
||||
if (e.name == "AbortError") {
|
||||
// We stopped due to the call to AbortController.abort(), so we did manage
|
||||
// to get the lock.
|
||||
window.parent.postMessage({ enabled: true }, "*");
|
||||
} else if (e.name == "NotAllowedError") {
|
||||
// This means requesting the lock failed.
|
||||
window.parent.postMessage({ enabled: false }, "*");
|
||||
} else {
|
||||
// We should not really hit this branch.
|
||||
window.parent.postMessage({ enabled: false }, "*");
|
||||
}
|
||||
});
|
||||
controller.abort();
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
|
||||
<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=966363">
|
||||
<object style="display:block;">
|
||||
<ruby></ruby>
|
||||
</object>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script>
|
||||
test(()=> {}, "no crash");
|
||||
</script>
|
|
@ -20,7 +20,7 @@ async function responder(event) {
|
|||
});
|
||||
changePaymentMethodReturned = response;
|
||||
} catch (err) {
|
||||
changePaymentMethodReturned = error.message;
|
||||
changePaymentMethodReturned = err.message;
|
||||
}
|
||||
return {methodName, details: {changePaymentMethodReturned}};
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
html5lib==1.0.1
|
||||
mozinfo==1.1.0
|
||||
mozlog==4.0
|
||||
mozlog==4.1
|
||||
mozdebug==0.1.1
|
||||
pillow==6.0.0
|
||||
urllib3[secure]==1.25.2
|
||||
|
|
|
@ -10,7 +10,7 @@ idl_test(
|
|||
['dom', 'html', 'permissions'],
|
||||
idl_array => {
|
||||
idl_array.add_objects({
|
||||
WakeLock: ['new WakeLock("screen")']
|
||||
WakeLock: []
|
||||
});
|
||||
}
|
||||
);
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
<meta charset="utf-8">
|
|
@ -0,0 +1 @@
|
|||
<meta charset="utf-8">
|
|
@ -0,0 +1,31 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>WakeLock: passing an AbortSignal already set aborts</title>
|
||||
<link rel="help" href="https://w3c.github.io/wake-lock/">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script>
|
||||
promise_test(t => {
|
||||
const abortController = new AbortController();
|
||||
const abortSignal = abortController.signal;
|
||||
abortController.abort();
|
||||
assert_true(abortSignal.aborted);
|
||||
|
||||
return promise_rejects(t, "AbortError", WakeLock.request('screen', { signal: abortSignal }));
|
||||
}, "A WakeLock request with an AbortSignal whose abort flag is set always aborts");
|
||||
|
||||
promise_test(async t => {
|
||||
const abortController = new AbortController();
|
||||
const abortSignal = abortController.signal;
|
||||
abortController.abort();
|
||||
assert_true(abortSignal.aborted);
|
||||
|
||||
const lock1 = WakeLock.request('screen', { signal: abortSignal });
|
||||
const lock2 = WakeLock.request('screen', { signal: abortSignal });
|
||||
const lock3 = WakeLock.request('system', { signal: abortSignal });
|
||||
|
||||
await promise_rejects(t, "AbortError", lock1);
|
||||
await promise_rejects(t, "AbortError", lock2);
|
||||
await promise_rejects(t, "AbortError", lock3);
|
||||
}, "The same AbortSignal can be used to cause multiple wake locks to abort");
|
||||
</script>
|
|
@ -0,0 +1,81 @@
|
|||
function getWakeLockObject(iframe, url) {
|
||||
return new Promise(resolve => {
|
||||
iframe.addEventListener(
|
||||
"load",
|
||||
() => {
|
||||
const { WakeLock } = iframe.contentWindow;
|
||||
resolve(WakeLock);
|
||||
},
|
||||
{ once: true }
|
||||
);
|
||||
iframe.src = url;
|
||||
});
|
||||
}
|
||||
|
||||
promise_test(async t => {
|
||||
const iframe = document.createElement("iframe");
|
||||
document.body.appendChild(iframe);
|
||||
// We first got to page1.html, grab a WakeLock object.
|
||||
const wakeLock1 = await getWakeLockObject(
|
||||
iframe,
|
||||
"/wake-lock/resources/page1.html"
|
||||
);
|
||||
// We navigate the iframe again, putting wakeLock1's document into an inactive state.
|
||||
const wakeLock2 = await getWakeLockObject(
|
||||
iframe,
|
||||
"/wake-lock/resources/page2.html"
|
||||
);
|
||||
// Now, wakeLock1's relevant global object's document is no longer active.
|
||||
// So, call .request(), and make sure it rejects appropriately.
|
||||
await promise_rejects(
|
||||
t,
|
||||
"NotAllowedError",
|
||||
wakeLock1.request('screen'),
|
||||
"Inactive document, so must throw NotAllowedError"
|
||||
);
|
||||
// We are done, so clean up.
|
||||
iframe.remove();
|
||||
}, "WakeLock.request() aborts if the document is not active.");
|
||||
|
||||
promise_test(async t => {
|
||||
// We nest two iframes and wait for them to load.
|
||||
const outerIframe = document.createElement("iframe");
|
||||
document.body.appendChild(outerIframe);
|
||||
// Load the outer iframe (we don't care about the awaited request)
|
||||
await getWakeLockObject(
|
||||
outerIframe,
|
||||
"/wake-lock/resources/page1.html"
|
||||
);
|
||||
|
||||
// Now we create the inner iframe
|
||||
const innerIframe = outerIframe.contentDocument.createElement("iframe");
|
||||
|
||||
// nest them
|
||||
outerIframe.contentDocument.body.appendChild(innerIframe);
|
||||
|
||||
// load innerIframe, and get the WakeLock instance
|
||||
const wakeLock = await getWakeLockObject(
|
||||
innerIframe,
|
||||
"/wake-lock/resources/page2.html"
|
||||
);
|
||||
|
||||
// Navigate the outer iframe to a new location.
|
||||
// Wait for the load event to fire.
|
||||
await new Promise(resolve => {
|
||||
outerIframe.addEventListener("load", resolve);
|
||||
outerIframe.src = "/wake-lock/resources/page2.html";
|
||||
});
|
||||
|
||||
// Now, request's relevant global object's document is still active
|
||||
// (it is the active document of the inner iframe), but is not fully active
|
||||
// (since the parent of the inner iframe is itself no longer active).
|
||||
// So, call request.show() and make sure it rejects appropriately.
|
||||
await promise_rejects(
|
||||
t,
|
||||
"NotAllowedError",
|
||||
wakeLock.request('screen'),
|
||||
"Active, but not fully active, so must throw NotAllowedError"
|
||||
);
|
||||
// We are done, so clean up.
|
||||
outerIframe.remove();
|
||||
}, "WakeLock.request() aborts if the document is active, but not fully active.");
|
|
@ -1,59 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>wake lock applicability test</title>
|
||||
<link rel="help" href="https://w3c.github.io/wake-lock/#dfn-applicable-wake-lock">
|
||||
<meta name="flags" content="interact">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<p>
|
||||
Lock and turn off the screen, then turn on and unlock the screen.
|
||||
</p>
|
||||
<p>
|
||||
Note: All the actions need to be done in 60 seconds, otherwise it will get TIMEOUT.
|
||||
</p>
|
||||
<script>
|
||||
|
||||
setup({ explicit_timeout: true });
|
||||
|
||||
promise_test(async t => {
|
||||
const wakeLock = new WakeLock("screen");
|
||||
|
||||
const controller = new AbortController();
|
||||
const signal = controller.signal;
|
||||
|
||||
await wakeLock.request({ signal });
|
||||
assert_true(wakeLock.active, "the active is true when wake lock is acquired");
|
||||
const eventWatcher = new EventWatcher(t, document, "visibilitychange");
|
||||
|
||||
//lock screen to fire 'visibilitychange'
|
||||
await eventWatcher.wait_for("visibilitychange");
|
||||
assert_true(document.hidden, "document is hidden when screen is locked");
|
||||
assert_false(wakeLock.active, "the screen wake lock is not active when screen is switched off");
|
||||
|
||||
//unlock screen to fire 'visibilitychange'
|
||||
await eventWatcher.wait_for("visibilitychange");
|
||||
assert_false(document.hidden, "document is visiable when screen is unlocked");
|
||||
assert_true(wakeLock.active, "the screen wake lock is active when screen is switched on again");
|
||||
controller.abort();
|
||||
}, "The screen wake lock isn't applicable after the screen is manually swiched off"
|
||||
+ " by the user until it is switched on again.");
|
||||
|
||||
|
||||
promise_test(async t => {
|
||||
const wakeLock = new WakeLock("system");
|
||||
|
||||
const controller = new AbortController();
|
||||
const signal = controller.signal;
|
||||
|
||||
await wakeLock.request({ signal });
|
||||
assert_true(wakeLock.active, "the active is true when wake lock is acquired");
|
||||
const eventWatcher = new EventWatcher(t, document, "visibilitychange");
|
||||
|
||||
//lock screen to fire 'visibilitychange'
|
||||
await eventWatcher.wait_for("visibilitychange");
|
||||
assert_true(document.hidden, "document is hidden when screen is locked");
|
||||
assert_true(wakeLock.active, "the system wake lock is still active when screen is switched off");
|
||||
controller.abort();
|
||||
}, "Manually switching off the screen will not affect the applicability of the system wake lock.");
|
||||
|
||||
</script>
|
|
@ -11,13 +11,13 @@
|
|||
const cross_origin_src =
|
||||
"https://{{domains[www]}}:{{ports[https][0]}}" + same_origin_src;
|
||||
|
||||
test(() => {
|
||||
assert_throws("NotAllowedError", () => new WakeLock("screen"));
|
||||
promise_test(t => {
|
||||
return promise_rejects(t, "NotAllowedError", WakeLock.request("screen"));
|
||||
}, 'Feature-Policy header {"wake-lock" : []} disallows the top-level document.');
|
||||
|
||||
async_test(t => {
|
||||
test_feature_availability(
|
||||
'new WakeLock("screen")',
|
||||
'WakeLock.request("screen")',
|
||||
t,
|
||||
same_origin_src,
|
||||
expect_feature_unavailable_default
|
||||
|
@ -26,7 +26,7 @@
|
|||
|
||||
async_test(t => {
|
||||
test_feature_availability(
|
||||
'new WakeLock("screen")',
|
||||
'WakeLock.request("screen")',
|
||||
t,
|
||||
cross_origin_src,
|
||||
expect_feature_unavailable_default
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<meta name="timeout" content="long">
|
||||
<title>Screen wake locks respect page visibility changes</title>
|
||||
<link rel="help" href="https://w3c.github.io/wake-lock/#dfn-requesting-the-wake-lock">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script>
|
||||
|
||||
promise_test(async t => {
|
||||
const controller = new AbortController();
|
||||
const screenWakeLock = WakeLock.request('screen', { signal: controller.signal });
|
||||
const systemWakeLock = WakeLock.request('system', { signal: controller.signal });
|
||||
const systemWakeLockPromise = new Promise((resolve, reject) => {
|
||||
systemWakeLock.catch(error => {
|
||||
assert_equals("AbortError", error.name, "systemWakeLock must have been aborted");
|
||||
assert_false(document.hidden, "systemWakeLock must have been aborted after the page is visible again");
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
const eventWatcher = new EventWatcher(t, document, "visibilitychange");
|
||||
await eventWatcher.wait_for("visibilitychange");
|
||||
assert_true(document.hidden, "document is hidden after the visibilitychange event");
|
||||
await promise_rejects(t, "AbortError", screenWakeLock, "existing screen locks are aborted");
|
||||
await promise_rejects(t, "NotAllowedError", WakeLock.request('screen'),
|
||||
"new screen locks are not allowed when the page is not visible");
|
||||
|
||||
await eventWatcher.wait_for("visibilitychange");
|
||||
assert_false(document.hidden, "document is no longer hidden after the visibilitychange event");
|
||||
controller.abort();
|
||||
|
||||
return systemWakeLockPromise;
|
||||
}, "Test screen locks respect page visibility changes and system locks are unchanged");
|
||||
|
||||
</script>
|
||||
|
||||
<p>Switch the page to the background, then switch back to it.</p>
|
|
@ -1,31 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>screen wake lock will not be actived in hidden document</title>
|
||||
<link rel="help" href="https://w3c.github.io/wake-lock/#dfn-requesting-the-wake-lock">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script>
|
||||
|
||||
promise_test(async t => {
|
||||
const wakeLock = new WakeLock("screen");
|
||||
|
||||
const controller = new AbortController();
|
||||
const signal = controller.signal;
|
||||
|
||||
await wakeLock.request({ signal });
|
||||
assert_true(wakeLock.active, "the active is true when wake lock is acquired");
|
||||
const eventWatcher = new EventWatcher(t, document, "visibilitychange");
|
||||
const win = window.open("about:blank", "_blank");
|
||||
|
||||
await eventWatcher.wait_for("visibilitychange");
|
||||
assert_true(document.hidden, "document is hidden when new window is opened");
|
||||
assert_false(wakeLock.active, "the active is false when document is hidden");
|
||||
win.close();
|
||||
|
||||
await eventWatcher.wait_for("visibilitychange");
|
||||
assert_false(document.hidden, "document is visiable when new window is closed");
|
||||
assert_true(wakeLock.active, "the active is true when document regains visibility");
|
||||
controller.abort();
|
||||
}, "Test that screen wake lock will not be actived in hidden document");
|
||||
|
||||
</script>
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
async_test(t => {
|
||||
test_feature_availability(
|
||||
'new WakeLock("screen")',
|
||||
'WakeLock.request("screen")',
|
||||
t,
|
||||
same_origin_src,
|
||||
expect_feature_available_default,
|
||||
|
@ -24,7 +24,7 @@
|
|||
|
||||
async_test(t => {
|
||||
test_feature_availability(
|
||||
'new WakeLock("screen")',
|
||||
'WakeLock.request("screen")',
|
||||
t,
|
||||
cross_origin_src,
|
||||
expect_feature_unavailable_default,
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
async_test(t => {
|
||||
test_feature_availability(
|
||||
'new WakeLock("screen")',
|
||||
'WakeLock.request("screen")',
|
||||
t,
|
||||
same_origin_src,
|
||||
expect_feature_available_default,
|
||||
|
@ -23,7 +23,7 @@
|
|||
|
||||
async_test(t => {
|
||||
test_feature_availability(
|
||||
'new WakeLock("screen")',
|
||||
'WakeLock.request("screen")',
|
||||
t,
|
||||
cross_origin_src,
|
||||
expect_feature_available_default,
|
||||
|
|
|
@ -11,17 +11,16 @@
|
|||
const cross_origin_src =
|
||||
"https://{{domains[www]}}:{{ports[https][0]}}" + same_origin_src;
|
||||
|
||||
test(() => {
|
||||
try {
|
||||
new WakeLock("screen");
|
||||
} catch (e) {
|
||||
assert_unreached(e);
|
||||
}
|
||||
promise_test(t => {
|
||||
const controller = new AbortController();
|
||||
const lock = WakeLock.request("screen", { signal: controller.signal });
|
||||
controller.abort();
|
||||
return promise_rejects(t, "AbortError", lock);
|
||||
}, 'Feature-Policy header {"wake-lock" : ["*"]} allows the top-level document.');
|
||||
|
||||
async_test(t => {
|
||||
test_feature_availability(
|
||||
'new WakeLock("screen")',
|
||||
'WakeLock.request("screen")',
|
||||
t,
|
||||
same_origin_src,
|
||||
expect_feature_available_default
|
||||
|
@ -30,7 +29,7 @@
|
|||
|
||||
async_test(t => {
|
||||
test_feature_availability(
|
||||
'new WakeLock("screen")',
|
||||
'WakeLock.request("screen")',
|
||||
t,
|
||||
cross_origin_src,
|
||||
expect_feature_available_default
|
||||
|
|
|
@ -12,17 +12,16 @@
|
|||
const cross_origin_src =
|
||||
"https://{{domains[www]}}:{{ports[https][0]}}" + same_origin_src;
|
||||
|
||||
test(t => {
|
||||
try {
|
||||
new WakeLock("screen");
|
||||
} catch (e) {
|
||||
assert_unreached(e);
|
||||
}
|
||||
promise_test(t => {
|
||||
const controller = new AbortController();
|
||||
const lock = WakeLock.request("screen", { signal: controller.signal });
|
||||
controller.abort();
|
||||
return promise_rejects(t, "AbortError", lock);
|
||||
}, 'Feature-Policy header wake-lock "self" allows the top-level document.');
|
||||
|
||||
async_test(t => {
|
||||
test_feature_availability(
|
||||
'new WakeLock("screen")',
|
||||
'WakeLock.request("screen")',
|
||||
t,
|
||||
same_origin_src,
|
||||
expect_feature_available_default
|
||||
|
@ -31,7 +30,7 @@
|
|||
|
||||
async_test(t => {
|
||||
test_feature_availability(
|
||||
'new WakeLock("screen")',
|
||||
'WakeLock.request("screen")',
|
||||
t,
|
||||
cross_origin_src,
|
||||
expect_feature_unavailable_default
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Wake Lock 'onactivechange' Test</title>
|
||||
<link rel="help" href="https://w3c.github.io/wake-lock/">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<script>
|
||||
|
||||
promise_test(async t => {
|
||||
const wakeLock = new WakeLock("screen");
|
||||
const eventWatcher = new EventWatcher(t, wakeLock, "activechange");
|
||||
assert_false(wakeLock.active, "the active is false before wake lock is acquired");
|
||||
|
||||
const controller = new AbortController();
|
||||
const signal = controller.signal;
|
||||
|
||||
await wakeLock.request({ signal });
|
||||
let evt1 = await eventWatcher.wait_for("activechange");
|
||||
assert_true(evt1.isTrusted && !evt1.bubbles && !evt1.cancelable && evt1 instanceof Event, "a simple event is fired");
|
||||
assert_equals(evt1.type, "activechange", "the event name is 'activechange'");
|
||||
assert_equals(evt1.target, wakeLock, "event.target is WakeLock.");
|
||||
assert_true(wakeLock.active, "the active is true when wake lock is acquired");
|
||||
|
||||
controller.abort();
|
||||
let evt2 = await eventWatcher.wait_for("activechange");
|
||||
assert_true(evt2.isTrusted && !evt2.bubbles && !evt2.cancelable && evt2 instanceof Event, "a simple event is fired");
|
||||
assert_false(wakeLock.active, "the active is false when wake lock is released");
|
||||
}, "Test that 'activechange' event is fire and wakeLock.active is valid");
|
||||
|
||||
</script>
|
|
@ -0,0 +1,98 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test ScriptProcessorNode</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/webaudio/resources/audit-util.js"></script>
|
||||
<script src="/webaudio/resources/audit.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
// Arbitrary sample rate
|
||||
const sampleRate = 48000;
|
||||
let audit = Audit.createTaskRunner();
|
||||
|
||||
audit.define(
|
||||
{
|
||||
label: 'test',
|
||||
description: 'ScriptProcessor with stopped input source'
|
||||
},
|
||||
(task, should) => {
|
||||
// Two channels for testing. Channel 0 is the output of the
|
||||
// scriptProcessor. Channel 1 is the oscillator so we can compare
|
||||
// the outputs.
|
||||
let context = new OfflineAudioContext({
|
||||
numberOfChannels: 2,
|
||||
length: sampleRate,
|
||||
sampleRate: sampleRate
|
||||
});
|
||||
|
||||
let merger = new ChannelMergerNode(
|
||||
context, {numberOfChannels: context.destination.channelCount});
|
||||
merger.connect(context.destination);
|
||||
|
||||
let src = new OscillatorNode(context);
|
||||
|
||||
// Arbitrary buffer size for the ScriptProcessorNode. Don't use 0;
|
||||
// we need to know the actual size to know the latency of the node
|
||||
// (easily).
|
||||
const spnSize = 512;
|
||||
let spn = context.createScriptProcessor(spnSize, 1, 1);
|
||||
|
||||
// Arrange for the ScriptProcessor to add |offset| to the input.
|
||||
const offset = 1;
|
||||
spn.onaudioprocess = (event) => {
|
||||
let input = event.inputBuffer.getChannelData(0);
|
||||
let output = event.outputBuffer.getChannelData(0);
|
||||
for (let k = 0; k < output.length; ++k) {
|
||||
output[k] = input[k] + offset;
|
||||
}
|
||||
};
|
||||
|
||||
src.connect(spn).connect(merger, 0, 0);
|
||||
src.connect(merger, 0, 1);
|
||||
|
||||
// Start and stop the source. The stop time is fairly arbitrary,
|
||||
// but use a render quantum boundary for simplicity.
|
||||
const stopFrame = RENDER_QUANTUM_FRAMES;
|
||||
src.start(0);
|
||||
src.stop(stopFrame / context.sampleRate);
|
||||
|
||||
context.startRendering()
|
||||
.then(buffer => {
|
||||
let ch0 = buffer.getChannelData(0);
|
||||
let ch1 = buffer.getChannelData(1);
|
||||
|
||||
let shifted = ch1.slice(0, stopFrame).map(x => x + offset);
|
||||
|
||||
// SPN has a basic latency of 2*|spnSize| fraems, so the
|
||||
// beginning is silent.
|
||||
should(
|
||||
ch0.slice(0, 2 * spnSize - 1),
|
||||
`ScriptProcessor output[0:${2 * spnSize - 1}]`)
|
||||
.beConstantValueOf(0);
|
||||
|
||||
// For the middle section (after adding latency), the output
|
||||
// should be the source shifted by |offset|.
|
||||
should(
|
||||
ch0.slice(2 * spnSize, 2 * spnSize + stopFrame),
|
||||
`ScriptProcessor output[${2 * spnSize}:${
|
||||
2 * spnSize + stopFrame - 1}]`)
|
||||
.beCloseToArray(shifted, {absoluteThreshold: 0});
|
||||
|
||||
// Output should be constant after the source has stopped.
|
||||
// Include the latency introduced by the node.
|
||||
should(
|
||||
ch0.slice(2 * spnSize + stopFrame),
|
||||
`ScriptProcessor output[${2 * spnSize + stopFrame}:]`)
|
||||
.beConstantValueOf(offset);
|
||||
})
|
||||
.then(() => task.done());
|
||||
});
|
||||
|
||||
audit.run();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -309,6 +309,21 @@ function listenToConnected(pc) {
|
|||
});
|
||||
}
|
||||
|
||||
// Returns a promise that resolves when |pc.connectionState| is in one of the
|
||||
// wanted states.
|
||||
function waitForConnectionStateChange(pc, wantedStates) {
|
||||
return new Promise((resolve) => {
|
||||
if (wantedStates.includes(pc.connectionState)) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
pc.addEventListener('connectionstatechange', () => {
|
||||
if (wantedStates.includes(pc.connectionState))
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Resolves when RTP packets have been received.
|
||||
function listenForSSRCs(t, receiver) {
|
||||
return new Promise((resolve) => {
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>DTLS fingerprint validation</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../RTCPeerConnection-helper.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
|
||||
// Tests that an invalid fingerprint leads to a connectionState 'failed'.
|
||||
promise_test(async t => {
|
||||
const pc1 = new RTCPeerConnection();
|
||||
const pc2 = new RTCPeerConnection();
|
||||
t.add_cleanup(() => pc1.close());
|
||||
t.add_cleanup(() => pc2.close());
|
||||
pc1.createDataChannel('datachannel');
|
||||
coupleIceCandidates(pc1, pc2);
|
||||
const offer = await pc1.createOffer();
|
||||
await pc2.setRemoteDescription(offer);
|
||||
await pc1.setLocalDescription(offer);
|
||||
const answer = await pc2.createAnswer();
|
||||
await pc1.setRemoteDescription(new RTCSessionDescription({
|
||||
type: answer.type,
|
||||
sdp: answer.sdp.replace(/a=fingerprint:sha-256 .*/g,
|
||||
'a=fingerprint:sha-256 00:00:00:00:00:00:00:00:00:00:00:00:00:' +
|
||||
'00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00'),
|
||||
}));
|
||||
await pc2.setLocalDescription(answer);
|
||||
|
||||
await waitForConnectionStateChange(pc1, ['failed']);
|
||||
await waitForConnectionStateChange(pc2, ['failed']);
|
||||
}, 'Connection fails if one side provides a wrong DTLS fingerprint');
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Loading…
Add table
Add a link
Reference in a new issue