Update web-platform-tests to revision 2dda7b8c10c7566fa6167a32b09c85d51baf2a85

This commit is contained in:
WPT Sync Bot 2018-08-16 21:32:15 -04:00
parent 25ebde78aa
commit 8edc7686ef
129 changed files with 5280 additions and 820 deletions

View file

@ -8,8 +8,8 @@
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.
const script = 'resources/sw.js';
const scope = 'resources/scope' + location.pathname;
const script = 'service_workers/sw.js';
const scope = 'service_workers/' + location.pathname;
const serviceWorkerRegistration =
await service_worker_unregister_and_register(test, script, scope);
@ -21,7 +21,7 @@ promise_test(async test => {
await promise_rejects(
test, new TypeError(),
serviceWorkerRegistration.backgroundFetch.fetch(
uniqueId(), ['resources/sw.js']),
uniqueId(), ['resources/feature-name.txt']),
'fetch() must reject on pending and installing workers');
}, 'Background Fetch requires an activated Service Worker');
@ -44,7 +44,9 @@ backgroundFetchTest(async (test, backgroundFetch) => {
// 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/sw.js', {mode: 'no-cors'});
const request =
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');
@ -56,8 +58,8 @@ backgroundFetchTest(async (test, backgroundFetch) => {
// 6.3.1.9.2: If |bgFetchMap[id]| exists, reject |promise| with a TypeError
// and abort these steps.
return promise_rejects(test, new TypeError(), Promise.all([
backgroundFetch.fetch('my-id', 'resources/sw.js'),
backgroundFetch.fetch('my-id', 'resources/feature-name.txt')
backgroundFetch.fetch('my-id', 'resources/feature-name.txt?1'),
backgroundFetch.fetch('my-id', 'resources/feature-name.txt?2')
]));
}, 'IDs must be unique among active Background Fetch registrations');

View file

@ -8,8 +8,8 @@
// https://wicg.github.io/background-fetch/#background-fetch-manager-getIds
promise_test(async test => {
const script = 'resources/sw.js';
const scope = 'resources/scope' + location.pathname;
const script = 'service_workers/sw.js';
const scope = 'service_workers/' + location.pathname;
const serviceWorkerRegistration =
await service_worker_unregister_and_register(test, script, scope);

View file

@ -8,8 +8,8 @@
// https://wicg.github.io/background-fetch/#background-fetch-manager-get
promise_test(async test => {
const script = 'resources/sw.js';
const scope = 'resources/scope' + location.pathname;
const script = 'service_workers/sw.js';
const scope = 'service_workers/' + location.pathname;
const serviceWorkerRegistration =
await service_worker_unregister_and_register(test, script, scope);

View file

@ -1,3 +0,0 @@
spec: https://wicg.github.io/budget-api/
suggested_reviewers:
- beverloo

View file

@ -1,24 +0,0 @@
// META: script=/resources/WebIDLParser.js
// META: script=/resources/idlharness.js
'use strict';
// See https://wicg.github.io/budget-api/
idl_test(
['budget-api'],
['html'],
async idl_array => {
idl_array.add_objects({ BudgetService: ['navigator.budget'] });
if (self.Window) {
idl_array.add_objects({ Navigator: ['navigator'] });
} else {
idl_array.add_objects({ WorkerNavigator: ['navigator'] });
}
const budgetStates = await navigator.budget.getBudget();
if (budgetStates.length) {
self.budgetState = budgetStates[0];
idl_array.add_objects({ BudgetState: ['budgetState'] });
}
}
);

View file

@ -229,9 +229,9 @@ test(t => {
const expected = [
{ offset: 0, computedOffset: 0, easing: "ease",
color: "rgb(0, 0, 0)", composite: null },
color: "rgb(0, 0, 0)", composite: "auto" },
{ offset: 1, computedOffset: 1, easing: "ease",
color: "rgb(255, 255, 255)", composite: null },
color: "rgb(255, 255, 255)", composite: "auto" },
];
for (let i = 0; i < frames.length; i++) {
@ -299,10 +299,10 @@ test(t => {
assert_equals(frames.length, 2, "number of frames");
const expected = [
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
marginBottom: "8px", marginLeft: "8px",
marginRight: "8px", marginTop: "8px" },
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
marginBottom: "16px", marginLeft: "16px",
marginRight: "16px", marginTop: "16px" },
];
@ -323,9 +323,9 @@ test(t => {
assert_equals(frames.length, 2, "number of frames");
const expected = [
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
color: "rgb(0, 0, 255)" },
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
color: "rgb(255, 255, 255)" },
];
@ -345,9 +345,9 @@ test(t => {
assert_equals(frames.length, 2, "number of frames");
const expected = [
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
color: "rgb(255, 255, 255)" },
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
color: "rgb(0, 0, 255)" },
];
@ -367,11 +367,11 @@ test(t => {
assert_equals(frames.length, 3, "number of frames");
const expected = [
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
color: "rgb(255, 255, 255)" },
{ offset: 0.5, computedOffset: 0.5, easing: "ease", composite: null,
{ offset: 0.5, computedOffset: 0.5, easing: "ease", composite: "auto",
color: "rgb(0, 0, 255)" },
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
color: "rgb(255, 255, 255)" },
];
@ -391,9 +391,9 @@ test(t => {
assert_equals(frames.length, 2, "number of frames");
const expected = [
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
marginTop: '50px', marginBottom: '100px' },
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
marginTop: '250px', marginBottom: '200px' },
];
@ -413,13 +413,13 @@ test(t => {
assert_equals(frames.length, 4, "number of frames");
const expected = [
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
color: "rgb(0, 0, 0)", marginTop: "8px" },
{ offset: 0.25, computedOffset: 0.25, easing: "ease", composite: null,
{ offset: 0.25, computedOffset: 0.25, easing: "ease", composite: "auto",
color: "rgb(0, 0, 255)" },
{ offset: 0.75, computedOffset: 0.75, easing: "ease", composite: null,
{ offset: 0.75, computedOffset: 0.75, easing: "ease", composite: "auto",
marginTop: "12px" },
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
color: "rgb(255, 255, 255)", marginTop: "16px" },
];
@ -439,13 +439,13 @@ test(t => {
assert_equals(frames.length, 4, "number of frames");
const expected = [
{ offset: 0, computedOffset: 0, easing: "linear", composite: null,
{ offset: 0, computedOffset: 0, easing: "linear", composite: "auto",
color: "rgb(0, 0, 0)", marginTop: "8px" },
{ offset: 0.25, computedOffset: 0.25, easing: "steps(1)", composite: null,
{ offset: 0.25, computedOffset: 0.25, easing: "steps(1)", composite: "auto",
color: "rgb(0, 0, 255)" },
{ offset: 0.75, computedOffset: 0.75, easing: "ease-in", composite: null,
{ offset: 0.75, computedOffset: 0.75, easing: "ease-in", composite: "auto",
marginTop: "12px" },
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
color: "rgb(255, 255, 255)", marginTop: "16px" },
];
@ -465,9 +465,9 @@ test(t => {
assert_equals(frames.length, 2, "number of frames");
const expected = [
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
color: "rgb(0, 0, 0)", marginTop: "8px" },
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
color: "rgb(255, 255, 255)", marginTop: "16px" },
];
@ -487,11 +487,11 @@ test(t => {
assert_equals(frames.length, 3, "number of frames");
const expected = [
{ offset: 0, computedOffset: 0, easing: "steps(1)", composite: null,
{ offset: 0, computedOffset: 0, easing: "steps(1)", composite: "auto",
color: "rgb(0, 0, 0)", fontSize: "16px" },
{ offset: 0, computedOffset: 0, easing: "linear", composite: null,
{ offset: 0, computedOffset: 0, easing: "linear", composite: "auto",
marginTop: "8px", paddingLeft: "2px" },
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
color: "rgb(255, 255, 255)", fontSize: "32px", marginTop: "16px",
paddingLeft: "4px" },
];
@ -512,11 +512,11 @@ test(t => {
assert_equals(frames.length, 3, "number of frames");
const expected = [
{ offset: 0, computedOffset: 0, easing: "steps(1)", composite: null,
{ offset: 0, computedOffset: 0, easing: "steps(1)", composite: "auto",
marginTop: "0px", marginRight: "0px", marginBottom: "0px" },
{ offset: 0.5, computedOffset: 0.5, easing: "steps(1)", composite: null,
{ offset: 0.5, computedOffset: 0.5, easing: "steps(1)", composite: "auto",
marginTop: "10px", marginRight: "10px", marginBottom: "10px" },
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
marginTop: "20px", marginRight: "20px", marginBottom: "20px" },
];
@ -536,17 +536,17 @@ test(t => {
assert_equals(frames.length, 6, "number of frames");
const expected = [
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
paddingTop: "30px" },
{ offset: 0.5, computedOffset: 0.5, easing: "ease", composite: null,
{ offset: 0.5, computedOffset: 0.5, easing: "ease", composite: "auto",
paddingTop: "20px" },
{ offset: 0.75, computedOffset: 0.75, easing: "ease", composite: null,
{ offset: 0.75, computedOffset: 0.75, easing: "ease", composite: "auto",
paddingTop: "20px" },
{ offset: 0.85, computedOffset: 0.85, easing: "ease", composite: null,
{ offset: 0.85, computedOffset: 0.85, easing: "ease", composite: "auto",
paddingTop: "30px" },
{ offset: 0.851, computedOffset: 0.851, easing: "ease", composite: null,
{ offset: 0.851, computedOffset: 0.851, easing: "ease", composite: "auto",
paddingTop: "60px" },
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
paddingTop: "70px" },
];
@ -568,9 +568,9 @@ test(t => {
assert_equals(frames.length, 2, "number of frames");
const expected = [
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
filter: "none" },
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
filter: "blur(5px) sepia(60%) saturate(30%)" },
];
@ -589,9 +589,9 @@ test(t => {
assert_equals(frames.length, 2, "number of frames");
const expected = [
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
filter: "drop-shadow(rgb(0, 255, 0) 10px 10px 10px)" },
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
filter: "drop-shadow(rgb(255, 0, 0) 50px 30px 10px)" },
];
@ -617,11 +617,11 @@ test(t => {
assert_equals(frames.length, 2, "number of frames");
const expected = [
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
textShadow: "rgb(0, 0, 0) 1px 1px 2px,"
+ " rgb(0, 0, 255) 0px 0px 16px,"
+ " rgb(0, 0, 255) 0px 0px 3.2px" },
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
textShadow: "none" },
];
@ -644,9 +644,9 @@ test(t => {
assert_equals(frames.length, 2, "number of frames");
const expected = [
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
backgroundSize: "auto auto" },
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
backgroundSize: "50% auto, 6px auto, contain" },
];
@ -676,9 +676,9 @@ test(t => {
assert_equals(frames.length, 2, "number of frames");
const expected = [
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
transform: "none" },
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
transform: "translate(100px, 0px)" },
];
for (let i = 0; i < frames.length; i++) {
@ -696,12 +696,12 @@ test(t => {
assert_equals(frames.length, 2, "number of frames");
const expected = [
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
marginBottom: "0px",
marginLeft: "0px",
marginRight: "0px",
marginTop: "0px" },
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
marginBottom: "100px",
marginLeft: "100px",
marginRight: "100px",
@ -722,9 +722,9 @@ test(t => {
assert_equals(frames.length, 2, "number of frames");
const expected = [
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
color: "rgb(0, 0, 0)" },
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
color: "rgb(0, 255, 0)" },
];
for (let i = 0; i < frames.length; i++) {
@ -742,9 +742,9 @@ test(t => {
assert_equals(frames.length, 2, "number of frames");
const expected = [
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
transform: "translate(100px, 0px)" },
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
transform: "none" },
];
for (let i = 0; i < frames.length; i++) {

View file

@ -0,0 +1,39 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Grid Layout Test: Content Distribution and the track sizing algorithm</title>
<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-grid/#grid-align">
<link rel="help" href="https://drafts.csswg.org/css-align/#content-distribution">
<link rel="help" href="https://drafts.csswg.org/css-align/#valdef-align-content-space-around">
<link rel="stylesheet" href="../../support/alignment.css">
<meta name="flags" content="ahem">
<meta name="assert" content="Content Distribution offset doesn't account for tracks with non-spanning items.">
<style>
.grid {
display: inline-grid;
background: grey;
grid-template-columns: 100px;
font: 20px/1 Ahem;
width: 200px;
}
.item1 {
background: green;
grid-column: 1;
grid-row: 1;
}
.item2 {
background: blue;
grid-column: 1;
grid-row: 2;
}
</style>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/check-layout-th.js"></script>
<body onload="checkLayout('.grid')">
<div class="grid justifyContentSpaceAround" data-expected-width="200" data-expected-height="60">
<div class="item1" data-expected-width="100" data-expected-height="40">XXXX XXX</div>
<div class="item2" data-expected-width="100" data-expected-height="20">XXX</div>
</div>
</body>

View file

@ -0,0 +1,39 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Grid Layout Test: Content Distribution and the track sizing algorithm</title>
<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-grid/#grid-align">
<link rel="help" href="https://drafts.csswg.org/css-align/#content-distribution">
<link rel="help" href="https://drafts.csswg.org/css-align/#valdef-align-content-space-between">
<link rel="stylesheet" href="../../support/alignment.css">
<meta name="flags" content="ahem">
<meta name="assert" content="Content Distribution offset doesn't account for relative sized tracks with non-spanning items.">
<style>
.grid {
display: inline-grid;
background: grey;
grid-template-columns: 50%;
font: 20px/1 Ahem;
}
.item1 {
background: green;
grid-column: 1;
grid-row: 1;
}
.item2 {
background: blue;
grid-column: 2;
grid-row: 1;
}
</style>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/check-layout-th.js"></script>
<body onload="checkLayout('.grid')">
<div class="grid justifyContentSpaceBetween" data-expected-width="220" data-expected-height="40">
<div class="item1" data-expected-width="110" data-expected-height="40">XXXX XXX</div>
<div class="item2" data-expected-width="60" data-expected-height="40">XXX</div>
</div>
</body>

View file

@ -0,0 +1,27 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>CSS Test: counter-* properties with a calc() expression</title>
<link rel="author" title="Ondřej Žára" href="https://ondras.zarovi.cz/"/>
<style type="text/css">
body {
white-space: nowrap;
}
</style>
</head>
<body>
<p>The following two lines should be the same:</p>
<div id="test">
<span id="a">8</span>
<span id="b">10</span>
</div>
<div id="reference">
<span>8</span>
<span>10</span>
</div>
</body>
</html>

View file

@ -0,0 +1,42 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>CSS Test: counter-* properties with a calc() expression</title>
<link rel="author" title="Ondřej Žára" href="https://ondras.zarovi.cz/"/>
<link rel="help" href="https://www.w3.org/TR/CSS21/generate.html#counters"/>
<link rel="help" href="https://www.w3.org/TR/CSS21/generate.html#propdef-content"/>
<link rel="help" href="https://www.w3.org/TR/CSS21/syndata.html#counter"/>
<link rel="help" href="https://www.w3.org/TR/css-values-3/#calc-notation"/>
<link rel="help" href="https://www.w3.org/TR/css-lists-3/#counter-properties"/>
<link rel="match" href="calc-in-counter-001-ref.xhtml"/>
<style type="text/css">
body {
white-space: nowrap;
}
#a { counter-reset: a calc(3 + 5); }
#a::before { content: counter(a); }
#b { counter-reset: b 0; counter-increment: b calc(4 + 6); }
#b::before { content: counter(b); }
</style>
</head>
<body>
<p>The following two lines should be the same:</p>
<div id="test">
<span id="a"></span>
<span id="b"></span>
</div>
<div id="reference">
<span>8</span>
<span>10</span>
</div>
</body>
</html>

View file

@ -138,5 +138,33 @@
<div class="b" style="margin-top: 30px"><div class="fixedSizeChild"/></div>
<div class="c" style="margin-top: 30px"/>
</div>
<!-- start -->
<div class="flexbox">
<div class="a"/>
</div>
<div class="flexbox">
<div class="b"><div class="fixedSizeChild"/></div>
<div class="a"/>
</div>
<div class="flexbox">
<div class="c"/>
<div class="b"><div class="fixedSizeChild"/></div>
<div class="a"/>
</div>
<!-- end -->
<div class="flexbox">
<div class="a" style="margin-top: 190px"/>
</div>
<div class="flexbox">
<div class="b" style="margin-top: 160px"><div class="fixedSizeChild"/></div>
<div class="a"/>
</div>
<div class="flexbox">
<div class="c" style="margin-top: 120px"/>
<div class="b"><div class="fixedSizeChild"/></div>
<div class="a"/>
</div>
</body>
</html>

View file

@ -147,5 +147,33 @@
<div class="b"><div class="fixedSizeChild"/></div>
<div class="c"/>
</div>
<!-- start -->
<div class="flexbox" style="align-content: start; flex-wrap: wrap-reverse">
<div class="a"/>
</div>
<div class="flexbox" style="align-content: start; flex-wrap: wrap-reverse">
<div class="a"/>
<div class="b"><div class="fixedSizeChild"/></div>
</div>
<div class="flexbox" style="align-content: start; flex-wrap: wrap-reverse">
<div class="a"/>
<div class="b"><div class="fixedSizeChild"/></div>
<div class="c"/>
</div>
<!-- end -->
<div class="flexbox" style="align-content: end; flex-wrap: wrap-reverse">
<div class="a"/>
</div>
<div class="flexbox" style="align-content: end; flex-wrap: wrap-reverse">
<div class="a"/>
<div class="b"><div class="fixedSizeChild"/></div>
</div>
<div class="flexbox" style="align-content: end; flex-wrap: wrap-reverse">
<div class="a"/>
<div class="b"><div class="fixedSizeChild"/></div>
<div class="c"/>
</div>
</body>
</html>

View file

@ -148,5 +148,33 @@
<div class="b"><div class="fixedSizeChild"/></div>
<div class="c"/>
</div>
<!-- start -->
<div class="flexbox" style="align-content: start; flex-wrap: wrap-reverse">
<div class="a"/>
</div>
<div class="flexbox" style="align-content: start; flex-wrap: wrap-reverse">
<div class="a"/>
<div class="b"><div class="fixedSizeChild"/></div>
</div>
<div class="flexbox" style="align-content: start; flex-wrap: wrap-reverse">
<div class="a"/>
<div class="b"><div class="fixedSizeChild"/></div>
<div class="c"/>
</div>
<!-- end -->
<div class="flexbox" style="align-content: end; flex-wrap: wrap-reverse">
<div class="a"/>
</div>
<div class="flexbox" style="align-content: end; flex-wrap: wrap-reverse">
<div class="a"/>
<div class="b"><div class="fixedSizeChild"/></div>
</div>
<div class="flexbox" style="align-content: end; flex-wrap: wrap-reverse">
<div class="a"/>
<div class="b"><div class="fixedSizeChild"/></div>
<div class="c"/>
</div>
</body>
</html>

View file

@ -141,5 +141,33 @@
<div class="b" style="margin-left: 30px"><div class="fixedSizeChild"/></div>
<div class="c" style="margin-left: 30px"/>
</div>
<!-- start -->
<div class="flexbox">
<div class="a"/>
</div>
<div class="flexbox">
<div class="b"><div class="fixedSizeChild"/></div>
<div class="a"/>
</div>
<div class="flexbox">
<div class="c"/>
<div class="b"><div class="fixedSizeChild"/></div>
<div class="a"/>
</div>
<!-- end -->
<div class="flexbox">
<div class="a" style="margin-left: 190px"/>
</div>
<div class="flexbox">
<div class="b" style="margin-left: 160px"><div class="fixedSizeChild"/></div>
<div class="a"/>
</div>
<div class="flexbox">
<div class="c" style="margin-left: 120px"/>
<div class="b"><div class="fixedSizeChild"/></div>
<div class="a"/>
</div>
</body>
</html>

View file

@ -147,5 +147,33 @@
<div class="b"><div class="fixedSizeChild"/></div>
<div class="c"/>
</div>
<!-- start -->
<div class="flexbox" style="align-content: start; flex-wrap: wrap-reverse">
<div class="a"/>
</div>
<div class="flexbox" style="align-content: start; flex-wrap: wrap-reverse">
<div class="a"/>
<div class="b"><div class="fixedSizeChild"/></div>
</div>
<div class="flexbox" style="align-content: start; flex-wrap: wrap-reverse">
<div class="a"/>
<div class="b"><div class="fixedSizeChild"/></div>
<div class="c"/>
</div>
<!-- end -->
<div class="flexbox" style="align-content: end; flex-wrap: wrap-reverse">
<div class="a"/>
</div>
<div class="flexbox" style="align-content: end; flex-wrap: wrap-reverse">
<div class="a"/>
<div class="b"><div class="fixedSizeChild"/></div>
</div>
<div class="flexbox" style="align-content: end; flex-wrap: wrap-reverse">
<div class="a"/>
<div class="b"><div class="fixedSizeChild"/></div>
<div class="c"/>
</div>
</body>
</html>

View file

@ -148,5 +148,33 @@
<div class="b"><div class="fixedSizeChild"/></div>
<div class="c"/>
</div>
<!-- start -->
<div class="flexbox" style="align-content: start; flex-wrap: wrap-reverse">
<div class="a"/>
</div>
<div class="flexbox" style="align-content: start; flex-wrap: wrap-reverse">
<div class="a"/>
<div class="b"><div class="fixedSizeChild"/></div>
</div>
<div class="flexbox" style="align-content: start; flex-wrap: wrap-reverse">
<div class="a"/>
<div class="b"><div class="fixedSizeChild"/></div>
<div class="c"/>
</div>
<!-- end -->
<div class="flexbox" style="align-content: end; flex-wrap: wrap-reverse">
<div class="a"/>
</div>
<div class="flexbox" style="align-content: end; flex-wrap: wrap-reverse">
<div class="a"/>
<div class="b"><div class="fixedSizeChild"/></div>
</div>
<div class="flexbox" style="align-content: end; flex-wrap: wrap-reverse">
<div class="a"/>
<div class="b"><div class="fixedSizeChild"/></div>
<div class="c"/>
</div>
</body>
</html>

View file

@ -0,0 +1,173 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>CSS Reftest Reference</title>
<link rel="author" title="Mihir Iyer" href="mailto:miyer@mozilla.com"/>
<style>
div.flexbox {
width: 200px;
margin-bottom: 2px;
background: lightgray;
height: 20px;
clear: all;
}
div.a {
width: 10px;
height: 20px;
background: lightgreen;
float: left;
}
div.b {
width: 30px;
height: 20px;
background: pink;
float: left;
}
div.c {
width: 40px;
height: 20px;
background: orange;
float: left;
}
/* Inside of 'b': */
div.fixedSizeChild {
width: 30px;
height: 10px;
background: purple;
}
</style>
</head>
<body>
<!-- default (stretch) -->
<div class="flexbox">
<div class="a"/>
</div>
<div class="flexbox">
<div class="a"/>
<div class="b" style="margin-left:80px; width:110px"><div class="fixedSizeChild"/></div>
</div>
<div class="flexbox">
<div class="a"/>
<div class="b" style="margin-left: 40px; width: 70px"><div class="fixedSizeChild"/></div>
<div class="c"/>
</div>
<!-- flex-start -->
<div class="flexbox">
<div class="a"/>
</div>
<div class="flexbox">
<div class="a"/>
<div class="b"><div class="fixedSizeChild"/></div>
</div>
<div class="flexbox">
<div class="a"/>
<div class="b"><div class="fixedSizeChild"/></div>
<div class="c"/>
</div>
<!-- flex-end -->
<div class="flexbox">
<div class="a" style="margin-left: 190px"/>
</div>
<div class="flexbox">
<div class="a" style="margin-left: 160px"/>
<div class="b"><div class="fixedSizeChild"/></div>
</div>
<div class="flexbox">
<div class="a" style="margin-left: 120px"/>
<div class="b"><div class="fixedSizeChild"/></div>
<div class="c"/>
</div>
<!-- center -->
<div class="flexbox">
<div class="a" style="margin-left: 95px"/>
</div>
<div class="flexbox">
<div class="a" style="margin-left: 80px"/>
<div class="b"><div class="fixedSizeChild"/></div>
</div>
<div class="flexbox">
<div class="a" style="margin-left: 60px"/>
<div class="b"><div class="fixedSizeChild"/></div>
<div class="c"/>
</div>
<!-- space-between -->
<div class="flexbox">
<div class="a"/>
</div>
<div class="flexbox">
<div class="a"/>
<div class="b" style="margin-left: 160px"><div class="fixedSizeChild"/></div>
</div>
<div class="flexbox">
<div class="a"/>
<div class="b" style="margin-left: 60px"><div class="fixedSizeChild"/></div>
<div class="c" style="margin-left: 60px"/>
</div>
<!-- space-around -->
<div class="flexbox">
<div class="a" style="margin-left: 95px"/>
</div>
<div class="flexbox">
<div class="a" style="margin-left: 40px"/>
<div class="b" style="margin-left: 80px"><div class="fixedSizeChild"/></div>
</div>
<div class="flexbox">
<div class="a" style="margin-left: 20px"/>
<div class="b" style="margin-left: 40px"><div class="fixedSizeChild"/></div>
<div class="c" style="margin-left: 40px"/>
</div>
<!-- space-evenly -->
<div class="flexbox">
<div class="a" style="margin-left: 95px"/>
</div>
<div class="flexbox">
<div class="a" style="margin-left: calc(160px / 3)"/>
<div class="b" style="margin-left: calc(160px / 3)"><div class="fixedSizeChild"/></div>
</div>
<div class="flexbox">
<div class="a" style="margin-left: 30px"/>
<div class="b" style="margin-left: 30px"><div class="fixedSizeChild"/></div>
<div class="c" style="margin-left: 30px"/>
</div>
<!-- start -->
<div class="flexbox">
<div class="a"/>
</div>
<div class="flexbox">
<div class="b"><div class="fixedSizeChild"/></div>
<div class="a"/>
</div>
<div class="flexbox">
<div class="c"/>
<div class="b"><div class="fixedSizeChild"/></div>
<div class="a"/>
</div>
<!-- end -->
<div class="flexbox">
<div class="a" style="margin-left: 190px"/>
</div>
<div class="flexbox">
<div class="b" style="margin-left: 160px"><div class="fixedSizeChild"/></div>
<div class="a"/>
</div>
<div class="flexbox">
<div class="c" style="margin-left: 120px"/>
<div class="b"><div class="fixedSizeChild"/></div>
<div class="a"/>
</div>
</body>
</html>

View file

@ -0,0 +1,179 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!-- Testcase with a series of horizontal flex containers, with 1-3 flex lines,
testing each possible value of the 'align-content' property. -->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>CSS Test: Testing 'align-content' in a vertical writing-mode flex container</title>
<link rel="author" title="Mihir Iyer" href="mailto:miyer@mozilla.com"/>
<link rel="help" href="http://www.w3.org/TR/css-flexbox-1/#align-content-property"/>
<link rel="match" href="flexbox-align-content-wmvert-001-ref.xhtml"/>
<style>
div.flexbox {
width: 200px;
height: 20px; /* Short, to force us to wrap */
display: flex;
flex-wrap: wrap;
margin-bottom: 2px;
background: lightgray;
writing-mode: vertical-lr;
}
div.a {
width: 10px;
height: 20px;
flex: none;
background: lightgreen;
}
div.b {
width: auto;
height: 20px; /* height comes from contents */
flex: none;
background: pink;
}
div.c {
width: 40px;
height: 20px;
flex: none;
background: orange;
}
/* Inside of 'b': */
div.fixedSizeChild {
width: 30px;
height: 10px;
background: purple;
}
</style>
</head>
<body>
<!-- default (stretch) -->
<div class="flexbox">
<div class="a"/>
</div>
<div class="flexbox">
<div class="a"/>
<div class="b"><div class="fixedSizeChild"/></div>
</div>
<div class="flexbox">
<div class="a"/>
<div class="b"><div class="fixedSizeChild"/></div>
<div class="c"/>
</div>
<!-- flex-start -->
<div class="flexbox" style="align-content: flex-start">
<div class="a"/>
</div>
<div class="flexbox" style="align-content: flex-start">
<div class="a"/>
<div class="b"><div class="fixedSizeChild"/></div>
</div>
<div class="flexbox" style="align-content: flex-start">
<div class="a"/>
<div class="b"><div class="fixedSizeChild"/></div>
<div class="c"/>
</div>
<!-- flex-end -->
<div class="flexbox" style="align-content: flex-end">
<div class="a"/>
</div>
<div class="flexbox" style="align-content: flex-end">
<div class="a"/>
<div class="b"><div class="fixedSizeChild"/></div>
</div>
<div class="flexbox" style="align-content: flex-end">
<div class="a"/>
<div class="b"><div class="fixedSizeChild"/></div>
<div class="c"/>
</div>
<!-- center -->
<div class="flexbox" style="align-content: center">
<div class="a"/>
</div>
<div class="flexbox" style="align-content: center">
<div class="a"/>
<div class="b"><div class="fixedSizeChild"/></div>
</div>
<div class="flexbox" style="align-content: center">
<div class="a"/>
<div class="b"><div class="fixedSizeChild"/></div>
<div class="c"/>
</div>
<!-- space-between -->
<div class="flexbox" style="align-content: space-between">
<div class="a"/>
</div>
<div class="flexbox" style="align-content: space-between">
<div class="a"/>
<div class="b"><div class="fixedSizeChild"/></div>
</div>
<div class="flexbox" style="align-content: space-between">
<div class="a"/>
<div class="b"><div class="fixedSizeChild"/></div>
<div class="c"/>
</div>
<!-- space-around -->
<div class="flexbox" style="align-content: space-around">
<div class="a"/>
</div>
<div class="flexbox" style="align-content: space-around">
<div class="a"/>
<div class="b"><div class="fixedSizeChild"/></div>
</div>
<div class="flexbox" style="align-content: space-around">
<div class="a"/>
<div class="b"><div class="fixedSizeChild"/></div>
<div class="c"/>
</div>
<!-- space-evenly -->
<div class="flexbox" style="align-content: space-evenly">
<div class="a"/>
</div>
<div class="flexbox" style="align-content: space-evenly">
<div class="a"/>
<div class="b"><div class="fixedSizeChild"/></div>
</div>
<div class="flexbox" style="align-content: space-evenly">
<div class="a"/>
<div class="b"><div class="fixedSizeChild"/></div>
<div class="c"/>
</div>
<!-- start -->
<div class="flexbox" style="align-content: start; flex-wrap: wrap-reverse">
<div class="a"/>
</div>
<div class="flexbox" style="align-content: start; flex-wrap: wrap-reverse">
<div class="a"/>
<div class="b"><div class="fixedSizeChild"/></div>
</div>
<div class="flexbox" style="align-content: start; flex-wrap: wrap-reverse">
<div class="a"/>
<div class="b"><div class="fixedSizeChild"/></div>
<div class="c"/>
</div>
<!-- end -->
<div class="flexbox" style="align-content: end; flex-wrap: wrap-reverse">
<div class="a"/>
</div>
<div class="flexbox" style="align-content: end; flex-wrap: wrap-reverse">
<div class="a"/>
<div class="b"><div class="fixedSizeChild"/></div>
</div>
<div class="flexbox" style="align-content: end; flex-wrap: wrap-reverse">
<div class="a"/>
<div class="b"><div class="fixedSizeChild"/></div>
<div class="c"/>
</div>
</body>
</html>

View file

@ -22,7 +22,7 @@
.flexbox > div { float: left }
.flex-start, .flex-end, .center, .baseline, .stretch,
.auto, .unspecified, .initial, .inherit {
.auto, .unspecified, .initial, .inherit, .self-start, .self-end {
width: 40px;
margin: 1px 2px 3px 4px;
border-width: 2px 3px 4px 5px;
@ -53,6 +53,16 @@
.stretch {
background: pink;
}
.self-start {
background: yellow;
}
.self-end {
background: purple;
}
.wmvertrev {
writing-mode: vertical-lr;
direction: rtl;
}
</style>
</head>
<body>
@ -81,5 +91,12 @@
<div class="stretch" style="height: 182px">stretch</div>
<div class="stretch big">a b c d e f</div>
</div>
<br/>
<div class="flexbox">
<div class="self-start">self-start</div>
<div class="self-start big">a b c d e f</div>
<div class="self-end wmvertrev">self-end</div>
<div class="self-end wmvertrev big">a b c d e f</div>
</div>
</body>
</html>

View file

@ -57,6 +57,18 @@
background: pink;
align-self: stretch;
}
.self-start {
background: yellow;
align-self: self-start;
}
.self-end {
background: purple;
align-self: self-end;
}
.wmvertrev {
writing-mode: vertical-lr;
direction: rtl;
}
</style>
</head>
<body>
@ -75,5 +87,12 @@
<div class="stretch">stretch</div>
<div class="stretch big">a b c d e f</div>
</div>
<br/>
<div class="flexbox">
<div class="self-start">self-start</div>
<div class="self-start big">a b c d e f</div>
<div class="self-end wmvertrev">self-end</div>
<div class="self-end wmvertrev big">a b c d e f</div>
</div>
</body>
</html>

View file

@ -18,7 +18,8 @@
font-size: 10px;
}
.flex-start, .flex-end, .center, .baseline, .stretch {
.flex-start, .flex-end, .center, .baseline, .stretch,
.self-start, .self-end {
clear: both;
margin: 1px 2px 3px 4px;
border-width: 2px 3px 4px 5px;
@ -58,6 +59,16 @@
.stretch {
background: pink;
}
.self-start {
background: yellow;
float: right;
text-align: right;
}
.self-end {
background: purple;
float: left;
text-align: right;
}
.clearFloats { clear: both }
</style>
</head>
@ -86,5 +97,11 @@
we use floats or inline-blocks, whose margins don't collapse. -->
<div class="stretch big" style="margin-top: 4px">a b c d e f</div>
</div>
<div class="flexbox">
<div class="self-start">self-start</div>
<div class="self-start big">a b c d e f</div>
<div class="self-end">self-end</div>
<div class="self-end big">a b c d e f</div>
</div>
</body>
</html>

View file

@ -56,6 +56,17 @@
background: pink;
align-self: stretch;
}
.self-start {
background: yellow;
align-self: self-start;
}
.self-end {
background: purple;
align-self: self-end;
}
.dirrtl {
direction: rtl;
}
</style>
</head>
<body>
@ -73,5 +84,11 @@
<div class="stretch">stretch</div>
<div class="stretch big">a b c d e f</div>
</div>
<div class="flexbox">
<div class="self-start dirrtl">self-start</div>
<div class="self-start dirrtl big">a b c d e f</div>
<div class="self-end dirrtl">self-end</div>
<div class="self-end dirrtl big">a b c d e f</div>
</div>
</body>
</html>

View file

@ -0,0 +1,105 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!-- Reference case for align-items / align-self behavior, using blocks in
place of flex items and using float and width keywords to emulate the
align-items / align-self properties. -->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>CSS Reftest Reference</title>
<link rel="author" title="Mihir Iyer" href="mailto:miyer@mozilla.com"/>
<style>
.flexbox {
border: 1px dashed blue;
width: 200px;
float: left;
font-size: 10px;
direction: rtl;
}
.flex-start, .flex-end, .center, .baseline, .stretch, .self-start, .self-end {
clear: both;
margin: 1px 2px 3px 4px;
border-width: 2px 3px 4px 5px;
padding: 3px 4px 5px 6px;
border-style: dotted;
}
div.big {
font-size: 20px;
width: 50px;
}
/* Classes for each of the various align-self values */
.flex-start {
background: lime;
float: right;
}
.flex-end {
background: orange;
float: left;
}
<!-- We center shrinkwrapped text by putting it into an inline-block, and
then wrapping that inline-block in a helper-div that has
"text-align:center" set. -->
.centerParent {
text-align: center;
}
.center {
background: lightblue;
display: inline-block;
text-align: right; /* Keep parent's centering from tweaking my text */
}
.baseline {
background: teal;
float: right;
}
.stretch {
background: pink;
}
.self-start {
background: yellow;
float: right;
}
.self-end {
background: purple;
float: left;
}
.clearFloats { clear: both }
</style>
</head>
<body>
<div class="flexbox">
<div class="flex-start">start</div>
<div class="flex-start big">a b c d e f</div>
<div class="flex-end">end</div>
<div class="flex-end big">a b c d e f</div>
<div class="clearFloats"></div>
<div class="centerParent">
<div class="center">center</div>
</div>
<div class="centerParent">
<div class="center big">a b c d e f</div>
</div>
</div>
<div class="flexbox">
<div class="baseline">base</div>
<div class="baseline big">abc</div>
<div class="clearFloats"></div>
<div class="stretch">stretch</div>
<!-- Force a 3px + 1px = 4px margin between this and the previous div
(to thwart the effects of margin-collapsing). This is the only
place we need this hack, because everywhere else in this test
we use floats or inline-blocks, whose margins don't collapse. -->
<div class="stretch big" style="margin-top: 4px">a b c d e f</div>
</div>
<div class="flexbox">
<div class="self-start">self-start</div>
<div class="self-start big">a b c d e f</div>
<div class="self-end">self-end</div>
<div class="self-end big">a b c d e f</div>
</div>
</body>
</html>

View file

@ -0,0 +1,92 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!-- Testcase for align-items / align-self behavior, with all the possible
values included on different items within a flex container, and with
margin/border/padding values on each item. -->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>CSS Test: Testing the behavior of 'align-self' with a vertical flex container, with margin/padding/border on the items and with 'direction:rtl'</title>
<link rel="author" title="Mihir Iyer" href="mailto:miyer@mozilla.com"/>
<link rel="help" href="http://www.w3.org/TR/css-flexbox-1/#align-items-property"/>
<link rel="match" href="flexbox-align-self-vert-rtl-005-ref.xhtml"/>
<style>
.flexbox {
border: 1px dashed blue;
width: 200px;
display: flex;
flex-direction: column;
float: left;
font-size: 10px;
direction: rtl;
}
.flexbox > div {
margin: 1px 2px 3px 4px;
border-width: 2px 3px 4px 5px;
padding: 3px 4px 5px 6px;
border-style: dotted;
}
div.big {
font-size: 20px;
width: 50px;
}
/* Classes for each of the various align-self values */
.flex-start {
background: lime;
align-self: flex-start;
}
.flex-end {
background: orange;
align-self: flex-end;
}
.center {
background: lightblue;
align-self: center;
}
.baseline {
background: teal;
align-self: baseline;
}
.stretch {
background: pink;
align-self: stretch;
}
.self-start {
background: yellow;
align-self: self-start;
}
.self-end {
background: purple;
align-self: self-end;
}
</style>
</head>
<body>
<div class="flexbox">
<div class="flex-start">start</div>
<div class="flex-start big">a b c d e f</div>
<div class="flex-end">end</div>
<div class="flex-end big">a b c d e f</div>
<div class="center">center</div>
<div class="center big">a b c d e f</div>
</div>
<div class="flexbox">
<div class="baseline">base</div>
<div class="baseline big">abc</div>
<div class="stretch">stretch</div>
<div class="stretch big">a b c d e f</div>
</div>
<div class="flexbox">
<div class="self-start dirrtl">self-start</div>
<div class="self-start dirrtl big">a b c d e f</div>
<div class="self-end dirrtl">self-end</div>
<div class="self-end dirrtl big nowidth">a b c d e f</div>
</div>
</body>
</html>

View file

@ -0,0 +1,192 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>CSS Reftest Reference</title>
<link rel="author" title="Mihir Iyer" href="mailto:miyer@mozilla.com"/>
<style>
body { line-height: 0; }
div.flexbox {
width: 200px;
margin-bottom: 2px;
direction: rtl;
}
div.flexbox > * {
display: inline-block;
}
div.a {
height: 20px;
width: 10px;
background: lightgreen;
}
div.b {
height: 20px;
width: 50px;
background: pink;
}
div.c {
height: 20px;
width: 100px;
background: orange;
}
.centerParent {
text-align: center;
}
.center {
display: inline-block;
}
</style>
</head>
<body>
<!-- default (start) -->
<div class="flexbox">
<div class="a"/>
</div>
<div class="flexbox">
<div class="a"/><div class="b"></div>
</div>
<div class="flexbox">
<div class="a"/><div class="b"/><div class="c"/>
</div>
<!-- flex-start -->
<div class="flexbox">
<div class="a"/>
</div>
<div class="flexbox">
<div class="a"/><div class="b"/>
</div>
<div class="flexbox">
<div class="a"/><div class="b"/><div class="c"/>
</div>
<!-- flex-end -->
<div class="flexbox" style="text-align: left">
<div class="a"/>
</div>
<div class="flexbox" style="text-align: left;">
<div class="a"/><div class="b"/>
</div>
<div class="flexbox" style="text-align: left;">
<div class="a"/><div class="b"/><div class="c"/>
</div>
<!-- center -->
<div class="centerParent">
<div class="flexbox">
<div class="a"/>
</div>
</div>
<div class="centerParent">
<div class="flexbox">
<div class="a"/><div class="b"/>
</div>
</div>
<div class="centerParent">
<div class="flexbox">
<div class="a"/><div class="b"/><div class="c"/>
</div>
</div>
<!-- space-between -->
<div class="flexbox">
<div class="a"/>
</div>
<div class="flexbox">
<div class="a"/><div class="b" style="float: left"/>
</div>
<div class="flexbox">
<div class="a" style="display:block; float: right"/>
<div class="c" style="float:left"/>
<!-- Use fixed-size margins to subtract space for "a" and "c", and then
use auto margins to center 'b' within the remaining space -->
<div style="display: block; margin-right: 10px; margin-left: 100px">
<div class="b" style="margin: auto"/>
</div>
</div>
<!-- space-around -->
<!-- Center "a" here just as we did above in the "center" case. -->
<div class="centerParent">
<div class="flexbox">
<div class="a"/>
</div>
</div>
<!-- For the rest, we'll use a flex container with invisible flexible items
instead of packing space. That's simpler than trying to hack up
a width-independent reference case for "justify-content: space-around".
(There are other reftests to ensure that basic flex container
behavior is correct, so it's safe to rely on it here.) -->
<div class="flexbox" style="display: flex">
<div style="flex: 0.5"/>
<div class="a"/>
<div style="flex: 1"/>
<div class="b"/>
<div style="flex: 0.5"/>
</div>
<div class="flexbox" style="display: flex">
<div style="flex: 0.5"/>
<div class="a"/>
<div style="flex: 1"/>
<div class="b"/>
<div style="flex: 1"/>
<div class="c"/>
<div style="flex: 0.5"/>
</div>
<!-- space-evenly -->
<!-- Center "a" here just as we did above in the "center" case. -->
<div class="centerParent">
<div class="flexbox">
<div class="a"/>
</div>
</div>
<!-- As above with space-around, we'll use a flex container with invisible
flexible items instead of packing space. -->
<div class="flexbox" style="display: flex">
<div style="flex: 1"/>
<div class="a"/>
<div style="flex: 1"/>
<div class="b"/>
<div style="flex: 1"/>
</div>
<div class="flexbox" style="display: flex">
<div style="flex: 1"/>
<div class="a"/>
<div style="flex: 1"/>
<div class="b"/>
<div style="flex: 1"/>
<div class="c"/>
<div style="flex: 1"/>
</div>
<!-- left -->
<div class="flexbox" style="text-align:left">
<div class="a"/>
</div>
<div class="flexbox" style="text-align:left">
<div class="a"/><div class="b"/>
</div>
<div class="flexbox" style="text-align:left">
<div class="a"/><div class="b"/><div class="c"/>
</div>
<!-- right -->
<div class="flexbox">
<div class="a"/>
</div>
<div class="flexbox">
<div class="a"/><div class="b"/>
</div>
<div class="flexbox">
<div class="a"/><div class="b"/><div class="c"/>
</div>
</body>
</html>

View file

@ -0,0 +1,140 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!-- Testcase to exercise each possible value of the 'justify-content'
property, in an auto-sized horizontal flex container. -->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>CSS Test: Testing 'justify-content' in an auto-sized reversed horizontal flex container</title>
<link rel="author" title="Mihir Iyer" href="mailto:miyer@mozilla.com"/>
<link rel="help" href="http://www.w3.org/TR/css-flexbox-1/#justify-content-property"/>
<link rel="match" href="flexbox-justify-content-horiz-006-ref.xhtml"/>
<style>
div.flexbox {
display: flex;
flex-direction: row-reverse;
width: 200px;
margin-bottom: 2px;
}
div.a {
height: 20px;
flex: 0 10px;
background: lightgreen;
}
div.b {
height: 20px;
flex: 0 50px;
background: pink;
}
div.c {
height: 20px;
flex: 0 100px;
background: orange;
}
</style>
</head>
<body>
<!-- default (start) -->
<div class="flexbox">
<div class="a"/>
</div>
<div class="flexbox">
<div class="a"/><div class="b"></div>
</div>
<div class="flexbox">
<div class="a"/><div class="b"/><div class="c"/>
</div>
<!-- flex-start -->
<div class="flexbox" style="justify-content: flex-start">
<div class="a"/>
</div>
<div class="flexbox" style="justify-content: flex-start">
<div class="a"/><div class="b"/>
</div>
<div class="flexbox" style="justify-content: flex-start">
<div class="a"/><div class="b"/><div class="c"/>
</div>
<!-- flex-end -->
<div class="flexbox" style="justify-content: flex-end">
<div class="a"/>
</div>
<div class="flexbox" style="justify-content: flex-end">
<div class="a"/><div class="b"/>
</div>
<div class="flexbox" style="justify-content: flex-end">
<div class="a"/><div class="b"/><div class="c"/>
</div>
<!-- center -->
<div class="flexbox" style="justify-content: center">
<div class="a"/>
</div>
<div class="flexbox" style="justify-content: center">
<div class="a"/><div class="b"/>
</div>
<div class="flexbox" style="justify-content: center">
<div class="a"/><div class="b"/><div class="c"/>
</div>
<!-- space-between -->
<div class="flexbox" style="justify-content: space-between">
<div class="a"/>
</div>
<div class="flexbox" style="justify-content: space-between">
<div class="a"/><div class="b"/>
</div>
<div class="flexbox" style="justify-content: space-between">
<div class="a"/><div class="b"/><div class="c"/>
</div>
<!-- space-around -->
<div class="flexbox" style="justify-content: space-around">
<div class="a"/>
</div>
<div class="flexbox" style="justify-content: space-around">
<div class="a"/><div class="b"/>
</div>
<div class="flexbox" style="justify-content: space-around">
<div class="a"/><div class="b"/><div class="c"/>
</div>
<!-- space-evenly -->
<div class="flexbox" style="justify-content: space-evenly">
<div class="a"/>
</div>
<div class="flexbox" style="justify-content: space-evenly">
<div class="a"/><div class="b"/>
</div>
<div class="flexbox" style="justify-content: space-evenly">
<div class="a"/><div class="b"/><div class="c"/>
</div>
<!-- left -->
<div class="flexbox" style="justify-content: left">
<div class="a"/>
</div>
<div class="flexbox" style="justify-content: left">
<div class="a"/><div class="b"/>
</div>
<div class="flexbox" style="justify-content: left">
<div class="a"/><div class="b"/><div class="c"/>
</div>
<!-- right -->
<div class="flexbox" style="justify-content: right">
<div class="a"/>
</div>
<div class="flexbox" style="justify-content: right">
<div class="a"/><div class="b"/>
</div>
<div class="flexbox" style="justify-content: right">
<div class="a"/><div class="b"/><div class="c"/>
</div>
</body>
</html>

View file

@ -0,0 +1,143 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>CSS Reftest Reference</title>
<link rel="author" title="Mihir Iyer" href="mailto:miyer@mozilla.com"/>
<style>
div.flexbox {
height: 200px;
margin-right: 2px;
float: left;
}
div.a {
width: 20px;
height: 10px;
background: lightgreen;
}
div.b {
width: 20px;
height: 50px;
background: pink;
}
div.c {
width: 20px;
height: 100px;
background: orange;
}
</style>
</head>
<body>
<!-- default (start) -->
<div class="flexbox">
<div class="a" style="margin-top:190px"/>
</div>
<div class="flexbox">
<div class="b" style="margin-top:140px"/><div class="a"></div>
</div>
<div class="flexbox">
<div class="c" style="margin-top:40px"/><div class="b"/><div class="a"/>
</div>
<!-- flex-start -->
<div class="flexbox">
<div class="a" style="margin-top:190px"/>
</div>
<div class="flexbox">
<div class="b" style="margin-top:140px"/><div class="a"></div>
</div>
<div class="flexbox">
<div class="c" style="margin-top:40px"/><div class="b"/><div class="a"/>
</div>
<!-- flex-end -->
<div class="flexbox">
<div class="a"/>
</div>
<div class="flexbox">
<div class="b"/><div class="a"/>
</div>
<div class="flexbox">
<div class="c"/><div class="b"/><div class="a"/>
</div>
<!-- center -->
<div class="flexbox">
<div class="a" style="margin-top: 95px"/>
</div>
<div class="flexbox">
<div class="b" style="margin-top: 70px"/><div class="a"/>
</div>
<div class="flexbox">
<div class="c" style="margin-top: 20px"/><div class="b"/><div class="a"/>
</div>
<!-- space-between -->
<div class="flexbox">
<div class="a" style="margin-top:190px"/>
</div>
<div class="flexbox">
<div class="b"/><div class="a" style="margin-top: 140px"/>
</div>
<div class="flexbox">
<div class="c"
/><div class="b" style="margin-top: 20px"
/><div class="a" style="margin-top: 20px"/>
</div>
<!-- space-around -->
<div class="flexbox">
<div class="a" style="margin-top: 95px"/>
</div>
<div class="flexbox">
<div class="b" style="margin-top: 35px"
/><div class="a" style="margin-top: 70px"/>
</div>
<div class="flexbox">
<div class="c" style="margin-top: calc(40px / 6)"
/><div class="b" style="margin-top: calc(40px / 3)"
/><div class="a" style="margin-top: calc(40px / 3)"/>
</div>
<!-- space-evenly -->
<div class="flexbox">
<div class="a" style="margin-top: 95px"/>
</div>
<div class="flexbox">
<div class="b" style="margin-top: calc(140px / 3)"
/><div class="a" style="margin-top: calc(140px / 3)"/>
</div>
<div class="flexbox">
<div class="c" style="margin-top: 10px"
/><div class="b" style="margin-top: 10px"
/><div class="a" style="margin-top: 10px"/>
</div>
<!-- left -->
<div class="flexbox">
<div class="a"/>
</div>
<div class="flexbox">
<div class="b"/><div class="a"/>
</div>
<div class="flexbox">
<div class="c"/><div class="b"/><div class="a"/>
</div>
<!-- right -->
<div class="flexbox">
<div class="a"/>
</div>
<div class="flexbox">
<div class="b"/><div class="a"/>
</div>
<div class="flexbox">
<div class="c"/><div class="b"/><div class="a"/>
</div>
</body>
</html>

View file

@ -0,0 +1,141 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!-- Testcase with a series of vertical flex containers, testing each
possible value of the 'justify-content' property. -->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>CSS Test: Testing 'justify-content' in a vertical flex container</title>
<link rel="author" title="Mihir Iyer" href="mailto:miyer@mozilla.com"/>
<link rel="help" href="http://www.w3.org/TR/css-flexbox-1/#justify-content-property"/>
<link rel="match" href="flexbox-justify-content-vert-006-ref.xhtml"/>
<style>
div.flexbox {
height: 200px;
display: flex;
flex-direction: column-reverse;
margin-right: 2px;
float: left;
}
div.a {
width: 20px;
flex: 0 10px;
background: lightgreen;
}
div.b {
width: 20px;
flex: 0 50px;
background: pink;
}
div.c {
width: 20px;
flex: 0 100px;
background: orange;
}
</style>
</head>
<body>
<!-- default (start) -->
<div class="flexbox">
<div class="a"/>
</div>
<div class="flexbox">
<div class="a"/><div class="b"></div>
</div>
<div class="flexbox">
<div class="a"/><div class="b"/><div class="c"/>
</div>
<!-- flex-start -->
<div class="flexbox" style="justify-content: flex-start">
<div class="a"/>
</div>
<div class="flexbox" style="justify-content: flex-start">
<div class="a"/><div class="b"/>
</div>
<div class="flexbox" style="justify-content: flex-start">
<div class="a"/><div class="b"/><div class="c"/>
</div>
<!-- flex-end -->
<div class="flexbox" style="justify-content: flex-end">
<div class="a"/>
</div>
<div class="flexbox" style="justify-content: flex-end">
<div class="a"/><div class="b"/>
</div>
<div class="flexbox" style="justify-content: flex-end">
<div class="a"/><div class="b"/><div class="c"/>
</div>
<!-- center -->
<div class="flexbox" style="justify-content: center">
<div class="a"/>
</div>
<div class="flexbox" style="justify-content: center">
<div class="a"/><div class="b"/>
</div>
<div class="flexbox" style="justify-content: center">
<div class="a"/><div class="b"/><div class="c"/>
</div>
<!-- space-between -->
<div class="flexbox" style="justify-content: space-between">
<div class="a"/>
</div>
<div class="flexbox" style="justify-content: space-between">
<div class="a"/><div class="b"/>
</div>
<div class="flexbox" style="justify-content: space-between">
<div class="a"/><div class="b"/><div class="c"/>
</div>
<!-- space-around -->
<div class="flexbox" style="justify-content: space-around">
<div class="a"/>
</div>
<div class="flexbox" style="justify-content: space-around">
<div class="a"/><div class="b"/>
</div>
<div class="flexbox" style="justify-content: space-around">
<div class="a"/><div class="b"/><div class="c"/>
</div>
<!-- space-evenly -->
<div class="flexbox" style="justify-content: space-evenly">
<div class="a"/>
</div>
<div class="flexbox" style="justify-content: space-evenly">
<div class="a"/><div class="b"/>
</div>
<div class="flexbox" style="justify-content: space-evenly">
<div class="a"/><div class="b"/><div class="c"/>
</div>
<!-- left -->
<div class="flexbox" style="justify-content: left">
<div class="a"/>
</div>
<div class="flexbox" style="justify-content: left">
<div class="a"/><div class="b"/>
</div>
<div class="flexbox" style="justify-content: left">
<div class="a"/><div class="b"/><div class="c"/>
</div>
<!-- right -->
<div class="flexbox" style="justify-content: right">
<div class="a"/>
</div>
<div class="flexbox" style="justify-content: right">
<div class="a"/><div class="b"/>
</div>
<div class="flexbox" style="justify-content: right">
<div class="a"/><div class="b"/><div class="c"/>
</div>
</body>
</html>

View file

@ -0,0 +1,143 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>CSS Reftest Reference</title>
<link rel="author" title="Mihir Iyer" href="mailto:miyer@mozilla.com"/>
<style>
div.flexbox {
height: 200px;
margin-right: 2px;
float: left;
}
div.a {
width: 20px;
height: 10px;
background: lightgreen;
}
div.b {
width: 20px;
height: 50px;
background: pink;
}
div.c {
width: 20px;
height: 100px;
background: orange;
}
</style>
</head>
<body>
<!-- default (start) -->
<div class="flexbox">
<div class="a" style="margin-top:190px"/>
</div>
<div class="flexbox">
<div class="b" style="margin-top:140px"/><div class="a"></div>
</div>
<div class="flexbox">
<div class="c" style="margin-top:40px"/><div class="b"/><div class="a"/>
</div>
<!-- flex-start -->
<div class="flexbox">
<div class="a" style="margin-top:190px"/>
</div>
<div class="flexbox">
<div class="b" style="margin-top:140px"/><div class="a"></div>
</div>
<div class="flexbox">
<div class="c" style="margin-top:40px"/><div class="b"/><div class="a"/>
</div>
<!-- flex-end -->
<div class="flexbox">
<div class="a"/>
</div>
<div class="flexbox">
<div class="b"/><div class="a"/>
</div>
<div class="flexbox">
<div class="c"/><div class="b"/><div class="a"/>
</div>
<!-- center -->
<div class="flexbox">
<div class="a" style="margin-top: 95px"/>
</div>
<div class="flexbox">
<div class="b" style="margin-top: 70px"/><div class="a"/>
</div>
<div class="flexbox">
<div class="c" style="margin-top: 20px"/><div class="b"/><div class="a"/>
</div>
<!-- space-between -->
<div class="flexbox">
<div class="a" style="margin-top:190px"/>
</div>
<div class="flexbox">
<div class="b"/><div class="a" style="margin-top: 140px"/>
</div>
<div class="flexbox">
<div class="c"
/><div class="b" style="margin-top: 20px"
/><div class="a" style="margin-top: 20px"/>
</div>
<!-- space-around -->
<div class="flexbox">
<div class="a" style="margin-top: 95px"/>
</div>
<div class="flexbox">
<div class="b" style="margin-top: 35px"
/><div class="a" style="margin-top: 70px"/>
</div>
<div class="flexbox">
<div class="c" style="margin-top: calc(40px / 6)"
/><div class="b" style="margin-top: calc(40px / 3)"
/><div class="a" style="margin-top: calc(40px / 3)"/>
</div>
<!-- space-evenly -->
<div class="flexbox">
<div class="a" style="margin-top: 95px"/>
</div>
<div class="flexbox">
<div class="b" style="margin-top: calc(140px / 3)"
/><div class="a" style="margin-top: calc(140px / 3)"/>
</div>
<div class="flexbox">
<div class="c" style="margin-top: 10px"
/><div class="b" style="margin-top: 10px"
/><div class="a" style="margin-top: 10px"/>
</div>
<!-- left -->
<div class="flexbox">
<div class="a"/>
</div>
<div class="flexbox">
<div class="b"/><div class="a"/>
</div>
<div class="flexbox">
<div class="c"/><div class="b"/><div class="a"/>
</div>
<!-- right -->
<div class="flexbox">
<div class="a" style="margin-top: 190px"/>
</div>
<div class="flexbox">
<div class="b" style="margin-top: 140px"/><div class="a"/>
</div>
<div class="flexbox">
<div class="c" style="margin-top: 40px"/><div class="b"/><div class="a"/>
</div>
</body>
</html>

View file

@ -0,0 +1,142 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!-- Testcase with a series of vertical flex containers, testing each
possible value of the 'justify-content' property. -->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>CSS Test: Testing 'justify-content' in a vertical writing mode flex container</title>
<link rel="author" title="Mihir Iyer" href="mailto:miyer@mozilla.com"/>
<link rel="help" href="http://www.w3.org/TR/css-flexbox-1/#justify-content-property"/>
<link rel="match" href="flexbox-justify-content-wmvert-001-ref.xhtml"/>
<style>
div.flexbox {
height: 200px;
display: flex;
flex-direction: row-reverse;
margin-right: 2px;
float: left;
writing-mode: vertical-lr;
}
div.a {
width: 20px;
flex: 0 10px;
background: lightgreen;
}
div.b {
width: 20px;
flex: 0 50px;
background: pink;
}
div.c {
width: 20px;
flex: 0 100px;
background: orange;
}
</style>
</head>
<body>
<!-- default (start) -->
<div class="flexbox">
<div class="a"/>
</div>
<div class="flexbox">
<div class="a"/><div class="b"></div>
</div>
<div class="flexbox">
<div class="a"/><div class="b"/><div class="c"/>
</div>
<!-- flex-start -->
<div class="flexbox" style="justify-content: flex-start">
<div class="a"/>
</div>
<div class="flexbox" style="justify-content: flex-start">
<div class="a"/><div class="b"/>
</div>
<div class="flexbox" style="justify-content: flex-start">
<div class="a"/><div class="b"/><div class="c"/>
</div>
<!-- flex-end -->
<div class="flexbox" style="justify-content: flex-end">
<div class="a"/>
</div>
<div class="flexbox" style="justify-content: flex-end">
<div class="a"/><div class="b"/>
</div>
<div class="flexbox" style="justify-content: flex-end">
<div class="a"/><div class="b"/><div class="c"/>
</div>
<!-- center -->
<div class="flexbox" style="justify-content: center">
<div class="a"/>
</div>
<div class="flexbox" style="justify-content: center">
<div class="a"/><div class="b"/>
</div>
<div class="flexbox" style="justify-content: center">
<div class="a"/><div class="b"/><div class="c"/>
</div>
<!-- space-between -->
<div class="flexbox" style="justify-content: space-between">
<div class="a"/>
</div>
<div class="flexbox" style="justify-content: space-between">
<div class="a"/><div class="b"/>
</div>
<div class="flexbox" style="justify-content: space-between">
<div class="a"/><div class="b"/><div class="c"/>
</div>
<!-- space-around -->
<div class="flexbox" style="justify-content: space-around">
<div class="a"/>
</div>
<div class="flexbox" style="justify-content: space-around">
<div class="a"/><div class="b"/>
</div>
<div class="flexbox" style="justify-content: space-around">
<div class="a"/><div class="b"/><div class="c"/>
</div>
<!-- space-evenly -->
<div class="flexbox" style="justify-content: space-evenly">
<div class="a"/>
</div>
<div class="flexbox" style="justify-content: space-evenly">
<div class="a"/><div class="b"/>
</div>
<div class="flexbox" style="justify-content: space-evenly">
<div class="a"/><div class="b"/><div class="c"/>
</div>
<!-- left -->
<div class="flexbox" style="justify-content: left">
<div class="a"/>
</div>
<div class="flexbox" style="justify-content: left">
<div class="a"/><div class="b"/>
</div>
<div class="flexbox" style="justify-content: left">
<div class="a"/><div class="b"/><div class="c"/>
</div>
<!-- right -->
<div class="flexbox" style="justify-content: right">
<div class="a"/>
</div>
<div class="flexbox" style="justify-content: right">
<div class="a"/><div class="b"/>
</div>
<div class="flexbox" style="justify-content: right">
<div class="a"/><div class="b"/><div class="c"/>
</div>
</body>
</html>

View file

@ -11,6 +11,7 @@
== flexbox-align-content-horiz-001b.xhtml flexbox-align-content-horiz-001-ref.xhtml
== flexbox-align-content-vert-001a.xhtml flexbox-align-content-vert-001-ref.xhtml
== flexbox-align-content-vert-001b.xhtml flexbox-align-content-vert-001-ref.xhtml
== flexbox-align-content-wmvert-001.xhtml flexbox-align-content-wmvert-001-ref.xhtml
# Tests for cross-axis alignment (align-self / align-items properties)
== flexbox-align-self-baseline-horiz-001a.xhtml flexbox-align-self-baseline-horiz-001-ref.xhtml
@ -39,6 +40,7 @@
== flexbox-align-self-vert-rtl-002.xhtml flexbox-align-self-vert-rtl-002-ref.xhtml
== flexbox-align-self-vert-rtl-003.xhtml flexbox-align-self-vert-rtl-003-ref.xhtml
== flexbox-align-self-vert-rtl-004.xhtml flexbox-align-self-vert-rtl-004-ref.xhtml
== flexbox-align-self-vert-rtl-005.xhtml flexbox-align-self-vert-rtl-005-ref.xhtml
== flexbox-align-items-center-nested-001.html flexbox-align-items-center-nested-001-ref.html
@ -158,12 +160,15 @@
== flexbox-justify-content-horiz-003.xhtml flexbox-justify-content-horiz-003-ref.xhtml
== flexbox-justify-content-horiz-004.xhtml flexbox-justify-content-horiz-004-ref.xhtml
== flexbox-justify-content-horiz-005.xhtml flexbox-justify-content-horiz-005-ref.xhtml
== flexbox-justify-content-horiz-006.xhtml flexbox-justify-content-horiz-006-ref.xhtml
== flexbox-justify-content-vert-001a.xhtml flexbox-justify-content-vert-001-ref.xhtml
== flexbox-justify-content-vert-001b.xhtml flexbox-justify-content-vert-001-ref.xhtml
== flexbox-justify-content-vert-002.xhtml flexbox-justify-content-vert-002-ref.xhtml
== flexbox-justify-content-vert-003.xhtml flexbox-justify-content-vert-003-ref.xhtml
== flexbox-justify-content-vert-004.xhtml flexbox-justify-content-vert-004-ref.xhtml
== flexbox-justify-content-vert-005.xhtml flexbox-justify-content-vert-005-ref.xhtml
== flexbox-justify-content-vert-006.xhtml flexbox-justify-content-vert-006-ref.xhtml
== flexbox-justify-content-wmvert-001.xhtml flexbox-justify-content-wmvert-001-ref.xhtml
# Tests for flexbox with margin, border, and/or padding on flex items
== flexbox-margin-auto-horiz-001.xhtml flexbox-margin-auto-horiz-001-ref.xhtml

View file

@ -18,6 +18,32 @@ the global scope.
NB: presently, testdriver.js only works in the top-level test browsing
context (and not therefore in any frame or window opened from it).
### `test_driver.bless(intent, action)`
#### `intent: a string describing the motivation for this invocation`
#### `action: an optional function`
This function simulates [activation][activation], allowing tests to
perform privileged operations that require user interaction. For
example, sandboxed iframes with the
`allow-top-navigation-by-user-activation` may only navigate their
parent's browsing context under these circumstances. The `intent`
string is presented to human operators when the test is not run in
automation.
This method returns a promise which is resolved with the result of
invoking the `action` function. If no such function is provided, the
promise is resolved with the value `undefined`.
Example:
```js
var mediaElement = document.createElement('video');
test_driver.bless('initiate media playback', function () {
mediaElement.play();
});
```
### `test_driver.click(element)`
#### `element: a DOM Element object`
@ -48,4 +74,5 @@ between the function being called and the promise settling.
To send special keys, one must send the respective key's codepoint. Since this uses the WebDriver protocol, you can find a [list for code points to special keys in the spec](https://w3c.github.io/webdriver/webdriver-spec.html#keyboard-actions).
For example, to send the tab key you would send "\uE004".
[activation]: https://html.spec.whatwg.org/multipage/interaction.html#activation
[testharness]: {{ site.baseurl }}{% link _writing-tests/testharness.md %}

View file

@ -56,16 +56,16 @@ test(t => {
assert_equals(counter++, 3);
}));
child.addEventListener("hi", t.step_func(e => {
assert_equals(window.event, e);
assert_equals(window.event, undefined);
assert_equals(counter++, 2);
}));
furtherChild.addEventListener("hi", t.step_func(e => {
host.appendChild(child);
assert_equals(window.event, e);
assert_equals(window.event, undefined);
assert_equals(counter++, 0);
}));
furtherChild.addEventListener("hi", t.step_func(e => {
assert_equals(window.event, e);
assert_equals(window.event, undefined);
assert_equals(counter++, 1);
}));
furtherChild.dispatchEvent(new Event("hi", { composed: true, bubbles: true }));
@ -75,7 +75,7 @@ test(t => {
async_test(t => {
const frame = document.body.appendChild(document.createElement("iframe"));
frame.src = "resources/event-global-extra-frame.html";
frame.onload = t.step_func_done(() => {
frame.onload = t.step_func_done((load_event) => {
const event = new Event("hi");
document.addEventListener("hi", frame.contentWindow.listener); // listener intentionally not wrapped in t.step_func
document.addEventListener("hi", t.step_func(e => {
@ -85,6 +85,6 @@ async_test(t => {
document.dispatchEvent(event);
assert_equals(frameState.event, event);
assert_equals(frameState.windowEvent, event);
assert_equals(frameState.parentEvent, undefined);
assert_equals(frameState.parentEvent, load_event);
});
}, "Listener from a different global");

View file

@ -0,0 +1,19 @@
// META: script=/common/utils.js
// META: script=../resources/utils.js
// META: script=/common/get-host-info.sub.js
// META: script=resources/corspreflight.js
const corsURL = get_host_info().HTTP_REMOTE_ORIGIN + dirname(location.pathname) + RESOURCES_DIR + "preflight.py";
promise_test(() => fetch("resources/not-cors-safelisted.json").then(res => res.json().then(runTests)), "Loading data…");
function runTests(testArray) {
testArray.forEach(testItem => {
const [headerName, headerValue] = testItem;
corsPreflight("Need CORS-preflight for " + headerName + "/" + headerValue + " header",
corsURL,
"GET",
true,
[[headerName, headerValue]]);
});
}

View file

@ -1,65 +1,7 @@
// META: script=/common/utils.js
// META: script=../resources/utils.js
// META: script=/common/get-host-info.sub.js
function headerNames(headers)
{
let names = [];
for (let header of headers)
names.push(header[0].toLowerCase());
return names
}
/*
Check preflight is done
Control if server allows method and headers and check accordingly
Check control access headers added by UA (for method and headers)
*/
function corsPreflight(desc, corsUrl, method, allowed, headers, safeHeaders) {
return promise_test(function(test) {
var uuid_token = token();
return fetch(RESOURCES_DIR + "clean-stash.py?token=" + uuid_token).then(function(response) {
var url = corsUrl + (corsUrl.indexOf("?") === -1 ? "?" : "&");
var urlParameters = "token=" + uuid_token + "&max_age=0";
var requestInit = {"mode": "cors", "method": method};
var requestHeaders = [];
if (headers)
requestHeaders.push.apply(requestHeaders, headers);
if (safeHeaders)
requestHeaders.push.apply(requestHeaders, safeHeaders);
requestInit["headers"] = requestHeaders;
if (allowed) {
urlParameters += "&allow_methods=" + method + "&control_request_headers";
if (headers) {
//Make the server allow the headers
urlParameters += "&allow_headers=" + headerNames(headers).join("%20%2C");
}
return fetch(url + urlParameters, requestInit).then(function(resp) {
assert_equals(resp.status, 200, "Response's status is 200");
assert_equals(resp.headers.get("x-did-preflight"), "1", "Preflight request has been made");
if (headers) {
var actualHeaders = resp.headers.get("x-control-request-headers").toLowerCase().split(",");
for (var i in actualHeaders)
actualHeaders[i] = actualHeaders[i].trim();
for (var header of headers)
assert_in_array(header[0].toLowerCase(), actualHeaders, "Preflight asked permission for header: " + header);
let accessControlAllowHeaders = headerNames(headers).sort().join(",");
assert_equals(resp.headers.get("x-control-request-headers"), accessControlAllowHeaders, "Access-Control-Allow-Headers value");
return fetch(RESOURCES_DIR + "clean-stash.py?token=" + uuid_token);
} else {
assert_equals(resp.headers.get("x-control-request-headers"), null, "Access-Control-Request-Headers should be omitted")
}
});
} else {
return promise_rejects(test, new TypeError(), fetch(url + urlParameters, requestInit)).then(function(){
return fetch(RESOURCES_DIR + "clean-stash.py?token=" + uuid_token);
});
}
});
}, desc);
}
// META: script=resources/corspreflight.js
var corsUrl = get_host_info().HTTP_REMOTE_ORIGIN + dirname(location.pathname) + RESOURCES_DIR + "preflight.py";

View file

@ -0,0 +1,58 @@
function headerNames(headers) {
let names = [];
for (let header of headers) {
names.push(header[0].toLowerCase());
}
return names;
}
/*
Check preflight is done
Control if server allows method and headers and check accordingly
Check control access headers added by UA (for method and headers)
*/
function corsPreflight(desc, corsUrl, method, allowed, headers, safeHeaders) {
return promise_test(function(test) {
var uuid_token = token();
return fetch(RESOURCES_DIR + "clean-stash.py?token=" + uuid_token).then(function(response) {
var url = corsUrl + (corsUrl.indexOf("?") === -1 ? "?" : "&");
var urlParameters = "token=" + uuid_token + "&max_age=0";
var requestInit = {"mode": "cors", "method": method};
var requestHeaders = [];
if (headers)
requestHeaders.push.apply(requestHeaders, headers);
if (safeHeaders)
requestHeaders.push.apply(requestHeaders, safeHeaders);
requestInit["headers"] = requestHeaders;
if (allowed) {
urlParameters += "&allow_methods=" + method + "&control_request_headers";
if (headers) {
//Make the server allow the headers
urlParameters += "&allow_headers=" + headerNames(headers).join("%20%2C");
}
return fetch(url + urlParameters, requestInit).then(function(resp) {
assert_equals(resp.status, 200, "Response's status is 200");
assert_equals(resp.headers.get("x-did-preflight"), "1", "Preflight request has been made");
if (headers) {
var actualHeaders = resp.headers.get("x-control-request-headers").toLowerCase().split(",");
for (var i in actualHeaders)
actualHeaders[i] = actualHeaders[i].trim();
for (var header of headers)
assert_in_array(header[0].toLowerCase(), actualHeaders, "Preflight asked permission for header: " + header);
let accessControlAllowHeaders = headerNames(headers).sort().join(",");
assert_equals(resp.headers.get("x-control-request-headers"), accessControlAllowHeaders, "Access-Control-Allow-Headers value");
return fetch(RESOURCES_DIR + "clean-stash.py?token=" + uuid_token);
} else {
assert_equals(resp.headers.get("x-control-request-headers"), null, "Access-Control-Request-Headers should be omitted")
}
});
} else {
return promise_rejects(test, new TypeError(), fetch(url + urlParameters, requestInit)).then(function(){
return fetch(RESOURCES_DIR + "clean-stash.py?token=" + uuid_token);
});
}
});
}, desc);
}

View file

@ -0,0 +1,11 @@
[
["accept", "\""],
["accept", "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678"],
["accept-language", "\u0001"],
["accept-language", "@"],
["content-language", "\u0001"],
["content-language", "@"],
["content-type", "text/html"],
["content-type", "text/plain; long=0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901"],
["test", "hi"]
]

View file

@ -0,0 +1,19 @@
promise_test(() => fetch("../cors/resources/not-cors-safelisted.json").then(res => res.json().then(runTests)), "Loading data…");
function runTests(testArray) {
testArray = testArray.concat([
["dpr", "2"],
["downlink", "1"], // https://wicg.github.io/netinfo/
["save-data", "on"],
["viewport-width", "100"],
["width", "100"]
]);
testArray.forEach(testItem => {
const [headerName, headerValue] = testItem;
test(() => {
const noCorsHeaders = new Request("about:blank", { mode: "no-cors" }).headers;
noCorsHeaders.append(headerName, headerValue);
assert_false(noCorsHeaders.has(headerName));
}, "\"no-cors\" Headers object cannot have " + headerName + "/" + headerValue + " as header");
});
}

View file

@ -0,0 +1,65 @@
<!DOCTYPE html>
<meta charset="utf-8"/>
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/fetch/sec-metadata/resources/helper.js></script>
<body>
<script>
promise_test(t => {
return new Promise((resolve, reject) => {
let key = "embed-same-origin";
let e = document.createElement('embed');
e.src = "https://{{host}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=" + key;
e.onload = e => {
let expected = {"destination":"embed", "site":"same-origin"};
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key)
.then(response => response.text())
.then(text => assert_header_equals(text, expected))
.then(_ => resolve())
.catch(e => reject(e));
};
document.body.appendChild(e);
})
}, "Same-Origin embed");
promise_test(t => {
return new Promise((resolve, reject) => {
let key = "embed-same-site";
let e = document.createElement('embed');
e.src = "https://{{hosts[][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=" + key;
e.onload = e => {
let expected = {"destination":"embed", "site":"same-site"};
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key)
.then(response => response.text())
.then(text => assert_header_equals(text, expected))
.then(_ => resolve())
.catch(e => reject(e));
};
document.body.appendChild(e);
})
}, "Same-Site embed");
promise_test(t => {
return new Promise((resolve, reject) => {
let key = "embed-cross-site";
let e = document.createElement('embed');
e.src = "https://{{hosts[alt][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=" + key;
e.onload = e => {
let expected = {"destination":"embed", "site":"cross-site"};
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key)
.then(response => response.text())
.then(text => assert_header_equals(text, expected))
.then(_ => resolve())
.catch(e => reject(e));
};
document.body.appendChild(e);
})
}, "Cross-Site embed");
</script>

View file

@ -10,7 +10,6 @@
assert_header_equals(j.header, {
"cause": undefined,
"destination": "",
"target": "subresource",
"site": "same-origin"
});
});
@ -23,7 +22,6 @@
assert_header_equals(j.header, {
"cause": undefined,
"destination": "",
"target": "subresource",
"site": "same-site"
});
});
@ -36,7 +34,6 @@
assert_header_equals(j.header, {
"cause": undefined,
"destination": "",
"target": "subresource",
"site": "cross-site"
});
});

View file

@ -0,0 +1,104 @@
<!DOCTYPE html>
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/fetch/sec-metadata/resources/helper.js></script>
<body>
<div id="test1">1</div>
<div id="test2">2</div>
<div id="test3">3</div>
<!-- Same-Origin request -->
<style>
@font-face {
font-family: myFirstFont;
src: url(https://{{host}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=font-same-origin);
}
#test1 {
font-family: myFirstFont;
}
</style>
<!-- Same-Site request -->
<style>
@font-face {
font-family: mySecondFont;
src: url(https://{{hosts[][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=font-same-site);
}
#test2 {
font-family: mySecondFont;
}
</style>
<!-- Cross-Site request -->
<style>
@font-face {
font-family: myThirdFont;
src: url(https://{{hosts[alt][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=font-cross-site);
}
#test3 {
font-family: myThirdFont;
}
</style>
</body>
<script>
document.fonts.ready.then(function () {
test_same_origin();
test_same_site();
test_cross_site();
});
function test_same_origin(){
var same_origin_test = async_test("Same-Origin font");
same_origin_test.step(function () {
key = "font-same-origin";
expected_same_origin = {"destination":"font", "site":"same-origin"};
// Requests from the server the saved value of the Sec-Metadata header
same_origin_xhr = new XMLHttpRequest();
same_origin_xhr.open("PUT", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key);
// Async test step triggered when the response is loaded
same_origin_xhr.onreadystatechange = same_origin_test.step_func(function () {
verify_response(same_origin_xhr, same_origin_test, expected_same_origin)
});
same_origin_xhr.send();
});
}
function test_same_site(){
var same_site_test = async_test("Same-Site font");
same_site_test.step(function () {
key = "font-same-site";
expected_same_site = {"destination":"font", "site":"same-site"};
// Requests from the server the saved value of the Sec-Metadata header
same_site_xhr = new XMLHttpRequest();
same_site_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key);
// Async test step triggered when the response is loaded
same_site_xhr.onreadystatechange = same_site_test.step_func(function () {
verify_response(same_site_xhr, same_site_test, expected_same_site)
});
same_site_xhr.send();
});
}
function test_cross_site(){
var cross_site_test = async_test("Cross-Site font");
cross_site_test.step(function () {
key = "font-cross-site";
expected_cross_site = {"destination":"font", "site":"cross-site"};
// Requests from the server the saved value of the Sec-Metadata header
cross_site_xhr = new XMLHttpRequest();
cross_site_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key);
// Async test step triggered when the response is loaded
cross_site_xhr.onreadystatechange = cross_site_test.step_func(function () {
verify_response(cross_site_xhr, cross_site_test, expected_cross_site)
});
cross_site_xhr.send();
});
}
</script>

View file

@ -13,8 +13,7 @@
assert_header_equals(e.data, {
"cause": "forced",
"destination": "document",
"target": "nested",
"destination": "nested-document",
"site": "same-origin"
});
t.done();
@ -32,8 +31,7 @@
assert_header_equals(e.data, {
"cause": "forced",
"destination": "document",
"target": "nested",
"destination": "nested-document",
"site": "same-site"
});
t.done();
@ -51,8 +49,7 @@
assert_header_equals(e.data, {
"cause": "forced",
"destination": "document",
"target": "nested",
"destination": "nested-document",
"site": "cross-site"
});
t.done();

View file

@ -14,7 +14,6 @@
assert_header_equals(decodeImageData(extractImageData(img)).headers["sec-metadata"], {
"cause": undefined,
"destination": "image",
"target": "subresource",
"site": "same-origin"
});
}),
@ -29,7 +28,6 @@
assert_header_equals(decodeImageData(extractImageData(img)).headers["sec-metadata"], {
"cause": undefined,
"destination": "image",
"target": "subresource",
"site": "same-site"
});
}),
@ -44,7 +42,6 @@
assert_header_equals(decodeImageData(extractImageData(img)).headers["sec-metadata"], {
"cause": undefined,
"destination": "image",
"target": "subresource",
"site": "cross-site"
});
}),

View file

@ -0,0 +1,65 @@
<!DOCTYPE html>
<meta charset="utf-8"/>
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/fetch/sec-metadata/resources/helper.js></script>
<body>
<script>
promise_test(t => {
return new Promise((resolve, reject) => {
let key = "object-same-origin";
let e = document.createElement('object');
e.data = "https://{{host}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=" + key;
e.onload = e => {
let expected = {"destination":"object", "site":"same-origin"};
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key)
.then(response => response.text())
.then(text => assert_header_equals(text, expected))
.then(_ => resolve())
.catch(e => reject(e));
};
document.body.appendChild(e);
})
}, "Same-Origin object");
promise_test(t => {
return new Promise((resolve, reject) => {
let key = "object-same-site";
let e = document.createElement('object');
e.data = "https://{{hosts[][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=" + key;
e.onload = e => {
let expected = {"destination":"object", "site":"same-site"};
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key)
.then(response => response.text())
.then(text => assert_header_equals(text, expected))
.then(_ => resolve())
.catch(e => reject(e));
};
document.body.appendChild(e);
})
}, "Same-Site object");
promise_test(t => {
return new Promise((resolve, reject) => {
let key = "object-cross-site";
let e = document.createElement('object');
e.data = "https://{{hosts[alt][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=" + key;
e.onload = e => {
let expected = {"destination":"object", "site":"cross-site"};
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key)
.then(response => response.text())
.then(text => assert_header_equals(text, expected))
.then(_ => resolve())
.catch(e => reject(e));
};
document.body.appendChild(e);
})
}, "Cross-Site object");
</script>

View file

@ -0,0 +1,30 @@
<!DOCTYPE html>
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/fetch/sec-metadata/resources/helper.js></script>
<body>
<!-- redirect Cross-Site -> Cross-Site -->
<img onload="test_cross_site()" onerror="test_cross_site()" src="https://{{hosts[alt][www]}}:{{ports[https][0]}}/xhr/resources/redirect.py?location=https://{{hosts[alt][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=redirect-cross-site-cross-site"></img>
</body>
<script>
function test_cross_site(){
var cross_site_test = async_test("Cross-Site -> Cross-Site redirect");
cross_site_test.step(function () {
filename = "redirect-cross-site-cross-site";
expected_cross_site = {"destination":"image", "site":"cross-site"};
// Requests from the server the saved value of the Sec-Metadata header
cross_site_xhr = new XMLHttpRequest();
cross_site_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + filename);
// Async test step triggered when the response is loaded
cross_site_xhr.onreadystatechange = cross_site_test.step_func(function () {
verify_response(cross_site_xhr, cross_site_test, expected_cross_site)
});
cross_site_xhr.send();
});
}
</script>

View file

@ -0,0 +1,31 @@
<!DOCTYPE html>
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/fetch/sec-metadata/resources/helper.js></script>
<body>
<!-- redirect Cross-Site -> Same-Origin -->
<img onload="test_same_origin()" onerror="test_same_origin()" src="https://{{hosts[alt][www]}}:{{ports[https][0]}}/xhr/resources/redirect.py?location=https://{{host}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=redirect-cross-site-same-origin"></img>
</body>
<script>
function test_same_origin(){
var same_origin_test = async_test("Cross-Site -> Same-Origin redirect");
same_origin_test.step(function () {
filename = "redirect-cross-site-same-origin";
expected_same_origin = {"destination":"image", "site":"cross-site"};
// Requests from the server the saved value of the Sec-Metadata header
same_origin_xhr = new XMLHttpRequest();
same_origin_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + filename);
// Async test step triggered when the response is loaded
same_origin_xhr.onreadystatechange = same_origin_test.step_func(function () {
verify_response(same_origin_xhr, same_origin_test, expected_same_origin)
});
same_origin_xhr.send();
});
}
</script>

View file

@ -0,0 +1,30 @@
<!DOCTYPE html>
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/fetch/sec-metadata/resources/helper.js></script>
<body>
<!-- redirect Cross-Site -> Same-Site -->
<img onload="test_same_site()" onerror="test_same_site()" src="https://{{hosts[alt][www]}}:{{ports[https][0]}}/xhr/resources/redirect.py?location=https://{{hosts[][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=redirect-cross-site-same-site"></img>
</body>
<script>
function test_same_site(){
var same_site_test = async_test("Cross-Site -> Same-Site redirect");
same_site_test.step(function () {
filename = "redirect-cross-site-same-site";
expected_same_site = {"destination":"image", "site":"cross-site"};
// Requests from the server the saved value of the Sec-Metadata header
same_site_xhr = new XMLHttpRequest();
same_site_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + filename);
// Async test step triggered when the response is loaded
same_site_xhr.onreadystatechange = same_site_test.step_func(function () {
verify_response(same_site_xhr, same_site_test, expected_same_site)
});
same_site_xhr.send();
});
}
</script>

View file

@ -0,0 +1,30 @@
<!DOCTYPE html>
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/fetch/sec-metadata/resources/helper.js></script>
<body>
<!-- redirect Same-Origin -> Cross-Site -->
<img onload="test_cross_site()" onerror="test_cross_site()" src="https://{{host}}:{{ports[https][0]}}/xhr/resources/redirect.py?location=https://{{hosts[alt][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=redirect-same-origin-cross-site"></img>
</body>
<script>
function test_cross_site(){
var cross_site_test = async_test("Same-Origin -> Cross-Site redirect");
cross_site_test.step(function () {
filename = "redirect-same-origin-cross-site";
expected_cross_site = {"destination":"image", "site":"same-origin"};
// Requests from the server the saved value of the Sec-Metadata header
cross_site_xhr = new XMLHttpRequest();
cross_site_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + filename);
// Async test step triggered when the response is loaded
cross_site_xhr.onreadystatechange = cross_site_test.step_func(function () {
verify_response(cross_site_xhr, cross_site_test, expected_cross_site)
});
cross_site_xhr.send();
});
}
</script>

View file

@ -0,0 +1,31 @@
<!DOCTYPE html>
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/fetch/sec-metadata/resources/helper.js></script>
<body>
<!-- redirect Same-Origin -> Same-Origin -->
<img onload="test_same_origin()" onerror="test_same_origin()" src="https://{{host}}:{{ports[https][0]}}/xhr/resources/redirect.py?location=https://{{host}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=redirect-same-origin-same-origin"></img>
</body>
<script>
function test_same_origin(){
var same_origin_test = async_test("Same-Origin -> Same-Origin redirect");
same_origin_test.step(function () {
filename = "redirect-same-origin-same-origin";
expected_same_origin = {"destination":"image", "site":"same-origin"};
// Requests from the server the saved value of the Sec-Metadata header
same_origin_xhr = new XMLHttpRequest();
same_origin_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + filename);
// Async test step triggered when the response is loaded
same_origin_xhr.onreadystatechange = same_origin_test.step_func(function () {
verify_response(same_origin_xhr, same_origin_test, expected_same_origin)
});
same_origin_xhr.send();
});
}
</script>

View file

@ -0,0 +1,31 @@
<!DOCTYPE html>
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/fetch/sec-metadata/resources/helper.js></script>
<body>
<!-- redirect Same-Origin -> Same-Site -->
<img onload="test_same_site()" onerror="test_same_site()" src="https://{{host}}:{{ports[https][0]}}/xhr/resources/redirect.py?location=https://{{hosts[][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=redirect-same-origin-same-site"></img>
</body>
<script>
function test_same_site(){
var same_site_test = async_test("Same-Origin -> Same-Site redirect");
same_site_test.step(function () {
filename = "redirect-same-origin-same-site";
expected_same_site = {"destination":"image", "site":"same-origin"};
// Requests from the server the saved value of the Sec-Metadata header
same_site_xhr = new XMLHttpRequest();
same_site_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + filename);
// Async test step triggered when the response is loaded
same_site_xhr.onreadystatechange = same_site_test.step_func(function () {
verify_response(same_site_xhr, same_site_test, expected_same_site)
});
same_site_xhr.send();
});
}
</script>

View file

@ -0,0 +1,31 @@
<!DOCTYPE html>
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/fetch/sec-metadata/resources/helper.js></script>
<body>
<!-- redirect Same-Site -> Cross-Site -->
<img onload="test_cross_site()" onerror="test_cross_site()" src="https://{{hosts[][www]}}:{{ports[https][0]}}/xhr/resources/redirect.py?location=https://{{hosts[alt][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=redirect-same-site-cross-site"></img>
</body>
<script>
function test_cross_site(){
var cross_site_test = async_test("Same-Site -> Cross-Site redirect");
cross_site_test.step(function () {
key = "redirect-same-site-cross-site";
expected_cross_site = {"destination":"image", "site":"same-site"};
// Requests from the server the saved value of the Sec-Metadata header
cross_site_xhr = new XMLHttpRequest();
cross_site_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key);
// Async test step triggered when the response is loaded
cross_site_xhr.onreadystatechange = cross_site_test.step_func(function () {
verify_response(cross_site_xhr, cross_site_test, expected_cross_site)
});
cross_site_xhr.send();
});
}
</script>

View file

@ -0,0 +1,31 @@
<!DOCTYPE html>
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/fetch/sec-metadata/resources/helper.js></script>
<body>
<!-- redirect Same-Site -> Same-Origin -->
<img onload="test_same_origin()" onerror="test_same_origin()" src="https://{{hosts[][www]}}:{{ports[https][0]}}/xhr/resources/redirect.py?location=https://{{host}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=redirect-same-site-same-origin"></img>
</body>
<script>
function test_same_origin(){
var same_origin_test = async_test("Same-Site -> Same-Origin redirect");
same_origin_test.step(function () {
key = "redirect-same-site-same-origin";
expected_same_origin = {"destination":"image", "site":"same-site"};
// Requests from the server the saved value of the Sec-Metadata header
same_origin_xhr = new XMLHttpRequest();
same_origin_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key);
// Async test step triggered when the response is loaded
same_origin_xhr.onreadystatechange = same_origin_test.step_func(function () {
verify_response(same_origin_xhr, same_origin_test, expected_same_origin)
});
same_origin_xhr.send();
});
}
</script>

View file

@ -0,0 +1,31 @@
<!DOCTYPE html>
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/fetch/sec-metadata/resources/helper.js></script>
<body>
<!-- redirect Same-Site -> Same-Site -->
<img onload="test_same_site()" onerror="test_same_site()" src="https://{{hosts[][www]}}:{{ports[https][0]}}/xhr/resources/redirect.py?location=https://{{hosts[][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=redirect-same-site-same-site"></img>
</body>
<script>
function test_same_site(){
var same_site_test = async_test("Same-Site -> Same-Site redirect");
same_site_test.step(function () {
key = "redirect-same-site-same-site";
expected_same_site = {"destination":"image", "site":"same-site"};
// Requests from the server the saved value of the Sec-Metadata header
same_site_xhr = new XMLHttpRequest();
same_site_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key);
// Async test step triggered when the response is loaded
same_site_xhr.onreadystatechange = same_site_test.step_func(function () {
verify_response(same_site_xhr, same_site_test, expected_same_site)
});
same_site_xhr.send();
});
}
</script>

View file

@ -0,0 +1,35 @@
<!DOCTYPE html>
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/fetch/sec-metadata/resources/helper.js></script>
<link id="style" href="https://foo.bar" rel="stylesheet">
<body></body>
<script>
let counter = 0;
document.addEventListener("securitypolicyviolation", (e) => {
counter++;
if (counter == 3) {
promise_test(t => {
expected = {"destination":"report", "site":"same-origin"};
return fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=report-same-origin")
.then(response => response.text())
.then(text => assert_header_equals(text, expected));
}, "Same-Origin report");
promise_test(t => {
expected = {"destination":"report", "site":"same-site"};
return fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=report-same-site")
.then(response => response.text())
.then(text => assert_header_equals(text, expected));
}, "Same-site report");
promise_test(t => {
expected = {"destination":"report", "site":"cross-site"};
return fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=report-cross-site")
.then(response => response.text())
.then(text => assert_header_equals(text, expected));
}, "Cross-site report");
}
});
</script>

View file

@ -0,0 +1,3 @@
Content-Security-Policy: style-src 'self' 'unsafe-inline'; report-uri /fetch/sec-metadata/resources/record-header.py?file=report-same-origin
Content-Security-Policy: style-src 'self' 'unsafe-inline'; report-uri https://{{hosts[][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=report-same-site
Content-Security-Policy: style-src 'self' 'unsafe-inline'; report-uri https://{{hosts[alt][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=report-cross-site

View file

@ -0,0 +1 @@
self.postMessage("Loaded");

View file

@ -8,5 +8,5 @@ def main(request, response):
headers.append(("Access-Control-Allow-Origin", request.headers["origin"]))
body = json.dumps({ "header": request.headers["sec-metadata"] })
body = json.dumps({ "header": request.headers.get("sec-metadata", "") })
return headers, body

View file

@ -3,6 +3,6 @@ import json
def main(request, response):
headers = [("Content-Type", "text/javascript")]
body = "var header = %s;" % json.dumps(request.headers["sec-metadata"]);
body = "var header = %s;" % json.dumps(request.headers.get("sec-metadata", ""));
return headers, body

View file

@ -9,9 +9,18 @@ function parse_metadata(value) {
}
function assert_header_equals(value, expected) {
// check that the returned value is an object, not a String
assert_not_equals(value, "", "Empty Sec-Metadata header.");
let result = parse_metadata(value);
assert_equals(result.cause, expected.cause, "cause");
assert_equals(result.destination, expected.destination, "destination");
assert_equals(result.target, expected.target, "target");
assert_equals(result.site, expected.site, "site");
}
function verify_response(xhr, test, expected){
if (xhr.readyState === 4) {
assert_header_equals(xhr.responseText, expected);
test.done();
}
}

View file

@ -0,0 +1,114 @@
import os
import uuid
import hashlib
import time
resourcePath = os.getcwd() + "/fetch/sec-metadata/resources/"
def main(request, response):
## Get the query parameter (key) from URL ##
## Tests will record POST requests (CSP Report) and GET (rest) ##
if request.GET:
key = request.GET['file']
elif request.POST:
key = request.POST['file']
## Convert the key from String to UUID valid String ##
testId = hashlib.md5(key).hexdigest()
## Handle the header retrieval request ##
if 'retrieve' in request.GET:
response.writer.write_status(200)
response.writer.end_headers()
header_value = request.server.stash.take(testId)
if header_value != None:
response.writer.write(header_value)
response.close_connection = True
## Record incoming Sec-Metadata header value
else:
## Return empty string as a default value ##
header = request.headers.get("Sec-Metadata", "")
try:
request.server.stash.put(testId, header)
except KeyError:
## The header is already recorded
pass
## Prevent the browser from caching returned responses and allow CORS ##
response.headers.set("Access-Control-Allow-Origin", "*")
response.headers.set("Cache-Control", "no-cache, no-store, must-revalidate")
response.headers.set("Pragma", "no-cache")
response.headers.set("Expires", "0")
## Add a valid ServiceWorker Content-Type ##
if key.startswith("serviceworker"):
response.headers.set("Content-Type", "application/javascript")
## Return a valid .vtt content for the <track> tag ##
if key.startswith("track"):
return "WEBVTT"
## Return a valid SharedWorker ##
if key.startswith("sharedworker"):
response.headers.set("Content-Type", "application/javascript")
file = open(resourcePath + "sharedWorker.js", "r")
shared_worker = file.read()
file.close()
return shared_worker
## Return a valid font content and Content-Type ##
if key.startswith("font"):
file = open("fonts/Ahem.ttf", "r")
font = file.read()
file.close()
return font
## Return a valid audio content and Content-Type ##
if key.startswith("audio"):
response.headers.set("Content-Type", "audio/mpeg")
file = open("media/sound_5.mp3", "r")
audio = file.read()
file.close()
return audio
## Return a valid video content and Content-Type ##
if key.startswith("video"):
response.headers.set("Content-Type", "video/mp4")
file = open("media/A4.mp4", "r")
video = file.read()
file.close()
return video
## Return a valid style content and Content-Type ##
if key.startswith("style") or key.startswith("embed") or key.startswith("object"):
response.headers.set("Content-Type", "text/html")
return "<html>EMBED!</html>"
## Return a valid image content and Content-Type for redirect requests ##
if key.startswith("redirect"):
response.headers.set("Content-Type", "image/jpeg")
file = open("media/1x1-green.png", "r")
image = file.read()
file.close()
return image
## Return a valid dedicated worker
if key.startswith("worker"):
response.headers.set("Content-Type", "application/javascript")
return "self.postMessage('loaded');"
## Return a valid XSLT
if key.startswith("xslt"):
response.headers.set("Content-Type", "text/xsl")
return """<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>"""

View file

@ -0,0 +1,9 @@
onconnect = function(e) {
var port = e.ports[0];
port.addEventListener('message', function(e) {
port.postMessage("Ready");
});
port.start();
}

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="https://{{host}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=xslt-same-origin" type="text/xsl" ?>
<?xml-stylesheet href="https://{{hosts[][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=xslt-same-site" type="text/xsl" ?>
<?xml-stylesheet href="https://{{hosts[alt][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=xslt-cross-site" type="text/xsl" ?>
<!-- postMessage parent back when the resources are loaded -->
<script xmlns="http://www.w3.org/1999/xhtml"><![CDATA[
setTimeout(function(){
if (window.opener)
window.opener.postMessage("", "*");
if (window.top != window)
window.top.postMessage("", "*");}, 100);
]]></script>

View file

@ -12,7 +12,6 @@
assert_header_equals(header, {
"cause": undefined,
"destination": "script",
"target": "subresource",
"site": "same-origin"
});
}, "Same-origin script");
@ -27,7 +26,6 @@
assert_header_equals(header, {
"cause": undefined,
"destination": "script",
"target": "subresource",
"site": "same-site"
});
}, "Same-site script");
@ -42,7 +40,6 @@
assert_header_equals(header, {
"cause": undefined,
"destination": "script",
"target": "subresource",
"site": "cross-site"
});
}, "Cross-site script");

View file

@ -0,0 +1,51 @@
<!DOCTYPE html>
<meta charset="utf-8"/>
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/fetch/sec-metadata/resources/helper.js></script>
<body>
<script>
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('/fetch/sec-metadata/resources/record-header.py?file=serviceworker-same-origin').then(function(registration) {
test_same_origin();
// uninstall the serviceworker after the test
navigator.serviceWorker.getRegistrations().then(function(registrations) {
for(let registration of registrations) {
registration.unregister()
}
})
}, function(err) {
// registration failed
});
});
}
else {
test(function () {
done();
}, "Browser does not support serviceworker");
}
</script>
</body>
<script>
function test_same_origin(){
var same_origin_test = async_test("Same-Origin serviceworker");
same_origin_test.step(function () {
key = "serviceworker-same-origin";
expected_same_origin = {"destination":"serviceworker", "site":"same-origin"};
// Requests from the server the saved value of the Sec-Metadata header
same_origin_xhr = new XMLHttpRequest();
same_origin_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key);
// Async test step triggered when the response is loaded
same_origin_xhr.onreadystatechange = same_origin_test.step_func(function () {
verify_response(same_origin_xhr, same_origin_test, expected_same_origin)
});
same_origin_xhr.send();
});
}
</script>

