mirror of
https://github.com/servo/servo.git
synced 2025-08-15 02:15:33 +01:00
Update web-platform-tests to revision 8f8ff0e2a61f2a24996404921fe853cb1fd9b432
This commit is contained in:
parent
e98cd07910
commit
141a52794b
58 changed files with 1615 additions and 276 deletions
|
@ -5,6 +5,9 @@
|
|||
// Covers basic functionality provided by BackgroundFetchManager.fetch().
|
||||
// https://wicg.github.io/background-fetch/#background-fetch-manager-fetch
|
||||
|
||||
const wait = milliseconds =>
|
||||
new Promise(resolve => step_timeout(resolve, milliseconds));
|
||||
|
||||
promise_test(async test => {
|
||||
// 6.3.1.9.2: If |registration|’s active worker is null, then reject promise
|
||||
// with a TypeError and abort these steps.
|
||||
|
@ -12,16 +15,16 @@ promise_test(async test => {
|
|||
const scope = 'service_workers/' + location.pathname;
|
||||
|
||||
const serviceWorkerRegistration =
|
||||
await service_worker_unregister_and_register(test, script, scope);
|
||||
await service_worker_unregister_and_register(test, script, scope);
|
||||
|
||||
assert_equals(
|
||||
serviceWorkerRegistration.active, null,
|
||||
'There must not be an activated worker');
|
||||
serviceWorkerRegistration.active, null,
|
||||
'There must not be an activated worker');
|
||||
|
||||
await promise_rejects(
|
||||
test, new TypeError(),
|
||||
serviceWorkerRegistration.backgroundFetch.fetch(
|
||||
uniqueId(), ['resources/feature-name.txt']),
|
||||
test, new TypeError(),
|
||||
serviceWorkerRegistration.backgroundFetch.fetch(
|
||||
uniqueId(), ['resources/feature-name.txt']),
|
||||
'fetch() must reject on pending and installing workers');
|
||||
|
||||
}, 'Background Fetch requires an activated Service Worker');
|
||||
|
@ -30,26 +33,26 @@ backgroundFetchTest(async (test, backgroundFetch) => {
|
|||
// 6.3.1.6: If |requests| is empty, then return a promise rejected with a
|
||||
// TypeError.
|
||||
await promise_rejects(
|
||||
test, new TypeError(), backgroundFetch.fetch(uniqueId(), []),
|
||||
'Empty sequences are treated as NULL');
|
||||
test, new TypeError(), backgroundFetch.fetch(uniqueId(), []),
|
||||
'Empty sequences are treated as NULL');
|
||||
|
||||
// 6.3.1.7.1: Let |internalRequest| be the request of the result of invoking
|
||||
// the Request constructor with |request|. If this throws an
|
||||
// exception, return a promise rejected with the exception.
|
||||
await promise_rejects(
|
||||
test, new TypeError(),
|
||||
backgroundFetch.fetch(uniqueId(), 'https://user:pass@domain/secret.txt'),
|
||||
'Exceptions thrown in the Request constructor are rethrown');
|
||||
test, new TypeError(),
|
||||
backgroundFetch.fetch(uniqueId(), 'https://user:pass@domain/secret.txt'),
|
||||
'Exceptions thrown in the Request constructor are rethrown');
|
||||
|
||||
// 6.3.1.7.2: If |internalRequest|’s mode is "no-cors", then return a
|
||||
// promise rejected with a TypeError.
|
||||
{
|
||||
const request =
|
||||
new Request('resources/feature-name.txt', {mode: 'no-cors'});
|
||||
new Request('resources/feature-name.txt', {mode: 'no-cors'});
|
||||
|
||||
await promise_rejects(
|
||||
test, new TypeError(), backgroundFetch.fetch(uniqueId(), request),
|
||||
'Requests must not be in no-cors mode');
|
||||
test, new TypeError(), backgroundFetch.fetch(uniqueId(), request),
|
||||
'Requests must not be in no-cors mode');
|
||||
}
|
||||
|
||||
}, 'Argument verification is done for BackgroundFetchManager.fetch()');
|
||||
|
@ -67,7 +70,7 @@ backgroundFetchTest(async (test, backgroundFetch) => {
|
|||
backgroundFetchTest(async (test, backgroundFetch) => {
|
||||
const registrationId = uniqueId();
|
||||
const registration =
|
||||
await backgroundFetch.fetch(registrationId, 'resources/feature-name.txt');
|
||||
await backgroundFetch.fetch(registrationId, 'resources/feature-name.txt');
|
||||
|
||||
assert_equals(registration.id, registrationId);
|
||||
assert_equals(registration.uploadTotal, 0);
|
||||
|
@ -75,6 +78,7 @@ backgroundFetchTest(async (test, backgroundFetch) => {
|
|||
assert_equals(registration.downloadTotal, 0);
|
||||
assert_equals(registration.result, '');
|
||||
assert_equals(registration.failureReason, '');
|
||||
assert_true(registration.recordsAvailable);
|
||||
// Skip `downloaded`, as the transfer may have started already.
|
||||
|
||||
const {type, eventRegistration, results} = await getMessageFromServiceWorker();
|
||||
|
@ -97,15 +101,15 @@ backgroundFetchTest(async (test, backgroundFetch) => {
|
|||
// Very large download total that will definitely exceed the quota.
|
||||
const options = {downloadTotal: Number.MAX_SAFE_INTEGER};
|
||||
await promise_rejects(
|
||||
test, 'QUOTA_EXCEEDED_ERR',
|
||||
backgroundFetch.fetch(registrationId, 'resources/feature-name.txt', options),
|
||||
'This fetch should have thrown a quota exceeded error');
|
||||
test, 'QUOTA_EXCEEDED_ERR',
|
||||
backgroundFetch.fetch(registrationId, 'resources/feature-name.txt', options),
|
||||
'This fetch should have thrown a quota exceeded error');
|
||||
|
||||
}, 'Background Fetch that exceeds the quota throws a QuotaExceededError');
|
||||
|
||||
backgroundFetchTest(async (test, backgroundFetch) => {
|
||||
const registration = await backgroundFetch.fetch(
|
||||
'my-id', ['resources/feature-name.txt', 'resources/feature-name.txt']);
|
||||
'my-id', ['resources/feature-name.txt', 'resources/feature-name.txt']);
|
||||
|
||||
const {type, eventRegistration, results} = await getMessageFromServiceWorker();
|
||||
assert_equals('backgroundfetchsuccess', type);
|
||||
|
@ -125,8 +129,8 @@ backgroundFetchTest(async (test, backgroundFetch) => {
|
|||
|
||||
backgroundFetchTest(async (test, backgroundFetch) => {
|
||||
const request =
|
||||
new Request('resources/feature-name.txt',
|
||||
{method: 'POST', body: 'TestBody'});
|
||||
new Request('resources/feature-name.txt',
|
||||
{method: 'POST', body: 'TestBody'});
|
||||
|
||||
const registration = await backgroundFetch.fetch('my-id', request);
|
||||
|
||||
|
@ -145,3 +149,25 @@ backgroundFetchTest(async (test, backgroundFetch) => {
|
|||
}
|
||||
|
||||
}, 'Fetches can have requests with a body');
|
||||
|
||||
backgroundFetchTest(async (test, backgroundFetch) => {
|
||||
const registrationId = uniqueId();
|
||||
const registration =
|
||||
await backgroundFetch.fetch(registrationId, 'resources/feature-name.txt');
|
||||
assert_true(registration.recordsAvailable);
|
||||
|
||||
const {type, eventRegistration, results} = await getMessageFromServiceWorker();
|
||||
assert_equals('backgroundfetchsuccess', type);
|
||||
assert_equals(results.length, 1);
|
||||
|
||||
// Wait for up to 5 seconds for the |eventRegistration|'s recordsAvailable
|
||||
// flag to be set to false, which happens after the successful invocation
|
||||
// of the ServiceWorker event has finished.
|
||||
for (let i = 0; i < 50; ++i) {
|
||||
if (!registration.recordsAvailable)
|
||||
break;
|
||||
await wait(100);
|
||||
}
|
||||
|
||||
assert_false(registration.recordsAvailable);
|
||||
}, 'recordsAvailable is false after onbackgroundfetchsuccess finishes execution.');
|
|
@ -43,6 +43,7 @@ backgroundFetchTest(async (test, backgroundFetch) => {
|
|||
assert_equals(registration.downloadTotal, 1234);
|
||||
assert_equals(registration.result, '');
|
||||
assert_equals(registration.failureReason, '');
|
||||
assert_true(registration.recordsAvailable);
|
||||
// Skip `downloaded`, as the transfer may have started already.
|
||||
|
||||
const secondRegistration = await backgroundFetch.get(registrationId);
|
||||
|
@ -52,6 +53,8 @@ backgroundFetchTest(async (test, backgroundFetch) => {
|
|||
assert_equals(secondRegistration.uploadTotal, registration.uploadTotal);
|
||||
assert_equals(secondRegistration.uploaded, registration.uploaded);
|
||||
assert_equals(secondRegistration.downloadTotal, registration.downloadTotal);
|
||||
assert_equals(secondRegistration.failureReason, registration.failureReason);
|
||||
assert_equals(secondRegistration.recordsAvailable, registration.recordsAvailable);
|
||||
|
||||
// While the transfer might have started, both BackgroundFetchRegistration
|
||||
// objects should have the latest progress values.
|
||||
|
|
|
@ -7,23 +7,31 @@
|
|||
<title>connect-src-eventsource-allowed</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src='../support/logTest.sub.js?logs=["Pass"]'></script>
|
||||
<script src='../support/logTest.sub.js?logs=["allowed"]'></script>
|
||||
<script src="../support/alertAssert.sub.js?alerts=[]"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
window.addEventListener('securitypolicyviolation', function(e) {
|
||||
log("FAIL");
|
||||
log("allowed");
|
||||
});
|
||||
|
||||
try {
|
||||
var es = new EventSource("http://{{host}}:{{ports[http][0]}}/content-security-policy/connect-src/resources/simple-event-stream");
|
||||
log("Pass");
|
||||
} catch (e) {
|
||||
log("Fail");
|
||||
}
|
||||
|
||||
try {
|
||||
var es = new EventSource("http://{{domains[www1]}}:{{ports[http][0]}}/content-security-policy/connect-src/resources/simple-event-stream");
|
||||
// Firefox and Chrome don't throw an exception and takes some time to close async
|
||||
if (es.readyState == EventSource.CONNECTING) {
|
||||
setTimeout( function() {
|
||||
es.readyState != EventSource.CLOSED ? log("allowed") : log("blocked");
|
||||
}, 1000);
|
||||
} else if (es.readyState == EventSource.CLOSED) {
|
||||
log("blocked");
|
||||
} else {
|
||||
log("allowed");
|
||||
}
|
||||
} catch (e) {
|
||||
log("blocked");
|
||||
}
|
||||
</script>
|
||||
<div id="log"></div>
|
||||
</body>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<title>connect-src-eventsource-blocked</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src='../support/logTest.sub.js?logs=["Pass","violated-directive=connect-src"]'></script>
|
||||
<script src='../support/logTest.sub.js?logs=["blocked","violated-directive=connect-src"]'></script>
|
||||
<script src="../support/alertAssert.sub.js?alerts=[]"></script>
|
||||
</head>
|
||||
|
||||
|
@ -16,21 +16,21 @@
|
|||
window.addEventListener('securitypolicyviolation', function(e) {
|
||||
log("violated-directive=" + e.violatedDirective);
|
||||
});
|
||||
|
||||
|
||||
try {
|
||||
var es = new EventSource("http://www1.{{host}}:{{ports[http][0]}}/content-security-policy/connect-src/resources/simple-event-stream");
|
||||
// Firefox doesn't throw an exception and takes some time to close async
|
||||
var es = new EventSource("http://{{domains[www1]}}:{{ports[http][0]}}/content-security-policy/connect-src/resources/simple-event-stream");
|
||||
// Firefox and Chrome don't throw an exception and takes some time to close async
|
||||
if (es.readyState == EventSource.CONNECTING) {
|
||||
setTimeout( function() {
|
||||
es.readyState != EventSource.CLOSED ? log("Fail") : log("Pass");
|
||||
}, 2);
|
||||
es.readyState != EventSource.CLOSED ? log("allowed") : log("blocked");
|
||||
}, 1000);
|
||||
} else if (es.readyState == EventSource.CLOSED) {
|
||||
log("Pass");
|
||||
log("blocked");
|
||||
} else {
|
||||
log("Fail");
|
||||
log("allowed");
|
||||
}
|
||||
} catch (e) {
|
||||
log("Pass");
|
||||
log("blocked");
|
||||
}
|
||||
</script>
|
||||
<div id="log"></div>
|
||||
|
|
|
@ -2,26 +2,31 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<!-- Programmatically converted from a WebKit Reftest, please forgive resulting idiosyncracies.-->
|
||||
<meta http-equiv="Content-Security-Policy" content="connect-src 'self' ws://127.0.0.1:8880; script-src 'self' 'unsafe-inline';">
|
||||
<title>connect-src-websocket-allowed</title>
|
||||
<!-- Programmatically converted from a WebKit Reftest, please forgive resulting idiosyncraciws.-->
|
||||
<meta http-equiv="Content-Security-Policy" content="connect-src 'self' ws://{{domains[www1]}}:{{ports[http][0]}}/echo; script-src 'self' 'unsafe-inline';">
|
||||
<title>connect-src-websocket-blocked</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src='../support/logTest.sub.js?logs=["Pass"]'></script>
|
||||
<script src='../support/logTest.sub.js?logs=["allowed"]'></script>
|
||||
<script src="../support/alertAssert.sub.js?alerts=[]"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
window.addEventListener('securitypolicyviolation', function(e) {
|
||||
log("Fail");
|
||||
log("violated-directive=" + e.violatedDirective);
|
||||
});
|
||||
|
||||
|
||||
try {
|
||||
var ws = new WebSocket("ws://127.0.0.1:8880/echo");
|
||||
log("Pass");
|
||||
var ws = new WebSocket("ws://{{domains[www1]}}:{{ports[http][0]}}/echo");
|
||||
|
||||
if (ws.readyState == WebSocket.CLOSING || ws.readyState == WebSocket.CLOSED) {
|
||||
log("blocked");
|
||||
} else {
|
||||
log("allowed");
|
||||
}
|
||||
} catch (e) {
|
||||
log("Fail");
|
||||
log("blocked");
|
||||
}
|
||||
|
||||
</script>
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<!-- Programmatically converted from a WebKit Reftest, please forgive resulting idiosyncracies.-->
|
||||
<meta http-equiv="Content-Security-Policy" content="connect-src 'self' ws://127.0.0.1:8880; script-src 'self' 'unsafe-inline';">
|
||||
<!-- Programmatically converted from a WebKit Reftest, please forgive resulting idiosyncraciws.-->
|
||||
<meta http-equiv="Content-Security-Policy" content="connect-src 'self'; script-src 'self' 'unsafe-inline';">
|
||||
<title>connect-src-websocket-blocked</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src='../support/logTest.sub.js?logs=["Pass","violated-directive=connect-src"]'></script>
|
||||
<script src='../support/logTest.sub.js?logs=["blocked","violated-directive=connect-src"]'></script>
|
||||
<script src="../support/alertAssert.sub.js?alerts=[]"></script>
|
||||
</head>
|
||||
|
||||
|
@ -18,10 +18,15 @@
|
|||
});
|
||||
|
||||
try {
|
||||
var ws = new WebSocket("ws://localhost:8880/echo");
|
||||
log("Fail");
|
||||
var ws = new WebSocket("ws://{{domains[www1]}}:{{ports[http][0]}}/echo");
|
||||
|
||||
if (ws.readyState == WebSocket.CLOSING || ws.readyState == WebSocket.CLOSED) {
|
||||
log("blocked");
|
||||
} else {
|
||||
log("allowed");
|
||||
}
|
||||
} catch (e) {
|
||||
log("Pass");
|
||||
log("blocked");
|
||||
}
|
||||
|
||||
</script>
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Security-Policy" content="connect-src 'self'; script-src 'self' 'unsafe-inline';">
|
||||
<title>connect-src-websocket-blocked</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src='../support/logTest.sub.js?logs=["allowed", "allowed"]'></script>
|
||||
<script src="../support/alertAssert.sub.js?alerts=[]"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
window.addEventListener('securitypolicyviolation', function(e) {
|
||||
log("violated-directive=" + e.violatedDirective);
|
||||
});
|
||||
|
||||
try {
|
||||
var ws = new WebSocket("ws://{{host}}:{{location[port]}}/echo");
|
||||
|
||||
if (ws.readyState == WebSocket.CLOSING || ws.readyState == WebSocket.CLOSED) {
|
||||
log("blocked");
|
||||
} else {
|
||||
log("allowed");
|
||||
}
|
||||
} catch (e) {
|
||||
log("blocked");
|
||||
}
|
||||
|
||||
try {
|
||||
var wss = new WebSocket("wss://{{host}}:{{location[port]}}/echo");
|
||||
|
||||
if (wss.readyState == WebSocket.CLOSING || wss.readyState == WebSocket.CLOSED) {
|
||||
log("blocked");
|
||||
} else {
|
||||
log("allowed");
|
||||
}
|
||||
} catch (e) {
|
||||
log("blocked");
|
||||
}
|
||||
|
||||
</script>
|
||||
<div id="log"></div>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -13,7 +13,7 @@
|
|||
</style>
|
||||
<p>Test passes if it has the same output than the reference.</p>
|
||||
<div class="wrapper">
|
||||
<span style="display: inline-block; margin: 1em 0; contain: layout;">
|
||||
<span style="display: inline-block; margin: 1em 0; vertical-align: top; contain: layout;">
|
||||
<div style="margin: 1em 0;">This text should have 2em top and bottom margins (margins do not collapse).</div>
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
|
||||
<link rel="help" href="https://www.w3.org/TR/css-contain-1/#containment-size">
|
||||
<link rel="match" href="reference/contain-size-021-ref.html">
|
||||
<link rel="match" href="reference/contain-size-023-ref.html">
|
||||
|
||||
<meta content="This test checks that when laying out an inline-block element with 'contain: size', the inline-block element must be treated as if it would have no contents. In this test, the inline-block element has text and no in-flow block descendant." name="assert">
|
||||
<meta name="flags" content="">
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
|
||||
<link rel="help" href="https://www.w3.org/TR/css-contain-1/#containment-size">
|
||||
<link rel="match" href="reference/contain-size-021-ref.html">
|
||||
<link rel="match" href="reference/contain-size-025-ref.html">
|
||||
|
||||
<meta content="This test checks that when laying out an inline-block element with 'contain: size', the inline-block element must be treated as if it would have no contents. In this test, the inline-block element has 2 in-flow block descendants made of images." name="assert">
|
||||
<meta name="flags" content="">
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
|
||||
<link rel="help" href="https://www.w3.org/TR/css-contain-1/#containment-size">
|
||||
<link rel="match" href="reference/contain-size-021-ref.html">
|
||||
<link rel="match" href="reference/contain-size-027-ref.html">
|
||||
|
||||
<meta content="This test checks that when laying out an inline-block element with 'contain: size', the inline-block element must be treated as if it would have no contents. In this test, the inline-block element has 2 in-flow block descendants made of text." name="assert">
|
||||
<meta name="flags" content="">
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
|
||||
<link rel="help" href="https://www.w3.org/TR/css-contain-1/#containment-size">
|
||||
<link rel="match" href="reference/contain-size-021-ref.html">
|
||||
<link rel="match" href="reference/contain-size-025-ref.html">
|
||||
|
||||
<meta content="This test checks that when laying out an inline replaced element with 'contain: size', the inline replaced element must be treated as having an intrinsic width and height of 0." name="assert">
|
||||
<meta name="flags" content="">
|
||||
|
|
|
@ -1,13 +1,31 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Containment Test: Reference file</title>
|
||||
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
|
||||
<style>
|
||||
div.inline-block {
|
||||
display: inline-block;
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
<meta charset="UTF-8">
|
||||
div#blue-test {
|
||||
background-color: blue;
|
||||
padding: 50px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
<title>CSS Reference Test</title>
|
||||
div#orange-reference {
|
||||
background-color: orange;
|
||||
}
|
||||
</style>
|
||||
|
||||
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
|
||||
<p>This test passes if the painted blue area is <strong>exactly as wide as</strong> the orange square.
|
||||
|
||||
<p>This test passes if the painted blue area is <strong>exactly as wide as</strong> the orange square.
|
||||
<div>
|
||||
<div id="blue-test" class="inline-block"><img src="../support/blue50wBy46h.png" alt="Image download support must be enabled"></div>
|
||||
</div>
|
||||
|
||||
<div><img src="../support/swatch-blue.png" width="100" height="100" alt="Image download support must be enabled"></div>
|
||||
|
||||
<div><img src="../support/swatch-orange.png" width="100" height="100" alt="Image download support must be enabled"></div>
|
||||
<div>
|
||||
<div id="orange-reference" class="inline-block"></div>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Containment Test: Reference file</title>
|
||||
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
|
||||
<style>
|
||||
div.inline-block {
|
||||
display: inline-block;
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
div#blue-test {
|
||||
background-color: blue;
|
||||
color: transparent;
|
||||
font-size: 100px;
|
||||
padding: 50px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
div#orange-reference {
|
||||
background-color: orange;
|
||||
}
|
||||
</style>
|
||||
|
||||
<p>This test passes if the painted blue area is <strong>exactly as wide as</strong> the orange square.
|
||||
|
||||
<div>
|
||||
<div id="blue-test" class="inline-block">B</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div id="orange-reference" class="inline-block"></div>
|
||||
</div>
|
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<meta charset="UTF-8">
|
||||
|
||||
<title>CSS Reference Test</title>
|
||||
|
||||
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
|
||||
|
||||
<p>This test passes if the painted blue area is <strong>exactly as wide as</strong> the orange square.
|
||||
|
||||
<div><img src="../support/swatch-blue.png" width="100" height="100" alt="Image download support must be enabled"></div>
|
||||
|
||||
<div><img src="../support/swatch-orange.png" width="100" height="100" alt="Image download support must be enabled"></div>
|
|
@ -0,0 +1,41 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Containment Test: Reference file</title>
|
||||
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
|
||||
<style>
|
||||
div.inline-block {
|
||||
display: inline-block;
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
div#blue-test {
|
||||
background-color: blue;
|
||||
color: transparent;
|
||||
font-size: 50px;
|
||||
line-height: 1;
|
||||
padding: 50px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
div#orange-reference {
|
||||
background-color: orange;
|
||||
}
|
||||
|
||||
span {
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
|
||||
<p>This test passes if the painted blue area is <strong>exactly as wide as</strong> the orange square.
|
||||
|
||||
<div>
|
||||
<div id="blue-test" class="inline-block">
|
||||
<span>B</span>
|
||||
<span>L</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div id="orange-reference" class="inline-block"></div>
|
||||
</div>
|
|
@ -0,0 +1,14 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Conic gradient with a two position color stop</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/css-images-4/#color-stop-syntax">
|
||||
<meta name="assert" content="A color stop with two positions create a hard transition">
|
||||
<link rel="match" href="support/100x100-blue-green.html">
|
||||
<style>
|
||||
#target {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background-color: red;
|
||||
background-image: conic-gradient(green 0% 180deg, blue 180deg);
|
||||
}
|
||||
</style>
|
||||
<div id="target"></div>
|
|
@ -0,0 +1,14 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Linear gradient with a two position color stop</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/css-images-4/#color-stop-syntax">
|
||||
<meta name="assert" content="A color stop with two positions create a hard transition">
|
||||
<link rel="match" href="support/100x100-blue-green.html">
|
||||
<style>
|
||||
#target {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background-color: red;
|
||||
background-image: linear-gradient(to right, blue 0% 50%, green 50%);
|
||||
}
|
||||
</style>
|
||||
<div id="target"></div>
|
|
@ -0,0 +1,14 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Radial gradient with a two position color stop</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/css-images-4/#color-stop-syntax">
|
||||
<meta name="assert" content="A color stop with two positions create a hard transition">
|
||||
<link rel="match" href="support/100x100-blue-green.html">
|
||||
<style>
|
||||
#target {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background-color: red;
|
||||
background-image: radial-gradient(ellipse 50px 10000px at 0px 50px, blue 0% 50px, green 50px);
|
||||
}
|
||||
</style>
|
||||
<div id="target"></div>
|
|
@ -0,0 +1,2 @@
|
|||
<!DOCTYPE html>
|
||||
<div style="width: 50px; height: 100px; background-color: green; border-left: 50px solid blue"></div>
|
|
@ -18,14 +18,29 @@
|
|||
register_length('--font-size-ex');
|
||||
register_length('--font-size-ch');
|
||||
register_length('--font-size-px');
|
||||
register_length('--font-size-em-via-var');
|
||||
register_length('--font-size-rem-via-var');
|
||||
register_length('--font-size-ex-via-var');
|
||||
register_length('--font-size-ch-via-var');
|
||||
</script>
|
||||
<style>
|
||||
:root {
|
||||
--unregistered-em: 10em;
|
||||
--unregistered-rem: 10rem;
|
||||
--unregistered-ex: 10ex;
|
||||
--unregistered-ch: 10ch;
|
||||
}
|
||||
|
||||
:root, #target {
|
||||
--font-size-em: 2em;
|
||||
--font-size-rem: 2rem;
|
||||
--font-size-ex: 2ex;
|
||||
--font-size-ch: 2ch;
|
||||
--font-size-px: 42px;
|
||||
--font-size-em-via-var: var(--unregistered-em);
|
||||
--font-size-rem-via-var: var(--unregistered-rem);
|
||||
--font-size-ex-via-var: var(--unregistered-ex);
|
||||
--font-size-ch-via-var: var(--unregistered-ch);
|
||||
}
|
||||
|
||||
#target {
|
||||
|
@ -40,8 +55,13 @@
|
|||
|
||||
// Compute a dimension (e.g. 1em) given a certain fontSize.
|
||||
function compute_dimension(dimension, fontSize, element = ref) {
|
||||
element.style = `font-size: ${fontSize}; margin-bottom: ${dimension};`;
|
||||
return getComputedStyle(element).marginBottom;
|
||||
try {
|
||||
element.attributeStyleMap.set('font-size', fontSize);
|
||||
element.attributeStyleMap.set('margin-bottom', dimension);
|
||||
return getComputedStyle(element).marginBottom;
|
||||
} finally {
|
||||
element.attributeStyleMap.clear();
|
||||
}
|
||||
}
|
||||
|
||||
function assert_property_equals(name, value, element = target) {
|
||||
|
@ -51,6 +71,11 @@
|
|||
|
||||
let unsetFontSize = compute_dimension('1em', 'unset');
|
||||
|
||||
add_result_callback(function(){
|
||||
target.attributeStyleMap.clear();
|
||||
document.documentElement.attributeStyleMap.clear();
|
||||
});
|
||||
|
||||
test(function() {
|
||||
target.style = 'font-size: var(--font-size-px);';
|
||||
assert_property_equals('font-size', '42px');
|
||||
|
@ -84,10 +109,9 @@
|
|||
|
||||
test(function() {
|
||||
let root = document.documentElement;
|
||||
root.style = 'font-size: var(--font-size-rem);';
|
||||
let expected1rem = compute_dimension('1rem', 'unset', root);
|
||||
let expected2rem = compute_dimension('2rem', 'unset', root);
|
||||
root.style = 'font-size: unset;';
|
||||
root.style = 'font-size: var(--font-size-rem);';
|
||||
assert_property_equals('font-size', expected1rem, root);
|
||||
assert_property_equals('--font-size-rem', expected2rem, root);
|
||||
}, 'Lengths with rem units may not be referenced from font-size on root element');
|
||||
|
@ -119,4 +143,31 @@
|
|||
root.style = 'font-size: unset;';
|
||||
}, 'Fallback triggered when rem unit cycle is detected on root element');
|
||||
|
||||
test(function() {
|
||||
target.style = 'font-size: var(--font-size-em-via-var);';
|
||||
assert_property_equals('font-size', unsetFontSize);
|
||||
assert_property_equals('--font-size-em-via-var', compute_dimension('10em', 'unset'));
|
||||
}, 'Lengths with em units are detected via var references');
|
||||
|
||||
test(function() {
|
||||
target.style = 'font-size: var(--font-size-ex-via-var);';
|
||||
assert_property_equals('font-size', unsetFontSize);
|
||||
assert_property_equals('--font-size-ex-via-var', compute_dimension('10ex', 'unset'));
|
||||
}, 'Lengths with ex units are detected via var references');
|
||||
|
||||
test(function() {
|
||||
target.style = 'font-size: var(--font-size-ch-via-var);';
|
||||
assert_property_equals('font-size', unsetFontSize);
|
||||
assert_property_equals('--font-size-ch-via-var', compute_dimension('10ch', 'unset'));
|
||||
}, 'Lengths with ch units are detected via var references');
|
||||
|
||||
test(function() {
|
||||
let root = document.documentElement;
|
||||
let expected1rem = compute_dimension('1rem', 'unset', root);
|
||||
let expected10rem = compute_dimension('10rem', 'unset', root);
|
||||
root.style = 'font-size: var(--font-size-rem-via-var);';
|
||||
assert_property_equals('font-size', expected1rem, root);
|
||||
assert_property_equals('--font-size-rem-via-var', expected10rem, root);
|
||||
}, 'Lengths with rem units are detected via var references');
|
||||
|
||||
</script>
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
<!doctype html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Tests: calc() and division for integers</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-values-4/#calc-range">
|
||||
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/2337">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<div id="test"></div>
|
||||
<script>
|
||||
const TESTS = [
|
||||
{
|
||||
specified: "calc(2)",
|
||||
computed: "2",
|
||||
description: "Sanity",
|
||||
},
|
||||
{
|
||||
specified: "calc(4 / 2)",
|
||||
computed: "2",
|
||||
description: "Basic division works",
|
||||
},
|
||||
{
|
||||
specified: "calc(1 / 2)",
|
||||
computed: "1",
|
||||
description: "Rounds up if fractional part is >= 0.5",
|
||||
},
|
||||
{
|
||||
specified: "calc(0.5)",
|
||||
computed: "1",
|
||||
description: "Accepts numbers, and rounds",
|
||||
},
|
||||
{
|
||||
specified: "calc(6 / 2.0)",
|
||||
computed: "3",
|
||||
description: "Operation between <integer> and <number> works",
|
||||
},
|
||||
{
|
||||
specified: "calc(1 / 3)",
|
||||
computed: "0",
|
||||
description: "Rounds down if fractional part is < 0.5",
|
||||
},
|
||||
{
|
||||
specified: "calc(calc(1 / 3) * 3)",
|
||||
computed: "1",
|
||||
description: "Only rounds at the end of the conversion",
|
||||
}
|
||||
];
|
||||
|
||||
const testElement = document.getElementById("test");
|
||||
for (const { specified, computed, description } of TESTS) {
|
||||
test(function() {
|
||||
testElement.style.zIndex = "42"; // Just something that we know it's valid and makes tests not rely on order.
|
||||
testElement.style.zIndex = specified;
|
||||
assert_equals(getComputedStyle(testElement).zIndex, computed);
|
||||
}, description);
|
||||
}
|
||||
</script>
|
|
@ -22,7 +22,7 @@ else
|
|||
fi
|
||||
|
||||
rsync -avz --delete --filter=". ./sync-tests-filter" "$MOZTREE"/layout/reftests/w3c-css/submitted/ ./
|
||||
sed -i -e 's/^\(\(fails\|needs-focus\|random\|skip\|asserts\|slow\|require-or\|silentfail\|pref\|test-pref\|ref-pref\|fuzzy\)[^ ]* *\?\)\+//;/^default-preferences /d;s/ \?# \?\(TC: \)\?[bB]ug.*//;s/ # Initial mulet triage:.*//' $(find . -name reftest.list)
|
||||
sed -i -e 's/^\(\(fails\|needs-focus\|random\|skip\|asserts\|slow\|require-or\|silentfail\|pref\|test-pref\|ref-pref\|fuzzy\)[^ ]* *\?\)\+//;/^default-preferences /d;s/ \?# \?\(TC: \)\?[bB]ug.*//' $(find . -name reftest.list)
|
||||
sed -i -e 's/-moz-crisp-edges/pixelated/g;s/-moz-min-content/min-content/g;s/-moz-max-content/max-content/g' $(find . -regex ".*\.\(xht\|xhtml\|html\|css\)")
|
||||
git add -A .
|
||||
git commit -m"Sync Mozilla CSS tests as of https://hg.mozilla.org/mozilla-central/rev/$MOZREV ." -e .
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
<!doctype html>
|
||||
<title>fieldset percentage padding</title>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<style>
|
||||
body { margin: 0; }
|
||||
.outer { width: 500px; position: relative; }
|
||||
fieldset { width: 100px; padding: 10%; margin: 0; border: none; }
|
||||
.overflow { overflow: auto; }
|
||||
</style>
|
||||
<div class=outer>
|
||||
<fieldset>
|
||||
<div id=no-overflow>x</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
<div class=outer>
|
||||
<fieldset class=overflow>
|
||||
<div id=with-overflow>x</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
<script>
|
||||
const noOverflow = document.getElementById('no-overflow');
|
||||
const withOverflow = document.getElementById('with-overflow');
|
||||
for (const div of [noOverflow, withOverflow]) {
|
||||
test(() => {
|
||||
assert_equals(div.offsetLeft, 50, "offsetLeft");
|
||||
assert_equals(div.clientWidth, 100, "clientWidth");
|
||||
assert_equals(div.offsetTop, 50, "offsetTop");
|
||||
}, div.id);
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,34 @@
|
|||
<!doctype html>
|
||||
<title>legend align to justify-self</title>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<fieldset><legend>x</legend></fieldset>
|
||||
<fieldset><legend align=left>x</legend></fieldset>
|
||||
<fieldset><legend align=center>x</legend></fieldset>
|
||||
<fieldset><legend align=right>x</legend></fieldset>
|
||||
<fieldset><legend align=lEfT>x</legend></fieldset>
|
||||
<fieldset><legend align=cEnTeR>x</legend></fieldset>
|
||||
<fieldset><legend align=rIgHt>x</legend></fieldset>
|
||||
<!-- invalid values -->
|
||||
<fieldset><legend align=justify>x</legend></fieldset>
|
||||
<fieldset><legend align="left ">x</legend></fieldset>
|
||||
<!-- dir -->
|
||||
<fieldset><legend dir=ltr>x</legend></fieldset>
|
||||
<fieldset><legend dir=rtl>x</legend></fieldset>
|
||||
<fieldset dir=rtl><legend dir=ltr>x</legend></fieldset>
|
||||
<fieldset dir=rtl><legend dir=rtl>x</legend></fieldset>
|
||||
<script>
|
||||
for (const fieldset of document.querySelectorAll('fieldset')) {
|
||||
test(() => {
|
||||
const legend = fieldset.firstChild;
|
||||
const align = legend.align.toLowerCase();
|
||||
let expected = 'auto';
|
||||
switch (align) {
|
||||
case 'left': expected = 'left'; break;
|
||||
case 'center': expected = 'center'; break;
|
||||
case 'right': expected = 'right'; break;
|
||||
}
|
||||
assert_equals(getComputedStyle(legend).justifySelf, expected);
|
||||
}, `${fieldset.outerHTML}`)
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,13 @@
|
|||
<!doctype html>
|
||||
<title>Reference for legend block margins</title>
|
||||
<style>
|
||||
body { margin: 0; }
|
||||
.fieldset { margin: 2em 1em 1em 1em; border: 1em solid green; }
|
||||
.legend { position: absolute; margin-top: -1em; margin-left: 1em; background: white; height: 1em; }
|
||||
.inner { margin: 2em 1em 1em 1em; height: 1em; }
|
||||
</style>
|
||||
<p>There should be no red.</p>
|
||||
<div class=fieldset>
|
||||
<div class=legend>X</div>
|
||||
<div class=inner>Y</div>
|
||||
</div>
|
|
@ -0,0 +1,16 @@
|
|||
<!doctype html>
|
||||
<title>legend block margins</title>
|
||||
<link rel=match href=legend-block-margins-ref.html>
|
||||
<style>
|
||||
body { margin: 0; }
|
||||
fieldset { margin: 1em; border: 1em solid green; padding: 0; background: white; }
|
||||
legend { margin: 1em; height: 1em; padding: 0; }
|
||||
.inner { margin: 1em; height: 1em; }
|
||||
.behind { position: absolute; left: 1em; right: 1em; margin-top: 1em; height: 6em; background: red; z-index: -1; }
|
||||
</style>
|
||||
<p>There should be no red.</p>
|
||||
<div class=behind></div>
|
||||
<fieldset>
|
||||
<legend>X</legend>
|
||||
<div class=inner>Y</div>
|
||||
</fieldset>
|
|
@ -0,0 +1,20 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Reference for tall legend</title>
|
||||
<style>
|
||||
body, p { margin: 0; }
|
||||
.legend { position: absolute; height: 160px; margin-left: 20px; inline-size: fit-content; background: lime }
|
||||
.fieldset {
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
margin-top: calc((/* half legend height */ 160px / 2) - (/* half top border */ 20px / 2));
|
||||
background: green;
|
||||
height: 40px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
.hello { margin-top: 160px; margin-left: 20px; }
|
||||
</style>
|
||||
<p>There should be no red.</p>
|
||||
<div class=legend>X</div>
|
||||
<div class=fieldset></div>
|
||||
<div class=hello>HELLO</div>
|
|
@ -0,0 +1,20 @@
|
|||
<!DOCTYPE html>
|
||||
<title>tall legend</title>
|
||||
<link rel=match href=legend-tall-ref.html>
|
||||
<style>
|
||||
body, p { margin: 0; }
|
||||
fieldset { height: 30px; margin: 0; border: 20px solid green; padding: 0px; background: red; }
|
||||
legend { height: 160px; background: lime; padding: 0; }
|
||||
#behind {
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
margin-top: calc((/* half legend height */ 160px / 2) - (/* half top border */ 20px / 2));
|
||||
background: red;
|
||||
height: 40px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
</style>
|
||||
<p>There should be no red.</p>
|
||||
<div id=behind></div>
|
||||
<fieldset><legend>X</legend>HELLO</fieldset>
|
|
@ -1,138 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Goal Parameter on JavaScript MIME</title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
|
||||
<meta description="This test checks the Async property on a dynamically-created script element. By default it should be true." />
|
||||
<link rel="author" title="" href="http://www.microsoft.com/" />
|
||||
<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-script-async"/>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script type="module">
|
||||
|
||||
function makeTest({
|
||||
fileName,
|
||||
scriptType,
|
||||
contentType,
|
||||
shouldLoad
|
||||
}) {
|
||||
const elem = Object.assign(document.createElement("script"), {
|
||||
type: scriptType,
|
||||
src: `./serve-with-content-type.py?fn=${scriptType === "module" ? "is-module-goal.mjs" : "is-script-goal.js"}&ct=${contentType}`
|
||||
});
|
||||
const name = `${shouldLoad ? "Loads" : "Errors on"} type=${scriptType} when given content-type=${decodeURIComponent(contentType)}`;
|
||||
const t = async_test(name);
|
||||
if (!shouldLoad) {
|
||||
elem.onload = t.unreached_func("Script should not load.");
|
||||
elem.onerror = t.step_func_done();
|
||||
} else {
|
||||
elem.onload = t.step_func_done();
|
||||
elem.onerror = t.unreached_func("Script should load.");
|
||||
}
|
||||
document.body.appendChild(elem);
|
||||
}
|
||||
makeTest({
|
||||
scriptType: 'module',
|
||||
contentType: 'text%2Fjavascript%3Bgoal=',
|
||||
shouldLoad: false
|
||||
});
|
||||
makeTest({
|
||||
scriptType: 'text/javascript',
|
||||
contentType: 'text%2Fjavascript%3Bgoal=',
|
||||
shouldLoad: false
|
||||
});
|
||||
makeTest({
|
||||
scriptType: 'text/javascript',
|
||||
contentType: 'text%2Fhtml%3Bgoal=script',
|
||||
shouldLoad: false
|
||||
});
|
||||
makeTest({
|
||||
scriptType: 'text/javascript',
|
||||
contentType: 'text%2Fjavascript%3Bgoal=%20script',
|
||||
shouldLoad: false
|
||||
});
|
||||
makeTest({
|
||||
scriptType: 'text/javascript',
|
||||
contentType: 'text%2Fjavascript%3Bgoal=script%20',
|
||||
shouldLoad: false
|
||||
});
|
||||
makeTest({
|
||||
scriptType: 'module',
|
||||
contentType: 'text%2Fhtml%3Bgoal=module',
|
||||
shouldLoad: false
|
||||
});
|
||||
makeTest({
|
||||
scriptType: 'module',
|
||||
contentType: 'text%2Fjavascript%3Bgoal=%20module',
|
||||
shouldLoad: false
|
||||
});
|
||||
makeTest({
|
||||
scriptType: 'module',
|
||||
contentType: 'text%2Fjavascript%3Bgoal=module%20',
|
||||
shouldLoad: false
|
||||
});
|
||||
makeTest({
|
||||
scriptType: 'module',
|
||||
contentType: 'text%2Fjavascript%3Bgoal=%22%20module%22',
|
||||
shouldLoad: false
|
||||
});
|
||||
makeTest({
|
||||
scriptType: 'text/javascript',
|
||||
contentType: 'text%2Fjavascript%3Bgoal=script',
|
||||
shouldLoad: true
|
||||
});
|
||||
makeTest({
|
||||
scriptType: 'text/javascript',
|
||||
contentType: 'text%2Fjavascript%3Bgoal=SCRIPT',
|
||||
shouldLoad: true
|
||||
});
|
||||
makeTest({
|
||||
scriptType: 'text/javascript',
|
||||
contentType: 'text%2Fjavascript%3BGOAL=script',
|
||||
shouldLoad: true
|
||||
});
|
||||
makeTest({
|
||||
scriptType: 'text/javascript',
|
||||
contentType: 'text%2Fjavascript%3BGoal=Script',
|
||||
shouldLoad: true
|
||||
});
|
||||
makeTest({
|
||||
scriptType: 'text/javascript',
|
||||
contentType: 'text%2Fjavascript%3BgOal=script',
|
||||
shouldLoad: true
|
||||
});
|
||||
makeTest({
|
||||
scriptType: 'text/javascript',
|
||||
contentType: 'text%2Fjavascript%3Bgoal=scrIpt',
|
||||
shouldLoad: true
|
||||
});
|
||||
makeTest({
|
||||
scriptType: 'text/javascript',
|
||||
contentType: 'text%2Fjavascript%3Bgoal=%22script%22',
|
||||
shouldLoad: true
|
||||
});
|
||||
makeTest({
|
||||
scriptType: 'text/javascript',
|
||||
contentType: 'text%2Fjavascript%3Bgoal=%22%5Cs%5Cc%5Cr%5Ci%5Cp%5Ct%22',
|
||||
shouldLoad: true
|
||||
});
|
||||
makeTest({
|
||||
scriptType: 'module',
|
||||
contentType: 'text%2Fjavascript%3Bgoal=%22%5Cm%5Co%5Cd%5Cu%5Cl%5Ce%22',
|
||||
shouldLoad: true
|
||||
});
|
||||
makeTest({
|
||||
scriptType: 'module',
|
||||
contentType: 'text%2Fjavascript%3Bgoal=module',
|
||||
shouldLoad: true
|
||||
});
|
||||
makeTest({
|
||||
scriptType: 'module',
|
||||
contentType: 'text%2Fjavascript%3Bgoal=%22module%22',
|
||||
shouldLoad: true
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -59,6 +59,13 @@ partial interface ServiceWorkerGlobalScope {
|
|||
attribute EventHandler onpaymentrequest;
|
||||
};
|
||||
|
||||
dictionary PaymentMethodChangeResponse {
|
||||
DOMString error;
|
||||
PaymentCurrencyAmount total;
|
||||
FrozenArray<PaymentDetailsModifier> modifiers;
|
||||
object paymentMethodErrors;
|
||||
};
|
||||
|
||||
[Constructor(DOMString type, PaymentRequestEventInit eventInitDict), Exposed=ServiceWorker]
|
||||
interface PaymentRequestEvent : ExtendableEvent {
|
||||
readonly attribute USVString topOrigin;
|
||||
|
@ -68,7 +75,9 @@ interface PaymentRequestEvent : ExtendableEvent {
|
|||
readonly attribute object total;
|
||||
readonly attribute FrozenArray<PaymentDetailsModifier> modifiers;
|
||||
readonly attribute DOMString instrumentKey;
|
||||
readonly attribute boolean requestBillingAddress;
|
||||
Promise<WindowClient?> openWindow(USVString url);
|
||||
Promise<PaymentMethodChangeResponse?> changePaymentMethod(DOMString methodName, optional object? methodDetails = null);
|
||||
void respondWith(Promise<PaymentHandlerResponse> handlerResponsePromise);
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Pointer Events pointer lock tests</title>
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<link rel="stylesheet" type="text/css" href="../pointerevent_styles.css">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script type="text/javascript" src="../pointerevent_support.js"></script>
|
||||
<style>
|
||||
#testContainer {
|
||||
touch-action: none;
|
||||
user-select: none;
|
||||
position: relative;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
var lock_change_count = 0;
|
||||
var mouseeventMovements = []
|
||||
var pointereventMovements = []
|
||||
|
||||
function resetTestState() {
|
||||
}
|
||||
|
||||
function run() {
|
||||
var test_pointerEvent = setup_pointerevent_test("pointermove getCoalescedEvents when lock test", ['mouse']);
|
||||
var div1 = document.getElementById("target");
|
||||
|
||||
on_event(div1, 'pointerdown', function(event) {
|
||||
div1.requestPointerLock();
|
||||
});
|
||||
on_event(div1, 'pointermove', function(event) {
|
||||
if (document.pointerLockElement == div1) {
|
||||
test_pointerEvent.step(function() {
|
||||
assert_greater_than(event.getCoalescedEvents().length, 0, "document.pointerLockElement should have coalesced events.");
|
||||
document.exitPointerLock();
|
||||
test_pointerEvent.done();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload="run()">
|
||||
<h1>PointerMove getCoalescedEvent in locked state test</h1>
|
||||
<h2 id="pointerTypeDescription"></h2>
|
||||
<h4>
|
||||
Test Description: This test checks if pointerevent.getCoalescedEvent work correctly when pointer is locked.
|
||||
<ol>
|
||||
<li>Press left button down on the green rectangle to lock pointer.</li>
|
||||
<li>Move the mouse</li>
|
||||
</ol>
|
||||
</ol>
|
||||
|
||||
Test passes if the proper behavior of the events is observed.
|
||||
</h4>
|
||||
<div id="testContainer">
|
||||
<div id="target" style="width:800px;height:250px;background:green"></div>
|
||||
</div>
|
||||
<div class="spacer"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -11,9 +11,14 @@
|
|||
</head>
|
||||
<body onload="run()">
|
||||
<h2>pointerrawmove</h2>
|
||||
<h4>Test Description: This test checks if pointerrawmove is dispatched correctly while in pointerlock mode. </h4>
|
||||
<p>Click in the box (and accept the pointerlock permission if asked).</p>
|
||||
<p>Move your mouse.</p>
|
||||
<h4>Test Description: This test checks if pointerrawmove is dispatched correctly while in pointerlock mode.
|
||||
<ol>
|
||||
<li>Click in the black box (and accept the pointerlock permission if asked).</li>
|
||||
<li>Move your mouse.</li>
|
||||
<li>Click in the purple box inside the iframe</li>
|
||||
<li>Move your mouse.</li>
|
||||
</ol>
|
||||
</h4>
|
||||
<div id="target0"></div>
|
||||
<iframe id="innerframe" src="../resources/pointerevent_pointerrawmove_in_pointerlock-iframe.html"></iframe>
|
||||
<script>
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>pointermove</title>
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<link rel="stylesheet" type="text/css" href="../pointerevent_styles.css">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<!-- Additional helper script for common checks across event types -->
|
||||
<script type="text/javascript" src="../pointerevent_support.js"></script>
|
||||
</head>
|
||||
<body onload="run()">
|
||||
<h2>pointerlock</h2>
|
||||
<h4>Test Description: This test checks if pointermove is dispatched correctly while in pointerlock mode.
|
||||
<ol>
|
||||
<li>Click in the black box (and accept the pointerlock permission if asked).</li>
|
||||
<li>Move your mouse.</li>
|
||||
<li>Click in the purple box inside the iframe</li>
|
||||
<li>Move your mouse.</li>
|
||||
</ol>
|
||||
</h4>
|
||||
<div id="target0"></div>
|
||||
<iframe id="innerframe" src="resources/pointerevent_pointermove_in_pointerlock-iframe.html"></iframe>
|
||||
<script>
|
||||
window.name="outerframe";
|
||||
var test_pointermove = async_test("pointermove event received");
|
||||
|
||||
function run() {
|
||||
var target0 = document.getElementById("target0");
|
||||
var innerframe = document.getElementById('innerframe');
|
||||
var target1 = innerframe.contentDocument.getElementById('target1');
|
||||
innerframe.contentWindow.name = "innerframe";
|
||||
|
||||
on_event(document, "pointerlockchange", function(event) {
|
||||
if (document.pointerLockElement == target0) {
|
||||
on_event(target0, "pointermove", function (event) {
|
||||
test_pointermove.step(function() {
|
||||
assert_equals(event.view.name, "outerframe", "View attribute of pointermove should be the target frame.");
|
||||
}, "View attribute of pointermove should be the target frame.");
|
||||
document.exitPointerLock();
|
||||
|
||||
on_event(target1, "click", function(event) {
|
||||
target1.requestPointerLock();
|
||||
});
|
||||
|
||||
on_event(innerframe.contentDocument, "pointerlockchange", function(event) {
|
||||
if (innerframe.contentDocument.pointerLockElement == target1) {
|
||||
on_event(target1, "pointermove", function (event) {
|
||||
innerframe_pointermoveReceived = true;
|
||||
test_pointermove.step(function() {
|
||||
assert_equals(event.view.name, "innerframe", "View attribute of pointermove should be the target frame.");
|
||||
}, "View attribute of pointermove should be the target frame.");
|
||||
innerframe.contentDocument.exitPointerLock();
|
||||
test_pointermove.done();
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
on_event(target0, "click", function(event) {
|
||||
target0.requestPointerLock();
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
<div id="complete-notice">
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,98 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Pointermove on button state changes</title>
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<meta name="assert" content="When a pointer changes button state and does not produce a different event, the pointermove event must be dispatched."/>
|
||||
<link rel="stylesheet" type="text/css" href="../pointerevent_styles.css">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<!-- Additional helper script for common checks across event types -->
|
||||
<script type="text/javascript" src="../pointerevent_support.js"></script>
|
||||
</head>
|
||||
<body onload="run()">
|
||||
<h2>PointerMove</h2>
|
||||
<h4>Test Description: This test checks if pointermove event are triggered by button state changes
|
||||
<ol>
|
||||
<li>Lick on the black rectangle to lock the pointer </li>
|
||||
<li>Press a button and hold it</li>
|
||||
<li>Press a second button</li>
|
||||
<li>Release the second button</li>
|
||||
<li>Release the first button to complete the test</li>
|
||||
</ol>
|
||||
</h4>
|
||||
<div id="target0" style="background:black"></div>
|
||||
<script>
|
||||
var eventTested = false;
|
||||
var detected_pointertypes = {};
|
||||
var test_pointermove = async_test("pointer locked pointermove events received for button state changes");
|
||||
add_completion_callback(showPointerTypes);
|
||||
|
||||
var step = 0;
|
||||
var firstButton = 0;
|
||||
var pointer_locked = false;
|
||||
|
||||
function run() {
|
||||
var target0 = document.getElementById("target0");
|
||||
|
||||
// When a pointer changes button state and the circumstances produce no other pointer event, the pointermove event must be dispatched.
|
||||
// 5.2.6
|
||||
|
||||
on_event(target0, "pointerdown", function (event) {
|
||||
if (pointer_locked) {
|
||||
detected_pointertypes[event.pointerType] = true;
|
||||
test_pointermove.step(function() {assert_true(step === 0, "There must not be more than one pointer down event.");});
|
||||
if (step == 0) {
|
||||
step = 1;
|
||||
firstButton = event.buttons;
|
||||
}
|
||||
}
|
||||
});
|
||||
on_event(target0, "pointermove", function (event) {
|
||||
if (pointer_locked) {
|
||||
detected_pointertypes[event.pointerType] = true;
|
||||
|
||||
if (step == 1 && event.button != -1) { // second button pressed
|
||||
test_pointermove.step(function() {assert_true(event.buttons !== firstButton, "The pointermove event must be triggered by pressing a second button.");});
|
||||
test_pointermove.step(function() {assert_true((event.buttons & firstButton) != 0, "The first button must still be reported pressed.");});
|
||||
step = 2;
|
||||
} else if (step == 2 && event.button != -1) { // second button released
|
||||
test_pointermove.step(function() {assert_true(event.buttons === firstButton, "The pointermove event must be triggered by releasing the second button.");});
|
||||
step = 3;
|
||||
}
|
||||
}
|
||||
});
|
||||
on_event(target0, "pointerup", function (event) {
|
||||
if (pointer_locked) {
|
||||
detected_pointertypes[event.pointerType] = true;
|
||||
test_pointermove.step(function() {assert_true(step === 3, "The pointerup event must be triggered after pressing and releasing the second button.");});
|
||||
test_pointermove.step(function() {assert_true(event.buttons === 0, "The pointerup event must be triggered by releasing the last pressed button.");});
|
||||
document.exitPointerLock();
|
||||
test_pointermove.done();
|
||||
eventTested = true;
|
||||
} else {
|
||||
target0.requestPointerLock();
|
||||
}
|
||||
});
|
||||
on_event(document, 'pointerlockchange', function(event) {
|
||||
if (document.pointerLockElement == target0)
|
||||
pointer_locked = true;
|
||||
else
|
||||
pointer_locked = false;
|
||||
});
|
||||
on_event(target0, "mouseup", function (event) {
|
||||
event.preventDefault();
|
||||
});
|
||||
on_event(target0, "contextmenu", function (event) {
|
||||
event.preventDefault();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
<h1>Pointer Lock Pointer Events pointermove on button state changes Tests</h1>
|
||||
<div id="complete-notice">
|
||||
<p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
|
||||
<p>Refresh the page to run the tests again.</p>
|
||||
</div>
|
||||
<div id="log"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,10 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<link rel="stylesheet" type="text/css" href="../../pointerevent_styles.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="target1"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,155 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<title>Restrictions on return value from `test`</title>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
function makeTest(...bodies) {
|
||||
const closeScript = '<' + '/script>';
|
||||
let src = `
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Document title</title>
|
||||
<script src="/resources/testharness.js?${Math.random()}">${closeScript}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="log"></div>`;
|
||||
bodies.forEach((body) => {
|
||||
src += '<script>(' + body + ')();' + closeScript;
|
||||
});
|
||||
|
||||
const iframe = document.createElement('iframe');
|
||||
|
||||
document.body.appendChild(iframe);
|
||||
iframe.contentDocument.write(src);
|
||||
|
||||
return new Promise((resolve) => {
|
||||
window.addEventListener('message', function onMessage(e) {
|
||||
if (e.source !== iframe.contentWindow) {
|
||||
return;
|
||||
}
|
||||
if (!e.data || e.data.type !=='complete') {
|
||||
return;
|
||||
}
|
||||
window.removeEventListener('message', onMessage);
|
||||
resolve(e.data);
|
||||
});
|
||||
|
||||
iframe.contentDocument.close();
|
||||
}).then(({ tests, status }) => {
|
||||
const summary = {
|
||||
harness: {
|
||||
status: getEnumProp(status, status.status),
|
||||
message: status.message
|
||||
},
|
||||
tests: {}
|
||||
};
|
||||
|
||||
tests.forEach((test) => {
|
||||
summary.tests[test.name] = getEnumProp(test, test.status);
|
||||
});
|
||||
|
||||
return summary;
|
||||
});
|
||||
}
|
||||
|
||||
function getEnumProp(object, value) {
|
||||
for (let property in object) {
|
||||
if (!/^[A-Z]+$/.test(property)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (object[property] === value) {
|
||||
return property;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
promise_test(() => {
|
||||
return makeTest(
|
||||
() => {
|
||||
test(() => undefined, 'before');
|
||||
test(() => null, 'null');
|
||||
test(() => undefined, 'after');
|
||||
}
|
||||
).then(({harness, tests}) => {
|
||||
assert_equals(harness.status, 'ERROR');
|
||||
assert_equals(
|
||||
harness.message,
|
||||
'test named "null" inappropriately returned a value'
|
||||
);
|
||||
assert_equals(tests.before, 'PASS');
|
||||
assert_equals(tests.null, 'PASS');
|
||||
assert_equals(tests.after, 'PASS');
|
||||
});
|
||||
}, 'test returning `null`');
|
||||
|
||||
promise_test(() => {
|
||||
return makeTest(
|
||||
() => {
|
||||
test(() => undefined, 'before');
|
||||
test(() => ({}), 'object');
|
||||
test(() => undefined, 'after');
|
||||
}
|
||||
).then(({harness, tests}) => {
|
||||
assert_equals(harness.status, 'ERROR');
|
||||
assert_equals(
|
||||
harness.message,
|
||||
'test named "object" inappropriately returned a value'
|
||||
);
|
||||
assert_equals(tests.before, 'PASS');
|
||||
assert_equals(tests.object, 'PASS');
|
||||
assert_equals(tests.after, 'PASS');
|
||||
});
|
||||
}, 'test returning an ordinary object');
|
||||
|
||||
promise_test(() => {
|
||||
return makeTest(
|
||||
() => {
|
||||
test(() => undefined, 'before');
|
||||
test(() => ({ then() {} }), 'thenable');
|
||||
test(() => undefined, 'after');
|
||||
}
|
||||
).then(({harness, tests}) => {
|
||||
assert_equals(harness.status, 'ERROR');
|
||||
assert_equals(
|
||||
harness.message,
|
||||
'test named "thenable" inappropriately returned a value, consider using `promise_test` instead'
|
||||
);
|
||||
assert_equals(tests.before, 'PASS');
|
||||
assert_equals(tests.thenable, 'PASS');
|
||||
assert_equals(tests.after, 'PASS');
|
||||
});
|
||||
}, 'test returning a thenable object');
|
||||
|
||||
promise_test(() => {
|
||||
return makeTest(
|
||||
() => {
|
||||
test(() => undefined, 'before');
|
||||
test(() => {
|
||||
const iframe = document.createElement('iframe');
|
||||
iframe.setAttribute('sandbox', '');
|
||||
document.body.appendChild(iframe);
|
||||
return iframe.contentWindow;
|
||||
}, 'restricted');
|
||||
test(() => undefined, 'after');
|
||||
}
|
||||
).then(({harness, tests}) => {
|
||||
assert_equals(harness.status, 'ERROR');
|
||||
assert_equals(
|
||||
harness.message,
|
||||
'test named "restricted" inappropriately returned a value'
|
||||
);
|
||||
assert_equals(tests.before, 'PASS');
|
||||
assert_equals(tests.restricted, 'PASS');
|
||||
assert_equals(tests.after, 'PASS');
|
||||
});
|
||||
}, 'test returning a restricted object');
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -541,7 +541,22 @@ policies and contribution forms [3].
|
|||
var test_name = name ? name : test_environment.next_default_test_name();
|
||||
properties = properties ? properties : {};
|
||||
var test_obj = new Test(test_name, properties);
|
||||
test_obj.step(func, test_obj, test_obj);
|
||||
var value = test_obj.step(func, test_obj, test_obj);
|
||||
|
||||
if (value !== undefined) {
|
||||
var msg = "test named \"" + test_name +
|
||||
"\" inappropriately returned a value";
|
||||
|
||||
try {
|
||||
if (value && value.hasOwnProperty("then")) {
|
||||
msg += ", consider using `promise_test` instead";
|
||||
}
|
||||
} catch (err) {}
|
||||
|
||||
tests.status.status = tests.status.ERROR;
|
||||
tests.status.message = msg;
|
||||
}
|
||||
|
||||
if (test_obj.phase === test_obj.phases.STARTED) {
|
||||
test_obj.done();
|
||||
}
|
||||
|
|
|
@ -47,15 +47,17 @@ def create_parser():
|
|||
parser.add_argument("--yes", "-y", dest="prompt", action="store_false", default=True,
|
||||
help="Don't prompt before installing components")
|
||||
parser.add_argument("--install-browser", action="store_true",
|
||||
help="Install the browser")
|
||||
help="Install the browser from the release channel specified by --channel "
|
||||
"(or the nightly channel by default).")
|
||||
parser.add_argument("--channel", action="store",
|
||||
choices=install.channel_by_name.keys(),
|
||||
default=None, help='Name of browser release channel.'
|
||||
'"stable" and "release" are synonyms for the latest browser stable release,'
|
||||
'"nightly", "dev", "experimental", and "preview" are all synonyms for '
|
||||
'the latest available development release. For WebDriver installs, '
|
||||
'we attempt to select an appropriate, compatible, version for the '
|
||||
'latest browser release on the selected channel.')
|
||||
default=None, help='Name of browser release channel. '
|
||||
'"stable" and "release" are synonyms for the latest browser stable '
|
||||
'release, "nightly", "dev", "experimental", and "preview" are all '
|
||||
'synonyms for the latest available development release. (For WebDriver '
|
||||
'installs, we attempt to select an appropriate, compatible version for '
|
||||
'the latest browser release on the selected channel.) '
|
||||
'This flag overrides --browser-channel.')
|
||||
parser._add_container_actions(wptcommandline.create_parser())
|
||||
return parser
|
||||
|
||||
|
@ -249,6 +251,9 @@ class Chrome(BrowserSetup):
|
|||
kwargs["webdriver_binary"] = webdriver_binary
|
||||
else:
|
||||
raise WptrunError("Unable to locate or install chromedriver binary")
|
||||
if kwargs["browser_channel"] == "dev":
|
||||
logger.info("Automatically turning on experimental features for Chrome Dev")
|
||||
kwargs["binary_args"].append("--enable-experimental-web-platform-features")
|
||||
|
||||
|
||||
class ChromeAndroid(BrowserSetup):
|
||||
|
@ -273,6 +278,7 @@ class ChromeAndroid(BrowserSetup):
|
|||
else:
|
||||
raise WptrunError("Unable to locate or install chromedriver binary")
|
||||
|
||||
|
||||
class ChromeWebDriver(Chrome):
|
||||
name = "chrome_webdriver"
|
||||
browser_cls = browser.ChromeWebDriver
|
||||
|
@ -453,6 +459,7 @@ def setup_wptrunner(venv, prompt=True, install_browser=False, **kwargs):
|
|||
setup_cls.install_requirements()
|
||||
|
||||
if install_browser and not kwargs["channel"]:
|
||||
logger.info("--install-browser is given but --channel is not set, default to nightly channel")
|
||||
kwargs["channel"] = "nightly"
|
||||
|
||||
if kwargs["channel"]:
|
||||
|
@ -480,7 +487,7 @@ def setup_wptrunner(venv, prompt=True, install_browser=False, **kwargs):
|
|||
|
||||
|
||||
def run(venv, **kwargs):
|
||||
#Remove arguments that aren't passed to wptrunner
|
||||
# Remove arguments that aren't passed to wptrunner
|
||||
prompt = kwargs.pop("prompt", True)
|
||||
install_browser = kwargs.pop("install_browser", False)
|
||||
|
||||
|
|
|
@ -236,7 +236,7 @@ class WebDriverRun(object):
|
|||
def _run(self):
|
||||
try:
|
||||
self.result = True, self.func(self.protocol, self.url, self.timeout)
|
||||
except client.TimeoutException:
|
||||
except (client.TimeoutException, client.ScriptTimeoutException):
|
||||
self.result = False, ("EXTERNAL-TIMEOUT", None)
|
||||
except (socket.timeout, client.UnknownErrorException):
|
||||
self.result = False, ("CRASH", None)
|
||||
|
|
|
@ -113,7 +113,7 @@ test(t => {
|
|||
'existing animation, the target effect\'s timing is updated to reflect ' +
|
||||
'the current time of the new animation.');
|
||||
|
||||
test(async t => {
|
||||
promise_test(async t => {
|
||||
const anim = createDiv(t).animate(null, 100 * MS_PER_SEC);
|
||||
anim.updatePlaybackRate(2);
|
||||
assert_equals(anim.playbackRate, 1);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue