Update web-platform-tests to revision 824f0c1df556305042b8aa8073c32e9ef86c3efa

This commit is contained in:
WPT Sync Bot 2018-10-18 21:30:10 -04:00
parent bcafe4188f
commit d0eccdba1a
131 changed files with 3087 additions and 705 deletions

View file

@ -37,3 +37,6 @@
[Revoke blob URL after creating Request, will fetch] [Revoke blob URL after creating Request, will fetch]
expected: FAIL expected: FAIL
[Revoke blob URL after calling fetch, fetch should succeed]
expected: FAIL

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,2 @@
[registered-property-interpolation-001.https.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[registered-property-interpolation-002.https.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[registered-property-interpolation-003.https.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[registered-property-interpolation-004.https.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[registered-property-interpolation-005.https.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[registered-property-interpolation-006.https.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[registered-property-interpolation-007.https.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[registered-property-interpolation-008.https.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[registered-property-interpolation-009.https.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[registered-property-interpolation-010.https.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[registered-property-stylemap.https.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[registered-property-value-001.https.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[registered-property-value-002.https.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[registered-property-value-003.https.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[registered-property-value-004.https.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[registered-property-value-005.https.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[registered-property-value-006.https.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[registered-property-value-007.https.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[registered-property-value-008.https.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[registered-property-value-009.https.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[registered-property-value-010.https.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[registered-property-value-011.https.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[registered-property-value-012.https.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[registered-property-value-013.https.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[registered-property-value-014.https.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[registered-property-value-015.https.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[registered-property-value-016.https.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[registered-property-value-017.https.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[registered-property-value-018.https.html]
expected: FAIL

View file

@ -1,4 +0,0 @@
[traverse_the_history_5.html]
[Multiple history traversals, last would be aborted]
expected: FAIL

View file

@ -257,3 +257,12 @@
[<audio> contents ok for element not being rendered ("<audio style='display:block'><source id='target' class='poke' style='display:block'>")] [<audio> contents ok for element not being rendered ("<audio style='display:block'><source id='target' class='poke' style='display:block'>")]
expected: FAIL expected: FAIL
[text-transform handles Turkish casing ("<div><div lang='tr' style='text-transform:uppercase'>i ı")]
expected: FAIL
[Whitespace around <img> should not be collapsed ("<div>abc <img> def")]
expected: FAIL
[Whitespace around <img> should not be collapsed ("<div>abc <img width=1 height=1> def")]
expected: FAIL

View file

@ -5,7 +5,7 @@
expected: TIMEOUT expected: TIMEOUT
[picture: source (max-width:500px) valid image, img valid image, resize to wide] [picture: source (max-width:500px) valid image, img valid image, resize to wide]
expected: TIMEOUT expected: FAIL
[picture: source (max-width:500px) valid image, img broken image, resize to narrow] [picture: source (max-width:500px) valid image, img broken image, resize to narrow]
expected: TIMEOUT expected: TIMEOUT
@ -13,3 +13,21 @@
[picture: source (max-width:500px) valid image, img valid image, resize to narrow] [picture: source (max-width:500px) valid image, img valid image, resize to narrow]
expected: FAIL expected: FAIL
[picture: source (max-width:500px) broken image, img valid image, resize to narrow]
expected: FAIL
[img (srcset 1 cand) valid image, resize to wide]
expected: FAIL
[picture: same URL in source (max-width:500px) and img, resize to wide]
expected: FAIL
[img (srcset 1 cand) valid image, resize to narrow]
expected: FAIL
[picture: source (max-width:500px) valid image, img broken image, resize to wide]
expected: FAIL
[picture: same URL in source (max-width:500px) and img, resize to narrow]
expected: FAIL

View file

@ -0,0 +1,4 @@
[DOMContentLoaded-defer.html]
[The end: DOMContentLoaded and defer scripts]
expected: FAIL

View file

@ -9,3 +9,6 @@
[document.open should throw an InvalidStateError with XML document even when the ignore-opens-during-unload counter is greater than 0 (during pagehide event)] [document.open should throw an InvalidStateError with XML document even when the ignore-opens-during-unload counter is greater than 0 (during pagehide event)]
expected: FAIL expected: FAIL
[document.open should throw an InvalidStateError with XML document even when there is an active parser executing script]
expected: FAIL

View file

@ -0,0 +1,283 @@
[limited-quirks.html]
[top: -\\31 .5]
expected: FAIL
[bottom: -1A]
expected: FAIL
[bottom: -1a]
expected: FAIL
[top: @1]
expected: FAIL
[top: "1a"]
expected: FAIL
[top: @a]
expected: FAIL
[bottom: "1"]
expected: FAIL
[bottom: -/**/1]
expected: FAIL
[top: +/**/1]
expected: FAIL
[bottom: @1a]
expected: FAIL
[top: 1\\31 ]
expected: FAIL
[top: url('1')]
expected: FAIL
[bottom: -\\31 ]
expected: FAIL
[top: calc(1)]
expected: FAIL
[top: \\31 ]
expected: FAIL
[bottom: +1\\31 ]
expected: FAIL
[bottom: 1\\31 .5]
expected: FAIL
[bottom: #0001]
expected: FAIL
[top: calc(2 * 2px)]
expected: FAIL
[bottom: 1a]
expected: FAIL
[bottom: A]
expected: FAIL
[bottom: #01]
expected: FAIL
[top: +\\31 .5]
expected: FAIL
[bottom: #1]
expected: FAIL
[top: -/**/1]
expected: FAIL
[bottom: +\\31 .5]
expected: FAIL
[bottom: \\31 ]
expected: FAIL
[bottom: calc(1)]
expected: FAIL
[top: #001]
expected: FAIL
[top: +\\31 ]
expected: FAIL
[bottom: +\\31 ]
expected: FAIL
[top: +1.5]
expected: FAIL
[top: +1\\31 ]
expected: FAIL
[bottom: @a]
expected: FAIL
[bottom: @1]
expected: FAIL
[top: #1]
expected: FAIL
[top: 1a]
expected: FAIL
[bottom: +1a]
expected: FAIL
[bottom: +1A]
expected: FAIL
[bottom: "a"]
expected: FAIL
[top: #00001]
expected: FAIL
[bottom: -1\\31 .5]
expected: FAIL
[top: "1"]
expected: FAIL
[bottom: 1.5]
expected: FAIL
[bottom: -\\31 .5]
expected: FAIL
[bottom: url('1')]
expected: FAIL
[bottom: -1.5]
expected: FAIL
[top: \\31 .5]
expected: FAIL
[bottom: "1a"]
expected: FAIL
[bottom: calc(2 * 2px)]
expected: FAIL
[bottom: +1\\31 .5]
expected: FAIL
[bottom: 1\\31 ]
expected: FAIL
[bottom: +/**/1]
expected: FAIL
[bottom: #00001]
expected: FAIL
[top: url(1)]
expected: FAIL
[bottom: #001]
expected: FAIL
[top: +1\\31 .5]
expected: FAIL
[top: -1a]
expected: FAIL
[top: -1A]
expected: FAIL
[bottom: url(1)]
expected: FAIL
[top: a]
expected: FAIL
[top: A]
expected: FAIL
[top: #000001]
expected: FAIL
[top: 1]
expected: FAIL
[top: 1\\31 .5]
expected: FAIL
[bottom: a]
expected: FAIL
[bottom: 1]
expected: FAIL
[bottom: +1]
expected: FAIL
[bottom: #000001]
expected: FAIL
[bottom: +a]
expected: FAIL
[bottom: +A]
expected: FAIL
[top: 1.5]
expected: FAIL
[top: +A]
expected: FAIL
[top: +a]
expected: FAIL
[top: +1]
expected: FAIL
[top: -1.5]
expected: FAIL
[top: -1\\31 .5]
expected: FAIL
[top: +1a]
expected: FAIL
[top: +1A]
expected: FAIL
[top: @1a]
expected: FAIL
[bottom: \\31 .5]
expected: FAIL
[top: "a"]
expected: FAIL
[top: #01]
expected: FAIL
[bottom: +1.5]
expected: FAIL
[bottom: -A]
expected: FAIL
[bottom: -a]
expected: FAIL
[bottom: -1\\31 ]
expected: FAIL
[top: #0001]
expected: FAIL
[bottom: -1]
expected: FAIL
[top: -\\31 ]
expected: FAIL
[top: -A]
expected: FAIL
[top: -a]
expected: FAIL
[top: -1]
expected: FAIL
[top: -1\\31 ]
expected: FAIL

View file

@ -0,0 +1,283 @@
[quirks.html]
[top: -\\31 .5]
expected: FAIL
[bottom: -1A]
expected: FAIL
[bottom: -1a]
expected: FAIL
[top: @1]
expected: FAIL
[top: "1a"]
expected: FAIL
[top: @a]
expected: FAIL
[bottom: "1"]
expected: FAIL
[bottom: -/**/1]
expected: FAIL
[top: +/**/1]
expected: FAIL
[bottom: @1a]
expected: FAIL
[top: 1\\31 ]
expected: FAIL
[top: url('1')]
expected: FAIL
[bottom: -\\31 ]
expected: FAIL
[top: calc(1)]
expected: FAIL
[top: \\31 ]
expected: FAIL
[bottom: +1\\31 ]
expected: FAIL
[bottom: 1\\31 .5]
expected: FAIL
[bottom: #0001]
expected: FAIL
[top: calc(2 * 2px)]
expected: FAIL
[bottom: 1a]
expected: FAIL
[bottom: A]
expected: FAIL
[bottom: #01]
expected: FAIL
[top: +\\31 .5]
expected: FAIL
[bottom: #1]
expected: FAIL
[top: -/**/1]
expected: FAIL
[bottom: +\\31 .5]
expected: FAIL
[bottom: \\31 ]
expected: FAIL
[bottom: calc(1)]
expected: FAIL
[top: #001]
expected: FAIL
[top: +\\31 ]
expected: FAIL
[bottom: +\\31 ]
expected: FAIL
[top: +1.5]
expected: FAIL
[top: +1\\31 ]
expected: FAIL
[bottom: @a]
expected: FAIL
[bottom: @1]
expected: FAIL
[top: #1]
expected: FAIL
[top: 1a]
expected: FAIL
[bottom: +1a]
expected: FAIL
[bottom: +1A]
expected: FAIL
[bottom: "a"]
expected: FAIL
[top: #00001]
expected: FAIL
[bottom: -1\\31 .5]
expected: FAIL
[top: "1"]
expected: FAIL
[bottom: 1.5]
expected: FAIL
[bottom: -\\31 .5]
expected: FAIL
[bottom: url('1')]
expected: FAIL
[bottom: -1.5]
expected: FAIL
[top: \\31 .5]
expected: FAIL
[bottom: "1a"]
expected: FAIL
[bottom: calc(2 * 2px)]
expected: FAIL
[bottom: +1\\31 .5]
expected: FAIL
[bottom: 1\\31 ]
expected: FAIL
[bottom: +/**/1]
expected: FAIL
[bottom: #00001]
expected: FAIL
[top: url(1)]
expected: FAIL
[bottom: #001]
expected: FAIL
[top: +1\\31 .5]
expected: FAIL
[top: -1a]
expected: FAIL
[top: -1A]
expected: FAIL
[bottom: url(1)]
expected: FAIL
[top: a]
expected: FAIL
[top: A]
expected: FAIL
[top: #000001]
expected: FAIL
[top: 1]
expected: FAIL
[top: 1\\31 .5]
expected: FAIL
[bottom: a]
expected: FAIL
[bottom: 1]
expected: FAIL
[bottom: +1]
expected: FAIL
[bottom: #000001]
expected: FAIL
[bottom: +a]
expected: FAIL
[bottom: +A]
expected: FAIL
[top: 1.5]
expected: FAIL
[top: +A]
expected: FAIL
[top: +a]
expected: FAIL
[top: +1]
expected: FAIL
[top: -1.5]
expected: FAIL
[top: -1\\31 .5]
expected: FAIL
[top: +1a]
expected: FAIL
[top: +1A]
expected: FAIL
[top: @1a]
expected: FAIL
[bottom: \\31 .5]
expected: FAIL
[top: "a"]
expected: FAIL
[top: #01]
expected: FAIL
[bottom: +1.5]
expected: FAIL
[bottom: -A]
expected: FAIL
[bottom: -a]
expected: FAIL
[bottom: -1\\31 ]
expected: FAIL
[top: #0001]
expected: FAIL
[bottom: -1]
expected: FAIL
[top: -\\31 ]
expected: FAIL
[top: -A]
expected: FAIL
[top: -a]
expected: FAIL
[top: -1]
expected: FAIL
[top: -1\\31 ]
expected: FAIL

View file

@ -1,13 +1,4 @@
[urlencoded-parser.any.html] [urlencoded-parser.any.html]
[request.formData() with input: a&b&c]
expected: FAIL
[request.formData() with input: _charset_=windows-1252&test=%C2x]
expected: FAIL
[response.formData() with input: a=b&c=d&]
expected: FAIL
[response.formData() with input: _charset_=windows-1252&test=%C2x] [response.formData() with input: _charset_=windows-1252&test=%C2x]
expected: FAIL expected: FAIL
@ -17,6 +8,9 @@
[response.formData() with input: a=b&c=d] [response.formData() with input: a=b&c=d]
expected: FAIL expected: FAIL
[response.formData() with input: &&&a=b&&&&c=d&]
expected: FAIL
[urlencoded-parser.any.worker.html] [urlencoded-parser.any.worker.html]
[request.formData() with input: a=b&c=d] [request.formData() with input: a=b&c=d]
@ -28,12 +22,9 @@
[request.formData() with input: a&b&c] [request.formData() with input: a&b&c]
expected: FAIL expected: FAIL
[request.formData() with input: &&&a=b&&&&c=d&]
expected: FAIL
[request.formData() with input: _charset_=windows-1252&test=%C2x] [request.formData() with input: _charset_=windows-1252&test=%C2x]
expected: FAIL expected: FAIL
[response.formData() with input: a=b&c=d] [response.formData() with input: a&b&c]
expected: FAIL expected: FAIL

View file

@ -0,0 +1,39 @@
[idlharness.any.html]
[WebAssembly namespace: operation validate(BufferSource)]
expected: FAIL
[WebAssembly namespace: operation compileStreaming([object Object\])]
expected: FAIL
[WebAssembly namespace: operation compile(BufferSource)]
expected: FAIL
[WebAssembly namespace: operation instantiateStreaming([object Object\], object)]
expected: FAIL
[WebAssembly namespace: operation instantiate(BufferSource, object)]
expected: FAIL
[WebAssembly namespace: operation instantiate(Module, object)]
expected: FAIL
[idlharness.any.worker.html]
[WebAssembly namespace: operation validate(BufferSource)]
expected: FAIL
[WebAssembly namespace: operation compileStreaming([object Object\])]
expected: FAIL
[WebAssembly namespace: operation compile(BufferSource)]
expected: FAIL
[WebAssembly namespace: operation instantiateStreaming([object Object\], object)]
expected: FAIL
[WebAssembly namespace: operation instantiate(BufferSource, object)]
expected: FAIL
[WebAssembly namespace: operation instantiate(Module, object)]
expected: FAIL

View file

@ -1,4 +1,5 @@
[realtimeanalyser-fft-scaling.html] [realtimeanalyser-fft-scaling.html]
expected: TIMEOUT
[X 2048-point FFT peak position is not equal to 64. Got 0.] [X 2048-point FFT peak position is not equal to 64. Got 0.]
expected: FAIL expected: FAIL

View file

@ -45,11 +45,14 @@ backgroundFetchTest(async (test, backgroundFetch) => {
assert_equals(type, 'backgroundfetchabort'); assert_equals(type, 'backgroundfetchabort');
assert_equals(results.length, 2);
const completedResult = results[0] || results[1];
// The abort might have gone through before the first result was persisted. // The abort might have gone through before the first result was persisted.
if (results.length === 1) { if (completedResult) {
assert_true(results[0].url.includes('resources/feature-name.txt')); assert_true(completedResult.url.includes('resources/feature-name.txt'));
assert_equals(results[0].status, 200); assert_equals(completedResult.status, 200);
assert_equals(results[0].text, expectedResultText); assert_equals(completedResult.text, expectedResultText);
} }
resolve(); resolve();
@ -57,3 +60,15 @@ backgroundFetchTest(async (test, backgroundFetch) => {
}); });
}, 'Calling BackgroundFetchRegistration.abort sets the correct fields and responses are still available'); }, 'Calling BackgroundFetchRegistration.abort sets the correct fields and responses are still available');
backgroundFetchTest(async (test, backgroundFetch) => {
const registration = await backgroundFetch.fetch(
uniqueId(), '/serviceworker/resources/slow-response.php');
assert_true(await registration.abort());
const {results} = await getMessageFromServiceWorker();
assert_equals(results.length, 1);
assert_false(results[0].response);
assert_equals(results[0].name, 'AbortError');
}, 'An aborted fetch throws a DOM exception when accessing an incomplete record', 'sw-abort.js');

View file

@ -266,7 +266,7 @@ backgroundFetchTest(async (test, backgroundFetch) => {
backgroundFetchTest(async (test, backgroundFetch) => { backgroundFetchTest(async (test, backgroundFetch) => {
const registration = await backgroundFetch.fetch( const registration = await backgroundFetch.fetch(
'my-id', 'my-id',
['https://example.com', 'http://example.com']); [location.origin, location.origin.replace('https', 'http')]);
const {type, eventRegistration, results} = await getMessageFromServiceWorker(); const {type, eventRegistration, results} = await getMessageFromServiceWorker();
@ -274,7 +274,11 @@ backgroundFetchTest(async (test, backgroundFetch) => {
assert_equals(eventRegistration.failureReason, 'fetch-error'); assert_equals(eventRegistration.failureReason, 'fetch-error');
assert_equals(results.length, 2); assert_equals(results.length, 2);
assert_true(results[0].url.includes('https://example.com'));
assert_equals(results[1].url, ''); const validResponse = results[0] ? results[0] : results[1];
const nullResponse = !results[0] ? results[0] : results[1];
assert_true(validResponse.url.includes(location.origin));
assert_equals(nullResponse, null);
}, 'Fetches with mixed content should fail.'); }, 'Fetches with mixed content should fail.');

View file

@ -0,0 +1,23 @@
importScripts('sw-helpers.js');
async function getFetchResult(record) {
try {
await record.responseReady;
} catch (e) {
return {
response: false,
name: e.name,
};
}
return {
response: true,
};
}
self.addEventListener('backgroundfetchabort', event => {
event.waitUntil(
event.registration.matchAll()
.then(records =>
Promise.all(records.map(record => getFetchResult(record))))
.then(results => sendMessageToDocument({results})));
});

View file

@ -2,9 +2,8 @@
importScripts('sw-helpers.js'); importScripts('sw-helpers.js');
async function getFetchResult(record) { async function getFetchResult(record) {
response = await record.responseReady; const response = await record.responseReady.catch(() => null);
if (!response) if (!response) return null;
return Promise.resolve(null);
return { return {
url: response.url, url: response.url,
@ -13,7 +12,7 @@ async function getFetchResult(record) {
}; };
} }
function handleBackgroundFetchUpdateEvent(event) { function handleBackgroundFetchEvent(event) {
event.waitUntil( event.waitUntil(
event.registration.matchAll() event.registration.matchAll()
.then(records => .then(records =>
@ -25,6 +24,6 @@ function handleBackgroundFetchUpdateEvent(event) {
})); }));
} }
self.addEventListener('backgroundfetchsuccess', handleBackgroundFetchUpdateEvent); self.addEventListener('backgroundfetchsuccess', handleBackgroundFetchEvent);
self.addEventListener('backgroundfetchfail', handleBackgroundFetchUpdateEvent); self.addEventListener('backgroundfetchfail', handleBackgroundFetchEvent);
self.addEventListener('backgroundfetchabort', handleBackgroundFetchUpdateEvent); self.addEventListener('backgroundfetchabort', handleBackgroundFetchEvent);

View file

@ -0,0 +1,22 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Inheritance of CSS Exclusions properties</title>
<link rel="help" href="https://drafts.csswg.org/css-exclusions/#property-index">
<meta name="assert" content="Properties do not inherit.">
<meta name="assert" content="Properties have initial values according to the spec.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/css/support/inheritance-testcommon.js"></script>
</head>
<body>
<div id="container">
<div id="target"></div>
</div>
<script>
assert_not_inherited('wrap-flow', 'auto', 'both');
assert_not_inherited('wrap-through', 'wrap', 'none');
</script>
</body>
</html>

View file

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html class="reftest-wait">
<title>Interpolated &lt;angle&gt; values reach worklet</title>
<link rel="help" href="https://www.w3.org/TR/css-paint-api-1/#examples">
<link rel="match" href="parse-input-arguments-ref.html">
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<script src="./resources/utils.js"></script>
<body>
<div id="target"></div>
<script>
try {
registerAndInterpolateProperty({
on: target, from: '100deg', to: '200deg',
name: '--prop', syntax: '<angle>'
});
expectWorkletValue(target, '--prop', '[CSSUnitValue 150deg]');
} catch(e) {
document.body.textContent = e;
takeScreenshot();
}
</script>
</body>
</html>

View file

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html class="reftest-wait">
<title>Interpolated &lt;color&gt; values reach worklet</title>
<link rel="help" href="https://www.w3.org/TR/css-paint-api-1/#examples">
<link rel="match" href="parse-input-arguments-ref.html">
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<script src="./resources/utils.js"></script>
<body>
<div id="target"></div>
<script>
try {
registerAndInterpolateProperty({
on: target, from: 'rgb(128, 100, 200)', to: 'red',
name: '--prop', syntax: '<color>'
});
expectWorkletValue(target, '--prop', '[CSSStyleValue rgb(192, 50, 100)]');
} catch(e) {
document.body.textContent = e;
takeScreenshot();
}
</script>
</body>
</html>

View file

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html class="reftest-wait">
<title>Interpolated &lt;integer&gt; values reach worklet</title>
<link rel="help" href="https://www.w3.org/TR/css-paint-api-1/#examples">
<link rel="match" href="parse-input-arguments-ref.html">
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<script src="./resources/utils.js"></script>
<body>
<div id="target"></div>
<script>
try {
registerAndInterpolateProperty({
on: target, from: '32', to: '64',
name: '--prop', syntax: '<integer>'
});
expectWorkletValue(target, '--prop', '[CSSUnitValue 48]');
} catch(e) {
document.body.textContent = e;
takeScreenshot();
}
</script>
</body>
</html>

View file

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html class="reftest-wait">
<title>Interpolated &lt;length-percentage&gt; values reach worklet</title>
<link rel="help" href="https://www.w3.org/TR/css-paint-api-1/#examples">
<link rel="match" href="parse-input-arguments-ref.html">
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<script src="./resources/utils.js"></script>
<body>
<div id="target"></div>
<script>
try {
registerAndInterpolateProperty({
on: target, from: '10px', to: '20%',
name: '--prop', syntax: '<length-percentage>'
});
expectWorkletValue(target, '--prop', '[CSSMathSum calc(5px + 10%)]');
} catch(e) {
document.body.textContent = e;
takeScreenshot();
}
</script>
</body>
</html>

View file

@ -0,0 +1,35 @@
<!DOCTYPE html>
<html class="reftest-wait">
<title>Interpolated &lt;length&gt; values reach worklet</title>
<link rel="help" href="https://www.w3.org/TR/css-paint-api-1/#examples">
<link rel="match" href="parse-input-arguments-ref.html">
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<script src="./resources/utils.js"></script>
<body>
<div id="target"></div>
<script>
try {
target.style.setProperty('font-size', '10px');
registerAndInterpolateProperty({
on: target, from: '10px', to: '20px',
name: '--prop-1', syntax: '<length>'
});
registerAndInterpolateProperty({
on: target, from: '100px', to: '20em',
name: '--prop-2', syntax: '<length>'
});
expectWorkletValues(target, {
'--prop-1': '[CSSUnitValue 15px]',
'--prop-2': '[CSSUnitValue 150px]'
});
} catch(e) {
document.body.textContent = e;
takeScreenshot();
}
</script>
</body>
</html>

View file

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html class="reftest-wait">
<title>Interpolated &lt;number&gt; values reach worklet</title>
<link rel="help" href="https://www.w3.org/TR/css-paint-api-1/#examples">
<link rel="match" href="parse-input-arguments-ref.html">
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<script src="./resources/utils.js"></script>
<body>
<div id="target"></div>
<script>
try {
registerAndInterpolateProperty({
on: target, from: '8.5', to: '16.5',
name: '--prop', syntax: '<number>'
});
expectWorkletValue(target, '--prop', '[CSSUnitValue 12.5]');
} catch(e) {
document.body.textContent = e;
takeScreenshot();
}
</script>
</body>
</html>

View file

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html class="reftest-wait">
<title>Interpolated &lt;percentage&gt; values reach worklet</title>
<link rel="help" href="https://www.w3.org/TR/css-paint-api-1/#examples">
<link rel="match" href="parse-input-arguments-ref.html">
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<script src="./resources/utils.js"></script>
<body>
<div id="target"></div>
<script>
try {
registerAndInterpolateProperty({
on: target, from: '40%', to: '60%',
name: '--prop', syntax: '<percentage>'
});
expectWorkletValue(target, '--prop', '[CSSUnitValue 50%]');
} catch(e) {
document.body.textContent = e;
takeScreenshot();
}
</script>
</body>
</html>

View file

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html class="reftest-wait">
<title>Interpolated &lt;resolution&gt; values reach worklet</title>
<link rel="help" href="https://www.w3.org/TR/css-paint-api-1/#examples">
<link rel="match" href="parse-input-arguments-ref.html">
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<script src="./resources/utils.js"></script>
<body>
<div id="target"></div>
<script>
try {
registerAndInterpolateProperty({
on: target, from: '100dppx', to: '900dppx',
name: '--prop', syntax: '<resolution>'
});
expectWorkletValue(target, '--prop', '[CSSUnitValue 500dppx]');
} catch(e) {
document.body.textContent = e;
takeScreenshot();
}
</script>
</body>
</html>

View file

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html class="reftest-wait">
<title>Interpolated &lt;time&gt; values reach worklet</title>
<link rel="help" href="https://www.w3.org/TR/css-paint-api-1/#examples">
<link rel="match" href="parse-input-arguments-ref.html">
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<script src="./resources/utils.js"></script>
<body>
<div id="target"></div>
<script>
try {
registerAndInterpolateProperty({
on: target, from: '42s', to: '62s',
name: '--prop', syntax: '<time>'
});
expectWorkletValue(target, '--prop', '[CSSUnitValue 52s]');
} catch(e) {
document.body.textContent = e;
takeScreenshot();
}
</script>
</body>
</html>

View file

@ -0,0 +1,33 @@
<!DOCTYPE html>
<html class="reftest-wait">
<title>Interpolated list values reach worklet</title>
<link rel="help" href="https://www.w3.org/TR/css-paint-api-1/#examples">
<link rel="match" href="parse-input-arguments-ref.html">
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<script src="./resources/utils.js"></script>
<body>
<div id="target"></div>
<script>
try {
registerAndInterpolateProperty({
on: target, from: '10px 20px', to: '20px 30px',
name: '--prop-1', syntax: '<length>+'
});
registerAndInterpolateProperty({
on: target, from: '10px', to: '20px',
name: '--prop-2', syntax: '<length>+'
});
expectWorkletValues(target, {
'--prop-1': ['[CSSUnitValue 15px]', '[CSSUnitValue 25px]'],
'--prop-2': '[CSSUnitValue 15px]'
});
} catch(e) {
document.body.textContent = e;
takeScreenshot();
}
</script>
</body>
</html>

View file

@ -0,0 +1,57 @@
<!DOCTYPE html>
<html class="reftest-wait">
<title>Test styleMap functions</title>
<link rel="help" href="https://www.w3.org/TR/css-paint-api-1/#examples">
<link rel="match" href="parse-input-arguments-ref.html">
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<script src="./resources/utils.js"></script>
<body>
<style>
#target {
width: 100px;
height: 100px;
background: paint(style-map);
}
</style>
<div id="target"></div>
<script>
try {
CSS.registerProperty({
name: '--prop',
syntax: '<length>+',
initialValue: '10px 10px 10px 10px',
inherits: false
});
const worklet = `
registerPaint('style-map', class {
static get inputProperties() { return ['--prop']; }
paint(ctx, geom, styleMap) {
let serialize = (v) => '[' + v.constructor.name + ' ' + v.toString() + ']';
let expected = '[CSSUnitValue 10px]';
let isExpected = x => serialize(x) === expected;
let pass = true;
pass &= styleMap.has('--prop');
pass &= isExpected(styleMap.get('--prop'));
pass &= styleMap.getAll('--prop').length == 4;
pass &= styleMap.getAll('--prop').every(isExpected);
pass &= Array.from(styleMap).filter(e => e[0] == '--prop')[0][1].length == 4;
pass &= Array.from(styleMap).filter(e => e[0] == '--prop')[0][1].every(isExpected);
ctx.strokeStyle = pass ? 'green' : 'red';
ctx.lineWidth = 4;
ctx.strokeRect(0, 0, geom.width, geom.height);
}
});`
importWorkletAndTerminateTestAfterAsyncPaint(CSS.paintWorklet, worklet);
} catch(e) {
document.body.textContent = e;
takeScreenshot();
}
</script>
</body>
</html>

View file

@ -1,174 +0,0 @@
<!DOCTYPE html>
<html class="reftest-wait">
<link rel="help" href="https://www.w3.org/TR/css-paint-api-1/#examples">
<link rel="match" href="parse-input-arguments-ref.html">
<style>
.container {
width: 100px;
height: 100px;
}
#canvas-geometry {
background-image: paint(geometry);
}
</style>
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<body>
<div id="canvas-geometry" class="container"></div>
<script id="code" type="text/worklet">
// Globals that must be prepended to this script:
// - debugLog: A function that logs errors.
// - props: Test data.
registerPaint('geometry', class {
static get inputProperties() { return props.map(p => p.name); }
paint(ctx, geom, styleMap) {
ctx.strokeStyle = 'green';
for (let prop of props) {
// Read values using get, getAll and iterator:
let valueFromGet = styleMap.get(prop.name);
let valueFromGetAll = styleMap.getAll(prop.name);
let valueFromIterator = Array.from(styleMap).filter(e => e[0] == prop.name)[0][1];
// Serialize 'actual'-values for all three cases:
let serialize = v => v.constructor.name + '=' + v.toString()
let actualFromGet = serialize(valueFromGet);
let actualFromGetAll = valueFromGetAll.map(serialize).join(',');
let actualFromIterator = valueFromIterator.map(serialize).join(',');
// Create 'expected'-values for all three cases:
let expectedForGet = prop.expected[0];
let expectedForGetAll = prop.expected.join(',');
let expectedForIterator = expectedForGetAll;
let pass = true;
// Assertions:
if (actualFromGet !== expectedForGet) {
debugLog(`FAIL: StylePropertyMap.get: actual: ${actualFromGet} expected: ${expectedForGet}`);
pass = false;
}
if (actualFromGetAll !== expectedForGetAll) {
debugLog(`FAIL: StylePropertyMap.getAll: actual: ${actualFromGetAll} expected: ${expectedForGetAll}`);
pass = false;
}
if (actualFromIterator !== expectedForIterator) {
debugLog(`FAIL: StylePropertyMap iterator: actual: ${actualFromIterator} expected: ${expectedForIterator}`);
pass = false;
}
if (!pass)
ctx.strokeStyle = 'red';
else
debugLog('PASS', prop.syntax, actualFromGetAll, expectedForGetAll);
}
ctx.lineWidth = 4;
ctx.strokeRect(0, 0, geom.width, geom.height);
}
});
</script>
<script>
// A copy of this array (automatically enriched with 'name' and 'expected')
// is also available in the worklet.
let props = [
// Initial values.
{ syntax: '*', initialValue: 'if(){}' },
{ syntax: '<angle>', initialValue: '42deg' },
{ syntax: '<color>', initialValue: '#fefefe' },
{ syntax: '<custom-ident>', initialValue: 'none' },
{ syntax: '<image>', initialValue: 'linear-gradient(red, red)' },
{ syntax: '<image>', initialValue: 'url(http://a.com/a)' },
{ syntax: '<integer>', initialValue: '42' },
{ syntax: '<length-percentage>', initialValue: '10%' },
{ syntax: '<length-percentage>', initialValue: '10px' },
{ syntax: '<length-percentage>', initialValue: 'calc(10px + 10%)' },
{ syntax: '<length>', initialValue: '1337px' },
{ syntax: '<number>', initialValue: '42.5' },
{ syntax: '<percentage>', initialValue: '42%' },
{ syntax: '<resolution>', initialValue: '300dpi' },
{ syntax: '<time>', initialValue: '3600s' },
{ syntax: '<url>', initialValue: 'url(http://a.com/a)' },
{ syntax: 'thing', initialValue: 'thing' },
{ syntax: '<length> | <angle>', initialValue: '1337px' },
{ syntax: '<angle> | <image>', initialValue: '1turn' },
{ syntax: '<length>+', initialValue: '1337px' },
{ syntax: '<length>+', initialValue: '1337px 1338px', count: 2 },
{ syntax: '<length>#', initialValue: '1337px' },
{ syntax: '<length>#', initialValue: '1337px, 1338px', count: 2 },
// Non-initial values:
{ syntax: '*', initialValue: 'fail', value: 'if(){}' },
{ syntax: '<angle> | fail', initialValue: 'fail', value: '42deg' },
{ syntax: '<color> | fail', initialValue: 'fail', value: '#fefefe' },
{ syntax: '<custom-ident> | fail', initialValue: 'fail', value: 'none' },
{ syntax: '<image> | fail', initialValue: 'fail', value: 'linear-gradient(red, red)' },
{ syntax: '<image> | fail', initialValue: 'fail', value: 'url(http://a.com/a)' },
{ syntax: '<integer> | fail', initialValue: 'fail', value: '42' },
{ syntax: '<length-percentage> | fail', initialValue: 'fail', value: '10%' },
{ syntax: '<length-percentage> | fail', initialValue: 'fail', value: '10px' },
{ syntax: '<length-percentage> | fail', initialValue: 'fail', value: 'calc(10px + 10%)' },
{ syntax: '<length> | fail', initialValue: 'fail', value: '1337px' },
{ syntax: '<number> | fail', initialValue: 'fail', value: '42.5' },
{ syntax: '<percentage> | fail', initialValue: 'fail', value: '42%' },
{ syntax: '<resolution> | fail', initialValue: 'fail', value: '300dpi' },
{ syntax: '<time> | fail', initialValue: 'fail', value: '3600s' },
{ syntax: '<url> | fail', initialValue: 'fail', value: 'url(http://a.com/a)' },
{ syntax: 'thing | fail', initialValue: 'fail', value: 'thing' },
{ syntax: '<length>+ | fail', initialValue: 'fail', value: '1337px' },
{ syntax: '<length>+ | fail', initialValue: 'fail', value: '1337px 1338px', count: 2 },
{ syntax: '<length># | fail', initialValue: 'fail', value: '1337px' },
{ syntax: '<length># | fail', initialValue: 'fail', value: '1337px, 1338px', count: 2 },
];
try {
let target = document.getElementById('canvas-geometry');
let pid = 1;
for (let p of props) {
p.name = `--prop-${++pid}`;
CSS.registerProperty({
name: p.name,
syntax: p.syntax,
initialValue: p.initialValue,
inherits: (typeof p.inherits !== 'undefined') ? p.inherits : false
});
if (typeof p.value !== 'undefined')
target.style.setProperty(p.name, p.value);
if (typeof p.count === 'undefined')
p.count = 1;
let getValue = p => (typeof p.value !== 'undefined') ? p.value : p.initialValue;
let serialize = v => v.constructor.name + '=' + v.toString();
let parse = function (p) {
if (p.count == 1)
return [CSSStyleValue.parse(p.name, getValue(p))];
return CSSStyleValue.parseAll(p.name, getValue(p));
};
// Generate expected value. We assume that CSSStyleValue.parse/All
// returns the correct CSSStyleValue subclass and value.
p.expected = parse(p).map(serialize);
}
// Adding '?debug' to the URL will cause this test to emit
// test results to console.log.
let debugMode = document.location.href.endsWith('?debug');
let code = [
`const props = ${JSON.stringify(props)};`,
`const debugLog = ${debugMode ? 'console.log' : 'function(){}'};`,
document.getElementById('code').textContent
].join('\n');
importWorkletAndTerminateTestAfterAsyncPaint(CSS.paintWorklet, code);
} catch(e) {
document.body.textContent = e;
takeScreenshot();
}
</script>
</body>
</html>

View file

@ -0,0 +1,27 @@
<!DOCTYPE html>
<html class="reftest-wait">
<title>Initial values reach worklet</title>
<link rel="help" href="https://www.w3.org/TR/css-paint-api-1/#examples">
<link rel="match" href="parse-input-arguments-ref.html">
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<script src="./resources/utils.js"></script>
<body>
<div id="target"></div>
<script>
try {
CSS.registerProperty({
name: '--prop',
syntax: '<length>',
initialValue: '42px',
inherits: false
});
expectWorkletValue(target, '--prop', '[CSSUnitValue 42px]');
} catch(e) {
document.body.textContent = e;
takeScreenshot();
}
</script>
</body>
</html>

View file

@ -0,0 +1,31 @@
<!DOCTYPE html>
<html class="reftest-wait">
<title>Inherited values reach worklet</title>
<link rel="help" href="https://www.w3.org/TR/css-paint-api-1/#examples">
<link rel="match" href="parse-input-arguments-ref.html">
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<script src="./resources/utils.js"></script>
<body>
<div id="outer">
<div id="target"></div>
</div>
<script>
try {
CSS.registerProperty({
name: '--prop',
syntax: '<length>',
initialValue: '0px',
inherits: true
});
outer.style.setProperty('--prop', '13px');
expectWorkletValue(target, '--prop', '[CSSUnitValue 13px]');
} catch(e) {
document.body.textContent = e;
takeScreenshot();
}
</script>
</body>
</html>

View file

@ -0,0 +1,28 @@
<!DOCTYPE html>
<html class="reftest-wait">
<title>Values of *-properties reach worklet</title>
<link rel="help" href="https://www.w3.org/TR/css-paint-api-1/#examples">
<link rel="match" href="parse-input-arguments-ref.html">
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<script src="./resources/utils.js"></script>
<body>
<div id="target"></div>
<script>
try {
CSS.registerProperty({
name: '--prop',
syntax: '*',
inherits: false
});
target.style.setProperty('--prop', 'if(){}');
expectWorkletValue(target, '--prop', '[CSSUnparsedValue if(){}]');
} catch(e) {
document.body.textContent = e;
takeScreenshot();
}
</script>
</body>
</html>

View file

@ -0,0 +1,29 @@
<!DOCTYPE html>
<html class="reftest-wait">
<title>Values of &lt;angle&gt;-properties reach worklet</title>
<link rel="help" href="https://www.w3.org/TR/css-paint-api-1/#examples">
<link rel="match" href="parse-input-arguments-ref.html">
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<script src="./resources/utils.js"></script>
<body>
<div id="target"></div>
<script>
try {
CSS.registerProperty({
name: '--prop',
syntax: '<angle>',
initialValue: '0deg',
inherits: false
});
target.style.setProperty('--prop', '100deg');
expectWorkletValue(target, '--prop', '[CSSUnitValue 100deg]');
} catch(e) {
document.body.textContent = e;
takeScreenshot();
}
</script>
</body>
</html>

View file

@ -0,0 +1,29 @@
<!DOCTYPE html>
<html class="reftest-wait">
<title>Values of &lt;color&gt;-properties reach worklet</title>
<link rel="help" href="https://www.w3.org/TR/css-paint-api-1/#examples">
<link rel="match" href="parse-input-arguments-ref.html">
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<script src="./resources/utils.js"></script>
<body>
<div id="target"></div>
<script>
try {
CSS.registerProperty({
name: '--prop',
syntax: '<color>',
initialValue: 'black',
inherits: false
});
target.style.setProperty('--prop', 'rgb(1, 2, 3)');
expectWorkletValue(target, '--prop', '[CSSStyleValue rgb(1, 2, 3)]');
} catch(e) {
document.body.textContent = e;
takeScreenshot();
}
</script>
</body>
</html>

View file

@ -0,0 +1,29 @@
<!DOCTYPE html>
<html class="reftest-wait">
<title>Values of &lt;custom-ident&gt;-properties reach worklet</title>
<link rel="help" href="https://www.w3.org/TR/css-paint-api-1/#examples">
<link rel="match" href="parse-input-arguments-ref.html">
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<script src="./resources/utils.js"></script>
<body>
<div id="target"></div>
<script>
try {
CSS.registerProperty({
name: '--prop',
syntax: '<custom-ident>',
initialValue: 'none',
inherits: false
});
target.style.setProperty('--prop', 'foo');
expectWorkletValue(target, '--prop', '[CSSKeywordValue foo]');
} catch(e) {
document.body.textContent = e;
takeScreenshot();
}
</script>
</body>
</html>

View file

@ -0,0 +1,40 @@
<!DOCTYPE html>
<html class="reftest-wait">
<title>Values of &lt;image&gt;-properties reach worklet</title>
<link rel="help" href="https://www.w3.org/TR/css-paint-api-1/#examples">
<link rel="match" href="parse-input-arguments-ref.html">
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<script src="./resources/utils.js"></script>
<body>
<div id="target"></div>
<script>
try {
CSS.registerProperty({
name: '--prop-1',
syntax: '<image> | none',
initialValue: 'none',
inherits: false
});
CSS.registerProperty({
name: '--prop-2',
syntax: '<image> | none',
initialValue: 'none',
inherits: false
});
target.style.setProperty('--prop-1', 'url("http://a/")');
target.style.setProperty('--prop-2', 'linear-gradient(red, red)');
expectWorkletValues(target, {
'--prop-1': ['[CSSImageValue url("http://a/")]'],
'--prop-2': ['[CSSStyleValue linear-gradient(red, red)]'],
});
} catch(e) {
document.body.textContent = e;
takeScreenshot();
}
</script>
</body>
</html>

View file

@ -0,0 +1,29 @@
<!DOCTYPE html>
<html class="reftest-wait">
<title>Values of &lt;integer&gt;-properties reach worklet</title>
<link rel="help" href="https://www.w3.org/TR/css-paint-api-1/#examples">
<link rel="match" href="parse-input-arguments-ref.html">
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<script src="./resources/utils.js"></script>
<body>
<div id="target"></div>
<script>
try {
CSS.registerProperty({
name: '--prop',
syntax: '<integer>',
initialValue: '0',
inherits: false
});
target.style.setProperty('--prop', '5');
expectWorkletValue(target, '--prop', '[CSSUnitValue 5]');
} catch(e) {
document.body.textContent = e;
takeScreenshot();
}
</script>
</body>
</html>

View file

@ -0,0 +1,49 @@
<!DOCTYPE html>
<html class="reftest-wait">
<title>Values of &lt;length-percentage&gt;-properties reach worklet</title>
<link rel="help" href="https://www.w3.org/TR/css-paint-api-1/#examples">
<link rel="match" href="parse-input-arguments-ref.html">
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<script src="./resources/utils.js"></script>
<body>
<div id="target"></div>
<script>
try {
CSS.registerProperty({
name: '--prop-1',
syntax: '<length-percentage>',
initialValue: '0',
inherits: false
});
CSS.registerProperty({
name: '--prop-2',
syntax: '<length-percentage>',
initialValue: '0',
inherits: false
});
CSS.registerProperty({
name: '--prop-3',
syntax: '<length-percentage>',
initialValue: '0',
inherits: false
});
target.style.setProperty('--prop-1', '10%');
target.style.setProperty('--prop-2', '10px');
target.style.setProperty('--prop-3', 'calc(10px + 10%)');
expectWorkletValues(target, {
'--prop-1': ['[CSSUnitValue 10%]'],
'--prop-2': ['[CSSUnitValue 10px]'],
'--prop-3': ['[CSSMathSum calc(10px + 10%)]'],
});
} catch(e) {
document.body.textContent = e;
takeScreenshot();
}
</script>
</body>
</html>

View file

@ -0,0 +1,41 @@
<!DOCTYPE html>
<html class="reftest-wait">
<title>Values of &lt;length&gt;-properties reach worklet</title>
<link rel="help" href="https://www.w3.org/TR/css-paint-api-1/#examples">
<link rel="match" href="parse-input-arguments-ref.html">
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<script src="./resources/utils.js"></script>
<body>
<div id="target"></div>
<script>
try {
CSS.registerProperty({
name: '--prop-1',
syntax: '<length>',
initialValue: '0',
inherits: false
});
CSS.registerProperty({
name: '--prop-2',
syntax: '<length>',
initialValue: '0',
inherits: false
});
target.style.setProperty('font-size', '20px');
target.style.setProperty('--prop-1', '100px');
target.style.setProperty('--prop-2', '10em');
expectWorkletValues(target, {
'--prop-1': ['[CSSUnitValue 100px]'],
'--prop-2': ['[CSSUnitValue 200px]']
});
} catch(e) {
document.body.textContent = e;
takeScreenshot();
}
</script>
</body>
</html>

View file

@ -0,0 +1,29 @@
<!DOCTYPE html>
<html class="reftest-wait">
<title>Values of &lt;number&gt;-properties reach worklet</title>
<link rel="help" href="https://www.w3.org/TR/css-paint-api-1/#examples">
<link rel="match" href="parse-input-arguments-ref.html">
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<script src="./resources/utils.js"></script>
<body>
<div id="target"></div>
<script>
try {
CSS.registerProperty({
name: '--prop',
syntax: '<number>',
initialValue: '0',
inherits: false
});
target.style.setProperty('--prop', '2.5');
expectWorkletValue(target, '--prop', '[CSSUnitValue 2.5]');
} catch(e) {
document.body.textContent = e;
takeScreenshot();
}
</script>
</body>
</html>

View file

@ -0,0 +1,29 @@
<!DOCTYPE html>
<html class="reftest-wait">
<title>Values of &lt;percentage&gt;-properties reach worklet</title>
<link rel="help" href="https://www.w3.org/TR/css-paint-api-1/#examples">
<link rel="match" href="parse-input-arguments-ref.html">
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<script src="./resources/utils.js"></script>
<body>
<div id="target"></div>
<script>
try {
CSS.registerProperty({
name: '--prop',
syntax: '<percentage>',
initialValue: '0%',
inherits: false
});
target.style.setProperty('--prop', '33%');
expectWorkletValue(target, '--prop', '[CSSUnitValue 33%]');
} catch(e) {
document.body.textContent = e;
takeScreenshot();
}
</script>
</body>
</html>

View file

@ -0,0 +1,29 @@
<!DOCTYPE html>
<html class="reftest-wait">
<title>Values of &lt;resolution&gt;-properties reach worklet</title>
<link rel="help" href="https://www.w3.org/TR/css-paint-api-1/#examples">
<link rel="match" href="parse-input-arguments-ref.html">
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<script src="./resources/utils.js"></script>
<body>
<div id="target"></div>
<script>
try {
CSS.registerProperty({
name: '--prop',
syntax: '<resolution>',
initialValue: '0dppx',
inherits: false
});
target.style.setProperty('--prop', '300dppx');
expectWorkletValue(target, '--prop', '[CSSUnitValue 300dppx]');
} catch(e) {
document.body.textContent = e;
takeScreenshot();
}
</script>
</body>
</html>

View file

@ -0,0 +1,29 @@
<!DOCTYPE html>
<html class="reftest-wait">
<title>Values of &lt;time&gt;-properties reach worklet</title>
<link rel="help" href="https://www.w3.org/TR/css-paint-api-1/#examples">
<link rel="match" href="parse-input-arguments-ref.html">
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<script src="./resources/utils.js"></script>
<body>
<div id="target"></div>
<script>
try {
CSS.registerProperty({
name: '--prop',
syntax: '<time>',
initialValue: '0s',
inherits: false
});
target.style.setProperty('--prop', '10s');
expectWorkletValue(target, '--prop', '[CSSUnitValue 10s]');
} catch(e) {
document.body.textContent = e;
takeScreenshot();
}
</script>
</body>
</html>

View file

@ -0,0 +1,29 @@
<!DOCTYPE html>
<html class="reftest-wait">
<title>Values of &lt;url&gt;-properties reach worklet</title>
<link rel="help" href="https://www.w3.org/TR/css-paint-api-1/#examples">
<link rel="match" href="parse-input-arguments-ref.html">
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<script src="./resources/utils.js"></script>
<body>
<div id="target"></div>
<script>
try {
CSS.registerProperty({
name: '--prop',
syntax: '<url> | none',
initialValue: 'none',
inherits: false
});
target.style.setProperty('--prop', 'url("http://a/")');
expectWorkletValue(target, '--prop', '[CSSStyleValue url("http://a/")]');
} catch(e) {
document.body.textContent = e;
takeScreenshot();
}
</script>
</body>
</html>

View file

@ -0,0 +1,29 @@
<!DOCTYPE html>
<html class="reftest-wait">
<title>Values of ident-properties reach worklet</title>
<link rel="help" href="https://www.w3.org/TR/css-paint-api-1/#examples">
<link rel="match" href="parse-input-arguments-ref.html">
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<script src="./resources/utils.js"></script>
<body>
<div id="target"></div>
<script>
try {
CSS.registerProperty({
name: '--prop',
syntax: 'foo | bar | none',
initialValue: 'none',
inherits: false
});
target.style.setProperty('--prop', 'bar');
expectWorkletValue(target, '--prop', '[CSSKeywordValue bar]');
} catch(e) {
document.body.textContent = e;
takeScreenshot();
}
</script>
</body>
</html>

View file

@ -0,0 +1,29 @@
<!DOCTYPE html>
<html class="reftest-wait">
<title>Values of ident-properties reach worklet</title>
<link rel="help" href="https://www.w3.org/TR/css-paint-api-1/#examples">
<link rel="match" href="parse-input-arguments-ref.html">
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<script src="./resources/utils.js"></script>
<body>
<div id="target"></div>
<script>
try {
CSS.registerProperty({
name: '--prop',
syntax: 'foo | bar | none',
initialValue: 'none',
inherits: false
});
target.style.setProperty('--prop', 'bar');
expectWorkletValue(target, '--prop', '[CSSKeywordValue bar]');
} catch(e) {
document.body.textContent = e;
takeScreenshot();
}
</script>
</body>
</html>

View file

@ -0,0 +1,49 @@
<!DOCTYPE html>
<html class="reftest-wait">
<title>Values of lists reach worklet</title>
<link rel="help" href="https://www.w3.org/TR/css-paint-api-1/#examples">
<link rel="match" href="parse-input-arguments-ref.html">
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<script src="./resources/utils.js"></script>
<body>
<div id="target"></div>
<script>
try {
CSS.registerProperty({
name: '--prop-1',
syntax: '<length>+ | none',
initialValue: 'none',
inherits: false
});
CSS.registerProperty({
name: '--prop-2',
syntax: '<length># | none',
initialValue: 'none',
inherits: false
});
CSS.registerProperty({
name: '--prop-3',
syntax: '<length># | none',
initialValue: 'none',
inherits: false
});
target.style.setProperty('--prop-1', '8px 16px');
target.style.setProperty('--prop-2', '8px, 16px');
target.style.setProperty('--prop-3', '8px');
expectWorkletValues(target, {
'--prop-1': ['[CSSUnitValue 8px]', '[CSSUnitValue 16px]'],
'--prop-2': ['[CSSUnitValue 8px]', '[CSSUnitValue 16px]'],
'--prop-3': ['[CSSUnitValue 8px]'],
});
} catch(e) {
document.body.textContent = e;
takeScreenshot();
}
</script>
</body>
</html>

View file

@ -0,0 +1,59 @@
// Register a property, and interpolate its value to the halfway point.
function registerAndInterpolateProperty(options) {
CSS.registerProperty({
name: options.name,
syntax: `${options.syntax} | none`,
initialValue: 'none',
inherits: false
});
let animation = options.on.animate([
{ [options.name]: options.from },
{ [options.name]: options.to }
], 1000);
animation.currentTime = 500;
animation.pause();
}
// Apply a paint worklet to 'target' which verifies that the worklet-side value
// of a set of properties is what we expect.
//
// The 'expected' parameter is an object where each key is the name of a
// property to check, and each corresponding value is an array with the expected
// (serialized) values for that property.
function expectWorkletValues(target, expected) {
const workletName = 'registered-property-value';
// Wrap any single values in an array. This makes it possible to omit the
// array if there is only one value.
const ensureArray = x => x.constructor === Array ? x : [x];
expected = Object.entries(expected).map(([k, v]) => [k, ensureArray(v)])
.map(x => ({[x[0]]: x[1]}))
.reduce((a, b) => Object.assign(a, b), {});
target.style.setProperty('width', '100px');
target.style.setProperty('height', '100px');
target.style.setProperty('background-image', `paint(${workletName})`);
const worklet = `
const expectedData = ${JSON.stringify(expected)};
const expectedKeys = Object.keys(expectedData).sort();
registerPaint('${workletName}', class {
static get inputProperties() { return expectedKeys; }
paint(ctx, geom, styleMap) {
let serialize = (v) => '[' + v.constructor.name + ' ' + v.toString() + ']';
let actual = expectedKeys.map(k => styleMap.getAll(k).map(serialize).join(', ')).join(' | ');
let expected = expectedKeys.map(k => expectedData[k].join(', ')).join(' | ');
ctx.strokeStyle = (actual === expected) ? 'green' : 'red';
ctx.lineWidth = 4;
ctx.strokeRect(0, 0, geom.width, geom.height);
}
});`
importWorkletAndTerminateTestAfterAsyncPaint(CSS.paintWorklet, worklet);
}
// Like expectWorkletValues, but can only test a single property.
function expectWorkletValue(target, property, expected) {
expectWorkletValues(target, { [property]: expected });
}

View file

@ -55,6 +55,10 @@ assert_valid("<number>", "-109");
assert_valid("<number>", "2.3e4"); assert_valid("<number>", "2.3e4");
assert_valid("<integer>", "-109"); assert_valid("<integer>", "-109");
assert_valid("<integer>", "19"); assert_valid("<integer>", "19");
assert_valid("<integer>", "calc(1)");
assert_valid("<integer>", "calc(1 + 2)");
assert_valid("<integer>", "calc(3.1415)");
assert_valid("<integer>", "calc(3.1415 + 3.1415)");
assert_valid("<angle>", "10deg"); assert_valid("<angle>", "10deg");
assert_valid("<angle>", "20.5rad"); assert_valid("<angle>", "20.5rad");

View file

@ -111,5 +111,17 @@ for (let element of [divWithFontSizeSet, divWithFontSizeInherited]) {
assert_computed_value('<transform-function>', 'translateX(calc(11em + 10%))', 'translateX(calc(110px + 10%))'); assert_computed_value('<transform-function>', 'translateX(calc(11em + 10%))', 'translateX(calc(110px + 10%))');
assert_computed_value('<transform-function>+', 'translateX(10%) scale(2)', 'translateX(10%) scale(2)'); assert_computed_value('<transform-function>+', 'translateX(10%) scale(2)', 'translateX(10%) scale(2)');
}, "<transform-function> values are computed correctly for " + id); }, "<transform-function> values are computed correctly for " + id);
test(function() {
assert_computed_value('<integer>', '15', '15');
assert_computed_value('<integer>', 'calc(15 + 15)', '30');
assert_computed_value('<integer>', 'calc(2.4)', '2');
assert_computed_value('<integer>', 'calc(2.6)', '3');
assert_computed_value('<integer>', 'calc(2.6 + 3.1)', '6');
}, "<integer> values are computed correctly for " + id);
test(function() {
assert_computed_value('<integer>+', '15 calc(2.4) calc(2.6)', '15 2 3');
}, "<integer>+ values are computed correctly for " + id);
} }
</script> </script>

View file

@ -382,8 +382,8 @@ test_style_property_map_set({
test_style_property_map_set({ test_style_property_map_set({
syntax: '<integer>', syntax: '<integer>',
initialValue: '0', initialValue: '0',
shouldAccept: [CSS.number(1), CSS.number(-42), '1', '-42'], shouldAccept: [CSS.number(1), CSS.number(-42), '1', '-42', 'calc(2.4)'],
shouldReject: [unparsed('42'), CSS.px(100), '50px', [CSS.number(42), '42']], shouldReject: [unparsed('42'), CSS.px(100), '50px', [CSS.number(42), '42'], 'calc(2px + 1px)'],
}); });
test_style_property_map_set({ test_style_property_map_set({
@ -482,8 +482,8 @@ test_style_property_map_set({
test_style_property_map_set({ test_style_property_map_set({
syntax: '<integer>+', syntax: '<integer>+',
initialValue: '0', initialValue: '0',
shouldAccept: [CSS.number(42), [CSS.number(42), '42'], '42 42'], shouldAccept: [CSS.number(42), [CSS.number(42), '42'], '42 42', 'calc(2.4) calc(2.6)'],
shouldReject: [[CSS.number(42), keyword('noint')], '42 noint'], shouldReject: [[CSS.number(42), keyword('noint')], '42 noint', 'calc(2px + 2px)'],
}); });
test_style_property_map_set({ test_style_property_map_set({

View file

@ -0,0 +1,23 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Inheritance of CSS Regions properties</title>
<link rel="help" href="https://drafts.csswg.org/css-regions/#property-index">
<meta name="assert" content="Properties inherit or not according to the spec.">
<meta name="assert" content="Properties have initial values according to the spec.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/css/support/inheritance-testcommon.js"></script>
</head>
<body>
<div id="container">
<div id="target"></div>
</div>
<script>
assert_not_inherited('flow-from', 'none', 'foo');
assert_not_inherited('flow-into', 'none', 'bar');
assert_not_inherited('region-fragment', 'auto', 'break');
</script>
</body>
</html>

View file

@ -0,0 +1,21 @@
<!doctype html>
<title>CSS Test: Invalidation of :host selectors</title>
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
<link rel="author" title="Mozilla" href="https://mozilla.org">
<link rel="help" href="https://drafts.csswg.org/css-scoping/#host-selector">
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1499603">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="host" style="color: green"></div>
<script>
host.attachShadow({ mode: "open" }).innerHTML = `
<style>
:host { color: red !important }
</style>
`;
test(function() {
assert_equals(getComputedStyle(host).color, "rgb(255, 0, 0)");
host.shadowRoot.querySelector("style").remove();
assert_equals(getComputedStyle(host).color, "rgb(0, 128, 0)");
}, ":host rules are properly invalidated when stylesheets are removed");
</script>

View file

@ -0,0 +1,21 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Inheritance of CSS Scroll Anchoring properties</title>
<link rel="help" href="https://drafts.csswg.org/css-scroll-anchoring/#property-index">
<meta name="assert" content="overflow-anchor does not inherit.">
<meta name="assert" content="overflow-anchor has initial value 'none'.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/css/support/inheritance-testcommon.js"></script>
</head>
<body>
<div id="container">
<div id="target"></div>
</div>
<script>
assert_not_inherited('overflow-anchor', 'auto', 'none');
</script>
</body>
</html>

View file

@ -4,7 +4,10 @@
<title>CSS Text Test reference</title> <title>CSS Text Test reference</title>
<link rel="author" title="Florian Rivoal" href="http://florian.rivoal.net/"> <link rel="author" title="Florian Rivoal" href="http://florian.rivoal.net/">
<style> <style>
div { padding-left: 50px; } div {
padding-left: 50px;
font-family: Ahem;
}
</style> </style>
<p>Test passes if there is a single black X below and no red. <p>Test passes if there is a single black X below and no red.

View file

@ -13,6 +13,7 @@ section, div {
border-right: 10px solid white; border-right: 10px solid white;
margin-right: 10px; margin-right: 10px;
padding-right: 10px; padding-right: 10px;
font-family: Ahem;
} }
div { div {
box-sizing: border-box; box-sizing: border-box;

View file

@ -13,6 +13,7 @@ section, div {
border-right: 10px solid white; border-right: 10px solid white;
margin-right: 10px; margin-right: 10px;
padding-right: 10px; padding-right: 10px;
font-family: Ahem;
} }
div { div {
box-sizing: border-box; box-sizing: border-box;

View file

@ -13,6 +13,7 @@ section, div {
border-right: 10px solid white; border-right: 10px solid white;
margin-right: 10px; margin-right: 10px;
padding-right: 10px; padding-right: 10px;
font-family: Ahem;
} }
div { div {
box-sizing: border-box; box-sizing: border-box;

View file

@ -0,0 +1,21 @@
<!doctype html>
<meta charset="utf-8">
<title>CSS Test: will-change: style changes are properly propagated to children if needed</title>
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
<link rel="author" title="Mozilla" href="https://mozilla.org">
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1499991">
<link rel="help" href="https://drafts.csswg.org/css-will-change/#will-change">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="outer">
<div id="inner" style="will-change: inherit"></div>
</div>
<script>
test(function() {
assert_equals(getComputedStyle(outer).willChange, "auto");
assert_equals(getComputedStyle(inner).willChange, "auto");
outer.style.willChange = "color";
assert_equals(getComputedStyle(outer).willChange, "color");
assert_equals(getComputedStyle(inner).willChange, "color");
}, "will-change change is properly propagated to children if needed");
</script>

View file

@ -116,7 +116,7 @@
"unknown/unknown", "unknown/unknown",
[88, 32, 88]], [88, 32, 88]],
["data:text/plain;a=\",\",X", ["data:text/plain;a=\",\",X",
"text/plain", "text/plain;a=\"\"",
[34, 44, 88]], [34, 44, 88]],
["data:text/plain;a=%2C,X", ["data:text/plain;a=%2C,X",
"text/plain;a=%2C", "text/plain;a=%2C",

View file

@ -58,6 +58,15 @@ testText("<div>abc <span style='display:inline-block'></span> def", "abc def",
testText("<div>abc <span style='display:inline-block'> def </span> ghi", "abc def ghi", "Trailing space at end of inline-block should be collapsed"); testText("<div>abc <span style='display:inline-block'> def </span> ghi", "abc def ghi", "Trailing space at end of inline-block should be collapsed");
testText("<div><input> <div>abc</div>", "abc", "Whitespace between <input> and block should be collapsed"); testText("<div><input> <div>abc</div>", "abc", "Whitespace between <input> and block should be collapsed");
testText("<div><span style='inline-block'></span> <div>abc</div>", "abc", "Whitespace between inline-block and block should be collapsed"); testText("<div><span style='inline-block'></span> <div>abc</div>", "abc", "Whitespace between inline-block and block should be collapsed");
testText("<div>abc <img> def", "abc def", "Whitespace around <img> should not be collapsed");
testText("<div>abc <img width=1 height=1> def", "abc def", "Whitespace around <img> should not be collapsed");
testText("<div><img> abc", " abc", "Leading whitesapce should not be collapsed");
testText("<div>abc <img>", "abc ", "Trailing whitesapce should not be collapsed");
testText("<div>abc <b></b> def", "abc def", "Whitespace around empty span should be collapsed");
testText("<div>abc <b><i></i></b> def", "abc def", "Whitespace around empty spans should be collapsed");
testText("<div><canvas></canvas> abc", " abc", "<canvas> should not collapse following space");
testText("<div>abc <img style='display:block'> def", "abc\ndef", "Replaced element <img> with display:block should be treated as block-level");
testText("<div>abc <canvas style='display:block'></canvas> def", "abc\ndef", "Replaced element <canvas> with display:block should be treated as block-level");
/**** Soft line breaks ****/ /**** Soft line breaks ****/

View file

@ -5,25 +5,24 @@
<script src="resources/test-helpers.sub.js"></script> <script src="resources/test-helpers.sub.js"></script>
<body> <body>
<script> <script>
var t = async_test('activation occurs after registration'); promise_test(function(t) {
t.step(function() {
var scope = 'resources/blank.html'; var scope = 'resources/blank.html';
var registration; var registration;
service_worker_unregister_and_register( return service_worker_unregister_and_register(
t, 'resources/empty-worker.js', scope) t, 'resources/empty-worker.js', scope)
.then(function(r) { .then(function(r) {
t.add_cleanup(function() {
return service_worker_unregister(t, scope);
});
registration = r; registration = r;
assert_equals( assert_equals(
r.installing.state, r.installing.state,
'installing', 'installing',
'worker should be in the "installing" state upon registration'); 'worker should be in the "installing" state upon registration');
return wait_for_state(t, r.installing, 'activated'); return wait_for_state(t, r.installing, 'activated');
}) });
.then(function() { }, 'activation occurs after registration');
service_worker_unregister_and_done(t, scope);
})
.catch(unreached_rejection(t));
});
</script> </script>
</body> </body>

View file

@ -60,8 +60,8 @@ function is_appcached() {
}); });
} }
async_test(function(t) { promise_test(function(t) {
service_worker_unregister(t, SERVICE_WORKER_SCOPE) return service_worker_unregister(t, SERVICE_WORKER_SCOPE)
.then(function() { .then(function() {
return install_appcache(); return install_appcache();
}) })
@ -74,6 +74,10 @@ async_test(function(t) {
t, SERVICE_WORKER_SCRIPT, SERVICE_WORKER_SCOPE); t, SERVICE_WORKER_SCRIPT, SERVICE_WORKER_SCOPE);
}) })
.then(function(r) { .then(function(r) {
t.add_cleanup(function() {
return service_worker_unregister(t, SERVICE_WORKER_SCOPE);
});
return wait_for_state(t, r.installing, 'activated'); return wait_for_state(t, r.installing, 'activated');
}) })
.then(function() { .then(function() {
@ -82,9 +86,7 @@ async_test(function(t) {
.then(function(result) { .then(function(result) {
assert_false(result, 'but serviceworkers should take priority'); assert_false(result, 'but serviceworkers should take priority');
frames.forEach(function(f) { f.remove(); }); frames.forEach(function(f) { f.remove(); });
service_worker_unregister_and_done(t, SERVICE_WORKER_SCOPE); });
})
.catch(unreached_rejection(t));
}, 'serviceworkers take priority over appcaches'); }, 'serviceworkers take priority over appcaches');
</script> </script>

View file

@ -4,15 +4,17 @@
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="resources/test-helpers.sub.js"></script> <script src="resources/test-helpers.sub.js"></script>
<script> <script>
var test;
var scope = 'resources/blank.html?client-id'; var scope = 'resources/blank.html?client-id';
var frame1, frame2; var frame1, frame2;
async_test(function(t) { promise_test(function(t) {
test = t; return service_worker_unregister_and_register(
service_worker_unregister_and_register(
t, 'resources/client-id-worker.js', scope) t, 'resources/client-id-worker.js', scope)
.then(function(registration) { .then(function(registration) {
t.add_cleanup(function() {
return service_worker_unregister(t, scope);
});
return wait_for_state(t, registration.installing, 'activated'); return wait_for_state(t, registration.installing, 'activated');
}) })
.then(function() { return with_iframe(scope + '#1'); }) .then(function() { return with_iframe(scope + '#1'); })
@ -25,11 +27,15 @@ async_test(function(t) {
.then(function(f) { .then(function(f) {
frame2 = f; frame2 = f;
var channel = new MessageChannel(); var channel = new MessageChannel();
channel.port1.onmessage = t.step_func(on_message);
return new Promise(function(resolve, reject) {
channel.port1.onmessage = resolve;
channel.port1.onmessageerror = reject;
f.contentWindow.navigator.serviceWorker.controller.postMessage( f.contentWindow.navigator.serviceWorker.controller.postMessage(
{port:channel.port2}, [channel.port2]); {port:channel.port2}, [channel.port2]);
});
}) })
.catch(unreached_rejection(t)); .then(on_message);
}, 'Client.id returns the client\'s ID.'); }, 'Client.id returns the client\'s ID.');
function on_message(e) { function on_message(e) {
@ -50,6 +56,5 @@ function on_message(e) {
assert_equals(e.data[1], e.data[3]); assert_equals(e.data[1], e.data[3]);
frame1.remove(); frame1.remove();
frame2.remove(); frame2.remove();
service_worker_unregister_and_done(test, scope);
} }
</script> </script>

View file

@ -5,7 +5,6 @@
<script src="resources/test-helpers.sub.js"></script> <script src="resources/test-helpers.sub.js"></script>
<script> <script>
const scope = 'resources/blank.html?clients-matchAll'; const scope = 'resources/blank.html?clients-matchAll';
const t = async_test('Test Clients.matchAll() with exact controller');
let frames = []; let frames = [];
function checkWorkerClients(worker, expected) { function checkWorkerClients(worker, expected) {
@ -33,10 +32,12 @@ let expected = [
['visible', false, new URL(scope + '#2', location).toString(), 'window', 'nested'] ['visible', false, new URL(scope + '#2', location).toString(), 'window', 'nested']
]; ];
t.step(_ => { promise_test(t => {
let script = 'resources/clients-matchall-worker.js'; let script = 'resources/clients-matchall-worker.js';
service_worker_unregister_and_register(t, script, scope) return service_worker_unregister_and_register(t, script, scope)
.then(registration => { .then(registration => {
t.add_cleanup(() => service_worker_unregister(t, scope));
return wait_for_state(t, registration.installing, 'activated'); return wait_for_state(t, registration.installing, 'activated');
}) })
.then(_ => with_iframe(scope + '#1') ) .then(_ => with_iframe(scope + '#1') )
@ -61,8 +62,6 @@ t.step(_ => {
}) })
.then(_ => { .then(_ => {
frames.forEach(f => f.remove() ); frames.forEach(f => f.remove() );
service_worker_unregister_and_done(t, scope);
})
.catch(unreached_rejection(t));
}); });
}, 'Test Clients.matchAll() with exact controller');
</script> </script>

View file

@ -67,12 +67,16 @@ function test_matchall(frame, expected, query_options) {
} }
// Run clients.matchAll without and with includeUncontrolled=true. // Run clients.matchAll without and with includeUncontrolled=true.
// (We want to run the two tests sequentially in the same async_test // (We want to run the two tests sequentially in the same promise_test
// so that we can use the same set of iframes without intefering each other. // so that we can use the same set of iframes without intefering each other.
async_test(function(t) { promise_test(function(t) {
service_worker_unregister_and_register( return service_worker_unregister_and_register(
t, 'resources/clients-matchall-worker.js', scope) t, 'resources/clients-matchall-worker.js', scope)
.then(function(registration) { .then(function(registration) {
t.add_cleanup(function() {
return service_worker_unregister(t, scope);
});
return wait_for_state(t, registration.installing, 'activated'); return wait_for_state(t, registration.installing, 'activated');
}) })
.then(function() { return create_iframes(scope); }) .then(function() { return create_iframes(scope); })
@ -85,9 +89,7 @@ async_test(function(t) {
}) })
.then(function() { .then(function() {
frames.forEach(function(f) { f.remove() }); frames.forEach(function(f) { f.remove() });
service_worker_unregister_and_done(t, scope); });
})
.catch(unreached_rejection(t));
}, 'Verify matchAll() respect includeUncontrolled'); }, 'Verify matchAll() respect includeUncontrolled');
</script> </script>

View file

@ -5,12 +5,15 @@
<script src="resources/test-helpers.sub.js"></script> <script src="resources/test-helpers.sub.js"></script>
<script> <script>
var scope = 'resources/blank.html?clients-matchAll'; var scope = 'resources/blank.html?clients-matchAll';
var t = async_test('Test Clients.matchAll()');
var frames = []; var frames = [];
t.step(function() { promise_test(function(t) {
service_worker_unregister_and_register( return service_worker_unregister_and_register(
t, 'resources/clients-matchall-worker.js', scope) t, 'resources/clients-matchall-worker.js', scope)
.then(function(registration) { .then(function(registration) {
t.add_cleanup(function() {
return service_worker_unregister(t, scope);
});
return wait_for_state(t, registration.installing, 'activated'); return wait_for_state(t, registration.installing, 'activated');
}) })
.then(function() { return with_iframe(scope + '#1'); }) .then(function() { return with_iframe(scope + '#1'); })
@ -22,12 +25,15 @@ t.step(function() {
.then(function(frame2) { .then(function(frame2) {
frames.push(frame2); frames.push(frame2);
var channel = new MessageChannel(); var channel = new MessageChannel();
channel.port1.onmessage = t.step_func(onMessage);
return new Promise(function(resolve) {
channel.port1.onmessage = resolve;
frame2.contentWindow.navigator.serviceWorker.controller.postMessage( frame2.contentWindow.navigator.serviceWorker.controller.postMessage(
{port:channel.port2}, [channel.port2]); {port:channel.port2}, [channel.port2]);
})
.catch(unreached_rejection(t));
}); });
})
.then(onMessage);
}, 'Test Clients.matchAll()');
var expected = [ var expected = [
// visibilityState, focused, url, type, frameType // visibilityState, focused, url, type, frameType
@ -40,6 +46,5 @@ function onMessage(e) {
assert_array_equals(e.data[0], expected[0]); assert_array_equals(e.data[0], expected[0]);
assert_array_equals(e.data[1], expected[1]); assert_array_equals(e.data[1], expected[1]);
frames.forEach(function(f) { f.remove(); }); frames.forEach(function(f) { f.remove(); });
service_worker_unregister_and_done(t, scope);
} }
</script> </script>

View file

@ -5,22 +5,25 @@
<script src="resources/test-helpers.sub.js"></script> <script src="resources/test-helpers.sub.js"></script>
<body> <body>
<script> <script>
var t = async_test('controller is cleared on disconnected window'); promise_test(function(t) {
t.step(function() {
var url = 'resources/empty-worker.js'; var url = 'resources/empty-worker.js';
var scope = 'resources/blank.html'; var scope = 'resources/blank.html';
var registration; var registration;
var controller; var controller;
var frame; var frame;
service_worker_unregister_and_register(t, url, scope) return service_worker_unregister_and_register(t, url, scope)
.then(t.step_func(function(swr) { .then(function(swr) {
t.add_cleanup(function() {
return service_worker_unregister(t, scope);
});
registration = swr; registration = swr;
return wait_for_state(t, registration.installing, 'activated'); return wait_for_state(t, registration.installing, 'activated');
})) })
.then(t.step_func(function() { .then(function() {
return with_iframe(scope) return with_iframe(scope)
})) })
.then(t.step_func(function(f) { .then(function(f) {
frame = f; frame = f;
var w = frame.contentWindow; var w = frame.contentWindow;
var swc = w.navigator.serviceWorker; var swc = w.navigator.serviceWorker;
@ -31,10 +34,7 @@ t.step(function() {
assert_equals(swc.controller, null, assert_equals(swc.controller, null,
'disconnected frame should not be controlled'); 'disconnected frame should not be controlled');
service_worker_unregister_and_done(t, scope);
}))
.catch(unreached_rejection(t));
}); });
}, 'controller is cleared on disconnected window');
</script> </script>
</body> </body>

View file

@ -5,22 +5,25 @@
<script src="resources/test-helpers.sub.js"></script> <script src="resources/test-helpers.sub.js"></script>
<body> <body>
<script> <script>
var t = async_test('controller is set for a controlled document'); promise_test(function(t) {
t.step(function() {
var url = 'resources/empty-worker.js'; var url = 'resources/empty-worker.js';
var scope = 'resources/blank.html'; var scope = 'resources/blank.html';
var registration; var registration;
var controller; var controller;
var frame; var frame;
service_worker_unregister_and_register(t, url, scope) return service_worker_unregister_and_register(t, url, scope)
.then(t.step_func(function(swr) { .then(function(swr) {
t.add_cleanup(function() {
return service_worker_unregister(t, scope);
});
registration = swr; registration = swr;
return wait_for_state(t, registration.installing, 'activated'); return wait_for_state(t, registration.installing, 'activated');
})) })
.then(t.step_func(function() { .then(function() {
return with_iframe(scope); return with_iframe(scope);
})) })
.then(t.step_func(function(f) { .then(function(f) {
frame = f; frame = f;
var w = frame.contentWindow; var w = frame.contentWindow;
controller = w.navigator.serviceWorker.controller; controller = w.navigator.serviceWorker.controller;
@ -32,14 +35,12 @@ t.step(function() {
assert_not_equals(controller, registration.active); assert_not_equals(controller, registration.active);
return w.navigator.serviceWorker.getRegistration(); return w.navigator.serviceWorker.getRegistration();
})) })
.then(t.step_func(function(frameRegistration) { .then(function(frameRegistration) {
// SW objects from same window should be equal // SW objects from same window should be equal
assert_equals(frameRegistration.active, controller); assert_equals(frameRegistration.active, controller);
frame.remove(); frame.remove();
service_worker_unregister_and_done(t, scope);
}))
.catch(unreached_rejection(t));
}); });
}, 'controller is set for a controlled document');
</script> </script>
</body> </body>

View file

@ -22,15 +22,19 @@ function sync_message(worker, message, transfer) {
function runTest(test, step, testBody) { function runTest(test, step, testBody) {
var scope = './resources/' + step; var scope = './resources/' + step;
var script = 'resources/extendable-event-async-waituntil.js?' + scope; var script = 'resources/extendable-event-async-waituntil.js?' + scope;
service_worker_unregister_and_register(test, script, scope) return service_worker_unregister_and_register(test, script, scope)
.then(function(registration) { .then(function(registration) {
test.add_cleanup(function() {
return service_worker_unregister(test, scope);
});
let worker = registration.installing; let worker = registration.installing;
var channel = new MessageChannel(); var channel = new MessageChannel();
var saw_message = new Promise(function(resolve) { var saw_message = new Promise(function(resolve) {
channel.port1.onmessage = function(e) { resolve(e.data); } channel.port1.onmessage = function(e) { resolve(e.data); }
}); });
wait_for_state(test, worker, 'activated') return wait_for_state(test, worker, 'activated')
.then(function() { .then(function() {
return sync_message(worker, { step: 'init', port: channel.port2 }, return sync_message(worker, { step: 'init', port: channel.port2 },
[channel.port2]); [channel.port2]);
@ -40,9 +44,7 @@ function runTest(test, step, testBody) {
.then(function(output) { .then(function(output) {
assert_equals(output.result, output.expected); assert_equals(output.result, output.expected);
}) })
.then(function() { return sync_message(worker, { step: 'done' }); }) .then(function() { return sync_message(worker, { step: 'done' }); });
.then(() => { service_worker_unregister_and_done(test, scope); })
.catch(unreached_rejection(test));
}); });
} }
@ -50,51 +52,51 @@ function msg_event_test(scope, test) {
var testBody = function(worker) { var testBody = function(worker) {
return sync_message(worker, { step: scope }); return sync_message(worker, { step: scope });
}; };
runTest(test, scope, testBody); return runTest(test, scope, testBody);
} }
async_test(msg_event_test.bind(this, 'no-current-extension-different-task'), promise_test(msg_event_test.bind(this, 'no-current-extension-different-task'),
'Test calling waitUntil in a different task without an existing extension throws'); 'Test calling waitUntil in a different task without an existing extension throws');
async_test(msg_event_test.bind(this, 'no-current-extension-different-microtask'), promise_test(msg_event_test.bind(this, 'no-current-extension-different-microtask'),
'Test calling waitUntil in a different microtask without an existing extension throws'); 'Test calling waitUntil in a different microtask without an existing extension throws');
async_test(msg_event_test.bind(this, 'current-extension-different-task'), promise_test(msg_event_test.bind(this, 'current-extension-different-task'),
'Test calling waitUntil in a different task with an existing extension succeeds'); 'Test calling waitUntil in a different task with an existing extension succeeds');
async_test(msg_event_test.bind(this, 'current-extension-expired-same-microtask-turn'), promise_test(msg_event_test.bind(this, 'current-extension-expired-same-microtask-turn'),
'Test calling waitUntil with an existing extension promise handler succeeds'); 'Test calling waitUntil with an existing extension promise handler succeeds');
// The promise handler will queue a new microtask after the check for new // The promise handler will queue a new microtask after the check for new
// extensions was performed. // extensions was performed.
async_test(msg_event_test.bind(this, 'current-extension-expired-same-microtask-turn-extra'), promise_test(msg_event_test.bind(this, 'current-extension-expired-same-microtask-turn-extra'),
'Test calling waitUntil at the end of the microtask turn throws'); 'Test calling waitUntil at the end of the microtask turn throws');
async_test(msg_event_test.bind(this, 'current-extension-expired-different-task'), promise_test(msg_event_test.bind(this, 'current-extension-expired-different-task'),
'Test calling waitUntil after the current extension expired in a different task fails'); 'Test calling waitUntil after the current extension expired in a different task fails');
async_test(msg_event_test.bind(this, 'script-extendable-event'), promise_test(msg_event_test.bind(this, 'script-extendable-event'),
'Test calling waitUntil on a script constructed ExtendableEvent throws exception'); 'Test calling waitUntil on a script constructed ExtendableEvent throws exception');
async_test(function(t) { promise_test(function(t) {
var testBody = function(worker) { var testBody = function(worker) {
return with_iframe('./resources/pending-respondwith-async-waituntil/dummy.html'); return with_iframe('./resources/pending-respondwith-async-waituntil/dummy.html');
} }
runTest(t, 'pending-respondwith-async-waituntil', testBody); return runTest(t, 'pending-respondwith-async-waituntil', testBody);
}, 'Test calling waitUntil asynchronously with pending respondWith promise.'); }, 'Test calling waitUntil asynchronously with pending respondWith promise.');
async_test(function(t) { promise_test(function(t) {
var testBody = function(worker) { var testBody = function(worker) {
return with_iframe('./resources/respondwith-microtask-sync-waituntil/dummy.html'); return with_iframe('./resources/respondwith-microtask-sync-waituntil/dummy.html');
} }
runTest(t, 'respondwith-microtask-sync-waituntil', testBody); return runTest(t, 'respondwith-microtask-sync-waituntil', testBody);
}, 'Test calling waitUntil synchronously inside microtask of respondWith promise.'); }, 'Test calling waitUntil synchronously inside microtask of respondWith promise.');
async_test(function(t) { promise_test(function(t) {
var testBody = function(worker) { var testBody = function(worker) {
return with_iframe('./resources/respondwith-microtask-async-waituntil/dummy.html'); return with_iframe('./resources/respondwith-microtask-async-waituntil/dummy.html');
} }
runTest(t, 'respondwith-microtask-async-waituntil', testBody); return runTest(t, 'respondwith-microtask-async-waituntil', testBody);
}, 'Test calling waitUntil asynchronously inside microtask of respondWith promise.'); }, 'Test calling waitUntil asynchronously inside microtask of respondWith promise.');

View file

@ -6,75 +6,85 @@
<script> <script>
function runTest(test, scope, onRegister) { function runTest(test, scope, onRegister) {
var script = 'resources/extendable-event-waituntil.js?' + scope; var script = 'resources/extendable-event-waituntil.js?' + scope;
service_worker_unregister_and_register(test, script, scope) return service_worker_unregister_and_register(test, script, scope)
.then(function(registration) { .then(function(registration) {
onRegister(registration.installing); test.add_cleanup(function() {
return service_worker_unregister(test, scope);
});
return onRegister(registration.installing);
}); });
} }
// Sends a SYN to the worker and asynchronously listens for an ACK; sets // Sends a SYN to the worker and asynchronously listens for an ACK; sets
// |obj.synced| to true once ack'd. // |obj.synced| to true once ack'd.
function syncWorker(test, worker, obj) { function syncWorker(worker, obj) {
var channel = new MessageChannel(); var channel = new MessageChannel();
worker.postMessage({port: channel.port2}, [channel.port2]); worker.postMessage({port: channel.port2}, [channel.port2]);
return new Promise(function(resolve) { return new Promise(function(resolve) {
channel.port1.onmessage = test.step_func(function(e) { channel.port1.onmessage = resolve;
}).then(function(e) {
var message = e.data; var message = e.data;
assert_equals(message, 'SYNC', assert_equals(message, 'SYNC',
'Should receive sync message from worker.'); 'Should receive sync message from worker.');
obj.synced = true; obj.synced = true;
channel.port1.postMessage('ACK'); channel.port1.postMessage('ACK');
resolve();
});
}); });
} }
async_test(function(t) { promise_test(function(t) {
// Passing scope as the test switch for worker script. // Passing scope as the test switch for worker script.
var scope = 'resources/install-fulfilled'; var scope = 'resources/install-fulfilled';
var onRegister = function(worker) { var onRegister = function(worker) {
var obj = {}; var obj = {};
return Promise.all([
syncWorker(worker, obj),
wait_for_state(t, worker, 'installed') wait_for_state(t, worker, 'installed')
.then(function() { ]).then(function() {
assert_true( assert_true(
obj.synced, obj.synced,
'state should be "installed" after the waitUntil promise ' + 'state should be "installed" after the waitUntil promise ' +
'for "oninstall" is fulfilled.'); 'for "oninstall" is fulfilled.');
service_worker_unregister_and_done(t, scope); service_worker_unregister_and_done(t, scope);
}) });
.catch(unreached_rejection(t));
syncWorker(t, worker, obj);
}; };
runTest(t, scope, onRegister); return runTest(t, scope, onRegister);
}, 'Test install event waitUntil fulfilled'); }, 'Test install event waitUntil fulfilled');
async_test(function(t) { promise_test(function(t) {
var scope = 'resources/install-multiple-fulfilled'; var scope = 'resources/install-multiple-fulfilled';
var onRegister = function(worker) { var onRegister = function(worker) {
var obj1 = {}; var obj1 = {};
var obj2 = {}; var obj2 = {};
return Promise.all([
syncWorker(worker, obj1),
syncWorker(worker, obj2),
wait_for_state(t, worker, 'installed') wait_for_state(t, worker, 'installed')
.then(function() { ]).then(function() {
assert_true( assert_true(
obj1.synced && obj2.synced, obj1.synced && obj2.synced,
'state should be "installed" after all waitUntil promises ' + 'state should be "installed" after all waitUntil promises ' +
'for "oninstall" are fulfilled.'); 'for "oninstall" are fulfilled.');
service_worker_unregister_and_done(t, scope); });
})
.catch(unreached_rejection(t));
syncWorker(t, worker, obj1);
syncWorker(t, worker, obj2);
}; };
runTest(t, scope, onRegister); return runTest(t, scope, onRegister);
}, 'Test ExtendableEvent multiple waitUntil fulfilled.'); }, 'Test ExtendableEvent multiple waitUntil fulfilled.');
async_test(function(t) { promise_test(function(t) {
var scope = 'resources/install-reject-precedence'; var scope = 'resources/install-reject-precedence';
var onRegister = function(worker) { var onRegister = function(worker) {
var obj1 = {}; var obj1 = {};
var obj2 = {}; var obj2 = {};
wait_for_state(t, worker, 'redundant')
return Promise.all([
syncWorker(worker, obj1)
.then(function() { .then(function() {
syncWorker(worker, obj2);
}),
wait_for_state(t, worker, 'redundant')
]).then(function() {
assert_true( assert_true(
obj1.synced, obj1.synced,
'The "redundant" state was entered after the first "extend ' + 'The "redundant" state was entered after the first "extend ' +
@ -85,61 +95,46 @@ async_test(function(t) {
'The "redundant" state was entered after the third "extend ' + 'The "redundant" state was entered after the third "extend ' +
'lifetime promise" resolved.' 'lifetime promise" resolved.'
); );
service_worker_unregister_and_done(t, scope);
})
.catch(unreached_rejection(t));
syncWorker(t, worker, obj1)
.then(function() {
syncWorker(t, worker, obj2);
}); });
}; };
runTest(t, scope, onRegister); return runTest(t, scope, onRegister);
}, 'Test ExtendableEvent waitUntil reject precedence.'); }, 'Test ExtendableEvent waitUntil reject precedence.');
async_test(function(t) { promise_test(function(t) {
var scope = 'resources/activate-fulfilled'; var scope = 'resources/activate-fulfilled';
var onRegister = function(worker) { var onRegister = function(worker) {
var obj = {}; var obj = {};
wait_for_state(t, worker, 'activating') return wait_for_state(t, worker, 'activating')
.then(function() { .then(function() {
syncWorker(t, worker, obj); return Promise.all([
return wait_for_state(t, worker, 'activated'); syncWorker(worker, obj),
wait_for_state(t, worker, 'activated')
]);
}) })
.then(function() { .then(function() {
assert_true( assert_true(
obj.synced, obj.synced,
'state should be "activated" after the waitUntil promise ' + 'state should be "activated" after the waitUntil promise ' +
'for "onactivate" is fulfilled.'); 'for "onactivate" is fulfilled.');
service_worker_unregister_and_done(t, scope); });
})
.catch(unreached_rejection(t));
}; };
runTest(t, scope, onRegister); return runTest(t, scope, onRegister);
}, 'Test activate event waitUntil fulfilled'); }, 'Test activate event waitUntil fulfilled');
async_test(function(t) { promise_test(function(t) {
var scope = 'resources/install-rejected'; var scope = 'resources/install-rejected';
var onRegister = function(worker) { var onRegister = function(worker) {
wait_for_state(t, worker, 'redundant') return wait_for_state(t, worker, 'redundant');
.then(function() {
service_worker_unregister_and_done(t, scope);
})
.catch(unreached_rejection(t));
}; };
runTest(t, scope, onRegister); return runTest(t, scope, onRegister);
}, 'Test install event waitUntil rejected'); }, 'Test install event waitUntil rejected');
async_test(function(t) { promise_test(function(t) {
var scope = 'resources/activate-rejected'; var scope = 'resources/activate-rejected';
var onRegister = function(worker) { var onRegister = function(worker) {
wait_for_state(t, worker, 'activated') return wait_for_state(t, worker, 'activated');
.then(function() {
service_worker_unregister_and_done(t, scope);
})
.catch(unreached_rejection(t));
}; };
runTest(t, scope, onRegister); return runTest(t, scope, onRegister);
}, 'Test activate event waitUntil rejected.'); }, 'Test activate event waitUntil rejected.');
</script> </script>

Some files were not shown because too many files have changed in this diff Show more