View file

@ -0,0 +1,44 @@
<!DOCTYPE html>
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/fetch/sec-metadata/resources/helper.js></script>
<script>
// TESTS //
if (window.Worker) {
// Same-Origin test
var sharedWorker = new SharedWorker('/fetch/sec-metadata/resources/record-header.py?file=sharedworker-same-origin');
sharedWorker.port.start();
sharedWorker.onerror = function(){
test_same_origin();
}
sharedWorker.port.onmessage = function(e) {
test_same_origin();
}
sharedWorker.port.postMessage("Ready");
}
function test_same_origin(){
var same_origin_test = async_test("Same-Origin sharedworker");
same_origin_test.step(function () {
key = "sharedworker-same-origin";
expected_same_origin = {"destination":"sharedworker", "site":"same-origin"};
// Requests from the server the saved value of the Sec-Metadata header
same_origin_xhr = new XMLHttpRequest();
same_origin_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key);
// Async test step triggered when the response is loaded
same_origin_xhr.onreadystatechange = same_origin_test.step_func(function () {
verify_response(same_origin_xhr, same_origin_test, expected_same_origin)
});
same_origin_xhr.send();
});
}
</script>
<body></body>

View file

@ -0,0 +1,75 @@
<!DOCTYPE html>
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/fetch/sec-metadata/resources/helper.js></script>
<script>
function test_same_origin() {
var same_origin_test = async_test("Same-Origin style");
same_origin_test.step(function () {
key = "style-same-origin";
expected_same_origin = {"destination":"style", "site":"same-origin"};
// Requests from the server the saved value of the Sec-Metadata header
same_origin_xhr = new XMLHttpRequest();
same_origin_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key);
// Async test step triggered when the response is loaded
same_origin_xhr.onreadystatechange = same_origin_test.step_func(function () {
verify_response(same_origin_xhr, same_origin_test, expected_same_origin)
});
same_origin_xhr.send();
});
}
function test_same_site() {
var same_site_test = async_test("Same-Site style");
same_site_test.step(function () {
key = "style-same-site";
expected_same_site = {"destination":"style", "site":"same-site"};
// Requests from the server the saved value of the Sec-Metadata header
same_site_xhr = new XMLHttpRequest();
same_site_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key);
// Async test step triggered when the response is loaded
same_site_xhr.onreadystatechange = same_site_test.step_func(function () {
verify_response(same_site_xhr, same_site_test, expected_same_site)
});
same_site_xhr.send();
});
}
function test_cross_site() {
var cross_site_test = async_test("Cross-Site style");
cross_site_test.step(function () {
key = "style-cross-site";
expected_cross_site = {"destination":"style", "site":"cross-site"};
// Requests from the server the saved value of the Sec-Metadata header
cross_site_xhr = new XMLHttpRequest();
cross_site_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key);
// Async test step triggered when the response is loaded
cross_site_xhr.onreadystatechange = cross_site_test.step_func(function () {
verify_response(cross_site_xhr, cross_site_test, expected_cross_site)
});
cross_site_xhr.send();
});
}
</script>
<body>
<!-- Same-Origin request -->
<link href="https://{{host}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=style-same-origin"
rel="stylesheet" onload="test_same_origin()" onerror="test_same_origin()">
<!-- Same-Site request -->
<link href="https://{{hosts[][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=style-same-site"
rel="stylesheet" onload="test_same_site()" onerror="test_same_site()">
<!-- Cross-Site request -->
<link href="https://{{hosts[alt][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=style-cross-site"
rel="stylesheet" onload="test_cross_site()" onerror="test_cross_site()">
</body>

View file

@ -0,0 +1,79 @@
<!DOCTYPE html>
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/fetch/sec-metadata/resources/helper.js></script>
<body>
</body>
<script>
function createVideoElement() {
let el = document.createElement('video');
el.src = "/media/movie_5.mp4";
el.setAttribute("controls", "");
el.setAttribute("crossorigin", "");
return el;
}
function createTrack() {
let el = document.createElement("track");
el.setAttribute("default", "");
el.setAttribute("kind", "captions");
el.setAttribute("srclang", "en");
return el;
}
promise_test(t => {
return new Promise((resolve, reject) => {
let video = createVideoElement();
let el = createTrack();
el.src = "https://{{host}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=track-same-origin";
el.onload = t.step_func(_ => {
expected = {"destination":"track", "site":"same-origin"};
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=track-same-origin")
.then(response => response.text())
.then(text => assert_header_equals(text, expected))
.then(_ => resolve());
});
video.appendChild(el);
document.body.appendChild(video);
});
}, "Same-Origin track");
promise_test(t => {
return new Promise((resolve, reject) => {
let video = createVideoElement();
let el = createTrack();
el.src = "https://{{hosts[][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=track-same-site";
el.onload = t.step_func(_ => {
expected = {"destination":"track", "site":"same-site"};
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=track-same-site")
.then(response => response.text())
.then(text => assert_header_equals(text, expected))
.then(resolve)
.catch(reject);
});
video.appendChild(el);
document.body.appendChild(video);
});
}, "Same-Site track");
promise_test(t => {
return new Promise((resolve, reject) => {
let video = createVideoElement();
let el = createTrack();
el.src = "https://{{hosts[alt][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=track-cross-site";
el.onload = t.step_func(_ => {
expected = {"destination":"track", "site":"cross-site"};
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=track-cross-site")
.then(response => response.text())
.then(text => assert_header_equals(text, expected))
.then(resolve)
.catch(reject);
});
video.appendChild(el);
document.body.appendChild(video);
});
}, "Cross-Site track");
</script>

View file

@ -17,7 +17,6 @@
assert_header_equals(e.data, {
"cause": "forced",
"destination": "document",
"target": "top-level",
"site": "same-origin"
});
t.done();
@ -34,7 +33,6 @@
assert_header_equals(e.data, {
"cause": "forced",
"destination": "document",
"target": "top-level",
"site": "same-site"
});
t.done();
@ -51,7 +49,6 @@
assert_header_equals(e.data, {
"cause": "forced",
"destination": "document",
"target": "top-level",
"site": "cross-site"
});
t.done();
@ -71,7 +68,6 @@
assert_header_equals(e.data, {
"cause": "user-activated",
"destination": "document",
"target": "top-level",
"site": "same-origin"
});
t.done();
@ -93,7 +89,6 @@
assert_header_equals(e.data, {
"cause": "user-activated",
"destination": "document",
"target": "top-level",
"site": "same-site"
});
t.done();
@ -115,7 +110,6 @@
assert_header_equals(e.data, {
"cause": "user-activated",
"destination": "document",
"target": "top-level",
"site": "cross-site"
});
t.done();

View file

@ -0,0 +1,23 @@
<!DOCTYPE html>
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/fetch/sec-metadata/resources/helper.js></script>
<script>
promise_test(t => {
return new Promise((resolve, reject) => {
let key = "worker-same-origin";
let w = new Worker("/fetch/sec-metadata/resources/record-header.py?file=" + key);
w.onmessage = e => {
let expected = {"destination":"worker", "site":"same-origin"};
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key)
.then(response => response.text())
.then(text => assert_header_equals(text, expected))
.then(_ => resolve())
.catch(e => reject(e));
};
});
}, "Same-Origin worker");
</script>
<body></body>

View file

@ -0,0 +1,38 @@
<!DOCTYPE html>
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/fetch/sec-metadata/resources/helper.js></script>
<script>
// Open a window with XML document which loads resources via <?xml-stylesheet/> tag
let w = window.open("resources/xslt-test.sub.xml");
window.addEventListener('message', function(e) {
if (e.source != w)
return;
promise_test(t => {
let expected = {"destination":"xslt", "site":"same-origin"};
return fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=xslt-same-origin")
.then(response => response.text())
.then(text => assert_header_equals(text, expected));
}, "Same-Origin xslt");
promise_test(t => {
let expected = {"destination":"xslt", "site":"same-site"};
return fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=xslt-same-site")
.then(response => response.text())
.then(text => assert_header_equals(text, expected));
}, "Same-site xslt");
promise_test(t => {
let expected = {"destination":"xslt", "site":"cross-site"};
return fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=xslt-cross-site")
.then(response => response.text())
.then(text => assert_header_equals(text, expected));
}, "Cross-site xslt");
w.close();
});
</script>

View file

@ -1,32 +1,49 @@
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<link rel="help" href="https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#constructing-the-form-data-set">
<link ref="help" href="https://xhr.spec.whatwg.org/#dom-formdata">
<link rel="help" href="https://fetch.spec.whatwg.org/#concept-bodyinit-extract">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<iframe name="frame1"></iframe>
<form accept-charset="iso-8859-1" target="frame1" action="/common/blank.html">
<input type="hidden" name="_charset_">
<iframe name="frame1" id="frame1"></iframe>
<form accept-charset="iso-8859-1" target="frame1" action="/common/blank.html" id="form1">
<input type="hidden" name="_charset_">
</form>
<iframe name="frame2" id="frame2"></iframe>
<form target="frame2" action="/common/blank.html" id="form2">
<input type="text" name="foo">
<button type="close" name="close" value="true">close</button>
<button type="button" name="button" value="true">button</button>
<button type="reset" name="reset" value="true">reset</button>
<button type="submit" name="submit" value="true">submit</button>
</form>
<script>
const form1 = document.getElementById('form1'),
form2 = document.getElementById('form2'),
frame1 = document.getElementById('frame1'),
frame2 = document.getElementById('frame2');
test(() => {
let formData = new FormData(document.querySelector('form'));
const formData = new FormData(form1);
assert_equals(formData.get('_charset_'), 'UTF-8');
}, 'FormData constructor always produces UTF-8 _charset_ value.');
let t = async_test('_charset_ control sets the expected encoding name.');
t.step(() => {
let iframe = document.querySelector('iframe');
iframe.onload = t.step_func_done(() => {
assert_not_equals(iframe.contentDocument.URL.indexOf('_charset_=windows-1252'), -1);
async_test(t => {
frame1.onload = t.step_func_done(() => {
assert_not_equals(frame1.contentDocument.URL.indexOf('_charset_=windows-1252'), -1);
});
document.querySelector('form').submit();
});
form1.submit();
}, '_charset_ control sets the expected encoding name.');
async_test(t => {
frame2.onload = t.step_func_done(() => {
assert_equals(frame2.contentDocument.URL.split("?")[1], 'foo=&submit=true');
});
form2.submit.click();
}, 'The button cannot be setted if it is not a submitter.');
</script>
</body>

View file

@ -1,15 +1,60 @@
for (const ev of ["unload", "beforeunload", "pagehide"]) {
for (const [ev, target] of [
["beforeunload", iframe => iframe.contentWindow],
["pagehide", iframe => iframe.contentWindow],
["unload", iframe => iframe.contentWindow],
["visibilitychange", iframe => iframe.contentDocument],
]) {
async_test(t => {
const iframe = document.body.appendChild(document.createElement("iframe"));
t.add_cleanup(() => iframe.remove());
iframe.src = "/common/blank.html";
iframe.onload = t.step_func(() => {
iframe.contentWindow.addEventListener(ev, t.step_func_done(() => {
target(iframe).addEventListener(ev, t.step_func_done(() => {
assert_not_equals(iframe.contentDocument.childNodes.length, 0);
assert_equals(iframe.contentDocument.open(), iframe.contentDocument);
assert_not_equals(iframe.contentDocument.childNodes.length, 0);
}));
iframe.src = "about:blank";
});
}, `document.open should bail out when ignore-opens-during-unload is greater than 0 during ${ev} event`);
}, `document.open should bail out when ignore-opens-during-unload is greater than 0 during ${ev} event (in top-level browsing context)`);
async_test(t => {
const iframe = document.body.appendChild(document.createElement("iframe"));
t.add_cleanup(() => iframe.remove());
iframe.src = "/common/blank.html?1";
iframe.onload = t.step_func(() => {
const doc = iframe.contentDocument;
const innerIframe = doc.body.appendChild(doc.createElement("iframe"));
innerIframe.src = "/common/blank.html?2";
innerIframe.onload = t.step_func(() => {
// Navigate the parent, listen on the child, and open() the parent.
target(innerIframe).addEventListener(ev, t.step_func_done(() => {
assert_not_equals(iframe.contentDocument.childNodes.length, 0);
iframe.contentDocument.open();
assert_not_equals(iframe.contentDocument.childNodes.length, 0);
}));
iframe.src = "about:blank";
});
});
}, `document.open should bail out when ignore-opens-during-unload is greater than 0 during ${ev} event (open(parent) while unloading parent and child)`);
async_test(t => {
const iframe = document.body.appendChild(document.createElement("iframe"));
t.add_cleanup(() => iframe.remove());
iframe.src = "/common/blank.html?1";
iframe.onload = t.step_func(() => {
const doc = iframe.contentDocument;
const innerIframe = doc.body.appendChild(doc.createElement("iframe"));
innerIframe.src = "/common/blank.html?2";
innerIframe.onload = t.step_func(() => {
// Navigate the child, listen on the child, and open() the parent.
target(innerIframe).addEventListener(ev, t.step_func_done(() => {
assert_not_equals(iframe.contentDocument.childNodes.length, 0);
iframe.contentDocument.open();
assert_equals(iframe.contentDocument.childNodes.length, 0);
}));
innerIframe.src = "about:blank";
});
});
}, `document.open should bail out when ignore-opens-during-unload is greater than 0 during ${ev} event (open(parent) while unloading child only)`);
}

View file

@ -0,0 +1,104 @@
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<title>TestDriver bless method</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script>
promise_test(() => {
return test_driver.bless('empty', () => {});
}, 'functions in the absence of a `body` element');
</script>
</head>
<body>
<script>
// At the time of this writing, the only standard requirement for user
// activation concerns the interaction between iframe elements and their parent
// browsing contexts [1]. Because testdriver.js currently cannot operate within
// an iframe, the standard requirement cannot be used to verify the correctness
// of the `bless` method. Instead, rely on the non-standard restriction on
// unattended media playback. Browsers which do not implement such a
// restriction will pass this test spuriously.
//
// [1] https://html.spec.whatwg.org/multipage/origin.html#attr-iframe-sandbox-allow-top-navigation-by-user-activation
promise_test(() => {
const video = document.createElement('video');
video.setAttribute('src', '/media/counting.ogv');
document.body.appendChild(video);
return test_driver.bless('start video playback', () => video.play())
}, 'user activation');
promise_test(() => {
return test_driver.bless('demonstrates return value without action')
.then((value) => {
assert_equals(value, undefined);
});
}, 'no action function provided');
promise_test(() => {
const expectedValue = {};
return test_driver.bless('demonstrate a synchronous return value', () => {
return expectedValue;
}).then((actualValue) => {
assert_equals(
actualValue,
expectedValue,
'the promise should be fulfilled with the returned value'
);
});
}, 'synchronous return value');
promise_test(() => {
const expectedError = new Error();
return test_driver.bless('demonstrates a synchronous error', () => {
throw expectedError;
})
.then(() => {
assert_unreached('the promise should be rejected');
}, (actualError) => {
assert_equals(
actualError,
expectedError,
'the promise should be rejected with the thrown value'
);
});
}, 'synchronous error');
promise_test(() => {
const expectedValue = {};
return test_driver.bless('demonstrate an asynchronous return value', () => {
return Promise.resolve(expectedValue);
}).then((actualValue) => {
assert_equals(
actualValue,
expectedValue,
'the promise should be fulfilled with the fulfillment value'
);
});
}, 'asynchronous return value');
promise_test(() => {
const expectedError = new Error();
return test_driver.bless('demonstrates an asynchronous error', () => {
return Promise.reject(expectedError);
})
.then(() => {
assert_unreached('the promise should be rejected');
}, (actualError) => {
assert_equals(
actualError,
expectedError,
'the promise should be rejected with the rejected value'
);
});
}, 'asynchronous error');
</script>
</body>

View file

@ -1,32 +0,0 @@
// GENERATED CONTENT - DO NOT EDIT
// Content was automatically extracted by Reffy into reffy-reports
// (https://github.com/tidoust/reffy-reports)
// Source: Web Budget API (https://wicg.github.io/budget-api/)
[Exposed=Window]
partial interface Navigator {
[SameObject] readonly attribute BudgetService budget;
};
[Exposed=Worker]
partial interface WorkerNavigator {
[SameObject] readonly attribute BudgetService budget;
};
[Exposed=(Window,Worker)]
interface BudgetService {
Promise<double> getCost(OperationType operation);
Promise<sequence<BudgetState>> getBudget();
Promise<boolean> reserve(OperationType operation);
};
[Exposed=(Window,Worker)]
interface BudgetState {
readonly attribute double budgetAt;
readonly attribute DOMTimeStamp time;
};
enum OperationType {
"silent-push"
};

View file

@ -0,0 +1,8 @@
// GENERATED CONTENT - DO NOT EDIT
// Content was automatically extracted by Reffy into reffy-reports
// (https://github.com/tidoust/reffy-reports)
// Source: MediaStreamTrack Content Hints (https://w3c.github.io/mst-content-hint/)
partial interface MediaStreamTrack {
attribute DOMString contentHint;
};

View file

@ -0,0 +1,3 @@
spec: https://w3c.github.io/mst-content-hint/
suggested_reviewers:
- alvestrand

View file

@ -0,0 +1,111 @@
<!DOCTYPE HTML>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<canvas id="canvas">
</canvas>
<script>
function createAudioTrack() {
ac = new AudioContext();
var osc = ac.createOscillator();
var dest = ac.createMediaStreamDestination();
osc.connect(dest);
audio_track = dest.stream.getAudioTracks()[0];
assert_equals(audio_track.kind, "audio");
return audio_track;
}
function createVideoTrack() {
canvas = document.getElementById("canvas");
video_track = canvas.captureStream().getVideoTracks()[0];
assert_equals(video_track.kind, "video");
return video_track;
}
test(t => {
audio_track = createAudioTrack();
assert_equals("", audio_track.contentHint);
video_track = createVideoTrack();
assert_equals("", video_track.contentHint);
}, "Tracks have empty default content hint");
test(t => {
audio_track = createAudioTrack();
audio_track.contentHint = "speech";
assert_equals(audio_track.contentHint, "speech");
audio_track.contentHint = "music";
assert_equals(audio_track.contentHint, "music");
audio_track.contentHint = "";
assert_equals(audio_track.contentHint, "");
}, "Accepts valid audio contentHints");
test(t => {
audio_track = createAudioTrack();
audio_track.contentHint = "speech";
assert_equals(audio_track.contentHint, "speech");
audio_track.contentHint = "motion";
assert_equals(audio_track.contentHint, "speech",
"Audio tracks should ignore video-only contentHints.");
audio_track.contentHint = "bogus";
assert_equals(audio_track.contentHint, "speech",
"Audio tracks should ignore garbage contentHints");
}, "Audio tracks ignore invalid/video contentHints");
test(t => {
video_track = createVideoTrack();
video_track.contentHint = "motion";
assert_equals(video_track.contentHint, "motion");
video_track.contentHint = "detail";
assert_equals(video_track.contentHint, "detail");
video_track.contentHint = "text";
assert_equals(video_track.contentHint, "text");
video_track.contentHint = "";
assert_equals(video_track.contentHint, "");
}, "Accepts valid video contentHints");
test(t => {
video_track = createVideoTrack();
video_track.contentHint = "motion";
assert_equals(video_track.contentHint, "motion");
video_track.contentHint = "speech";
assert_equals(video_track.contentHint, "motion",
"Video tracks should ignore audio-only contentHints.");
video_track.contentHint = "bogus";
assert_equals(video_track.contentHint, "motion",
"Video tracks should ignore garbage contentHints");
}, "Video tracks ignore invalid/audio contentHints");
test(t => {
video_track = createVideoTrack();
video_track.contentHint = "motion";
assert_equals(video_track.contentHint, "motion");
// Cloning a track should preserve contentHint.
video_track_clone = video_track.clone();
assert_equals(video_track_clone.contentHint, "motion");
// Changing a cloned track's contentHint should not change the original.
video_track_clone.contentHint = "detail";
assert_equals(video_track_clone.contentHint, "detail");
assert_equals(video_track.contentHint, "motion");
}, "Cloned video tracks have separate contentHints");
test(t => {
audio_track = createAudioTrack();
audio_track.contentHint = "speech";
assert_equals(audio_track.contentHint, "speech");
// Cloning a track should preserve contentHint.
audio_track_clone = audio_track.clone();
assert_equals(audio_track_clone.contentHint, "speech");
// Changing a cloned track's contentHint should not change the original.
audio_track_clone.contentHint = "music";
assert_equals(audio_track_clone.contentHint, "music");
assert_equals(audio_track.contentHint, "speech");
}, "Cloned audio tracks have separate contentHints");
</script>

View file

@ -0,0 +1,19 @@
// META: script=/resources/WebIDLParser.js
// META: script=/resources/idlharness.js
// META: script=/webrtc/RTCPeerConnection-helper.js
'use strict';
idl_test(
['mst-content-hint'],
['mediacapture-streams', 'dom'],
async idl_array => {
idl_array.add_objects({
MediaStreamTrack: ['audioTrack', 'videoTrack'],
});
const stream = await getNoiseStream({ audio: true, video: true });
self.audioTrack = stream.getAudioTracks()[0];
self.videoTrack = stream.getVideoTracks()[0];
}
);

View file

@ -1,273 +0,0 @@
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
'use strict';
(function() {
var mojomId = 'device/usb/public/mojom/chooser_service.mojom';
if (mojo.internal.isMojomLoaded(mojomId)) {
console.warn('The following mojom is loaded multiple times: ' + mojomId);
return;
}
mojo.internal.markMojomLoaded(mojomId);
var bindings = mojo;
var associatedBindings = mojo;
var codec = mojo.internal;
var validator = mojo.internal;
var exports = mojo.internal.exposeNamespace('device.mojom');
var device$ =
mojo.internal.exposeNamespace('device.mojom');
if (mojo.config.autoLoadMojomDeps) {
mojo.internal.loadMojomIfNecessary(
'device/usb/public/mojom/device.mojom', 'device.mojom.js');
}
var device_manager$ =
mojo.internal.exposeNamespace('device.mojom');
if (mojo.config.autoLoadMojomDeps) {
mojo.internal.loadMojomIfNecessary(
'device/usb/public/mojom/device_manager.mojom', 'device_manager.mojom.js');
}
function UsbChooserService_GetPermission_Params(values) {
this.initDefaults_();
this.initFields_(values);
}
UsbChooserService_GetPermission_Params.prototype.initDefaults_ = function() {
this.deviceFilters = null;
};
UsbChooserService_GetPermission_Params.prototype.initFields_ = function(fields) {
for(var field in fields) {
if (this.hasOwnProperty(field))
this[field] = fields[field];
}
};
UsbChooserService_GetPermission_Params.validate = function(messageValidator, offset) {
var err;
err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
if (err !== validator.validationError.NONE)
return err;
var kVersionSizes = [
{version: 0, numBytes: 16}
];
err = messageValidator.validateStructVersion(offset, kVersionSizes);
if (err !== validator.validationError.NONE)
return err;
// validate UsbChooserService_GetPermission_Params.deviceFilters
err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 0, 8, new codec.PointerTo(device_manager$.UsbDeviceFilter), false, [0], 0);
if (err !== validator.validationError.NONE)
return err;
return validator.validationError.NONE;
};
UsbChooserService_GetPermission_Params.encodedSize = codec.kStructHeaderSize + 8;
UsbChooserService_GetPermission_Params.decode = function(decoder) {
var packed;
var val = new UsbChooserService_GetPermission_Params();
var numberOfBytes = decoder.readUint32();
var version = decoder.readUint32();
val.deviceFilters = decoder.decodeArrayPointer(new codec.PointerTo(device_manager$.UsbDeviceFilter));
return val;
};
UsbChooserService_GetPermission_Params.encode = function(encoder, val) {
var packed;
encoder.writeUint32(UsbChooserService_GetPermission_Params.encodedSize);
encoder.writeUint32(0);
encoder.encodeArrayPointer(new codec.PointerTo(device_manager$.UsbDeviceFilter), val.deviceFilters);
};
function UsbChooserService_GetPermission_ResponseParams(values) {
this.initDefaults_();
this.initFields_(values);
}
UsbChooserService_GetPermission_ResponseParams.prototype.initDefaults_ = function() {
this.result = null;
};
UsbChooserService_GetPermission_ResponseParams.prototype.initFields_ = function(fields) {
for(var field in fields) {
if (this.hasOwnProperty(field))
this[field] = fields[field];
}
};
UsbChooserService_GetPermission_ResponseParams.validate = function(messageValidator, offset) {
var err;
err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
if (err !== validator.validationError.NONE)
return err;
var kVersionSizes = [
{version: 0, numBytes: 16}
];
err = messageValidator.validateStructVersion(offset, kVersionSizes);
if (err !== validator.validationError.NONE)
return err;
// validate UsbChooserService_GetPermission_ResponseParams.result
err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, device$.UsbDeviceInfo, true);
if (err !== validator.validationError.NONE)
return err;
return validator.validationError.NONE;
};
UsbChooserService_GetPermission_ResponseParams.encodedSize = codec.kStructHeaderSize + 8;
UsbChooserService_GetPermission_ResponseParams.decode = function(decoder) {
var packed;
var val = new UsbChooserService_GetPermission_ResponseParams();
var numberOfBytes = decoder.readUint32();
var version = decoder.readUint32();
val.result = decoder.decodeStructPointer(device$.UsbDeviceInfo);
return val;
};
UsbChooserService_GetPermission_ResponseParams.encode = function(encoder, val) {
var packed;
encoder.writeUint32(UsbChooserService_GetPermission_ResponseParams.encodedSize);
encoder.writeUint32(0);
encoder.encodeStructPointer(device$.UsbDeviceInfo, val.result);
};
var kUsbChooserService_GetPermission_Name = 0;
function UsbChooserServicePtr(handleOrPtrInfo) {
this.ptr = new bindings.InterfacePtrController(UsbChooserService,
handleOrPtrInfo);
}
function UsbChooserServiceAssociatedPtr(associatedInterfacePtrInfo) {
this.ptr = new associatedBindings.AssociatedInterfacePtrController(
UsbChooserService, associatedInterfacePtrInfo);
}
UsbChooserServiceAssociatedPtr.prototype =
Object.create(UsbChooserServicePtr.prototype);
UsbChooserServiceAssociatedPtr.prototype.constructor =
UsbChooserServiceAssociatedPtr;
function UsbChooserServiceProxy(receiver) {
this.receiver_ = receiver;
}
UsbChooserServicePtr.prototype.getPermission = function() {
return UsbChooserServiceProxy.prototype.getPermission
.apply(this.ptr.getProxy(), arguments);
};
UsbChooserServiceProxy.prototype.getPermission = function(deviceFilters) {
var params = new UsbChooserService_GetPermission_Params();
params.deviceFilters = deviceFilters;
return new Promise(function(resolve, reject) {
var builder = new codec.MessageV1Builder(
kUsbChooserService_GetPermission_Name,
codec.align(UsbChooserService_GetPermission_Params.encodedSize),
codec.kMessageExpectsResponse, 0);
builder.encodeStruct(UsbChooserService_GetPermission_Params, params);
var message = builder.finish();
this.receiver_.acceptAndExpectResponse(message).then(function(message) {
var reader = new codec.MessageReader(message);
var responseParams =
reader.decodeStruct(UsbChooserService_GetPermission_ResponseParams);
resolve(responseParams);
}).catch(function(result) {
reject(Error("Connection error: " + result));
});
}.bind(this));
};
function UsbChooserServiceStub(delegate) {
this.delegate_ = delegate;
}
UsbChooserServiceStub.prototype.getPermission = function(deviceFilters) {
return this.delegate_ && this.delegate_.getPermission && this.delegate_.getPermission(deviceFilters);
}
UsbChooserServiceStub.prototype.accept = function(message) {
var reader = new codec.MessageReader(message);
switch (reader.messageName) {
default:
return false;
}
};
UsbChooserServiceStub.prototype.acceptWithResponder =
function(message, responder) {
var reader = new codec.MessageReader(message);
switch (reader.messageName) {
case kUsbChooserService_GetPermission_Name:
var params = reader.decodeStruct(UsbChooserService_GetPermission_Params);
this.getPermission(params.deviceFilters).then(function(response) {
var responseParams =
new UsbChooserService_GetPermission_ResponseParams();
responseParams.result = response.result;
var builder = new codec.MessageV1Builder(
kUsbChooserService_GetPermission_Name,
codec.align(UsbChooserService_GetPermission_ResponseParams.encodedSize),
codec.kMessageIsResponse, reader.requestID);
builder.encodeStruct(UsbChooserService_GetPermission_ResponseParams,
responseParams);
var message = builder.finish();
responder.accept(message);
});
return true;
default:
return false;
}
};
function validateUsbChooserServiceRequest(messageValidator) {
var message = messageValidator.message;
var paramsClass = null;
switch (message.getName()) {
case kUsbChooserService_GetPermission_Name:
if (message.expectsResponse())
paramsClass = UsbChooserService_GetPermission_Params;
break;
}
if (paramsClass === null)
return validator.validationError.NONE;
return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes());
}
function validateUsbChooserServiceResponse(messageValidator) {
var message = messageValidator.message;
var paramsClass = null;
switch (message.getName()) {
case kUsbChooserService_GetPermission_Name:
if (message.isResponse())
paramsClass = UsbChooserService_GetPermission_ResponseParams;
break;
}
if (paramsClass === null)
return validator.validationError.NONE;
return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes());
}
var UsbChooserService = {
name: 'device.mojom.UsbChooserService',
kVersion: 0,
ptrClass: UsbChooserServicePtr,
proxyClass: UsbChooserServiceProxy,
stubClass: UsbChooserServiceStub,
validateRequest: validateUsbChooserServiceRequest,
validateResponse: validateUsbChooserServiceResponse,
};
UsbChooserServiceStub.prototype.validator = validateUsbChooserServiceRequest;
UsbChooserServiceProxy.prototype.validator = validateUsbChooserServiceResponse;
exports.UsbChooserService = UsbChooserService;
exports.UsbChooserServicePtr = UsbChooserServicePtr;
exports.UsbChooserServiceAssociatedPtr = UsbChooserServiceAssociatedPtr;
})();

View file

@ -1 +0,0 @@
Content-Type: text/javascript; charset=utf-8

View file

@ -282,6 +282,166 @@
encoder.skip(1);
encoder.skip(1);
};
function WebUsbService_GetPermission_Params(values) {
this.initDefaults_();
this.initFields_(values);
}
WebUsbService_GetPermission_Params.prototype.initDefaults_ = function() {
this.deviceFilters = null;
};
WebUsbService_GetPermission_Params.prototype.initFields_ = function(fields) {
for(var field in fields) {
if (this.hasOwnProperty(field))
this[field] = fields[field];
}
};
WebUsbService_GetPermission_Params.generate = function(generator_) {
var generated = new WebUsbService_GetPermission_Params;
generated.deviceFilters = generator_.generateArray(function() {
return generator_.generateStruct(device.mojom.UsbDeviceFilter, false);
});
return generated;
};
WebUsbService_GetPermission_Params.prototype.mutate = function(mutator_) {
if (mutator_.chooseMutateField()) {
this.deviceFilters = mutator_.mutateArray(this.deviceFilters, function(val) {
return mutator_.mutateStruct(val, device.mojom.UsbDeviceFilter, false);
});
}
return this;
};
WebUsbService_GetPermission_Params.prototype.getHandleDeps = function() {
var handles = [];
return handles;
};
WebUsbService_GetPermission_Params.prototype.setHandles = function() {
this.setHandlesInternal_(arguments, 0);
};
WebUsbService_GetPermission_Params.prototype.setHandlesInternal_ = function(handles, idx) {
return idx;
};
WebUsbService_GetPermission_Params.validate = function(messageValidator, offset) {
var err;
err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
if (err !== validator.validationError.NONE)
return err;
var kVersionSizes = [
{version: 0, numBytes: 16}
];
err = messageValidator.validateStructVersion(offset, kVersionSizes);
if (err !== validator.validationError.NONE)
return err;
// validate WebUsbService_GetPermission_Params.deviceFilters
err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 0, 8, new codec.PointerTo(device_manager$.UsbDeviceFilter), false, [0], 0);
if (err !== validator.validationError.NONE)
return err;
return validator.validationError.NONE;
};
WebUsbService_GetPermission_Params.encodedSize = codec.kStructHeaderSize + 8;
WebUsbService_GetPermission_Params.decode = function(decoder) {
var packed;
var val = new WebUsbService_GetPermission_Params();
var numberOfBytes = decoder.readUint32();
var version = decoder.readUint32();
val.deviceFilters = decoder.decodeArrayPointer(new codec.PointerTo(device_manager$.UsbDeviceFilter));
return val;
};
WebUsbService_GetPermission_Params.encode = function(encoder, val) {
var packed;
encoder.writeUint32(WebUsbService_GetPermission_Params.encodedSize);
encoder.writeUint32(0);
encoder.encodeArrayPointer(new codec.PointerTo(device_manager$.UsbDeviceFilter), val.deviceFilters);
};
function WebUsbService_GetPermission_ResponseParams(values) {
this.initDefaults_();
this.initFields_(values);
}
WebUsbService_GetPermission_ResponseParams.prototype.initDefaults_ = function() {
this.result = null;
};
WebUsbService_GetPermission_ResponseParams.prototype.initFields_ = function(fields) {
for(var field in fields) {
if (this.hasOwnProperty(field))
this[field] = fields[field];
}
};
WebUsbService_GetPermission_ResponseParams.generate = function(generator_) {
var generated = new WebUsbService_GetPermission_ResponseParams;
generated.result = generator_.generateStruct(device.mojom.UsbDeviceInfo, true);
return generated;
};
WebUsbService_GetPermission_ResponseParams.prototype.mutate = function(mutator_) {
if (mutator_.chooseMutateField()) {
this.result = mutator_.mutateStruct(this.result, device.mojom.UsbDeviceInfo, true);
}
return this;
};
WebUsbService_GetPermission_ResponseParams.prototype.getHandleDeps = function() {
var handles = [];
return handles;
};
WebUsbService_GetPermission_ResponseParams.prototype.setHandles = function() {
this.setHandlesInternal_(arguments, 0);
};
WebUsbService_GetPermission_ResponseParams.prototype.setHandlesInternal_ = function(handles, idx) {
return idx;
};
WebUsbService_GetPermission_ResponseParams.validate = function(messageValidator, offset) {
var err;
err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
if (err !== validator.validationError.NONE)
return err;
var kVersionSizes = [
{version: 0, numBytes: 16}
];
err = messageValidator.validateStructVersion(offset, kVersionSizes);
if (err !== validator.validationError.NONE)
return err;
// validate WebUsbService_GetPermission_ResponseParams.result
err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, device$.UsbDeviceInfo, true);
if (err !== validator.validationError.NONE)
return err;
return validator.validationError.NONE;
};
WebUsbService_GetPermission_ResponseParams.encodedSize = codec.kStructHeaderSize + 8;
WebUsbService_GetPermission_ResponseParams.decode = function(decoder) {
var packed;
var val = new WebUsbService_GetPermission_ResponseParams();
var numberOfBytes = decoder.readUint32();
var version = decoder.readUint32();
val.result = decoder.decodeStructPointer(device$.UsbDeviceInfo);
return val;
};
WebUsbService_GetPermission_ResponseParams.encode = function(encoder, val) {
var packed;
encoder.writeUint32(WebUsbService_GetPermission_ResponseParams.encodedSize);
encoder.writeUint32(0);
encoder.encodeStructPointer(device$.UsbDeviceInfo, val.result);
};
function WebUsbService_SetClient_Params(values) {
this.initDefaults_();
this.initFields_(values);
@ -366,7 +526,8 @@
};
var kWebUsbService_GetDevices_Name = 0;
var kWebUsbService_GetDevice_Name = 1;
var kWebUsbService_SetClient_Name = 2;
var kWebUsbService_GetPermission_Name = 2;
var kWebUsbService_SetClient_Name = 3;
function WebUsbServicePtr(handleOrPtrInfo) {
this.ptr = new bindings.InterfacePtrController(WebUsbService,
@ -426,6 +587,31 @@
var message = builder.finish();
this.receiver_.accept(message);
};
WebUsbServicePtr.prototype.getPermission = function() {
return WebUsbServiceProxy.prototype.getPermission
.apply(this.ptr.getProxy(), arguments);
};
WebUsbServiceProxy.prototype.getPermission = function(deviceFilters) {
var params_ = new WebUsbService_GetPermission_Params();
params_.deviceFilters = deviceFilters;
return new Promise(function(resolve, reject) {
var builder = new codec.MessageV1Builder(
kWebUsbService_GetPermission_Name,
codec.align(WebUsbService_GetPermission_Params.encodedSize),
codec.kMessageExpectsResponse, 0);
builder.encodeStruct(WebUsbService_GetPermission_Params, params_);
var message = builder.finish();
this.receiver_.acceptAndExpectResponse(message).then(function(message) {
var reader = new codec.MessageReader(message);
var responseParams =
reader.decodeStruct(WebUsbService_GetPermission_ResponseParams);
resolve(responseParams);
}).catch(function(result) {
reject(Error("Connection error: " + result));
});
}.bind(this));
};
WebUsbServicePtr.prototype.setClient = function() {
return WebUsbServiceProxy.prototype.setClient
.apply(this.ptr.getProxy(), arguments);
@ -451,6 +637,9 @@
WebUsbServiceStub.prototype.getDevice = function(guid, deviceRequestd) {
return this.delegate_ && this.delegate_.getDevice && this.delegate_.getDevice(guid, deviceRequestd);
}
WebUsbServiceStub.prototype.getPermission = function(deviceFilters) {
return this.delegate_ && this.delegate_.getPermission && this.delegate_.getPermission(deviceFilters);
}
WebUsbServiceStub.prototype.setClient = function(client) {
return this.delegate_ && this.delegate_.setClient && this.delegate_.setClient(client);
}
@ -491,6 +680,22 @@
responder.accept(message);
});
return true;
case kWebUsbService_GetPermission_Name:
var params = reader.decodeStruct(WebUsbService_GetPermission_Params);
this.getPermission(params.deviceFilters).then(function(response) {
var responseParams =
new WebUsbService_GetPermission_ResponseParams();
responseParams.result = response.result;
var builder = new codec.MessageV1Builder(
kWebUsbService_GetPermission_Name,
codec.align(WebUsbService_GetPermission_ResponseParams.encodedSize),
codec.kMessageIsResponse, reader.requestID);
builder.encodeStruct(WebUsbService_GetPermission_ResponseParams,
responseParams);
var message = builder.finish();
responder.accept(message);
});
return true;
default:
return false;
}
@ -508,6 +713,10 @@
if (!message.expectsResponse() && !message.isResponse())
paramsClass = WebUsbService_GetDevice_Params;
break;
case kWebUsbService_GetPermission_Name:
if (message.expectsResponse())
paramsClass = WebUsbService_GetPermission_Params;
break;
case kWebUsbService_SetClient_Name:
if (!message.expectsResponse() && !message.isResponse())
paramsClass = WebUsbService_SetClient_Params;
@ -526,6 +735,10 @@
if (message.isResponse())
paramsClass = WebUsbService_GetDevices_ResponseParams;
break;
case kWebUsbService_GetPermission_Name:
if (message.isResponse())
paramsClass = WebUsbService_GetPermission_ResponseParams;
break;
}
if (paramsClass === null)
return validator.validationError.NONE;
@ -548,6 +761,9 @@
getDevice: {
params: WebUsbService_GetDevice_Params,
},
getPermission: {
params: WebUsbService_GetPermission_Params,
},
setClient: {
params: WebUsbService_SetClient_Params,
},

View file

@ -13,10 +13,6 @@ let internal = {
webUsbService: null,
webUsbServiceInterceptor: null,
webUsbServiceCrossFrameProxy: null,
chooser: null,
chooserInterceptor: null,
chooserCrossFrameProxy: null,
};
// Converts an ECMAScript String object to an instance of
@ -376,6 +372,17 @@ class FakeWebUsbService {
}
}
getPermission(deviceFilters) {
return new Promise(resolve => {
if (navigator.usb.test.onrequestdevice) {
navigator.usb.test.onrequestdevice(
new USBDeviceRequestEvent(deviceFilters, resolve));
} else {
resolve({ result: null });
}
});
}
setClient(client) {
this.client_ = client;
}
@ -403,27 +410,6 @@ class USBDeviceRequestEvent {
}
}
class FakeChooserService {
constructor() {
this.bindingSet_ = new mojo.BindingSet(device.mojom.UsbChooserService);
}
addBinding(handle) {
this.bindingSet_.addBinding(this, handle);
}
getPermission(deviceFilters) {
return new Promise(resolve => {
if (navigator.usb.test.onrequestdevice) {
navigator.usb.test.onrequestdevice(
new USBDeviceRequestEvent(deviceFilters, resolve));
} else {
resolve({ result: null });
}
});
}
}
// Unlike FakeDevice this class is exported to callers of USBTest.addFakeDevice.
class FakeUSBDevice {
constructor() {
@ -472,15 +458,6 @@ class USBTest {
internal.webUsbServiceCrossFrameProxy = new CrossFrameHandleProxy(
handle => internal.webUsbService.addBinding(handle));
internal.chooser = new FakeChooserService();
internal.chooserInterceptor =
new MojoInterfaceInterceptor(device.mojom.UsbChooserService.name);
internal.chooserInterceptor.oninterfacerequest =
e => internal.chooser.addBinding(e.handle);
internal.chooserInterceptor.start();
internal.chooserCrossFrameProxy = new CrossFrameHandleProxy(
handle => internal.chooser.addBinding(handle));
// Wait for a call to GetDevices() to pass between the renderer and the
// mock in order to establish that everything is set up.
await navigator.usb.getDevices();
@ -498,13 +475,6 @@ class USBTest {
e => internal.webUsbServiceCrossFrameProxy.forwardHandle(e.handle);
otherWindow.webUsbServiceInterceptor.start();
otherWindow.chooserInterceptor =
new otherWindow.MojoInterfaceInterceptor(
device.mojom.UsbChooserService.name);
otherWindow.chooserInterceptor.oninterfacerequest =
e => internal.chooserCrossFrameProxy.forwardHandle(e.handle);
otherWindow.chooserInterceptor.start();
// Wait for a call to GetDevices() to pass between the renderer and the
// mock in order to establish that everything is set up.
await otherWindow.navigator.usb.getDevices();

View file

@ -1,25 +0,0 @@
def main(request, response):
if "clear-vary-value-override-cookie" in request.GET:
response.unset_cookie("vary-value-override")
return "vary cookie cleared"
set_cookie_vary = request.GET.first("set-vary-value-override-cookie",
default="")
if set_cookie_vary:
response.set_cookie("vary-value-override", set_cookie_vary)
return "vary cookie set"
# If there is a vary-value-override cookie set, then use its value
# for the VARY header no matter what the query string is set to. This
# override is necessary to test the case when two URLs are identical
# (including query), but differ by VARY header.
cookie_vary = request.cookies.get("vary-value-override");
if cookie_vary:
response.headers.set("vary", cookie_vary)
else:
# If there is no cookie, then use the query string value, if present.
query_vary = request.GET.first("vary", default="")
if query_vary:
response.headers.set("vary", query_vary)
return "vary response"

View file

@ -267,84 +267,4 @@ cache_test(function(cache, test) {
'twice.');
}, 'Cache.addAll called with the same Request object specified twice');
cache_test(async function(cache, test) {
const url = '../resources/vary.py?vary=x-shape';
let requests = [
new Request(url, { headers: { 'x-shape': 'circle' }}),
new Request(url, { headers: { 'x-shape': 'square' }}),
];
let result = await cache.addAll(requests);
assert_equals(result, undefined, 'Cache.addAll() should succeed');
}, 'Cache.addAll should succeed when entries differ by vary header');
cache_test(async function(cache, test) {
const url = '../resources/vary.py?vary=x-shape';
let requests = [
new Request(url, { headers: { 'x-shape': 'circle' }}),
new Request(url, { headers: { 'x-shape': 'circle' }}),
];
await promise_rejects(
test,
'InvalidStateError',
cache.addAll(requests),
'Cache.addAll() should reject when entries are duplicate by vary header');
}, 'Cache.addAll should reject when entries are duplicate by vary header');
// VARY header matching is asymmetric. Determining if two entries are duplicate
// depends on which entry's response is used in the comparison. The target
// response's VARY header determines what request headers are examined. This
// test verifies that Cache.addAll() duplicate checking handles this asymmetric
// behavior correctly.
cache_test(async function(cache, test) {
const base_url = '../resources/vary.py';
// Define a request URL that sets a VARY header in the
// query string to be echoed back by the server.
const url = base_url + '?vary=x-size';
// Set a cookie to override the VARY header of the response
// when the request is made with credentials. This will
// take precedence over the query string vary param. This
// is a bit confusing, but it's necessary to construct a test
// where the URL is the same, but the VARY headers differ.
//
// Note, the test could also pass this information in additional
// request headers. If the cookie approach becomes too unwieldy
// this test could be rewritten to use that technique.
await fetch(base_url + '?set-vary-value-override-cookie=x-shape');
test.add_cleanup(_ => fetch(base_url + '?clear-vary-value-override-cookie'));
let requests = [
// This request will result in a Response with a "Vary: x-shape"
// header. This *will not* result in a duplicate match with the
// other entry.
new Request(url, { headers: { 'x-shape': 'circle',
'x-size': 'big' },
credentials: 'same-origin' }),
// This request will result in a Response with a "Vary: x-size"
// header. This *will* result in a duplicate match with the other
// entry.
new Request(url, { headers: { 'x-shape': 'square',
'x-size': 'big' },
credentials: 'omit' }),
];
await promise_rejects(
test,
'InvalidStateError',
cache.addAll(requests),
'Cache.addAll() should reject when one entry has a vary header ' +
'matching an earlier entry.');
// Test the reverse order now.
await promise_rejects(
test,
'InvalidStateError',
cache.addAll(requests.reverse()),
'Cache.addAll() should reject when one entry has a vary header ' +
'matching a later entry.');
}, 'Cache.addAll should reject when one entry has a vary header ' +
'matching another entry');
done();

View file

@ -1,19 +1,37 @@
async function wait_for_performance_entries(url) {
let entries = performance.getEntriesByName(url);
if (entries.length > 0) {
return entries;
}
return new Promise((resolve) => {
new PerformanceObserver((list) => {
const entries = list.getEntriesByName(url);
if (entries.length > 0) {
resolve(entries);
}
}).observe({ entryTypes: ['resource'] });
});
}
self.addEventListener('activate', event => {
event.waitUntil(self.registration.navigationPreload.enable());
});
self.addEventListener('fetch', event => {
let headers;
event.respondWith(
event.preloadResponse
.then(response => {
var headers = response.headers;
return response.text().then(text =>
new Response(
JSON.stringify({
decodedBodySize: headers.get('X-Decoded-Body-Size'),
encodedBodySize: headers.get('X-Encoded-Body-Size'),
timingEntries: performance.getEntriesByName(event.request.url)
}),
{headers: {'Content-Type': 'text/html'}}));
}));
headers = response.headers;
return response.text()
})
.then(_ => wait_for_performance_entries(event.request.url))
.then(entries =>
new Response(
JSON.stringify({
decodedBodySize: headers.get('X-Decoded-Body-Size'),
encodedBodySize: headers.get('X-Encoded-Body-Size'),
timingEntries: entries
}),
{headers: {'Content-Type': 'text/html'}})));
});

View file

@ -0,0 +1,73 @@
<?xml version="1.0" encoding="utf-8"?>
<svg id="svg-root"
width="100%" height="100%" viewBox="0 0 480 360"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:html="http://www.w3.org/1999/xhtml">
<g id="testmeta">
<title>Text in Shape — 001</title>
<html:link rel="author"
title="Tavmjong Bah"
href="mailto:tavmjong@free.fr"/>
<html:link rel="reviewer"
title="NAME_OF_REVIEWER"
href="mailto:EMAIL OR http://CONTACT_PAGE" />
<!-- YYYY-MM-DD -->
<html:link rel="help"
href="https://svgwg.org/svg2-draft/text.html#TextShapeInside"/>
<metadata class="flags">TOKENS</metadata>
<desc class="assert">TEST ASSERTION</desc>
</g>
<style id="test-font" type="text/css">
/* Standard Font (if needed). */
@font-face {
font-family: FreeSans;
src: url("fonts/FreeSans.woff") format("woff"),
local("FreeSans");
}
text { font-family: FreeSans, sans-serif }
</style>
<style id="test-style" type="text/css">
/* Style that is being tested (if needed). */
text { font-family: FreeSans, sans-serif }
</style>
<defs>
<circle id="Circle1" cx="120" cy="180" r="100"/>
<circle id="Circle2" cx="360" cy="240" r="100"/>
<rect id="Rect1" x="120" y="80" width="240" height="80" style="shape-margin: 20px;"/>
<rect id="Rect2" x="120" y="260" width="240" height="80" style="shape-margin: 20px;"/>
<circle id="Circle1x" cx="120" cy="180" r="80"/>
<circle id="Circle2x" cx="360" cy="240" r="80"/>
<rect id="Rect1x" x="100" y="60" width="280" height="120"/>
<rect id="Rect2x" x="100" y="240" width="280" height="120"/>
</defs>
<g style="fill:none;stroke:lightblue">
<use xlink:href="#Rect1" />
<use xlink:href="#Rect2" />
<use xlink:href="#Circle1" />
<use xlink:href="#Circle2" />
</g>
<g style="fill:none;stroke:lightblue;stroke-dasharray:5 5">
<use xlink:href="#Rect1x" />
<use xlink:href="#Rect2x" style="shape-margin: 20px;" />
<use xlink:href="#Circle1x" />
<use xlink:href="#Circle2x" />
</g>
<g id="test-body-reference" style="font-size:16px">
<text style="text-anchor:middle">
<tspan x="74.1" y="157.3">Lorem</tspan>
<tspan x="71" y="177.3">ipsum</tspan>
<tspan x="120" y="197.3">dolor sit amet,</tspan>
<tspan x="120" y="217.3">consectetur</tspan>
<tspan x="360" y="197.2">adipisicing elit,</tspan>
<tspan x="360" y="217.2">sed do eiusmod</tspan>
<tspan x="401.3" y="237.2">tempor </tspan>
</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View file

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="utf-8"?>
<svg id="svg-root"
width="100%" height="100%" viewBox="0 0 480 360"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:html="http://www.w3.org/1999/xhtml">
<g id="testmeta">
<title>Text in Shape — 001</title>
<html:link rel="author"
title="Tavmjong Bah"
href="mailto:tavmjong@free.fr"/>
<html:link rel="reviewer"
title="NAME_OF_REVIEWER"
href="mailto:EMAIL OR http://CONTACT_PAGE" />
<!-- YYYY-MM-DD -->
<html:link rel="help"
href="https://svgwg.org/svg2-draft/text.html#TextShapeInside"/>
<html:link rel="match" href="text-complex-001-ref.svg" />
<metadata class="flags">TOKENS</metadata>
<desc class="assert">TEST ASSERTION</desc>
</g>
<style id="test-font" type="text/css">
/* Standard Font (if needed). */
@font-face {
font-family: FreeSans;
src: url("fonts/FreeSans.woff") format("woff"),
local("FreeSans");
}
text { font-family: FreeSans, sans-serif }
</style>
<style id="test-style" type="text/css">
/* Style that is being tested (if needed). */
text { font-family: FreeSans, sans-serif }
</style>
<defs>
<circle id="Circle1" cx="120" cy="180" r="100"/>
<circle id="Circle2" cx="360" cy="240" r="100"/>
<rect id="Rect1" x="120" y="80" width="240" height="80" style="shape-margin: 20px;"/>
<rect id="Rect2" x="120" y="260" width="240" height="80" style="shape-margin: 20px;"/>
<circle id="Circle1x" cx="120" cy="180" r="80"/>
<circle id="Circle2x" cx="360" cy="240" r="80"/>
<rect id="Rect1x" x="100" y="60" width="280" height="120"/>
<rect id="Rect2x" x="100" y="240" width="280" height="120"/>
</defs>
<g style="fill:none;stroke:lightblue">
<use xlink:href="#Rect1" />
<use xlink:href="#Rect2" />
<use xlink:href="#Circle1" />
<use xlink:href="#Circle2" />
</g>
<g style="fill:none;stroke:lightblue;stroke-dasharray:5 5">
<use xlink:href="#Rect1x" />
<use xlink:href="#Rect2x" style="shape-margin: 20px;" />
<use xlink:href="#Circle1x" />
<use xlink:href="#Circle2x" />
</g>
<g id="test-body-content" style="font-size:16px;line-spacing:1.25">
<text style="shape-inside:url(#Circle1) url(#Circle2);
shape-subtract:url(#Rect1) url(#Rect2);
shape-padding:20px;
text-align: center;">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

View file

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="utf-8"?>
<svg id="svg-root"
width="100%" height="100%" viewBox="0 0 480 360"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:html="http://www.w3.org/1999/xhtml">
<g id="testmeta">
<title>Text in Shape — 002</title>
<html:link rel="author"
title="Tavmjong Bah"
href="mailto:tavmjong@free.fr"/>
<html:link rel="reviewer"
title="NAME_OF_REVIEWER"
href="mailto:EMAIL OR http://CONTACT_PAGE" />
<!-- YYYY-MM-DD -->
<html:link rel="help"
href="https://svgwg.org/svg2-draft/text.html#TextShapeInside"/>
<metadata class="flags">TOKENS</metadata>
<desc class="assert">TEST ASSERTION</desc>
</g>
<style id="test-font" type="text/css">
/* Standard Font (if needed). */
@font-face {
font-family: FreeSans;
src: url("fonts/FreeSans.woff") format("woff"),
local("FreeSans");
}
text { font-family: FreeSans, sans-serif }
</style>
<style id="test-style" type="text/css">
/* Style that is being tested (if needed). */
text { font-family: FreeSans, sans-serif }
</style>
<defs>
<circle id="Circle1" cx="360" cy="180" r="100"/>
<circle id="Circle2" cx="120" cy="240" r="100"/>
<rect id="Rect1" x="120" y="80" width="240" height="80" style="shape-margin: 20px;"/>
<rect id="Rect2" x="120" y="260" width="240" height="80" style="shape-margin: 20px;"/>
<circle id="Circle1x" cx="360" cy="180" r="80"/>
<circle id="Circle2x" cx="120" cy="240" r="80"/>
<rect id="Rect1x" x="100" y="60" width="280" height="120"/>
<rect id="Rect2x" x="100" y="240" width="280" height="120"/>
</defs>
<g style="fill:none;stroke:lightblue">
<use xlink:href="#Rect1" />
<use xlink:href="#Rect2" />
<use xlink:href="#Circle1" />
<use xlink:href="#Circle2" />
</g>
<g style="fill:none;stroke:lightblue;stroke-dasharray:5 5">
<use xlink:href="#Rect1x" />
<use xlink:href="#Rect2x" style="shape-margin: 20px;" />
<use xlink:href="#Circle1x" />
<use xlink:href="#Circle2x" />
</g>
<g id="test-body-reference" style="font-size:16px;direction:rtl">
<text style="text-anchor:middle">
<tspan x="398.9" y="137.9">لكن</tspan>
<tspan x="406.1" y="158.5">لا بد أن</tspan>
<tspan x="408.9" y="179.2">أوضح لك</tspan>
<tspan x="360.0" y="199.8">أن كل هذه الأفكار</tspan>
<tspan x="360" y="220.5">المغلوطة حول</tspan>
<tspan x="120" y="197.8">استنكار النشوة</tspan>
<tspan x="120" y="218.5">وتمجيد الألم نشأت</tspan>
<tspan x="76.0" y="239.1">بالفعل،</tspan>
</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View file

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="utf-8"?>
<svg id="svg-root"
width="100%" height="100%" viewBox="0 0 480 360"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:html="http://www.w3.org/1999/xhtml">
<g id="testmeta">
<title>Text in Shape — 002</title>
<html:link rel="author"
title="Tavmjong Bah"
href="mailto:tavmjong@free.fr"/>
<html:link rel="reviewer"
title="NAME_OF_REVIEWER"
href="mailto:EMAIL OR http://CONTACT_PAGE" />
<!-- YYYY-MM-DD -->
<html:link rel="help"
href="https://svgwg.org/svg2-draft/text.html#TextShapeInside"/>
<html:link rel="match" href="text-complex-002-ref.svg" />
<metadata class="flags">TOKENS</metadata>
<desc class="assert">TEST ASSERTION</desc>
</g>
<style id="test-font" type="text/css">
/* Standard Font (if needed). */
@font-face {
font-family: FreeSans;
src: url("fonts/FreeSans.woff") format("woff"),
local("FreeSans");
}
text { font-family: FreeSans, sans-serif }
</style>
<style id="test-style" type="text/css">
/* Style that is being tested (if needed). */
text { font-family: FreeSans, sans-serif }
</style>
<defs>
<circle id="Circle1" cx="360" cy="180" r="100"/>
<circle id="Circle2" cx="120" cy="240" r="100"/>
<rect id="Rect1" x="120" y="80" width="240" height="80" style="shape-margin: 20px;"/>
<rect id="Rect2" x="120" y="260" width="240" height="80" style="shape-margin: 20px;"/>
<circle id="Circle1x" cx="360" cy="180" r="80"/>
<circle id="Circle2x" cx="120" cy="240" r="80"/>
<rect id="Rect1x" x="100" y="60" width="280" height="120"/>
<rect id="Rect2x" x="100" y="240" width="280" height="120"/>
</defs>
<g style="fill:none;stroke:lightblue">
<use xlink:href="#Rect1" />
<use xlink:href="#Rect2" />
<use xlink:href="#Circle1" />
<use xlink:href="#Circle2" />
</g>
<g style="fill:none;stroke:lightblue;stroke-dasharray:5 5">
<use xlink:href="#Rect1x" />
<use xlink:href="#Rect2x" style="shape-margin: 20px;" />
<use xlink:href="#Circle1x" />
<use xlink:href="#Circle2x" />
</g>
<g id="test-body-content" style="font-size:16px;line-spacing:1.25;direction:rtl ">
<text style="shape-inside:url(#Circle1) url(#Circle2);
shape-subtract:url(#Rect1) url(#Rect2);
shape-padding:20px;
text-align: center;">لكن لا بد أن أوضح لك أن كل هذه الأفكار المغلوطة حول استنكار النشوة وتمجيد الألم نشأت بالفعل، وسأعرض لك التفاصيل</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View file

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="utf-8"?>
<svg id="svg-root"
width="100%" height="100%" viewBox="0 0 480 360"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:html="http://www.w3.org/1999/xhtml">
<g id="testmeta">
<title>Text in Shape — 001</title>
<html:link rel="author"
title="Tavmjong Bah"
href="mailto:tavmjong@free.fr"/>
<html:link rel="reviewer"
title="NAME_OF_REVIEWER"
href="mailto:EMAIL OR http://CONTACT_PAGE" />
<!-- YYYY-MM-DD -->
<html:link rel="help"
href="https://svgwg.org/svg2-draft/text.html#TextShapeInside"/>
<metadata class="flags">TOKENS</metadata>
<desc class="assert">TEST ASSERTION</desc>
</g>
<style id="test-font" type="text/css">
/* Standard Font (if needed). */
@font-face {
font-family: FreeSans;
src: url("fonts/FreeSans.woff") format("woff"),
local("FreeSans");
}
text { font-family: FreeSans, sans-serif }
</style>
<style id="test-style" type="text/css">
/* Style that is being tested (if needed). */
text { font-family: FreeSans, sans-serif }
</style>
<defs>
<rect id="TestRect" x="90" y="100" width="300" height="40"/>
</defs>
<g id="test-body-reference" style="font-size:16px">
<g transform="translate(0,0)">
<use xlink:href="#TestRect" style="fill:none;stroke:lightblue"/>
<text>
<tspan x="90" y="114.8">Lorem ipsum dolor sit amet, consectetur</tspan>
<tspan x="90" y="134.8">adipisicing elit,</tspan>
</text>
</g>
<g transform="translate(0,60)">
<use xlink:href="#TestRect" style="fill:none;stroke:lightblue"/>
<text style="text-anchor:middle">
<tspan x="240" y="114.8">Lorem ipsum dolor sit amet, consectetur</tspan>
<tspan x="240" y="134.8">adipisicing elit,</tspan>
</text>
</g>
<g transform="translate(0,120)">
<use xlink:href="#TestRect" style="fill:none;stroke:lightblue"/>
<text style="text-anchor:end">
<tspan x="390" y="114.8">Lorem ipsum dolor sit amet, consectetur</tspan>
<tspan x="390" y="134.8">adipisicing elit,</tspan>
</text>
</g>
<g transform="translate(0,180)">
<use xlink:href="#TestRect" style="fill:none;stroke:lightblue"/>
<text>
<tspan x="90" y="114.8">Lorem</tspan>
<tspan x="142.9">ipsum</tspan>
<tspan x="193.4">dolor</tspan>
<tspan x="236.8">sit</tspan>
<tspan x="261.2">amet,</tspan>
<tspan x="308.9">consectetur</tspan>
<tspan x="90" y="134.8">adipisicing elit,</tspan>
</text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View file

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="utf-8"?>
<svg id="svg-root"
width="100%" height="100%" viewBox="0 0 480 360"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:html="http://www.w3.org/1999/xhtml">
<g id="testmeta">
<title>Text in Shape — 001</title>
<html:link rel="author"
title="Tavmjong Bah"
href="mailto:tavmjong@free.fr"/>
<html:link rel="reviewer"
title="NAME_OF_REVIEWER"
href="mailto:EMAIL OR http://CONTACT_PAGE" />
<!-- YYYY-MM-DD -->
<html:link rel="help"
href="https://svgwg.org/svg2-draft/text.html#TextShapeInside"/>
<html:link rel="match" href="text-shape-inside-001-ref.svg" />
<metadata class="flags">TOKENS</metadata>
<desc class="assert">TEST ASSERTION</desc>
</g>
<style id="test-font" type="text/css">
/* Standard Font (if needed). */
@font-face {
font-family: FreeSans;
src: url("fonts/FreeSans.woff") format("woff"),
local("FreeSans");
}
text { font-family: FreeSans, sans-serif }
</style>
<style id="test-style" type="text/css">
/* Style that is being tested (if needed). */
text { font-family: FreeSans, sans-serif }
</style>
<defs>
<rect id="TestRect" x="90" y="100" width="300" height="40"/>
</defs>
<g id="test-body-content" style="font-size:16px;line-spacing:1.25">
<g transform="translate(0,0)">
<use xlink:href="#TestRect" style="fill:none;stroke:lightblue"/>
<text style="shape-inside:url(#TestRect)">Lorem ipsum dolor sit amet, consectetur adipisicing elit,</text>
</g>
<g transform="translate(0,60)">
<use xlink:href="#TestRect" style="fill:none;stroke:lightblue"/>
<text style="shape-inside:url(#TestRect);text-align:center">Lorem ipsum dolor sit amet, consectetur adipisicing elit,</text>
</g>
<g transform="translate(0,120)">
<use xlink:href="#TestRect" style="fill:none;stroke:lightblue"/>
<text style="shape-inside:url(#TestRect);text-align:right">Lorem ipsum dolor sit amet, consectetur adipisicing elit,</text>
</g>
<g transform="translate(0,180)">
<use xlink:href="#TestRect" style="fill:none;stroke:lightblue"/>
<text style="shape-inside:url(#TestRect);text-align:justify">Lorem ipsum dolor sit amet, consectetur adipisicing elit,</text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View file

@ -0,0 +1,76 @@
<?xml version="1.0" encoding="utf-8"?>
<svg id="svg-root"
width="100%" height="100%" viewBox="0 0 480 360"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:html="http://www.w3.org/1999/xhtml">
<g id="testmeta">
<title>Text in Shape — 002</title>
<html:link rel="author"
title="Tavmjong Bah"
href="mailto:tavmjong@free.fr"/>
<html:link rel="reviewer"
title="NAME_OF_REVIEWER"
href="mailto:EMAIL OR http://CONTACT_PAGE" />
<!-- YYYY-MM-DD -->
<html:link rel="help"
href="https://svgwg.org/svg2-draft/text.html#TextShapeInside"/>
<metadata class="flags">TOKENS</metadata>
<desc class="assert">TEST ASSERTION</desc>
</g>
<style id="test-font" type="text/css">
/* Standard Font (if needed). */
@font-face {
font-family: FreeSans;
src: url("fonts/FreeSans.woff") format("woff"),
local("FreeSans");
}
text { font-family: FreeSans, sans-serif }
</style>
<style id="test-style" type="text/css">
/* Style that is being tested (if needed). */
text { font-family: FreeSans, sans-serif }
</style>
<defs>
<rect id="TestRect" x="90" y="100" width="60" height="200"/>
</defs>
<g id="test-body-reference" style="font-size:16px">
<g transform="translate(0,0)">
<use xlink:href="#TestRect" style="fill:none;stroke:lightblue"/>
<text transform="translate(250,10) rotate(90)">
<tspan x="90" y="114.8">Lorem ipsum dolor sit amet,</tspan>
<tspan x="90" y="134.8">consectetur adipisicing elit,</tspan>
</text>
</g>
<g transform="translate(80,0)">
<use xlink:href="#TestRect" style="fill:none;stroke:lightblue"/>
<text transform="translate(250,-40) rotate(90)" style="text-anchor:middle">
<tspan x="240" y="114.8">Lorem ipsum dolor sit amet,</tspan>
<tspan x="240" y="134.8">consectetur adipisicing elit,</tspan>
</text>
</g>
<g transform="translate(160,0)">
<use xlink:href="#TestRect" style="fill:none;stroke:lightblue"/>
<text transform="translate(250,-90) rotate(90)" style="text-anchor:end">
<tspan x="390" y="114.8">Lorem ipsum dolor sit amet,</tspan>
<tspan x="390" y="134.8">consectetur adipisicing elit,</tspan>
</text>
</g>
<g transform="translate(240,0)">
<use xlink:href="#TestRect" style="fill:none;stroke:lightblue"/>
<text transform="translate(250,-150) rotate(90)">
<tspan x="250" y="114.8">Lorem</tspan>
<tspan x="300.3">ipsum</tspan>
<tspan x="348.2">dolor</tspan>
<tspan x="389">sit</tspan>
<tspan x="410.9">amet,</tspan>
<tspan x="250" y="134.8">consectetur adipisicing elit,</tspan>
</text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View file

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="utf-8"?>
<svg id="svg-root"
width="100%" height="100%" viewBox="0 0 480 360"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:html="http://www.w3.org/1999/xhtml">
<g id="testmeta">
<title>Text in Shape — 002</title>
<html:link rel="author"
title="Tavmjong Bah"
href="mailto:tavmjong@free.fr"/>
<html:link rel="reviewer"
title="NAME_OF_REVIEWER"
href="mailto:EMAIL OR http://CONTACT_PAGE" />
<!-- YYYY-MM-DD -->
<html:link rel="help"
href="https://svgwg.org/svg2-draft/text.html#TextShapeInside"/>
<html:link rel="match" href="text-shape-inside-002-ref.svg" />
<metadata class="flags">TOKENS</metadata>
<desc class="assert">TEST ASSERTION</desc>
</g>
<style id="test-font" type="text/css">
/* Standard Font (if needed). */
@font-face {
font-family: FreeSans;
src: url("fonts/FreeSans.woff") format("woff"),
local("FreeSans");
}
text { font-family: FreeSans, sans-serif }
</style>
<style id="test-style" type="text/css">
/* Style that is being tested (if needed). */
text { font-family: FreeSans, sans-serif }
</style>
<defs>
<rect id="TestRect" x="90" y="100" width="60" height="200"/>
</defs>
<g id="test-body-content" style="font-size:16px;line-spacing:1.25;writing-mode:tb-rl">
<g transform="translate(0,0)">
<use xlink:href="#TestRect" style="fill:none;stroke:lightblue"/>
<text style="shape-inside:url(#TestRect)">Lorem ipsum dolor sit amet, consectetur adipisicing elit,</text>
</g>
<g transform="translate(80,0)">
<use xlink:href="#TestRect" style="fill:none;stroke:lightblue"/>
<text style="shape-inside:url(#TestRect);text-align:center">Lorem ipsum dolor sit amet, consectetur adipisicing elit,</text>
</g>
<g transform="translate(160,0)">
<use xlink:href="#TestRect" style="fill:none;stroke:lightblue"/>
<text style="shape-inside:url(#TestRect);text-align:right">Lorem ipsum dolor sit amet, consectetur adipisicing elit,</text>
</g>
<g transform="translate(240,0)">
<use xlink:href="#TestRect" style="fill:none;stroke:lightblue"/>
<text style="shape-inside:url(#TestRect);text-align:justify">Lorem ipsum dolor sit amet, consectetur adipisicing elit,</text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View file

@ -301,6 +301,8 @@ def get_parser():
help="Include files in the worktree that are not in version control")
parser.add_argument("--show-type", action="store_true",
help="Print the test type along with each affected test")
parser.add_argument("--null", action="store_true",
help="Separate items with a null byte")
return parser
@ -326,8 +328,11 @@ def run_changed_files(**kwargs):
changed, _ = files_changed(revish, kwargs["ignore_rules"],
include_uncommitted=kwargs["modified"],
include_new=kwargs["new"])
separator = "\0" if kwargs["null"] else "\n"
for item in sorted(changed):
print(os.path.relpath(item, wpt_root))
sys.stdout.write(os.path.relpath(item, wpt_root) + separator)
def run_tests_affected(**kwargs):
@ -346,6 +351,9 @@ def run_tests_affected(**kwargs):
if kwargs["show_type"]:
wpt_manifest = load_manifest(manifest_path)
message = "{path}\t{item_type}"
message += "\0" if kwargs["null"] else "\n"
for item in sorted(tests_changed | dependents):
results = {
"path": os.path.relpath(item, wpt_root)
@ -355,4 +363,4 @@ def run_tests_affected(**kwargs):
if len(item_types) != 1:
item_types = [" ".join(item_types)]
results["item_type"] = item_types.pop()
print(message.format(**results))
sys.stdout.write(message.format(**results))

View file

@ -270,6 +270,25 @@ html/browsers/offline/appcache/workers/resources/appcache-worker.py
assert err == ""
@pytest.mark.xfail(sys.platform == "win32",
reason="Tests currently don't work on Windows for path reasons")
def test_files_changed_null(capsys):
commit = "9047ac1d9f51b1e9faa4f9fad9c47d109609ab09"
with pytest.raises(SystemExit) as excinfo:
wpt.main(argv=["files-changed", "--null", "%s~..%s" % (commit, commit)])
assert excinfo.value.code == 0
out, err = capsys.readouterr()
assert out == "\0".join(["html/browsers/offline/appcache/workers/appcache-worker.html",
"html/browsers/offline/appcache/workers/resources/appcache-dedicated-worker-not-in-cache.js",
"html/browsers/offline/appcache/workers/resources/appcache-shared-worker-not-in-cache.js",
"html/browsers/offline/appcache/workers/resources/appcache-worker-data.py",
"html/browsers/offline/appcache/workers/resources/appcache-worker-import.py",
"html/browsers/offline/appcache/workers/resources/appcache-worker.manifest",
"html/browsers/offline/appcache/workers/resources/appcache-worker.py",
""])
assert err == ""
def test_files_changed_ignore():
from tools.wpt.testfiles import exclude_ignored
files = ["resources/testharness.js", "resources/webidl2/index.js", "test/test.js"]
@ -304,6 +323,25 @@ def test_tests_affected(capsys, manifest_dir):
assert "infrastructure/reftest-wait.html" in out
@pytest.mark.slow # this updates the manifest
@pytest.mark.xfail(sys.platform == "win32",
reason="Tests currently don't work on Windows for path reasons")
def test_tests_affected_null(capsys, manifest_dir):
# This doesn't really work properly for random commits because we test the files in
# the current working directory for references to the changed files, not the ones at
# that specific commit. But we can at least test it returns something sensible.
# The test will fail if the file we assert is renamed, so we choose a stable one.
commit = "9bf1daa3d8b4425f2354c3ca92c4cf0398d329dd"
with pytest.raises(SystemExit) as excinfo:
wpt.main(argv=["tests-affected", "--null", "--metadata", manifest_dir, "%s~..%s" % (commit, commit)])
assert excinfo.value.code == 0
out, err = capsys.readouterr()
tests = out.split("\0")
assert "dom/interfaces.html" in tests
assert "html/dom/interfaces.https.html" in tests
@pytest.mark.slow
@pytest.mark.xfail(sys.platform == "win32",
reason="Tests currently don't work on Windows for path reasons")

View file

@ -817,11 +817,12 @@ class InternalRefTestImplementation(object):
def run_test(self, test):
references = self.get_references(test)
timeout = (test.timeout * 1000) * self.timeout_multiplier
rv = self.executor.protocol.marionette._send_message("reftest:run",
{"test": self.executor.test_url(test),
"references": references,
"expected": test.expected(),
"timeout": test.timeout * 1000})["value"]
"timeout": timeout})["value"]
return rv
def get_references(self, node):

View file

@ -64,25 +64,23 @@ class TestInputFile(TestUsingServer):
finally:
InputFile.max_buffer_size = old_max_buf
@pytest.mark.xfail(sys.version_info >= (3,), reason="wptserve only works on Py2")
def test_iter(self):
@wptserve.handlers.handler
def handler(request, response):
f = request.raw_input
return " ".join(line for line in f)
return b" ".join(line for line in f)
route = ("POST", "/test/test_iter", handler)
self.server.router.register(*route)
resp = self.request(route[1], method="POST", body="12345\nabcdef\r\nzyxwv")
resp = self.request(route[1], method="POST", body=b"12345\nabcdef\r\nzyxwv")
self.assertEqual(200, resp.getcode())
self.assertEqual(["12345\n", "abcdef\r\n", "zyxwv"], resp.read().split(" "))
self.assertEqual([b"12345\n", b"abcdef\r\n", b"zyxwv"], resp.read().split(b" "))
@pytest.mark.xfail(sys.version_info >= (3,), reason="wptserve only works on Py2")
def test_iter_input_longer_than_buffer(self):
@wptserve.handlers.handler
def handler(request, response):
f = request.raw_input
return " ".join(line for line in f)
return b" ".join(line for line in f)
route = ("POST", "/test/test_iter", handler)
self.server.router.register(*route)
@ -90,15 +88,14 @@ class TestInputFile(TestUsingServer):
old_max_buf = InputFile.max_buffer_size
InputFile.max_buffer_size = 10
try:
resp = self.request(route[1], method="POST", body="12345\nabcdef\r\nzyxwv")
resp = self.request(route[1], method="POST", body=b"12345\nabcdef\r\nzyxwv")
self.assertEqual(200, resp.getcode())
self.assertEqual(["12345\n", "abcdef\r\n", "zyxwv"], resp.read().split(" "))
self.assertEqual([b"12345\n", b"abcdef\r\n", b"zyxwv"], resp.read().split(b" "))
finally:
InputFile.max_buffer_size = old_max_buf
class TestRequest(TestUsingServer):
@pytest.mark.xfail(sys.version_info >= (3,), reason="wptserve only works on Py2")
def test_body(self):
@wptserve.handlers.handler
def handler(request, response):
@ -107,10 +104,9 @@ class TestRequest(TestUsingServer):
route = ("POST", "/test/test_body", handler)
self.server.router.register(*route)
resp = self.request(route[1], method="POST", body="12345ab\ncdef")
self.assertEqual("12345ab\ncdef", resp.read())
resp = self.request(route[1], method="POST", body=b"12345ab\ncdef")
self.assertEqual(b"12345ab\ncdef", resp.read())
@pytest.mark.xfail(sys.version_info >= (3,), reason="wptserve only works on Py2")
def test_route_match(self):
@wptserve.handlers.handler
def handler(request, response):
@ -119,7 +115,7 @@ class TestRequest(TestUsingServer):
route = ("GET", "/test/{match}_*", handler)
self.server.router.register(*route)
resp = self.request("/test/some_route")
self.assertEqual("some route", resp.read())
self.assertEqual(b"some route", resp.read())
class TestAuth(TestUsingServer):

View file

@ -29,8 +29,8 @@ test(t => {
anim.effect.composite = 'add';
const keyframes = anim.effect.getKeyframes();
assert_equals(keyframes[0].composite, null,
'unspecified keyframe composite value should be null even ' +
assert_equals(keyframes[0].composite, 'auto',
'unspecified keyframe composite value should be auto even ' +
'if effect composite is set');
}, 'Unspecified keyframe composite value when setting effect composite');

View file

@ -88,7 +88,7 @@ test(t => {
const effect = new KeyframeEffect(target, {
left: ['10px', '20px']
}, { composite });
assert_equals(effect.getKeyframes()[0].composite, null,
assert_equals(effect.getKeyframes()[0].composite, 'auto',
`resulting composite for '${composite}'`);
}
for (const composite of gBadOptionsCompositeValueTests) {
@ -98,7 +98,7 @@ test(t => {
}, { composite: composite });
});
}
}, 'composite value is null if the composite operation specified on the ' +
}, 'composite value is auto if the composite operation specified on the ' +
'keyframe effect is being used');
for (const subtest of gKeyframesTests) {

View file

@ -193,21 +193,21 @@ test(() => {
computedOffset: 0,
easing: 'linear',
left: '100px',
composite: null,
composite: 'auto',
},
{
offset: null,
computedOffset: 0.5,
easing: 'linear',
left: '300px',
composite: null,
composite: 'auto',
},
{
offset: null,
computedOffset: 1,
easing: 'linear',
left: '200px',
composite: null,
composite: 'auto',
},
]);
}, 'Keyframes are read from a custom iterator');
@ -228,21 +228,21 @@ test(() => {
computedOffset: 0,
easing: 'linear',
left: '100px',
composite: null,
composite: 'auto',
},
{
offset: null,
computedOffset: 0.5,
easing: 'linear',
left: '300px',
composite: null,
composite: 'auto',
},
{
offset: null,
computedOffset: 1,
easing: 'linear',
left: '200px',
composite: null,
composite: 'auto',
},
]);
}, '\'easing\' and \'offset\' are ignored on iterable objects');
@ -261,14 +261,14 @@ test(() => {
easing: 'linear',
left: '100px',
top: '200px',
composite: null,
composite: 'auto',
},
{
offset: null,
computedOffset: 0.5,
easing: 'linear',
left: '300px',
composite: null,
composite: 'auto',
},
{
offset: null,
@ -276,7 +276,7 @@ test(() => {
easing: 'linear',
left: '200px',
top: '100px',
composite: null,
composite: 'auto',
},
]);
}, 'Keyframes are read from a custom iterator with multiple properties'
@ -295,21 +295,21 @@ test(() => {
computedOffset: 0,
easing: 'linear',
left: '100px',
composite: null,
composite: 'auto',
},
{
offset: 0.75,
computedOffset: 0.75,
easing: 'linear',
left: '250px',
composite: null,
composite: 'auto',
},
{
offset: null,
computedOffset: 1,
easing: 'linear',
left: '200px',
composite: null,
composite: 'auto',
},
]);
}, 'Keyframes are read from a custom iterator with where an offset is'
@ -349,9 +349,9 @@ test(() => {
{ done: true },
]));
assert_frame_lists_equal(effect.getKeyframes(), [
{ left: '100px', offset: null, computedOffset: 0, easing: 'linear', composite: null },
{ offset: null, computedOffset: 0.5, easing: 'linear', composite: null },
{ left: '200px', offset: null, computedOffset: 1, easing: 'linear', composite: null },
{ left: '100px', offset: null, computedOffset: 0, easing: 'linear', composite: 'auto' },
{ offset: null, computedOffset: 0.5, easing: 'linear', composite: 'auto' },
{ left: '200px', offset: null, computedOffset: 1, easing: 'linear', composite: 'auto' },
]);
}, 'An undefined keyframe returned from a custom iterator should be treated as a'
+ ' default keyframe');
@ -364,9 +364,9 @@ test(() => {
{ done: true },
]));
assert_frame_lists_equal(effect.getKeyframes(), [
{ left: '100px', offset: null, computedOffset: 0, easing: 'linear', composite: null },
{ offset: null, computedOffset: 0.5, easing: 'linear', composite: null },
{ left: '200px', offset: null, computedOffset: 1, easing: 'linear', composite: null },
{ left: '100px', offset: null, computedOffset: 0, easing: 'linear', composite: 'auto' },
{ offset: null, computedOffset: 0.5, easing: 'linear', composite: 'auto' },
{ left: '200px', offset: null, computedOffset: 1, easing: 'linear', composite: 'auto' },
]);
}, 'A null keyframe returned from a custom iterator should be treated as a'
+ ' default keyframe');
@ -377,7 +377,7 @@ test(() => {
{ done: true },
]));
assert_frame_lists_equal(effect.getKeyframes(), [
{ offset: null, computedOffset: 1, easing: 'linear', composite: null }
{ offset: null, computedOffset: 1, easing: 'linear', composite: 'auto' }
]);
}, 'A list of values returned from a custom iterator should be ignored');
@ -437,14 +437,14 @@ test(() => {
computedOffset: 0,
easing: 'linear',
height: '100px',
composite: null,
composite: 'auto',
},
{
offset: null,
computedOffset: 1,
easing: 'linear',
height: '200px',
composite: null,
composite: 'auto',
},
]);
}, 'Only enumerable properties on keyframes are read');
@ -468,14 +468,14 @@ test(() => {
computedOffset: 0,
easing: 'linear',
top: '100px',
composite: null,
composite: 'auto',
},
{
offset: null,
computedOffset: 1,
easing: 'linear',
top: '200px',
composite: null,
composite: 'auto',
},
]);
}, 'Only properties defined directly on keyframes are read');
@ -496,14 +496,14 @@ test(() => {
computedOffset: 0,
easing: 'linear',
height: '100px',
composite: null,
composite: 'auto',
},
{
offset: null,
computedOffset: 1,
easing: 'linear',
height: '200px',
composite: null,
composite: 'auto',
},
]);
}, 'Only enumerable properties on property-indexed keyframes are read');
@ -527,14 +527,14 @@ test(() => {
computedOffset: 0,
easing: 'linear',
top: '100px',
composite: null,
composite: 'auto',
},
{
offset: null,
computedOffset: 1,
easing: 'linear',
top: '200px',
composite: null,
composite: 'auto',
},
]);
}, 'Only properties defined directly on property-indexed keyframes are read');

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