Update web-platform-tests to revision 55351d32dd26ea3ad42a8f5973e943ba0342c812

This commit is contained in:
WPT Sync Bot 2020-01-28 08:23:29 +00:00
parent 1b7223a284
commit 81d0cdbb2c
159 changed files with 2809 additions and 967 deletions

File diff suppressed because it is too large Load diff

View file

@ -2,3 +2,6 @@
[Hit test intersecting scaled box] [Hit test intersecting scaled box]
expected: FAIL expected: FAIL
[Hit test within unscaled box]
expected: FAIL

View file

@ -1,3 +0,0 @@
[transofrmed-preserve-3d-1.html]
type: reftest
disabled: https://github.com/servo/servo/issues/9087

View file

@ -312,18 +312,24 @@
[fetch(): separate response Content-Type: text/plain ] [fetch(): separate response Content-Type: text/plain ]
expected: NOTRUN expected: NOTRUN
[<iframe>: separate response Content-Type: text/html;" text/plain]
expected: FAIL
[<iframe>: combined response Content-Type: text/html;charset=gbk text/plain text/html]
expected: FAIL
[<iframe>: separate response Content-Type: text/plain */*] [<iframe>: separate response Content-Type: text/plain */*]
expected: FAIL expected: FAIL
[<iframe>: combined response Content-Type: text/html;" \\" text/plain]
expected: FAIL
[<iframe>: combined response Content-Type: text/html;x=" text/plain] [<iframe>: combined response Content-Type: text/html;x=" text/plain]
expected: FAIL expected: FAIL
[<iframe>: combined response Content-Type: text/html;" text/plain]
expected: FAIL
[<iframe>: combined response Content-Type: */* text/html]
expected: FAIL
[<iframe>: separate response Content-Type: text/html */*;charset=gbk]
expected: FAIL
[<iframe>: separate response Content-Type: text/html */*]
expected: FAIL
[<iframe>: separate response Content-Type: text/html;" \\" text/plain]
expected: FAIL

View file

@ -11,12 +11,6 @@
[X-Content-Type-Options%3A%20nosniff%0C] [X-Content-Type-Options%3A%20nosniff%0C]
expected: FAIL expected: FAIL
[X-Content-Type-Options%3A%20%22nosniFF%22] [X-Content-Type-Options%3A%20%2Cnosniff]
expected: FAIL
[X-Content-Type-Options%3A%20no%0D%0AX-Content-Type-Options%3A%20nosniff]
expected: FAIL
[Content-Type-Options%3A%20nosniff]
expected: FAIL expected: FAIL

View file

@ -8,7 +8,7 @@
expected: FAIL expected: FAIL
[Embedded credentials are treated as network errors in new windows.] [Embedded credentials are treated as network errors in new windows.]
expected: FAIL expected: TIMEOUT
[Embedded credentials matching the top-level are treated as network errors for cross-origin URLs.] [Embedded credentials matching the top-level are treated as network errors for cross-origin URLs.]
expected: TIMEOUT expected: TIMEOUT

View file

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

View file

@ -1,5 +1,5 @@
[embedded-opener-remove-frame.html] [embedded-opener-remove-frame.html]
expected: TIMEOUT expected: CRASH
[opener and "removed" embedded documents] [opener and "removed" embedded documents]
expected: FAIL expected: FAIL

View file

@ -1,5 +1,6 @@
[iframe_sandbox_popups_escaping-3.html] [iframe_sandbox_popups_escaping-3.html]
type: testharness type: testharness
expected: TIMEOUT
[Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used] [Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used]
expected: FAIL expected: TIMEOUT

View file

@ -1,6 +1,5 @@
[iframe_sandbox_popups_nonescaping-1.html] [iframe_sandbox_popups_nonescaping-1.html]
type: testharness type: testharness
expected: TIMEOUT
[Check that popups from a sandboxed iframe do not escape the sandbox] [Check that popups from a sandboxed iframe do not escape the sandbox]
expected: NOTRUN expected: FAIL

View file

@ -24,3 +24,6 @@
[[textarea\] The validity.customError must be true if the custom validity error message is not empty] [[textarea\] The validity.customError must be true if the custom validity error message is not empty]
expected: FAIL expected: FAIL
[[select\] The validity.customError must be false if the custom validity error message is empty]
expected: FAIL

View file

@ -1,5 +1,5 @@
[form-double-submit-3.html] [form-double-submit-3.html]
expected: ERROR expected: ERROR
[<button> should have the same double-submit protection as <input type=submit>] [<button> should have the same double-submit protection as <input type=submit>]
expected: FAIL expected: TIMEOUT

View file

@ -1,8 +0,0 @@
[anchor-with-inline-element.html]
expected: TIMEOUT
[Clicking on anchor with embedded inline element should navigate instead of opening details]
expected: NOTRUN
[Expected <a> containing <i> to navigate]
expected: NOTRUN

View file

@ -0,0 +1,2 @@
[errorhandling.html]
expected: CRASH

View file

@ -10,3 +10,6 @@
[Verifies the resolution of entry.startTime is at least 20 microseconds.] [Verifies the resolution of entry.startTime is at least 20 microseconds.]
expected: TIMEOUT expected: TIMEOUT
[Verifies the resolution of performance.now() is at least 5 microseconds.]
expected: FAIL

View file

@ -1,5 +1,4 @@
[crossorigin-sandwich-TAO.sub.html] [crossorigin-sandwich-TAO.sub.html]
expected: ERROR
[There should be one entry.] [There should be one entry.]
expected: FAIL expected: FAIL

View file

@ -0,0 +1,10 @@
[ar_hittest_subscription_states.https.html]
[Hit test subscription succeeds if the feature was requested]
expected: FAIL
[Hit test subscription fails if the feature was not requested]
expected: FAIL
[Hit test subscription fails if the feature was requested but the session already ended]
expected: FAIL

View file

@ -27,30 +27,6 @@
height: 400px; height: 400px;
} }
.thirdRowFirstColumn {
background-color: green;
grid-column: 1;
grid-row: 3;
}
.fourthRowFirstColumn {
background-color: deepskyblue;
grid-column: 1;
grid-row: 4;
}
.fourthRowSecondColumn {
background-color: maroon;
grid-column: 2;
grid-row: 4;
}
.thirdRowFirstColumn {
background-color: green;
grid-column: 1;
grid-row: 3;
}
.fourthRowFirstColumn { .fourthRowFirstColumn {
background-color: deepskyblue; background-color: deepskyblue;
grid-column: 1; grid-column: 1;

View file

@ -27,30 +27,6 @@
height: 400px; height: 400px;
} }
.thirdRowFirstColumn {
background-color: green;
grid-column: 1;
grid-row: 3;
}
.fourthRowFirstColumn {
background-color: deepskyblue;
grid-column: 1;
grid-row: 4;
}
.fourthRowSecondColumn {
background-color: maroon;
grid-column: 2;
grid-row: 4;
}
.thirdRowFirstColumn {
background-color: green;
grid-column: 1;
grid-row: 3;
}
.fourthRowFirstColumn { .fourthRowFirstColumn {
background-color: deepskyblue; background-color: deepskyblue;
grid-column: 1; grid-column: 1;

View file

@ -22,30 +22,6 @@
grid-auto-rows: auto; grid-auto-rows: auto;
} }
.thirdRowFirstColumn {
background-color: green;
grid-column: 1;
grid-row: 3;
}
.fourthRowFirstColumn {
background-color: deepskyblue;
grid-column: 1;
grid-row: 4;
}
.fourthRowSecondColumn {
background-color: maroon;
grid-column: 2;
grid-row: 4;
}
.thirdRowFirstColumn {
background-color: green;
grid-column: 1;
grid-row: 3;
}
.fourthRowFirstColumn { .fourthRowFirstColumn {
background-color: deepskyblue; background-color: deepskyblue;
grid-column: 1; grid-column: 1;

View file

@ -29,11 +29,7 @@
width: 50px; width: 50px;
height: 40px; height: 40px;
} }
.thirdRowFirstColumn {
background-color: green;
grid-column: 1;
grid-row: 3;
}
</style> </style>
<script src="/resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>

View file

@ -0,0 +1,85 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Grid Layout test:item alignment with orthogonal flows, vertical-lr writing mode</title>
<link rel="author" title="Rossana Monteriso" href="mailto:rmonteriso@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-align-3/#alignment-values">
<link rel="help" href="https://drafts.csswg.org/css-writing-modes-4/#orthogonal-flows">
<meta name="assert" content="This test checks that grid item alignment works as expected with vertical-lr and horizontal-tb orthogonal flows">
<meta name="flags" content="ahem">
<link rel="stylesheet" href="/css/support/grid.css">
<link rel="stylesheet" href="/css/support/alignment.css">
<link rel="stylesheet" href="/css/support/width-keyword-classes.css">
<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
<style>
.container {
position: relative;
}
.grid {
grid-template-columns: 100px 100px;
grid-template-rows: 150px 150px 150px;
font-size: 10px;
}
.item {
width: 50px;
height: 20px;
}
</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')">
<p>This test checks that grid items alignment works as expected with VERTICAL-LR vs HORIZONTAL-TB orthogonal flows.</p>
<p>Direction: LTR vs LTR</p>
<div class="container">
<div class="grid fit-content verticalLR directionLTR">
<div class="item firstRowFirstColumn horizontalTB selfEnd" data-offset-x="100" data-offset-y="80">end</div>
<div class="item firstRowSecondColumn horizontalTB selfCenter" data-offset-x="50" data-offset-y="140">center</div>
<div class="item secondRowFirstColumn horizontalTB selfStart" data-offset-x="150" data-offset-y="0">start</div>
<div class="item secondRowSecondColumn horizontalTB selfSelfEnd" data-offset-x="250" data-offset-y="180">s-end</div>
<div class="item thirdRowFirstColumn horizontalTB selfSelfStart" data-offset-x="300" data-offset-y="0">s-start</div>
<div class="item thirdRowSecondColumn horizontalTB" data-offset-x="300" data-offset-y="100">default</div>
</div>
</div>
<p>Direction: RTL vs LTR</p>
<div class="container">
<div class="grid fit-content verticalLR directionRTL">
<div class="item firstRowFirstColumn directionLTR horizontalTB selfEnd" data-offset-x="100" data-offset-y="100">end</div>
<div class="item firstRowSecondColumn directionLTR horizontalTB selfCenter" data-offset-x="50" data-offset-y="40">center</div>
<div class="item secondRowFirstColumn directionLTR horizontalTB selfStart" data-offset-x="150" data-offset-y="180">start</div>
<div class="item secondRowSecondColumn directionLTR horizontalTB selfSelfEnd" data-offset-x="250" data-offset-y="80">s-end</div>
<div class="item thirdRowFirstColumn directionLTR horizontalTB selfSelfStart" data-offset-x="300" data-offset-y="100">s-start</div>
<div class="item thirdRowSecondColumn directionLTR horizontalTB" data-offset-x="300" data-offset-y="80">default</div>
</div>
</div>
<p>Direction: LTR vs RTL</p>
<div class="container">
<div class="grid fit-content verticalLR directionLTR">
<div class="item firstRowFirstColumn directionRTL horizontalTB selfEnd" data-offset-x="100" data-offset-y="80">end</div>
<div class="item firstRowSecondColumn directionRTL horizontalTB selfCenter" data-offset-x="50" data-offset-y="140">center</div>
<div class="item secondRowFirstColumn directionRTL horizontalTB selfStart" data-offset-x="150" data-offset-y="0">start</div>
<div class="item secondRowSecondColumn directionRTL horizontalTB selfSelfEnd" data-offset-x="150" data-offset-y="180">s-end</div>
<div class="item thirdRowFirstColumn directionRTL horizontalTB selfSelfStart" data-offset-x="400" data-offset-y="0">s-start</div>
<div class="item thirdRowSecondColumn directionRTL horizontalTB" data-offset-x="300" data-offset-y="100">default</div>
</div>
</div>
<p>Direction: RTL vs RTL</p>
<div class="container">
<div class="grid fit-content verticalLR directionRTL">
<div class="item firstRowFirstColumn horizontalTB selfEnd" data-offset-x="100" data-offset-y="100">end</div>
<div class="item firstRowSecondColumn horizontalTB selfCenter" data-offset-x="50" data-offset-y="40">center</div>
<div class="item secondRowFirstColumn horizontalTB selfStart" data-offset-x="150" data-offset-y="180">start</div>
<div class="item secondRowSecondColumn horizontalTB selfSelfEnd" data-offset-x="150" data-offset-y="80">s-end</div>
<div class="item thirdRowFirstColumn horizontalTB selfSelfStart" data-offset-x="400" data-offset-y="100">s-start</div>
<div class="item thirdRowSecondColumn horizontalTB" data-offset-x="300" data-offset-y="80">default</div>
</div>
</div>
</body>

View file

@ -0,0 +1,86 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Grid Layout test:item alignment with orthogonal flows, vertical-rl writing mode</title>
<link rel="author" title="Rossana Monteriso" href="mailto:rmonteriso@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-align-3/#alignment-values">
<link rel="help" href="https://drafts.csswg.org/css-writing-modes-4/#orthogonal-flows">
<meta name="assert" content="This test checks that grid item alignment works as expected with vertical-rl and horizontal-tb orthogonal flows">
<meta name="flags" content="ahem">
<link rel="stylesheet" href="/css/support/grid.css">
<link rel="stylesheet" href="/css/support/alignment.css">
<link rel="stylesheet" href="/css/support/width-keyword-classes.css">
<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
<style>
.container {
position: relative;
}
.grid {
grid-template-columns: 100px 100px;
grid-template-rows: 150px 150px 150px;
font-size: 10px;
}
.item {
width: 50px;
height: 20px;
}
</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')">
<p>This test checks that grid items alignment works as expected with VERTICAL-RL vs HORIZONTAL-TB orthogonal flows.</p>
<p>Direction: LTR vs LTR</p>
<div class="container">
<div class="grid fit-content verticalRL directionLTR">
<div class="item firstRowFirstColumn horizontalTB selfEnd" data-offset-x="300" data-offset-y="80">end</div>
<div class="item firstRowSecondColumn horizontalTB selfCenter" data-offset-x="350" data-offset-y="140">center</div>
<div class="item secondRowFirstColumn horizontalTB selfStart" data-offset-x="250" data-offset-y="0">start</div>
<div class="item secondRowSecondColumn horizontalTB selfSelfEnd" data-offset-x="250" data-offset-y="180">s-end</div>
<div class="item thirdRowFirstColumn horizontalTB selfSelfStart" data-offset-x="0" data-offset-y="0">s-start</div>
<div class="item thirdRowSecondColumn horizontalTB" data-offset-x="100" data-offset-y="100">default</div>
</div>
</div>
<p>Direction: RTL vs LTR</p>
<div class="container">
<div class="grid fit-content verticalRL directionRTL">
<div class="item firstRowFirstColumn directionLTR horizontalTB selfEnd" data-offset-x="300" data-offset-y="100">end</div>
<div class="item firstRowSecondColumn directionLTR horizontalTB selfCenter" data-offset-x="350" data-offset-y="40">center</div>
<div class="item secondRowFirstColumn directionLTR horizontalTB selfStart" data-offset-x="250" data-offset-y="180">start</div>
<div class="item secondRowSecondColumn directionLTR horizontalTB selfSelfEnd" data-offset-x="250" data-offset-y="80">s-end</div>
<div class="item thirdRowFirstColumn directionLTR horizontalTB selfSelfStart" data-offset-x="0" data-offset-y="100">s-start</div>
<div class="item thirdRowSecondColumn directionLTR horizontalTB" data-offset-x="100" data-offset-y="80">default</div>
</div>
</div>
<p>Direction: LTR vs RTL</p>
<div class="container">
<div class="grid fit-content verticalRL directionLTR">
<div class="item firstRowFirstColumn directionRTL horizontalTB selfEnd" data-offset-x="300" data-offset-y="80">end</div>
<div class="item firstRowSecondColumn directionRTL horizontalTB selfCenter" data-offset-x="350" data-offset-y="140">center</div>
<div class="item secondRowFirstColumn directionRTL horizontalTB selfStart" data-offset-x="250" data-offset-y="0">start</div>
<div class="item secondRowSecondColumn directionRTL horizontalTB selfSelfEnd" data-offset-x="150" data-offset-y="180">s-end</div>
<div class="item thirdRowFirstColumn directionRTL horizontalTB selfSelfStart" data-offset-x="100" data-offset-y="0">s-start</div>
<div class="item thirdRowSecondColumn directionRTL horizontalTB" data-offset-x="100" data-offset-y="100">default</div>
</div>
</div>
<p>Direction: RTL vs RTL</p>
<div class="container">
<div class="grid fit-content verticalRL directionRTL">
<div class="item firstRowFirstColumn horizontalTB selfEnd" data-offset-x="300" data-offset-y="100">end</div>
<div class="item firstRowSecondColumn horizontalTB selfCenter" data-offset-x="350" data-offset-y="40">center</div>
<div class="item secondRowFirstColumn horizontalTB selfStart" data-offset-x="250" data-offset-y="180">start</div>
<div class="item secondRowSecondColumn horizontalTB selfSelfEnd" data-offset-x="150" data-offset-y="80">s-end</div>
<div class="item thirdRowFirstColumn horizontalTB selfSelfStart" data-offset-x="100" data-offset-y="100">s-start</div>
<div class="item thirdRowSecondColumn horizontalTB" data-offset-x="100" data-offset-y="80">default</div>
</div>
</div>
</body>

View file

@ -0,0 +1,125 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Grid Layout test: item alignment with orthogonal flows</title>
<link rel="author" title="Rossana Monteriso" href="mailto:rmonteriso@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-align-3/#alignment-values">
<link rel="help" href="https://drafts.csswg.org/css-writing-modes-4/#orthogonal-flows">
<meta name="assert" content="This test checks that grid item alignment works as expected with horizontal-tb and vertical-rl/vertical-lr orthogonal flows">
<meta name="flags" content="ahem">
<link rel="stylesheet" href="/css/support/grid.css">
<link rel="stylesheet" href="/css/support/alignment.css">
<link rel="stylesheet" href="/css/support/width-keyword-classes.css">
<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
<style>
.container {
position: relative;
}
.grid {
grid-template-columns: 100px 100px;
grid-template-rows: 150px 150px 150px;
font-size: 10px;
}
.item {
width: 20px;
height: 50px;
}
</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')">
<p>This test checks that grid items alignment works as expected with HORIZONTAL-TB vs VERTICAL-RL orthogonal flows.</p>
<p>Orthogonal flows: HORIZONTAL-TB vs VERTICAL-RL</p>
<p>Direction: LTR vs LTR</p>
<div class="container">
<div class="grid fit-content directionLTR">
<div class="item firstRowFirstColumn verticalRL selfEnd" data-offset-x="80" data-offset-y="100">end</div>
<div class="item firstRowSecondColumn verticalRL selfCenter" data-offset-x="140" data-offset-y="50">center</div>
<div class="item secondRowFirstColumn verticalRL selfStart" data-offset-x="0" data-offset-y="150">start</div>
<div class="item secondRowSecondColumn verticalRL selfSelfEnd" data-offset-x="100" data-offset-y="250">s-end</div>
<div class="item thirdRowFirstColumn verticalRL selfSelfStart" data-offset-x="80" data-offset-y="300">s-start</div>
<div class="item thirdRowSecondColumn verticalRL" data-offset-x= "100" data-offset-y="300">default</div>
</div>
</div>
<p>Direction: RTL vs LTR</p>
<div class="container">
<div class="grid fit-content directionRTL">
<div class="item firstRowFirstColumn directionLTR verticalRL selfEnd" data-offset-x="100" data-offset-y="100">end</div>
<div class="item firstRowSecondColumn directionLTR verticalRL selfCenter" data-offset-x="40" data-offset-y="50">center</div>
<div class="item secondRowFirstColumn directionLTR verticalRL selfStart" data-offset-x="180" data-offset-y="150">start</div>
<div class="item secondRowSecondColumn directionLTR verticalRL selfSelfEnd" data-offset-x="0" data-offset-y="250">s-end</div>
<div class="item thirdRowFirstColumn directionLTR verticalRL selfSelfStart" data-offset-x="180" data-offset-y="300">s-start</div>
<div class="item thirdRowSecondColumn directionLTR verticalRL" data-offset-x="80" data-offset-y="300">default</div>
</div>
</div>
<p>Direction: LTR vs RTL</p>
<div class="container">
<div class="grid fit-content directionLTR">
<div class="item firstRowFirstColumn directionRTL verticalRL selfEnd" data-offset-x="80" data-offset-y="100">end</div>
<div class="item firstRowSecondColumn directionRTL verticalRL selfCenter" data-offset-x="140" data-offset-y="50">center</div>
<div class="item secondRowFirstColumn directionRTL verticalRL selfStart" data-offset-x="0" data-offset-y="150">start</div>
<div class="item secondRowSecondColumn directionRTL verticalRL selfSelfEnd" data-offset-x="100" data-offset-y="150">s-end</div>
<div class="item thirdRowFirstColumn directionRTL verticalRL selfSelfStart" data-offset-x="80" data-offset-y="400">s-start</div>
<div class="item thirdRowSecondColumn directionRTL verticalRL" data-offset-x="100" data-offset-y="300">default</div>
</div>
</div>
<p>Direction: RTL vs RTL</p>
<div class="container">
<div class="grid fit-content directionRTL">
<div class="item firstRowFirstColumn verticalRL selfEnd" data-offset-x="100" data-offset-y="100">end</div>
<div class="item firstRowSecondColumn verticalRL selfCenter" data-offset-x="40" data-offset-y="50">center</div>
<div class="item secondRowFirstColumn verticalRL selfStart" data-offset-x="180" data-offset-y="150">start</div>
<div class="item secondRowSecondColumn verticalRL selfSelfEnd" data-offset-x="0" data-offset-y="150">s-end</div>
<div class="item thirdRowFirstColumn verticalRL selfSelfStart" data-offset-x="180" data-offset-y="400">s-start</div>
<div class="item thirdRowSecondColumn verticalRL" data-offset-x="80" data-offset-y="300">default</div>
</div>
</div>
<!-- HORIZONTAL-TB vs VERTICAL-LR -->
<p>Orthogonal flows: HORIZONTAL-TB vs VERTICAL-LR</p>
<p>Direction: LTR vs LTR</p>
<div class="container">
<div class="grid fit-content drectionLTR">
<div class="item firstRowFirstColumn verticalLR selfEnd" data-offset-x="80" data-offset-y="100">end</div>
<div class="item firstRowSecondColumn verticalLR selfCenter" data-offset-x="140" data-offset-y="50">center</div>
<div class="item secondRowFirstColumn verticalLR selfStart" data-offset-x="0" data-offset-y="150">start</div>
<div class="item secondRowSecondColumn verticalLR selfSelfEnd" data-offset-x="180" data-offset-y="250">s-end</div>
<div class="item thirdRowFirstColumn verticalLR selfSelfStart" data-offset-x="0" data-offset-y="300">s-start</div>
<div class="item thirdRowSecondColumn verticalLR" data-offset-x="100" data-offset-y="300">default</div>
</div>
</div>
<p>Direction: RTL vs LTR</p>
<div class="container">
<div class="grid fit-content directionRTL">
<div class="item firstRowFirstColumn directionLTR verticalLR selfEnd" data-offset-x="100" data-offset-y="100">end</div>
<div class="item firstRowSecondColumn directionLTR verticalLR selfCenter" data-offset-x="40" data-offset-y="50">center</div>
<div class="item secondRowFirstColumn directionLTR verticalLR selfStart" data-offset-x="180" data-offset-y="150">start</div>
<div class="item secondRowSecondColumn directionLTR verticalLR selfSelfEnd" data-offset-x="80" data-offset-y="250">s-end</div>
<div class="item thirdRowFirstColumn directionLTR verticalLR selfSelfStart" data-offset-x="100" data-offset-y="300">s-start</div>
<div class="item thirdRowSecondColumn directionLTR verticalLR" data-offset-x="80" data-offset-y="300">default</div>
</div>
</div>
<p>Direction: RTL vs RTL</p>
<div class="container">
<div class="grid fit-content directionRTL">
<div class="item firstRowFirstColumn verticalLR selfEnd" data-offset-x="100" data-offset-y="100">end</div>
<div class="item firstRowSecondColumn verticalLR selfCenter" data-offset-x="40" data-offset-y="50">center</div>
<div class="item secondRowFirstColumn verticalLR selfStart" data-offset-x="180" data-offset-y="150">start</div>
<div class="item secondRowSecondColumn verticalLR selfSelfEnd" data-offset-x="80" data-offset-y="150">s-end</div>
<div class="item thirdRowFirstColumn verticalLR selfSelfStart" data-offset-x="100" data-offset-y="400">s-start</div>
<div class="item thirdRowSecondColumn verticalLR" data-offset-x="80" data-offset-y="300">default</div>
</div>
</div>
</body>

View file

@ -0,0 +1,22 @@
<!doctype html>
<title>Grid items only stretch if block-size computes to auto</title>
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/4525">
<link rel="help" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
<link rel="help" href="https://mozilla.org" title="Mozilla">
<link rel="match" href="grid-item-non-auto-height-stretch-ref.html">
<style>
#grid {
display: grid;
width: 100px;
height: 100px;
grid-template: 100% / 100%;
background: green;
}
#item {
height: max-content;
background: red;
}
</style>
<div id="grid">
<div id="item"></div>
</div>

View file

@ -0,0 +1,23 @@
<!doctype html>
<title>Grid items only stretch if block-size computes to auto</title>
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/4525">
<link rel="help" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
<link rel="help" href="https://mozilla.org" title="Mozilla">
<link rel="match" href="grid-item-non-auto-height-stretch-ref.html">
<style>
#grid {
writing-mode: vertical-lr;
display: grid;
width: 100px;
height: 100px;
grid-template: 100% / 100%;
background: green;
}
#item {
width: max-content;
background: red;
}
</style>
<div id="grid">
<div id="item"></div>
</div>

View file

@ -0,0 +1,22 @@
<!doctype html>
<title>Grid items only stretch if block-size computes to auto</title>
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/4525">
<link rel="help" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
<link rel="help" href="https://mozilla.org" title="Mozilla">
<link rel="match" href="grid-item-non-auto-height-stretch-ref.html">
<style>
#grid {
display: grid;
width: 100px;
height: 100px;
grid-template: 100% / 100%;
background: green;
}
#item {
height: min-content;
background: red;
}
</style>
<div id="grid">
<div id="item"></div>
</div>

View file

@ -0,0 +1,23 @@
<!doctype html>
<title>Grid items only stretch if block-size computes to auto</title>
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/4525">
<link rel="help" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
<link rel="help" href="https://mozilla.org" title="Mozilla">
<link rel="match" href="grid-item-non-auto-height-stretch-ref.html">
<style>
#grid {
writing-mode: vertical-lr;
display: grid;
width: 100px;
height: 100px;
grid-template: 100% / 100%;
background: green;
}
#item {
width: min-content;
background: red;
}
</style>
<div id="grid">
<div id="item"></div>
</div>

View file

@ -0,0 +1,10 @@
<!doctype html>
<title>CSS test reference</title>
<style>
#ref {
width: 100px;
height: 100px;
background: green;
}
</style>
<div id="ref"></div>

View file

@ -61,7 +61,7 @@ x {
<div class="grid"> <div class="grid">
<i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i> <i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i>
<div class="subgrid"> <div class="subgrid">
<x style="grid-column:3; right:33px">x</x> <x style="grid-column:3; right:27px">x</x>
</div> </div>
</div> </div>
@ -117,7 +117,7 @@ x {
<div class="grid"> <div class="grid">
<i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i> <i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i>
<div class="subgrid hr"> <div class="subgrid hr">
<x style="grid-column:auto/1; left:-33px">x</x> <x style="grid-column:auto/1; left:-27px">x</x>
</div> </div>
</div> </div>

View file

@ -0,0 +1,233 @@
<!DOCTYPE HTML>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html><head>
<meta charset="utf-8">
<title>Reference: subgrid margin/border/padding that overflow the edge track</title>
<link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com">
<style>
html,body {
color:black; background-color:white; font:16px/1 monospace; margin:0; padding:0;
}
.grid {
display: inline-grid;
grid: auto / 7px 30px 10px 20px 5px;
justify-content: space-around;
align-content: start;
border: 3px solid;
width: 80px;
}
.rtl { direction: rtl; }
.subgrid {
display: grid;
min-width: 0;
min-height: 30px;
background: pink;
border:1px solid;
margin: 0 4px 0 3px;
position: relative;
justify-content: space-between;
}
.c1 { width: 30px; grid-column: 2 / span 1; grid: auto / 26px; }
.rtl > .c1 { grid: auto / 25px; }
.c1.plr { padding-right: 100px; }
.rtl > .c1.plr { padding: 0 0 0 100px; }
.c2 { width: 33px; grid-column: 2 / span 2; grid: auto / 26px 5px; }
.rtl > .c2 { grid: auto / 25px 6px; }
.c2.plr { padding-right: 97px; }
.rtl > .c2.plr { padding: 0 0 0 97px; }
.c3 { width: 55px; grid-column: 2 / span 3; grid: auto / 26px 10px 15px; }
.rtl > .c3 { grid: auto / 25px 10px 16px; }
.c3.plr { padding-right: 75px; }
.rtl > .c3.plr { padding: 0 0 0 75px; }
y {
background: blue;
height: 10px;
}
y:nth-of-type(1) { grid-column: 2; }
y:nth-of-type(2) { grid-column: 4; }
x { background: silver; }
x:nth-of-type(2) { background: purple; }
x:nth-of-type(3) { background: magenta; }
a {
position: absolute;
grid-column-start: 1;
inset: 0;
top: 3px;
border-top: 2px solid grey;
}
a:nth-of-type(2) {
grid-column-start: 2;
top: 6px;
}
a:nth-of-type(3) {
grid-column-start: 3;
top: 9px;
}
b {
position: absolute;
grid-column-end: 1;
inset: 0;
top: 12px;
border-top: 2px solid grey;
}
b:nth-of-type(2) {
grid-column-end: 2;
top: 15px;
}
b:nth-of-type(3) {
grid-column-end: 3;
top: 18px;
}
.f { float:left; margin-left:80px; }
.z { height:0; }
.s2 { grid-column:2; }
.gl { left: -2px; }
.e2 { grid-column-end:2; }
.gr { right: -2px; }
</style>
</head>
<body>
<div class=f>
<div class="grid">
<y></y><y></y>
<div class="subgrid c3 pr"><x></x><a></a><b></b><x></x><a></a><b></b><a></a><b></b></div>
</div>
<br>
<div class="grid">
<y></y><y></y>
<div class="subgrid c3 pl"><x class="z"></x><a class="s2 gl"></a><b class="e2"></b><x></x><a></a><b></b><x></x><a></a><b></b></div>
</div>
<br>
<div class="grid">
<y></y><y></y>
<div class="subgrid c3 plr"><x class="z"></x><a class="s2 gl"></a><b class="e2"></b><x></x><a></a><b></b><x class="z"></x><a></a><b></b></div>
</div>
<br>
<div class="grid rtl">
<y></y><y></y>
<div class="subgrid c3 pr"><x class="z"></x><a class="s2 gr"></a><b class="e2"></b><x></x><a></a><b></b><x></x><a></a><b></b></div>
</div>
<br>
<div class="grid rtl">
<y></y><y></y>
<div class="subgrid c3 pl"><x></x><a></a><b></b><x></x><a></a><b></b><x class="z"></x><a></a><b></b></div>
</div>
<br>
<div class="grid rtl">
<y></y><y></y>
<div class="subgrid c3 plr"><x class="z"></x><a class="s2 gr"></a><b class="e2"></b><x></x><a></a><b></b><x class="z"></x><a></a><b></b></div>
</div>
</div>
<div class=f>
<div class="grid">
<y></y><y></y>
<div class="subgrid c2 pr"><x></x><a></a><b></b><x class="z"></x><a></a><b></b></div>
</div>
<br>
<div class="grid">
<y></y><y></y>
<div class="subgrid c2 pl"><x class="z"></x><a class="s2 gl"></a><b class="e2"></b><x></x><a></a><b></b></div>
</div>
<br>
<div class="grid">
<y></y><y></y>
<div class="subgrid c2 plr"><a class="s2 gl"></a><b class="e2"></b><a></a><b></b></div>
</div>
<br>
<div class="grid rtl">
<y></y><y></y>
<div class="subgrid c2 pr"><x class="z"></x><a class="s2 gr"></a><b class="e2"></b><x></x><a></a><b></b></div>
</div>
<br>
<div class="grid rtl">
<y></y><y></y>
<div class="subgrid c2 pl"><x></x><a></a><b></b><x class="z"></x><a></a><b></b></div>
</div>
<br>
<div class="grid rtl">
<y></y><y></y>
<div class="subgrid c2 plr"><a class="s2 gr"></a><b class="e2"></b><a></a><b></b></div>
</div>
</div>
<div class=f>
<div class="grid">
<y></y><y></y>
<div class="subgrid c1 pr"><a></a><b></b></div>
</div>
<br>
<div class="grid">
<y></y><y></y>
<div class="subgrid c1 pl"><a class="s2"></a><b class="e2"></b></div>
</div>
<br>
<div class="grid">
<y></y><y></y>
<div class="subgrid c1 plr"><a class="s2"></a><b class="e2"></b></div>
</div>
<br>
<div class="grid rtl">
<y></y><y></y>
<div class="subgrid c1 pr"><a class="s2"></a><b class="e2"></b></div>
</div>
<br>
<div class="grid rtl">
<y></y><y></y>
<div class="subgrid c1 pl"><a></a><b></b></div>
</div>
<br>
<div class="grid rtl">
<y></y><y></y>
<div class="subgrid c1 plr"><a class="s2"></a><b class="e2"></b></div>
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,222 @@
<!DOCTYPE HTML>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html><head>
<meta charset="utf-8">
<title>CSS Grid Test: subgrid margin/border/padding that overflow the edge track</title>
<link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com">
<link rel="help" href="https://drafts.csswg.org/css-grid-2">
<link rel="match" href="subgrid-mbp-overflow-001-ref.html">
<style>
html,body {
color:black; background-color:white; font:16px/1 monospace; margin:0; padding:0;
}
.grid {
display: inline-grid;
grid: auto / 7px 30px 10px 20px 5px;
justify-content: space-around;
align-content: start;
border: 3px solid;
width: 80px;
}
.rtl { direction: rtl; }
.subgrid {
display: grid;
grid: auto / subgrid;
min-width: 0;
min-height: 30px;
background: pink;
border:1px solid;
margin: 0 4px 0 3px;
position: relative;
}
.c1 { grid-column: 2 / span 1; }
.c2 { grid-column: 2 / span 2; }
.c3 { grid-column: 2 / span 3; }
.pr { padding-right: 30px; }
.pl { padding-left: 30px; }
.plr { padding: 0 50px 0 80px; }
y {
background: blue;
height: 10px;
}
y:nth-of-type(1) { grid-column: 2; }
y:nth-of-type(2) { grid-column: 4; }
x { background: silver; }
x:nth-of-type(2) { background: purple; }
x:nth-of-type(3) { background: magenta; }
a {
position: absolute;
grid-column-start: 1;
inset: 0;
top: 3px;
border-top: 2px solid grey;
}
a:nth-of-type(2) {
grid-column-start: 2;
top: 6px;
}
a:nth-of-type(3) {
grid-column-start: 3;
top: 9px;
}
b {
position: absolute;
grid-column-end: 1;
inset: 0;
top: 12px;
border-top: 2px solid grey;
}
b:nth-of-type(2) {
grid-column-end: 2;
top: 15px;
}
b:nth-of-type(3) {
grid-column-end: 3;
top: 18px;
}
.f { float:left; margin-left:80px; }
</style>
</head>
<body>
<div class=f>
<div class="grid">
<y></y><y></y>
<div class="subgrid c3 pr"><x></x><a></a><b></b><x></x><a></a><b></b><x></x><a></a><b></b></div>
</div>
<br>
<div class="grid">
<y></y><y></y>
<div class="subgrid c3 pl"><x></x><a></a><b></b><x></x><a></a><b></b><x></x><a></a><b></b></div>
</div>
<br>
<div class="grid">
<y></y><y></y>
<div class="subgrid c3 plr"><x></x><a></a><b></b><x></x><a></a><b></b><x></x><a></a><b></b></div>
</div>
<br>
<div class="grid rtl">
<y></y><y></y>
<div class="subgrid c3 pr"><x></x><a></a><b></b><x></x><a></a><b></b><x></x><a></a><b></b></div>
</div>
<br>
<div class="grid rtl">
<y></y><y></y>
<div class="subgrid c3 pl"><x></x><a></a><b></b><x></x><a></a><b></b><x></x><a></a><b></b></div>
</div>
<br>
<div class="grid rtl">
<y></y><y></y>
<div class="subgrid c3 plr"><x></x><a></a><b></b><x></x><a></a><b></b><x></x><a></a><b></b></div>
</div>
</div>
<div class=f>
<div class="grid">
<y></y><y></y>
<div class="subgrid c2 pr"><x></x><a></a><b></b><x></x><a></a><b></b></div>
</div>
<br>
<div class="grid">
<y></y><y></y>
<div class="subgrid c2 pl"><x></x><a></a><b></b><x></x><a></a><b></b></div>
</div>
<br>
<div class="grid">
<y></y><y></y>
<div class="subgrid c2 plr"><x></x><a></a><b></b><x></x><a></a><b></b></div>
</div>
<br>
<div class="grid rtl">
<y></y><y></y>
<div class="subgrid c2 pr"><x></x><a></a><b></b><x></x><a></a><b></b></div>
</div>
<br>
<div class="grid rtl">
<y></y><y></y>
<div class="subgrid c2 pl"><x></x><a></a><b></b><x></x><a></a><b></b></div>
</div>
<br>
<div class="grid rtl">
<y></y><y></y>
<div class="subgrid c2 plr"><x></x><a></a><b></b><x></x><a></a><b></b></div>
</div>
</div>
<div class=f>
<div class="grid">
<y></y><y></y>
<div class="subgrid c1 pr"><x></x><a></a><b></b></div>
</div>
<br>
<div class="grid">
<y></y><y></y>
<div class="subgrid c1 pl"><x></x><a></a><b></b></div>
</div>
<br>
<div class="grid">
<y></y><y></y>
<div class="subgrid c1 plr"><x></x><a></a><b></b></div>
</div>
<br>
<div class="grid rtl">
<y></y><y></y>
<div class="subgrid c1 pr"><x></x><a></a><b></b></div>
</div>
<br>
<div class="grid rtl">
<y></y><y></y>
<div class="subgrid c1 pl"><x></x><a></a><b></b></div>
</div>
<br>
<div class="grid rtl">
<y></y><y></y>
<div class="subgrid c1 plr"><x></x><a></a><b></b></div>
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,224 @@
<!DOCTYPE HTML>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html><head>
<meta charset="utf-8">
<title>CSS Grid Test: orthogonal writing-mode subgrid margin/border/padding that overflow the edge track</title>
<link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com">
<link rel="help" href="https://drafts.csswg.org/css-grid-2">
<link rel="match" href="subgrid-mbp-overflow-001-ref.html">
<style>
html,body {
color:black; background-color:white; font:16px/1 monospace; margin:0; padding:0;
}
.grid {
display: inline-grid;
grid: auto / 7px 30px 10px 20px 5px;
justify-content: space-around;
align-content: start;
border: 3px solid;
width: 80px;
}
.rtl { direction: rtl; }
.subgrid {
display: grid;
grid: subgrid / auto;
min-width: 0;
min-height: 30px;
background: pink;
border:1px solid;
margin: 0 4px 0 3px;
position: relative;
writing-mode: vertical-lr;
}
.rtl > .subgrid { writing-mode: vertical-rl; }
.c1 { grid-column: 2 / span 1; }
.c2 { grid-column: 2 / span 2; }
.c3 { grid-column: 2 / span 3; }
.pr { padding-right: 30px; }
.pl { padding-left: 30px; }
.plr { padding: 0 50px 0 80px; }
y {
background: blue;
height: 10px;
}
y:nth-of-type(1) { grid-column: 2; }
y:nth-of-type(2) { grid-column: 4; }
x { background: silver; }
x:nth-of-type(2) { background: purple; }
x:nth-of-type(3) { background: magenta; }
a {
position: absolute;
grid-row-start: 1;
inset: 0;
top: 3px;
border-top: 2px solid grey;
}
a:nth-of-type(2) {
grid-row-start: 2;
top: 6px;
}
a:nth-of-type(3) {
grid-row-start: 3;
top: 9px;
}
b {
position: absolute;
grid-row-end: 1;
inset: 0;
top: 12px;
border-top: 2px solid grey;
}
b:nth-of-type(2) {
grid-row-end: 2;
top: 15px;
}
b:nth-of-type(3) {
grid-row-end: 3;
top: 18px;
}
.f { float:left; margin-left:80px; }
</style>
</head>
<body>
<div class=f>
<div class="grid">
<y></y><y></y>
<div class="subgrid c3 pr"><x></x><a></a><b></b><x></x><a></a><b></b><x></x><a></a><b></b></div>
</div>
<br>
<div class="grid">
<y></y><y></y>
<div class="subgrid c3 pl"><x></x><a></a><b></b><x></x><a></a><b></b><x></x><a></a><b></b></div>
</div>
<br>
<div class="grid">
<y></y><y></y>
<div class="subgrid c3 plr"><x></x><a></a><b></b><x></x><a></a><b></b><x></x><a></a><b></b></div>
</div>
<br>
<div class="grid rtl">
<y></y><y></y>
<div class="subgrid c3 pr"><x></x><a></a><b></b><x></x><a></a><b></b><x></x><a></a><b></b></div>
</div>
<br>
<div class="grid rtl">
<y></y><y></y>
<div class="subgrid c3 pl"><x></x><a></a><b></b><x></x><a></a><b></b><x></x><a></a><b></b></div>
</div>
<br>
<div class="grid rtl">
<y></y><y></y>
<div class="subgrid c3 plr"><x></x><a></a><b></b><x></x><a></a><b></b><x></x><a></a><b></b></div>
</div>
</div>
<div class=f>
<div class="grid">
<y></y><y></y>
<div class="subgrid c2 pr"><x></x><a></a><b></b><x></x><a></a><b></b></div>
</div>
<br>
<div class="grid">
<y></y><y></y>
<div class="subgrid c2 pl"><x></x><a></a><b></b><x></x><a></a><b></b></div>
</div>
<br>
<div class="grid">
<y></y><y></y>
<div class="subgrid c2 plr"><x></x><a></a><b></b><x></x><a></a><b></b></div>
</div>
<br>
<div class="grid rtl">
<y></y><y></y>
<div class="subgrid c2 pr"><x></x><a></a><b></b><x></x><a></a><b></b></div>
</div>
<br>
<div class="grid rtl">
<y></y><y></y>
<div class="subgrid c2 pl"><x></x><a></a><b></b><x></x><a></a><b></b></div>
</div>
<br>
<div class="grid rtl">
<y></y><y></y>
<div class="subgrid c2 plr"><x></x><a></a><b></b><x></x><a></a><b></b></div>
</div>
</div>
<div class=f>
<div class="grid">
<y></y><y></y>
<div class="subgrid c1 pr"><x></x><a></a><b></b></div>
</div>
<br>
<div class="grid">
<y></y><y></y>
<div class="subgrid c1 pl"><x></x><a></a><b></b></div>
</div>
<br>
<div class="grid">
<y></y><y></y>
<div class="subgrid c1 plr"><x></x><a></a><b></b></div>
</div>
<br>
<div class="grid rtl">
<y></y><y></y>
<div class="subgrid c1 pr"><x></x><a></a><b></b></div>
</div>
<br>
<div class="grid rtl">
<y></y><y></y>
<div class="subgrid c1 pl"><x></x><a></a><b></b></div>
</div>
<br>
<div class="grid rtl">
<y></y><y></y>
<div class="subgrid c1 plr"><x></x><a></a><b></b></div>
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,173 @@
<!DOCTYPE HTML>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html><head>
<meta charset="utf-8">
<title>Reference: subgrid margin/border/padding that overflow the edge track</title>
<link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com">
<style>
html,body {
color:black; background-color:white; font:16px/1 monospace; margin:0; padding:0;
}
.grid {
display: inline-grid;
grid: auto / 7px 30px 10px 20px 5px;
justify-content: space-around;
align-content: start;
border: 3px solid;
width: 80px;
}
.rtl { direction: rtl; }
.ltr { direction: ltr; }
.subgrid {
display: grid;
justify-content: space-between;
justify-self: self-start;
min-width: 0;
min-height: 30px;
background: pink;
border:1px solid;
margin: 0 4px 0 3px;
position: relative;
}
.c1 { grid-column: 4 / span 1; }
.c3 { grid-column: 2 / span 3; }
y {
background: blue;
height: 10px;
}
y:nth-of-type(1) { grid-column: 2; }
y:nth-of-type(2) { grid-column: 4; }
x { background: silver; border-inline-start: 2px solid lime; }
x:nth-of-type(2) { background: purple; }
x:nth-of-type(3) { background: magenta; }
a {
position: absolute;
grid-column-start: 1;
inset: 0;
top: 3px;
border-top: 2px solid grey;
}
a:nth-of-type(2) {
grid-column-start: 2;
top: 6px;
}
a:nth-of-type(3) {
grid-column-start: 3;
top: 9px;
}
b {
position: absolute;
grid-column-end: 1;
inset: 0;
top: 12px;
border-top: 2px solid grey;
}
b:nth-of-type(2) {
grid-column-end: 2;
top: 15px;
}
b:nth-of-type(3) {
grid-column-end: 3;
top: 18px;
}
.f { float:left; margin-left:10px; }
.c1 { width: 30px; }
.ltr.c1.pl > x, .rtl.c1.pr > x {
padding-inline-start: 15px;
border-inline: none;
border-inline-end: 2px solid lime;
background: pink;
}
.ltr.c1.pl > x { padding-inline-start: 16px; }
.rtl.c1.pr > a { width: 15px; margin-inline-start: 15px; }
.ltr.c1.pl > a { width: 14px; margin-inline-start: 16px;}
.rtl.c1.pr > b { width: 15px; }
.ltr.c1.pl > b { width: 16px; }
.c3 { width: 55px; grid: auto / 15px 10px 26px; }
.rtl.c3.pl { padding-inline-end: 4px; }
.ltr.c3.pr { padding-inline-end: 5px; }
.ltr.c3 { grid: auto / 16px 10px 25px; }
.rtl.c3.pr > a:nth-of-type(1) { width: 40px; right: 15px; }
.ltr.c3.pl > a:nth-of-type(1) { width: 39px; left: 16px; }
.rtl.c3.pr > b:nth-of-type(1),
.rtl.c3.pr > b:nth-of-type(2){ width: 15px; }
.ltr.c3.pl > b:nth-of-type(1),
.ltr.c3.pl > b:nth-of-type(2){ width: 16px; }
x.zero { background: pink; }
</style>
</head>
<body>
<div class=f>
<div class="grid ltr">
<y></y><y></y>
<div class="subgrid rtl c3 pr"><x class="zero" style="margin-right:15px"></x><a></a><b></b><x></x><a></a><b></b><x></x><a></a><b></b></div>
</div>
<br>
<div class="grid ltr">
<y></y><y></y>
<div class="subgrid rtl c3 pl"><x></x><a></a><b></b><x></x><a></a><b></b><x class="zero"></x><a></a><b></b></div>
</div>
<br>
<div class="grid rtl">
<y></y><y></y>
<div class="subgrid ltr c3 pr"><x></x><a></a><b></b><x></x><a></a><b></b><x class="zero"></x><a></a><b></b></div>
</div>
<br>
<div class="grid rtl">
<y></y><y></y>
<div class="subgrid ltr c3 pl"><x class="zero" style="margin-left:16px"></x><a></a><b></b><x></x><a></a><b></b><x></x><a></a><b></b></div>
</div>
</div>
<div class=f>
<div class="grid ltr">
<y></y><y></y>
<div class="subgrid rtl c1 pr"><x></x><a></a><b></b></div>
</div>
<br>
<div class="grid ltr">
<y></y><y></y>
<div class="subgrid rtl c1 pl"><x></x><a></a><b></b></div>
</div>
<br>
<div class="grid rtl">
<y></y><y></y>
<div class="subgrid ltr c1 pr"><x></x><a></a><b></b></div>
</div>
<br>
<div class="grid rtl">
<y></y><y></y>
<div class="subgrid ltr c1 pl"><x></x><a></a><b></b></div>
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,151 @@
<!DOCTYPE HTML>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html><head>
<meta charset="utf-8">
<title>CSS Grid Test: subgrid margin/border/padding that overflow the edge track</title>
<link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com">
<link rel="help" href="https://drafts.csswg.org/css-grid-2">
<link rel="match" href="subgrid-mbp-overflow-003-ref.html">
<style>
html,body {
color:black; background-color:white; font:16px/1 monospace; margin:0; padding:0;
}
.grid {
display: inline-grid;
grid: auto / 7px 30px 10px 20px 5px;
justify-content: space-around;
align-content: start;
border: 3px solid;
width: 80px;
}
.rtl { direction: rtl; }
.ltr { direction: ltr; }
.subgrid {
display: grid;
grid: auto / subgrid;
justify-self: self-start;
min-width: 0;
min-height: 30px;
background: pink;
border:1px solid;
margin: 0 4px 0 3px;
position: relative;
}
.c1 { grid-column: 4 / span 1; }
.c3 { grid-column: 2 / span 3; }
.pr { padding-right: 30px; }
.pl { padding-left: 30px; }
y {
background: blue;
height: 10px;
}
y:nth-of-type(1) { grid-column: 2; }
y:nth-of-type(2) { grid-column: 4; }
x { background: silver; border-inline-start: 2px solid lime; }
x:nth-of-type(2) { background: purple; }
x:nth-of-type(3) { background: magenta; }
a {
position: absolute;
grid-column-start: 1;
inset: 0;
top: 3px;
border-top: 2px solid grey;
}
a:nth-of-type(2) {
grid-column-start: 2;
top: 6px;
}
a:nth-of-type(3) {
grid-column-start: 3;
top: 9px;
}
b {
position: absolute;
grid-column-end: 1;
inset: 0;
top: 12px;
border-top: 2px solid grey;
}
b:nth-of-type(2) {
grid-column-end: 2;
top: 15px;
}
b:nth-of-type(3) {
grid-column-end: 3;
top: 18px;
}
.f { float:left; margin-left:10px; }
</style>
</head>
<body>
<div class=f>
<div class="grid ltr">
<y></y><y></y>
<div class="subgrid rtl c3 pr"><x></x><a></a><b></b><x></x><a></a><b></b><x></x><a></a><b></b></div>
</div>
<br>
<div class="grid ltr">
<y></y><y></y>
<div class="subgrid rtl c3 pl"><x></x><a></a><b></b><x></x><a></a><b></b><x></x><a></a><b></b></div>
</div>
<br>
<div class="grid rtl">
<y></y><y></y>
<div class="subgrid ltr c3 pr"><x></x><a></a><b></b><x></x><a></a><b></b><x></x><a></a><b></b></div>
</div>
<br>
<div class="grid rtl">
<y></y><y></y>
<div class="subgrid ltr c3 pl"><x></x><a></a><b></b><x></x><a></a><b></b><x></x><a></a><b></b></div>
</div>
</div>
<div class=f>
<div class="grid ltr">
<y></y><y></y>
<div class="subgrid rtl c1 pr"><x></x><a></a><b></b></div>
</div>
<br>
<div class="grid ltr">
<y></y><y></y>
<div class="subgrid rtl c1 pl"><x></x><a></a><b></b></div>
</div>
<br>
<div class="grid rtl">
<y></y><y></y>
<div class="subgrid ltr c1 pr"><x></x><a></a><b></b></div>
</div>
<br>
<div class="grid rtl">
<y></y><y></y>
<div class="subgrid ltr c1 pl"><x></x><a></a><b></b></div>
</div>
</div>
</body>
</html>

View file

@ -4,7 +4,7 @@
<title>CSS Transforms API Test: transform preserve-3d</title> <title>CSS Transforms API Test: transform preserve-3d</title>
<link rel="author" title="loveky" href="mailto:ylzcylx@gmail.com"> <link rel="author" title="loveky" href="mailto:ylzcylx@gmail.com">
<link rel="help" href="http://www.w3.org/TR/css-transforms-1/#transform-property"> <link rel="help" href="http://www.w3.org/TR/css-transforms-1/#transform-property">
<link rel="match" href="reference/transofrmed-preserve-3d-1-ref.html"> <link rel="match" href="reference/transformed-preserve-3d-1-ref.html">
<meta name="assert" content="The transformed div should establishe a 3D rendering context"> <meta name="assert" content="The transformed div should establishe a 3D rendering context">
<style> <style>
div { div {

View file

@ -4,7 +4,7 @@
<title>CSS Transforms API Test: transform rotateX</title> <title>CSS Transforms API Test: transform rotateX</title>
<link rel="author" title="loveky" href="mailto:ylzcylx@gmail.com"> <link rel="author" title="loveky" href="mailto:ylzcylx@gmail.com">
<link rel="help" href="http://www.w3.org/TR/css-transforms-1/#transform-property"> <link rel="help" href="http://www.w3.org/TR/css-transforms-1/#transform-property">
<link rel="match" href="reference/transofrmed-rotateX-3-ref.html"> <link rel="match" href="reference/transformed-rotateX-3-ref.html">
<meta name="assert" content="The transformed div should rotateX by 180 degrees"> <meta name="assert" content="The transformed div should rotateX by 180 degrees">
<style> <style>
div { div {

View file

@ -4,7 +4,7 @@
<title>CSS Transforms API Test: transform rotateY</title> <title>CSS Transforms API Test: transform rotateY</title>
<link rel="author" title="loveky" href="mailto:ylzcylx@gmail.com"> <link rel="author" title="loveky" href="mailto:ylzcylx@gmail.com">
<link rel="help" href="http://www.w3.org/TR/css-transforms-1/#transform-property"> <link rel="help" href="http://www.w3.org/TR/css-transforms-1/#transform-property">
<link rel="match" href="reference/transofrmed-rotateY-1-ref.html"> <link rel="match" href="reference/transformed-rotateY-1-ref.html">
<meta name="assert" content="The transformed div should rotate 90 degrees"> <meta name="assert" content="The transformed div should rotate 90 degrees">
<style> <style>
div { div {

View file

@ -86,6 +86,12 @@
grid-row: 2; grid-row: 2;
} }
.thirdRowFirstColumn {
background-color: green;
grid-column: 1;
grid-row: 3;
}
.thirdRowSecondColumn { .thirdRowSecondColumn {
background-color: red; background-color: red;
grid-column: 2; grid-column: 2;

View file

@ -0,0 +1,64 @@
<!DOCTYPE html>
<html>
<head>
<title>Test advertised required document policy</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script> </head>
<body>
<h1>Test advertised required document policy</h1>
<script>
// The top-level document has a document policy, as well as a required document
// policy (for subframes) which is stricter. This test should load (the required
// policy should not block this page,) but the requirements should be applied to
// nested content.
callbacks = {};
window.addEventListener('message', ev => {
var id = ev.data.id;
if (id && callbacks[id]) {
callbacks[id](ev.data.requiredPolicy || null);
}
});
async_test(t => {
var iframe = document.createElement('iframe');
iframe.src = "/document-policy/echo-policy.py?id=1";
callbacks["1"] = t.step_func_done(result => {
assert_equals(result, "unoptimized-lossless-images;bpp=1.0");
});
document.body.appendChild(iframe);
}, "Child frame with no explicit policy should have the same required policy as its parent.");
async_test(t => {
var iframe = document.createElement('iframe');
iframe.src = "/document-policy/echo-policy.py?id=2";
iframe.policy = "unoptimized-lossless-images;bpp=4";
callbacks["2"] = t.step_func_done(result => {
assert_equals(result, "unoptimized-lossless-images;bpp=1.0");
});
document.body.appendChild(iframe);
}, "Child frame with a less strict required policy should have the stricter value from the parent's policy applied.");
async_test(t => {
var iframe = document.createElement('iframe');
iframe.src = "/document-policy/echo-policy.py?id=3";
iframe.policy = "unoptimized-lossless-images;bpp=0.9";
callbacks["3"] = t.step_func_done(result => {
assert_equals(result, "unoptimized-lossless-images;bpp=0.9");
});
document.body.appendChild(iframe);
}, "Child frame may have a stricter policy than the parent.");
async_test(t => {
var iframe = document.createElement('iframe');
iframe.src = "/document-policy/echo-policy.py?id=4";
iframe.policy = "no-font-display-late-swap";
callbacks["4"] = t.step_func_done(result => {
assert_equals(result, "no-font-display-late-swap, unoptimized-lossless-images;bpp=1.0");
});
document.body.appendChild(iframe);
}, "Any unrelated policy directives should combine with the parent's required policy.");
</script>
</body>
</html>

View file

@ -0,0 +1,2 @@
Document-Policy: unoptimized-lossless-images;bpp=1.1
Require-Document-Policy: unoptimized-lossless-images;bpp=1.0

View file

@ -12,9 +12,7 @@
let firstInputSeen = false; let firstInputSeen = false;
let eventSeen = false; let eventSeen = false;
async_test(t => { async_test(t => {
if (!window.PerformanceEventTiming) assert_precondition(window.PerformanceEventTiming, 'Event Timing is not supported.');
assert_unreached("PerformanceEventTiming is not supported");
const validateEntry = t.step_func(entry => { const validateEntry = t.step_func(entry => {
if (entry.entryType === 'first-input') if (entry.entryType === 'first-input')
firstInputSeen = true; firstInputSeen = true;

View file

@ -21,9 +21,7 @@
let timeAfterSecondClick; let timeAfterSecondClick;
let observedEntries = []; let observedEntries = [];
async_test(function(t) { async_test(function(t) {
if (!window.PerformanceEventTiming) assert_precondition(window.PerformanceEventTiming, 'Event Timing is not supported.');
assert_unreached("PerformanceEventTiming is not supported");
new PerformanceObserver(t.step_func(entryList => { new PerformanceObserver(t.step_func(entryList => {
observedEntries = observedEntries.concat(entryList.getEntries().filter( observedEntries = observedEntries.concat(entryList.getEntries().filter(
entry => entry.name === 'mousedown')); entry => entry.name === 'mousedown'));

View file

@ -47,10 +47,8 @@
clickTimeMin."); clickTimeMin.");
} }
async_test(async function(t) { promise_test(async t => {
assert_precondition(window.PerformanceEventTiming, assert_precondition(window.PerformanceEventTiming, "Event Timing is not supported");
"PerformanceEventTiming is not supported");
clickTimeMin = performance.now(); clickTimeMin = performance.now();
let observedEntries = false; let observedEntries = false;
const observerPromise = new Promise(resolve => { const observerPromise = new Promise(resolve => {
@ -84,7 +82,6 @@
t.step(() => { t.step(() => {
validateChildFrameEntries(childFrameData); validateChildFrameEntries(childFrameData);
}); });
t.done();
}, "Event Timing: entries should only be observable by its own frame."); }, "Event Timing: entries should only be observable by its own frame.");
</script> </script>

View file

@ -20,9 +20,7 @@
PerformanceObserver should observe one and only one entry. PerformanceObserver should observe one and only one entry.
*/ */
async_test(function(t) { async_test(function(t) {
if (!window.PerformanceEventTiming) assert_precondition(window.PerformanceEventTiming, 'Event Timing is not supported.');
assert_unreached("PerformanceEventTiming is not supported");
let hasObservedFirstInput = false; let hasObservedFirstInput = false;
new PerformanceObserver(t.step_func((entryList) => { new PerformanceObserver(t.step_func((entryList) => {
assert_false(hasObservedFirstInput); assert_false(hasObservedFirstInput);

View file

@ -18,9 +18,7 @@
delayCalled = true; delayCalled = true;
} }
async_test(function(t) { async_test(function(t) {
if (!window.PerformanceEventTiming) assert_precondition(window.PerformanceEventTiming, 'Event Timing is not supported.');
assert_unreached("PerformanceEventTiming is not supported");
const observer = new PerformanceObserver(t.step_func_done((entryList) => { const observer = new PerformanceObserver(t.step_func_done((entryList) => {
const entries = entryList.getEntries().filter(e => e.name === 'mousedown'); const entries = entryList.getEntries().filter(e => e.name === 'mousedown');
// There must only be one click entry: from the clickAndBlockMain() call. // There must only be one click entry: from the clickAndBlockMain() call.

View file

@ -30,9 +30,7 @@
Validate entries Validate entries
*/ */
async_test(function(t) { async_test(function(t) {
if (!window.PerformanceEventTiming) { assert_precondition(window.PerformanceEventTiming, 'Event Timing is not supported.');
assert_unreached('PerformanceEventTiming is not implemented');
}
new PerformanceObserver(t.step_func_done(() => { new PerformanceObserver(t.step_func_done(() => {
validateEntries(); validateEntries();
t.done(); t.done();

View file

@ -12,9 +12,7 @@
<script> <script>
async_test(function(t) { async_test(function(t) {
if (!window.PerformanceEventTiming) assert_precondition(window.PerformanceEventTiming, 'Event Timing is not supported.');
assert_unreached("PerformanceEventTiming is not supported");
function testEntries() { function testEntries() {
// First callback is not ensured to have the entry. // First callback is not ensured to have the entry.
if (performance.getEntriesByType('first-input').length === 0) { if (performance.getEntriesByType('first-input').length === 0) {

View file

@ -1,6 +1,7 @@
test(() => { test(() => {
if (typeof PerformanceObserver.supportedEntryTypes === "undefined") assert_precondition(window.PerformanceEventTiming, 'Event Timing is not supported.');
assert_unreached("supportedEntryTypes is not supported."); assert_precondition(typeof PerformanceObserver.supportedEntryTypes !== "undefined",
'supportedEntryTypes is not supported');
const types = PerformanceObserver.supportedEntryTypes; const types = PerformanceObserver.supportedEntryTypes;
assert_true(types.includes("first-input"), assert_true(types.includes("first-input"),
"There should be 'first-input' in PerformanceObserver.supportedEntryTypes"); "There should be 'first-input' in PerformanceObserver.supportedEntryTypes");

View file

@ -35,9 +35,7 @@
} }
async_test(function(t) { async_test(function(t) {
if (!window.PerformanceEventTiming) assert_precondition(window.PerformanceEventTiming, 'Event Timing is not supported.');
assert_unreached("PerformanceEventTiming is not supported");
new PerformanceObserver(t.step_func_done(entryList => { new PerformanceObserver(t.step_func_done(entryList => {
const observerCallbackTime = performance.now(); const observerCallbackTime = performance.now();
const entries = entryList.getEntries().filter( const entries = entryList.getEntries().filter(

View file

@ -10,9 +10,7 @@
<button id='button'>Generate a 'click' event</button> <button id='button'>Generate a 'click' event</button>
<script> <script>
async_test(function (t) { async_test(function (t) {
if (!window.PerformanceEventTiming) { assert_precondition(window.PerformanceEventTiming, 'Event Timing is not supported.');
assert_unreached("PerformanceEventTiming is not implemented");
}
const observer = new PerformanceObserver( const observer = new PerformanceObserver(
t.step_func_done(function(entryList) { t.step_func_done(function(entryList) {
const entry = entryList.getEntries()[0]; const entry = entryList.getEntries()[0];

View file

@ -31,7 +31,7 @@ var testElements = [
types: [], types: [],
testData: [ testData: [
{conditions: {message: "My custom error"}, expected: true, name: "[target] The validity.customError must be true if the custom validity error message is not empty"}, {conditions: {message: "My custom error"}, expected: true, name: "[target] The validity.customError must be true if the custom validity error message is not empty"},
{conditions: {message: ""}, expected: false, name: "[target] The validity.customError must be false i the custom validity error message is empty"} {conditions: {message: ""}, expected: false, name: "[target] The validity.customError must be false if the custom validity error message is empty"}
] ]
}, },
{ {

View file

@ -1,77 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>summary element: clicking on anchor containing inline element</title>
<link rel="author" title="Yu Han" href="mailto:yuzhehan@chromium.org">
<link rel="help" href="https://html.spec.whatwg.org/C/#the-summary-element">
<link rel="help" href="https://html.spec.whatwg.org/multipage/text-level-semantics.html#the-a-element">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<details id="details_i">
<summary>Anchor text is wrapped with &lt;i&gt; tag <a href="#with_i_tag"><i id="with_i">permalink</i></a></summary>
<p>asdf</p>
</details>
<details id="details_span">
<summary>This one uses &lt;span&gt;. <a href="#with_span_tag"><span id="with_span">permalink</span></a></summary>
<p>asdf</p>
</details>
<details id="details_svg">
<summary>
<svg style="width: 100px;" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<a href="#inside_svg_w_circle">
<circle id="svg_circle" cx="50" cy="40" r="35"/>
</a>
<a href="#inside_svg_w_text">
<text id="svg_text" x="50" y="90" text-anchor="middle">
&lt;circle&gt;
</text>
</a>
</svg>
</summary>
<p>asdf</p>
</details>
<script>
function testClickingOnInlineElement(detailsId, targetId, expected, testName) {
const details = document.getElementById(detailsId);
const target = document.getElementById(targetId);
const test = async_test(testName);
const promise = new Promise((resolve, reject) => {
window.onhashchange = test.step_func_done(() => {
assert_false(details.open);
assert_true(location.hash === expected);
resolve();
});
});
if (target.click) {
target.click();
}
else {
// svg element don't have click method
target.dispatchEvent(new MouseEvent('click', {
view: window,
bubbles: true,
cancelable: true
}));
}
return promise;
};
async function testAll() {
try {
await testClickingOnInlineElement("details_i", "with_i", "#with_i_tag", "Expected <a> containing <i> to navigate");
await testClickingOnInlineElement("details_span", "with_span", "#with_span_tag", "Expected <a> containing <span> to navigate");
await testClickingOnInlineElement("details_svg", "svg_circle", "#inside_svg_w_circle", "Expected <a>, inside svg, containing <circle> to navigate");
await testClickingOnInlineElement("details_svg", "svg_text", "#inside_svg_w_text", "Expected <a>, inside svg, containing <text> to navigate");
} catch (exception) {
assert_unreached("should NOT-THROW exception");
}
};
var allTests = async_test("Clicking on anchor with embedded inline element should navigate instead of opening details");
testAll().then(()=>{ allTests.done(); });
</script>

View file

@ -229,7 +229,8 @@ interface RTCPeerConnectionIceErrorEvent : Event {
}; };
dictionary RTCPeerConnectionIceErrorEventInit : EventInit { dictionary RTCPeerConnectionIceErrorEventInit : EventInit {
DOMString hostCandidate; DOMString? address;
unsigned short? port;
DOMString url; DOMString url;
required unsigned short errorCode; required unsigned short errorCode;
USVString statusText; USVString statusText;

View file

@ -10,13 +10,14 @@
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="resources/util.js"></script> <script src="resources/util.js"></script>
<script> <script>
async_test(async function(t) { promise_test(async t => {
assert_precondition(window.LayoutShift, 'LayoutShift entries are not supported'); assert_precondition(window.LayoutShift, 'Layout Instability is not supported.');
// Wait for the initial render to complete. // Wait for the initial render to complete.
await waitForAnimationFrames(2); await waitForAnimationFrames(2);
const startTime = performance.now(); const startTime = performance.now();
new PerformanceObserver(t.step_func_done(list => { return new Promise(resolve => {
new PerformanceObserver(t.step_func(list => {
const endTime = performance.now(); const endTime = performance.now();
assert_equals(list.getEntries().length, 1); assert_equals(list.getEntries().length, 1);
const entry = list.getEntries()[0]; const entry = list.getEntries()[0];
@ -33,9 +34,11 @@ async_test(async function(t) {
assert_equals(performance.getEntriesByType('layout-shift').length, 0, 'getEntriesByType should have no layout-shift entries'); assert_equals(performance.getEntriesByType('layout-shift').length, 0, 'getEntriesByType should have no layout-shift entries');
assert_equals(performance.getEntriesByName('', 'layout-shift').length, 0, 'getEntriesByName should have no layout-shift entries'); assert_equals(performance.getEntriesByName('', 'layout-shift').length, 0, 'getEntriesByName should have no layout-shift entries');
assert_equals(performance.getEntries().filter(e => e.entryType === 'layout-shift').length, 0, 'getEntries should have no layout-shift entries'); assert_equals(performance.getEntries().filter(e => e.entryType === 'layout-shift').length, 0, 'getEntries should have no layout-shift entries');
resolve();
})).observe({type: 'layout-shift'}); })).observe({type: 'layout-shift'});
// Modify the position of the div. // Modify the position of the div.
document.getElementById('myDiv').style = "top: 60px"; document.getElementById('myDiv').style = "top: 60px";
});
}, 'Layout shift before onload is not buffered into the performance timeline.'); }, 'Layout shift before onload is not buffered into the performance timeline.');
</script> </script>

View file

@ -10,18 +10,19 @@
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="resources/util.js"></script> <script src="resources/util.js"></script>
<script> <script>
async_test(async function(t) { promise_test(async t => {
assert_precondition(window.LayoutShift, 'LayoutShift entries are not supported'); assert_precondition(window.LayoutShift, 'Layout Instability is not supported.');
// Wait for the initial render to complete. // Wait for the initial render to complete.
await waitForAnimationFrames(2); await waitForAnimationFrames(2);
const startTime = performance.now(); const startTime = performance.now();
return new Promise(resolve => {
// First observer creates second in callback to ensure the entry has been dispatched by the time // First observer creates second in callback to ensure the entry has been dispatched by the time
// the second observer begins observing. // the second observer begins observing.
new PerformanceObserver(() => { new PerformanceObserver(() => {
const endTime = performance.now(); const endTime = performance.now();
// Second observer requires 'buffered: true' to see entries. // Second observer requires 'buffered: true' to see entries.
new PerformanceObserver(t.step_func_done(list => { new PerformanceObserver(t.step_func(list => {
assert_equals(list.getEntries().length, 1); assert_equals(list.getEntries().length, 1);
const entry = list.getEntries()[0]; const entry = list.getEntries()[0];
assert_equals(entry.entryType, "layout-shift"); assert_equals(entry.entryType, "layout-shift");
@ -29,10 +30,12 @@ async_test(async function(t) {
assert_less_than_equal(entry.startTime, endTime); assert_less_than_equal(entry.startTime, endTime);
assert_equals(entry.duration, 0.0); assert_equals(entry.duration, 0.0);
assert_equals(entry.value, computeExpectedScore(300 * (100 + 60), 60)); assert_equals(entry.value, computeExpectedScore(300 * (100 + 60), 60));
resolve();
})).observe({'type': 'layout-shift', buffered: true}); })).observe({'type': 'layout-shift', buffered: true});
}).observe({type: 'layout-shift'}); }).observe({type: 'layout-shift'});
// Modify the position of the div to cause a layout-shift entry. // Modify the position of the div to cause a layout-shift entry.
document.getElementById('myDiv').style = "top: 60px"; document.getElementById('myDiv').style = "top: 60px";
});
}, 'PerformanceObserver with buffered flag sees previous layout-shift entry.'); }, 'PerformanceObserver with buffered flag sees previous layout-shift entry.');
</script> </script>
</body> </body>

View file

@ -21,14 +21,15 @@
<script> <script>
let timeAfterClick; let timeAfterClick;
async_test(async function(t) { promise_test(async t => {
assert_precondition(window.LayoutShift, 'LayoutShift entries are not supported'); assert_precondition(window.LayoutShift, 'Layout Instability is not supported.');
// Wait for the initial render to complete. // Wait for the initial render to complete.
await waitForAnimationFrames(2); await waitForAnimationFrames(2);
const startTime = performance.now(); const startTime = performance.now();
return new Promise(resolve => {
const observer = new PerformanceObserver( const observer = new PerformanceObserver(
t.step_func_done(function(entryList) { t.step_func(entryList => {
const endTime = performance.now(); const endTime = performance.now();
assert_equals(entryList.getEntries().length, 1); assert_equals(entryList.getEntries().length, 1);
const entry = entryList.getEntries()[0]; const entry = entryList.getEntries()[0];
@ -43,6 +44,7 @@ async_test(async function(t) {
// We should see that there was a click input entry. // We should see that there was a click input entry.
assert_equals(entry.hadRecentInput, true); assert_equals(entry.hadRecentInput, true);
assert_greater_than_equal(timeAfterClick, entry.lastInputTime); assert_greater_than_equal(timeAfterClick, entry.lastInputTime);
resolve();
}) })
); );
observer.observe({entryTypes: ['layout-shift']}); observer.observe({entryTypes: ['layout-shift']});
@ -52,6 +54,7 @@ async_test(async function(t) {
// Modify the position of the div. // Modify the position of the div.
document.getElementById('myDiv').style = "top: 60px"; document.getElementById('myDiv').style = "top: 60px";
}); });
});
}, 'Layout shift right after user input is observable via PerformanceObserver.'); }, 'Layout shift right after user input is observable via PerformanceObserver.');
</script> </script>

View file

@ -7,8 +7,9 @@
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script> <script>
test(() => { test(() => {
if (typeof PerformanceObserver.supportedEntryTypes === "undefined") assert_precondition(window.LayoutShift, 'Layout Instability is not supported.');
assert_unreached("supportedEntryTypes is not supported."); assert_precondition(typeof PerformanceObserver.supportedEntryTypes !== "undefined",
'supportedEntryTypes is not supported.');
assert_greater_than(PerformanceObserver.supportedEntryTypes.indexOf("layout-shift"), -1, assert_greater_than(PerformanceObserver.supportedEntryTypes.indexOf("layout-shift"), -1,
"There should be an entry 'layout-shift' in PerformanceObserver.supportedEntryTypes"); "There should be an entry 'layout-shift' in PerformanceObserver.supportedEntryTypes");
}, "supportedEntryTypes contains 'layoutShift'."); }, "supportedEntryTypes contains 'layoutShift'.");

View file

@ -10,13 +10,14 @@
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="resources/util.js"></script> <script src="resources/util.js"></script>
<script> <script>
async_test(async function(t) { promise_test(async t => {
assert_precondition(window.LayoutShift, 'LayoutShift entries are not supported'); assert_precondition(window.LayoutShift, 'Layout Instability is not supported.');
// Wait for the initial render to complete. // Wait for the initial render to complete.
await waitForAnimationFrames(2); await waitForAnimationFrames(2);
return new Promise(resolve => {
const observer = new PerformanceObserver( const observer = new PerformanceObserver(
t.step_func_done(function(entryList) { t.step_func(entryList => {
const entry = entryList.getEntries()[0]; const entry = entryList.getEntries()[0];
assert_equals(typeof(entry.toJSON), 'function'); assert_equals(typeof(entry.toJSON), 'function');
const json = entry.toJSON(); const json = entry.toJSON();
@ -34,12 +35,14 @@ async_test(async function(t) {
]; ];
for (const key of keys) { for (const key of keys) {
assert_equals(json[key], entry[key], assert_equals(json[key], entry[key],
'LayoutShift ${key} entry does not match its toJSON value'); `LayoutShift ${key} entry does not match its toJSON value`);
} }
resolve();
}) })
); );
observer.observe({type: 'layout-shift'}); observer.observe({type: 'layout-shift'});
document.getElementById('myDiv').style = "top: 60px"; document.getElementById('myDiv').style = "top: 60px";
});
}, 'Test toJSON() in LayoutShift.'); }, 'Test toJSON() in LayoutShift.');
</script> </script>
</body> </body>

View file

@ -84,11 +84,11 @@ var testParameter = test(function() {
]; ];
assert_throws_js(TypeError, assert_throws_js(TypeError,
function() { var capturer = new ImageCapture(); }, function() { var capturer = new ImageCapture(); },
'an ImageCapturer can not be created with no parameter'); 'an ImageCapturer cannot be created with no parameter');
invalidParameters.map(parameter => { invalidParameters.map(parameter => {
assert_throws_js(TypeError, assert_throws_js(TypeError,
function() { var capturer = new ImageCapture(parameter); }, function() { var capturer = new ImageCapture(parameter); },
`an ImageCapturer can not be created with a ${parameter} parameter`); `an ImageCapturer cannot be created with a ${parameter} parameter`);
}); });
}, 'throw "TypeError" if parameter is not MediaStreamTrack.'); }, 'throw "TypeError" if parameter is not MediaStreamTrack.');

View file

@ -208,6 +208,7 @@ class MockRuntime {
"local-floor": device.mojom.XRSessionFeature.REF_SPACE_LOCAL_FLOOR, "local-floor": device.mojom.XRSessionFeature.REF_SPACE_LOCAL_FLOOR,
"bounded-floor": device.mojom.XRSessionFeature.REF_SPACE_BOUNDED_FLOOR, "bounded-floor": device.mojom.XRSessionFeature.REF_SPACE_BOUNDED_FLOOR,
"unbounded": device.mojom.XRSessionFeature.REF_SPACE_UNBOUNDED, "unbounded": device.mojom.XRSessionFeature.REF_SPACE_UNBOUNDED,
"hit-test": device.mojom.XRSessionFeature.HIT_TEST,
}; };
static sessionModeToMojoMap = { static sessionModeToMojoMap = {

View file

@ -46,7 +46,7 @@ function checkScroll() {
}; };
let key = (new URL(document.location)).searchParams.get("key"); let key = (new URL(document.location)).searchParams.get("key");
stashResults(key, results); stashResultsThenClose(key, results);
} }
// Ensure two animation frames on load to test the fallback to element anchor, // Ensure two animation frames on load to test the fallback to element anchor,

View file

@ -1,8 +1,10 @@
// Put test results into Stash // Put test results into Stash
function stashResults(key, results) { function stashResultsThenClose(key, results) {
fetch(`/scroll-to-text-fragment/stash.py?key=${key}`, { fetch(`/scroll-to-text-fragment/stash.py?key=${key}`, {
method: 'POST', method: 'POST',
body: JSON.stringify(results) body: JSON.stringify(results)
}).then(() => {
window.close();
}); });
} }
@ -18,6 +20,10 @@ function fetchResults(key, resolve, reject) {
} catch(e) { } catch(e) {
reject(); reject();
} }
} else {
// We keep trying to fetch results as the target page may not have stashed
// them yet.
fetchResults(key, resolve, reject);
} }
}); });
} }

View file

@ -10,8 +10,4 @@ def main(request, response):
else: else:
# Request for result data from test page # Request for result data from test page
value = request.server.stash.take(key, '/scroll-to-text-fragment/') value = request.server.stash.take(key, '/scroll-to-text-fragment/')
# Poll until data is stashed
while value is None:
time.sleep(.1)
value = request.server.stash.take(key, '/scroll-to-text-fragment/')
return value return value

View file

@ -1,98 +1,90 @@
<!doctype html> <!doctype html>
<html>
<meta charset="utf-8"> <meta charset="utf-8">
<title>This removes and adds an animation element while the animation is repeating</title> <title>Remove and add an animation element while the animation is repeating</title>
<script src="/resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="/resources/SVGAnimationTestCase-testharness.js"></script> <svg>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<animate id="anim" attributeName="visibility" to="visible" begin="0s" dur="2s" repeatCount="4"/> <animate id="anim" attributeName="visibility" to="visible" begin="0s" dur="2s" repeatCount="4"/>
<rect x="0" y="0" width="100" height="100" fill="rgb(0, 255, 0)"> <rect x="0" y="0" width="50" height="50" fill="lime">
<set attributeName="fill" to="rgb(255, 0, 0)" begin="anim.repeat(0)"/> <set attributeName="fill" to="red" begin="anim.repeat(0)"/>
</rect> </rect>
<rect x="200" y="0" width="100" height="100" fill="rgb(255, 0, 0)"> <rect x="50" y="0" width="50" height="50" fill="red">
<set attributeName="fill" to="rgb(0, 255, 0)" begin="anim.repeat(1)"/> <set attributeName="fill" to="lime" begin="anim.repeat(1)"/>
</rect> </rect>
<rect x="0" y="200" width="100" height="100" fill="rgb(255, 0, 0)"> <rect x="0" y="50" width="50" height="50" fill="red">
<set attributeName="fill" to="rgb(0, 255, 0)" begin="anim.repeat(2)"/> <set attributeName="fill" to="lime" begin="anim.repeat(2)"/>
</rect> </rect>
<rect x="200" y="200" width="100" height="100" fill="rgb(255, 0, 0)"> <rect x="50" y="50" width="50" height="50" fill="red">
<set attributeName="fill" to="rgb(0, 255, 0)" begin="anim.repeat(3)"/> <set attributeName="fill" to="lime" begin="anim.repeat(3)"/>
</rect> </rect>
</svg> </svg>
<script> <script>
var rootSVGElement = document.querySelector("svg"); function recreate(anim) {
var epsilon = 1.0; anim.parentNode.removeChild(anim);
return document.querySelector('svg').appendChild(anim.cloneNode());
}
// Setup animation test function waitFrame() {
function sample1() { return new Promise(resolve => {
expectFillColor(rect1, 0, 255, 0, "1.1"); window.requestAnimationFrame(resolve);
expectFillColor(rect2, 255, 0, 0, "1.2"); });
expectFillColor(rect3, 255, 0, 0, "1.3"); }
expectFillColor(rect4, 255, 0, 0, "1.4");
}
function sample2() { function checkSetElements(setElements, expected) {
expectFillColor(rect1, 0, 255, 0, "2.1"); let fillValues = Array.from(setElements).map(set => {
expectFillColor(rect2, 0, 255, 0, "2.2"); return getComputedStyle(set.targetElement, '').fill;
expectFillColor(rect3, 255, 0, 0, "2.3"); });
expectFillColor(rect4, 255, 0, 0, "2.4"); let remappedExpected = expected.map(color => {
} const colorMap = {'red': 'rgb(255, 0, 0)', 'lime': 'rgb(0, 255, 0)'};
return colorMap[color];
function sample3() { })
expectFillColor(rect1, 0, 255, 0, "3.1"); assert_array_equals(fillValues, remappedExpected);
expectFillColor(rect2, 0, 255, 0, "3.2"); }
expectFillColor(rect3, 0, 255, 0, "3.3");
expectFillColor(rect4, 255, 0, 0, "3.4");
}
function sample4() {
expectFillColor(rect1, 0, 255, 0, "4.1");
expectFillColor(rect2, 0, 255, 0, "4.2");
expectFillColor(rect3, 0, 255, 0, "4.3");
expectFillColor(rect4, 0, 255, 0, "4.4");
}
function recreate() {
var anim1 = rootSVGElement.ownerDocument.getElementById("anim");
anim1.parentNode.removeChild(anim1);
var anim2 = createSVGElement("animate");
anim2.setAttribute("id", "anim");
anim2.setAttribute("attributeName", "visibility");
anim2.setAttribute("to", "visible");
anim2.setAttribute("begin", "0s");
anim2.setAttribute("dur", "2s");
anim2.setAttribute("repeatCount", "4");
rootSVGElement.appendChild(anim2);
}
smil_async_test((t) => {
var rects = rootSVGElement.ownerDocument.getElementsByTagName("rect");
rect1 = rects[0];
rect2 = rects[1];
rect3 = rects[2];
rect4 = rects[3];
const expectedValues = [
// [animationId, time, sampleCallback]
["anim", 1.999, sample1],
["anim", 2.000, sample2],
["anim", 2.999, sample2],
["anim", 4.000, sample3],
["anim", 5.0, recreate],
["anim", 5.999, sample3],
["anim", 6.000, sample4],
];
runAnimationTest(t, expectedValues);
});
window.animationStartsImmediately = true;
promise_test(t => {
let svg = document.querySelector('svg');
let anim = document.getElementById('anim');
let animWatcher = new EventWatcher(t, anim, ['beginEvent', 'repeatEvent']);
// Wait for #anims 'beginEvent' and then step through the
// 'repeatEvents' one at a time.
let stepsPromise = animWatcher.wait_for('beginEvent').then(() => {
checkSetElements(setElements, ['lime', 'red', 'red', 'red']);
svg.setCurrentTime(1.999);
return animWatcher.wait_for('repeatEvent');
}).then(() => {
return waitFrame();
}).then(() => {
checkSetElements(setElements, ['lime', 'lime', 'red', 'red']);
svg.setCurrentTime(2.999);
return waitFrame();
}).then(() => {
checkSetElements(setElements, ['lime', 'lime', 'red', 'red']);
svg.setCurrentTime(3.999);
return animWatcher.wait_for('repeatEvent');
}).then(() => {
return waitFrame();
}).then(() => {
checkSetElements(setElements, ['lime', 'lime', 'lime', 'red']);
let newAnim = recreate(anim);
let animWatcher = new EventWatcher(t, newAnim, ['repeatEvent']);
svg.setCurrentTime(5.999);
return animWatcher.wait_for('repeatEvent');
}).then(() => {
return waitFrame();
}).then(() => {
checkSetElements(setElements, ['lime', 'lime', 'lime', 'lime']);
});
let setElements = document.getElementsByTagName('set');
let setBeginWatchers = Array.from(setElements).map(element => {
return new EventWatcher(t, element, 'beginEvent');
});
// Expect 'beginEvent' to be dispatched once for all but the first 'set' element.
let setPromises = setBeginWatchers.slice(1).map(watcher => {
return watcher.wait_for('beginEvent').then(evt => {
let target = evt.target.targetElement;
assert_equals(getComputedStyle(target, '').fill, 'rgb(0, 255, 0)');
});
});
return Promise.all([stepsPromise, ...setPromises]);
});
</script> </script>

View file

@ -5,14 +5,10 @@ SCRIPT_DIR=$(cd $(dirname "$0") && pwd -P)
WPT_ROOT=$SCRIPT_DIR/../.. WPT_ROOT=$SCRIPT_DIR/../..
cd $WPT_ROOT cd $WPT_ROOT
add_wpt_hosts() {
./wpt make-hosts-file | sudo tee -a /etc/hosts
}
test_infrastructure() { test_infrastructure() {
local ARGS=""; local ARGS="";
if [ $PRODUCT == "firefox" ]; then if [ $PRODUCT == "firefox" ]; then
ARGS="--install-browser" ARGS="--binary=~/build/firefox/firefox"
else else
ARGS=$1 ARGS=$1
fi fi
@ -24,7 +20,6 @@ main() {
./wpt manifest --rebuild -p ~/meta/MANIFEST.json ./wpt manifest --rebuild -p ~/meta/MANIFEST.json
for PRODUCT in "${PRODUCTS[@]}"; do for PRODUCT in "${PRODUCTS[@]}"; do
if [[ "$PRODUCT" == "chrome" ]]; then if [[ "$PRODUCT" == "chrome" ]]; then
add_wpt_hosts
test_infrastructure "--binary=$(which google-chrome-unstable) --channel dev" test_infrastructure "--binary=$(which google-chrome-unstable) --channel dev"
else else
test_infrastructure test_infrastructure

View file

@ -36,11 +36,14 @@ the serialization of a GitHub event payload.
""" """
import argparse import argparse
import fnmatch
import json import json
import os import os
import subprocess import subprocess
import sys import sys
import tarfile
import tempfile import tempfile
import zipfile
from socket import error as SocketError # NOQA: N812 from socket import error as SocketError # NOQA: N812
import errno import errno
try: try:
@ -169,15 +172,16 @@ def install_webkitgtk_from_apt_repository(channel):
run(["sudo", "apt-get", "-qqy", "-t", "bionic-wpt-webkit-updates", "install", "webkit2gtk-driver"]) run(["sudo", "apt-get", "-qqy", "-t", "bionic-wpt-webkit-updates", "install", "webkit2gtk-driver"])
# Download an URL in chunks and saves it to a file descriptor (truncating it)
# It doesn't close the descriptor, but flushes it on success.
# It retries the download in case of ECONNRESET up to max_retries.
def download_url_to_descriptor(fd, url, max_retries=3): def download_url_to_descriptor(fd, url, max_retries=3):
"""Download an URL in chunks and saves it to a file descriptor (truncating it)
It doesn't close the descriptor, but flushes it on success.
It retries the download in case of ECONNRESET up to max_retries."""
download_succeed = False download_succeed = False
if max_retries < 0: if max_retries < 0:
max_retries = 0 max_retries = 0
for current_retry in range(max_retries+1): for current_retry in range(max_retries+1):
try: try:
print("INFO: Downloading %s Try %d/%d" % (url, current_retry + 1, max_retries))
resp = urlopen(url) resp = urlopen(url)
# We may come here in a retry, ensure to truncate fd before start writing. # We may come here in a retry, ensure to truncate fd before start writing.
fd.seek(0) fd.seek(0)
@ -246,7 +250,65 @@ def set_variables(event):
os.environ["GITHUB_BRANCH"] = branch os.environ["GITHUB_BRANCH"] = branch
def task_url(task_id):
root_url = os.environ['TASKCLUSTER_ROOT_URL']
if root_url == 'https://taskcluster.net':
queue_base = "https://queue.taskcluster.net/v1/task"
else:
queue_base = root_url + "/api/queue/v1/task"
return "%s/%s" % (queue_base, task_id)
def download_artifacts(artifacts):
artifact_list_by_task = {}
for artifact in artifacts:
base_url = task_url(artifact["task"])
if artifact["task"] not in artifact_list_by_task:
resp = urlopen(base_url + "/artifacts")
artifacts_data = json.load(resp)
artifact_list_by_task[artifact["task"]] = artifacts_data
artifacts_data = artifact_list_by_task[artifact["task"]]
print("DEBUG: Got artifacts %s" % artifacts_data)
found = False
for candidate in artifacts_data["artifacts"]:
print("DEBUG: candidate: %s glob: %s" % (candidate["name"], artifact["glob"]))
if fnmatch.fnmatch(candidate["name"], artifact["glob"]):
found = True
print("INFO: Fetching aritfact %s from task %s" % (candidate["name"], artifact["task"]))
file_name = candidate["name"].rsplit("/", 1)[1]
url = base_url + "/artifacts/" + candidate["name"]
dest_path = os.path.expanduser(os.path.join("~", artifact["dest"], file_name))
dest_dir = os.path.dirname(dest_path)
if not os.path.exists(dest_dir):
os.makedirs(dest_dir)
with open(dest_path, "wb") as f:
download_url_to_descriptor(f, url)
if artifact.get("extract"):
unpack(dest_path)
if not found:
print("WARNING: No artifact found matching %s in task %s" % (artifact["glob"], artifact["task"]))
def unpack(path):
dest = os.path.dirname(path)
if tarfile.is_tarfile(path):
run(["tar", "-xf", path], cwd=os.path.dirname(path))
elif zipfile.is_zipfile(path):
with zipfile.ZipFile(path) as archive:
archive.extractall(dest)
else:
print("ERROR: Don't know how to extract %s" % path)
raise Exception
def setup_environment(args): def setup_environment(args):
if "TASK_ARTIFACTS" in os.environ:
artifacts = json.loads(os.environ["TASK_ARTIFACTS"])
download_artifacts(artifacts)
if args.hosts_file: if args.hosts_file:
make_hosts_file() make_hosts_file()
@ -364,15 +426,8 @@ def fetch_event_data():
# For example under local testing # For example under local testing
return None return None
root_url = os.environ['TASKCLUSTER_ROOT_URL'] url = task_url(task_id)
if root_url == 'https://taskcluster.net': resp = urlopen(url)
queue_base = "https://queue.taskcluster.net/v1/task"
else:
queue_base = root_url + "/api/queue/v1/task"
resp = urlopen("%s/%s" % (queue_base, task_id))
task_data = json.load(resp) task_data = json.load(resp)
event_data = task_data.get("extra", {}).get("github_event") event_data = task_data.get("extra", {}).get("github_event")
if event_data is not None: if event_data is not None:

View file

@ -9,10 +9,18 @@ import subprocess
import sys import sys
browser_specific_args = { browser_specific_args = {
"firefox": ["--install-browser"],
"servo": ["--install-browser", "--processes=12"] "servo": ["--install-browser", "--processes=12"]
} }
def get_browser_args(product):
if product == "firefox":
local_binary = os.path.expanduser(os.path.join("~", "build", "firefox", "firefox"))
if os.path.exists(local_binary):
return ["--binary=%s" % local_binary]
print("WARNING: Local firefox binary not found")
return ["--install-browser"]
return browser_specific_args.get(product, [])
def find_wptreport(args): def find_wptreport(args):
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
@ -66,7 +74,7 @@ def main(product, commit_range, wpt_args):
"--no-headless", "--no-headless",
"--verify-log-full" "--verify-log-full"
] ]
wpt_args += browser_specific_args.get(product, []) wpt_args += get_browser_args(product)
# Hack to run servo with one process only for wdspec # Hack to run servo with one process only for wdspec
if product == "servo" and "--test-type=wdspec" in wpt_args: if product == "servo" and "--test-type=wdspec" in wpt_args:

View file

@ -40,6 +40,14 @@ top-level properties:
* `name`: Optional String. Name to use for the task overriding the * `name`: Optional String. Name to use for the task overriding the
property name. This is useful in combination with substitutions property name. This is useful in combination with substitutions
described below. described below.
* `download-artifacts`: Optional Object. An artifact to download from
a task that this task depends on. This has the following properties:
- `task` - Name of the task producing the artifact
- `glob` - A glob pattern for the filename of the artifact
- `dest` - A directory reltive to the home directory in which to place
the artifact
- `extract` - Optional. A boolean indicating whether an archive artifact
should be extracted in-place.
## Task Expansions ## Task Expansions

View file

@ -214,7 +214,7 @@ def get_owner(event):
return "web-platform-tests@users.noreply.github.com" return "web-platform-tests@users.noreply.github.com"
def create_tc_task(event, task, taskgroup_id, depends_on_ids): def create_tc_task(event, task, taskgroup_id, depends_on_ids, env_extra=None):
command = build_full_command(event, task) command = build_full_command(event, task)
task_id = taskcluster.slugId() task_id = taskcluster.slugId()
task_data = { task_data = {
@ -241,12 +241,24 @@ def create_tc_task(event, task, taskgroup_id, depends_on_ids):
"github_event": json.dumps(event) "github_event": json.dumps(event)
} }
} }
if env_extra:
task_data["payload"]["env"].update(env_extra)
if depends_on_ids: if depends_on_ids:
task_data["dependencies"] = depends_on_ids task_data["dependencies"] = depends_on_ids
task_data["requires"] = "all-completed" task_data["requires"] = "all-completed"
return task_id, task_data return task_id, task_data
def get_artifact_data(artifact, task_id_map):
task_id, data = task_id_map[artifact["task"]]
return {
"task": task_id,
"glob": artifact["glob"],
"dest": artifact["dest"],
"extract": artifact.get("extract", False)
}
def build_task_graph(event, all_tasks, tasks): def build_task_graph(event, all_tasks, tasks):
task_id_map = OrderedDict() task_id_map = OrderedDict()
taskgroup_id = os.environ.get("TASK_ID", taskcluster.slugId()) taskgroup_id = os.environ.get("TASK_ID", taskcluster.slugId())
@ -259,7 +271,14 @@ def build_task_graph(event, all_tasks, tasks):
add_task(depends_name, add_task(depends_name,
all_tasks[depends_name]) all_tasks[depends_name])
depends_on_ids.append(task_id_map[depends_name][0]) depends_on_ids.append(task_id_map[depends_name][0])
task_id, task_data = create_tc_task(event, task, taskgroup_id, depends_on_ids) env_extra = {}
if "download-artifacts" in task:
env_extra["TASK_ARTIFACTS"] = json.dumps(
[get_artifact_data(artifact, task_id_map)
for artifact in task["download-artifacts"]])
task_id, task_data = create_tc_task(event, task, taskgroup_id, depends_on_ids,
env_extra=env_extra)
task_id_map[task_name] = (task_id, task_data) task_id_map[task_name] = (task_id, task_data)
for task_name, task in iteritems(tasks): for task_name, task in iteritems(tasks):

View file

@ -82,6 +82,11 @@ components:
browser-firefox: browser-firefox:
depends-on: depends-on:
- download-firefox-${vars.channel} - download-firefox-${vars.channel}
download-artifacts:
- task: download-firefox-${vars.channel}
glob: public/results/firefox-${vars.channel}.*
dest: build/
extract: true
browser-webkitgtk_minibrowser: {} browser-webkitgtk_minibrowser: {}
@ -281,7 +286,7 @@ tasks:
download-firefox-${vars.channel}: download-firefox-${vars.channel}:
use: use:
- wpt-base - wpt-base
command: "./wpt install --download-only --destination /home/test/artifacts/ --channel=${vars.channel} firefox browser" command: "./wpt install --download-only --destination /home/test/artifacts/ --channel=${vars.channel} --rename=firefox-${vars.channel} firefox browser"
- lint: - lint:
use: use:
@ -429,10 +434,12 @@ tasks:
- infrastructure/ tests: - infrastructure/ tests:
description: >- description: >-
Smoketests for wptrunner Smoketests for wptrunner
vars:
channel: nightly
use: use:
- wpt-base - wpt-base
- trigger-pr - trigger-pr
- tox-python2 - browser-firefox
command: ./tools/ci/ci_wptrunner_infrastructure.sh command: ./tools/ci/ci_wptrunner_infrastructure.sh
install: install:
- libnss3-tools - libnss3-tools

View file

@ -127,7 +127,8 @@ def test_verify_payload():
'wpt-chrome-dev-crashtest-1', 'wpt-chrome-dev-crashtest-1',
'lint'}), 'lint'}),
("pr_event.json", True, {".taskcluster.yml",".travis.yml","tools/ci/start.sh"}, ("pr_event.json", True, {".taskcluster.yml",".travis.yml","tools/ci/start.sh"},
{'lint', {'download-firefox-nightly',
'lint',
'tools/ unittests (Python 2)', 'tools/ unittests (Python 2)',
'tools/ unittests (Python 3.6)', 'tools/ unittests (Python 3.6)',
'tools/ unittests (Python 3.8)', 'tools/ unittests (Python 3.8)',

View file

@ -41,6 +41,14 @@ def handle_remove_readonly(func, path, exc):
raise raise
def get_ext(filename):
"""Get the extension from a filename with special handling for .tar.foo"""
name, ext = os.path.splitext(filename)
if name.endswith(".tar"):
ext = ".tar%s" % ext
return ext
class Browser(object): class Browser(object):
__metaclass__ = ABCMeta __metaclass__ = ABCMeta
@ -48,8 +56,13 @@ class Browser(object):
self.logger = logger self.logger = logger
@abstractmethod @abstractmethod
def download(self, dest=None, channel=None): def download(self, dest=None, channel=None, rename=None):
"""Download a package or installer for the browser""" """Download a package or installer for the browser
:param dest: Directory in which to put the dowloaded package
:param channel: Browser channel to download
:param rename: Optional name for the downloaded package; the original
extension is preserved.
"""
return NotImplemented return NotImplemented
@abstractmethod @abstractmethod
@ -133,7 +146,7 @@ class Firefox(Browser):
return dest return dest
def download(self, dest=None, channel="nightly"): def download(self, dest=None, channel="nightly", rename=None):
product = { product = {
"nightly": "firefox-nightly-latest-ssl", "nightly": "firefox-nightly-latest-ssl",
"beta": "firefox-beta-latest-ssl", "beta": "firefox-beta-latest-ssl",
@ -177,6 +190,9 @@ class Firefox(Browser):
if not filename: if not filename:
filename = "firefox.tar.bz2" filename = "firefox.tar.bz2"
if rename:
filename = "%s%s" % (rename, get_ext(filename))
installer_path = os.path.join(dest, filename) installer_path = os.path.join(dest, filename)
with open(installer_path, "wb") as f: with open(installer_path, "wb") as f:
@ -441,7 +457,7 @@ class FirefoxAndroid(Browser):
product = "firefox_android" product = "firefox_android"
requirements = "requirements_firefox.txt" requirements = "requirements_firefox.txt"
def download(self, dest=None, channel=None): def download(self, dest=None, channel=None, rename=None):
if dest is None: if dest is None:
dest = os.pwd dest = os.pwd
@ -464,7 +480,10 @@ class FirefoxAndroid(Browser):
(task_id, "public/build/geckoview-androidTest.apk")) (task_id, "public/build/geckoview-androidTest.apk"))
resp.raise_for_status() resp.raise_for_status()
apk_path = os.path.join(dest, "geckoview-androidTest.apk") filename = "geckoview-androidTest.apk"
if rename:
filename = "%s%s" % (rename, get_ext(filename)[1])
apk_path = os.path.join(dest, filename)
with open(apk_path, "wb") as f: with open(apk_path, "wb") as f:
f.write(resp.content) f.write(resp.content)
@ -500,7 +519,7 @@ class Chrome(Browser):
product = "chrome" product = "chrome"
requirements = "requirements_chrome.txt" requirements = "requirements_chrome.txt"
def download(self, dest=None, channel=None): def download(self, dest=None, channel=None, rename=None):
raise NotImplementedError raise NotImplementedError
def install(self, dest=None, channel=None): def install(self, dest=None, channel=None):
@ -658,7 +677,7 @@ class ChromeAndroidBase(Browser):
super(ChromeAndroidBase, self).__init__(logger) super(ChromeAndroidBase, self).__init__(logger)
self.device_serial = None self.device_serial = None
def download(self, dest=None, channel=None): def download(self, dest=None, channel=None, rename=None):
raise NotImplementedError raise NotImplementedError
def install(self, dest=None, channel=None): def install(self, dest=None, channel=None):
@ -766,7 +785,7 @@ class ChromeiOS(Browser):
product = "chrome_ios" product = "chrome_ios"
requirements = "requirements_chrome_ios.txt" requirements = "requirements_chrome_ios.txt"
def download(self, dest=None, channel=None): def download(self, dest=None, channel=None, rename=None):
raise NotImplementedError raise NotImplementedError
def install(self, dest=None, channel=None): def install(self, dest=None, channel=None):
@ -802,7 +821,7 @@ class Opera(Browser):
self.logger.warning("Unable to find the browser binary.") self.logger.warning("Unable to find the browser binary.")
return None return None
def download(self, dest=None, channel=None): def download(self, dest=None, channel=None, rename=None):
raise NotImplementedError raise NotImplementedError
def install(self, dest=None, channel=None): def install(self, dest=None, channel=None):
@ -874,7 +893,7 @@ class EdgeChromium(Browser):
edgedriver_name = "msedgedriver" edgedriver_name = "msedgedriver"
requirements = "requirements_edge_chromium.txt" requirements = "requirements_edge_chromium.txt"
def download(self, dest=None, channel=None): def download(self, dest=None, channel=None, rename=None):
raise NotImplementedError raise NotImplementedError
def install(self, dest=None, channel=None): def install(self, dest=None, channel=None):
@ -975,7 +994,7 @@ class Edge(Browser):
product = "edge" product = "edge"
requirements = "requirements_edge.txt" requirements = "requirements_edge.txt"
def download(self, dest=None, channel=None): def download(self, dest=None, channel=None, rename=None):
raise NotImplementedError raise NotImplementedError
def install(self, dest=None, channel=None): def install(self, dest=None, channel=None):
@ -1009,7 +1028,7 @@ class InternetExplorer(Browser):
product = "ie" product = "ie"
requirements = "requirements_ie.txt" requirements = "requirements_ie.txt"
def download(self, dest=None, channel=None): def download(self, dest=None, channel=None, rename=None):
raise NotImplementedError raise NotImplementedError
def install(self, dest=None, channel=None): def install(self, dest=None, channel=None):
@ -1037,7 +1056,7 @@ class Safari(Browser):
product = "safari" product = "safari"
requirements = "requirements_safari.txt" requirements = "requirements_safari.txt"
def download(self, dest=None, channel=None): def download(self, dest=None, channel=None, rename=None):
raise NotImplementedError raise NotImplementedError
def install(self, dest=None, channel=None): def install(self, dest=None, channel=None):
@ -1107,14 +1126,15 @@ class Servo(Browser):
url = "https://download.servo.org/nightly/%s/servo-latest%s" % (platform, extension) url = "https://download.servo.org/nightly/%s/servo-latest%s" % (platform, extension)
return get(url) return get(url)
def download(self, dest=None, channel="nightly"): def download(self, dest=None, channel="nightly", rename=None):
if dest is None: if dest is None:
dest = os.pwd dest = os.pwd
resp = self._get(dest, channel) resp = self._get(dest, channel)
_, extension, _ = self.platform_components() _, extension, _ = self.platform_components()
with open(os.path.join(dest, "servo-latest%s" % (extension,)), "w") as f: filename = rename if rename is not None else "servo-latest"
with open(os.path.join(dest, "%s%s" % (filename, extension,)), "w") as f:
f.write(resp.content) f.write(resp.content)
def install(self, dest=None, channel="nightly"): def install(self, dest=None, channel="nightly"):
@ -1161,7 +1181,7 @@ class Sauce(Browser):
product = "sauce" product = "sauce"
requirements = "requirements_sauce.txt" requirements = "requirements_sauce.txt"
def download(self, dest=None, channel=None): def download(self, dest=None, channel=None, rename=None):
raise NotImplementedError raise NotImplementedError
def install(self, dest=None, channel=None): def install(self, dest=None, channel=None):
@ -1186,7 +1206,7 @@ class WebKit(Browser):
product = "webkit" product = "webkit"
requirements = "requirements_webkit.txt" requirements = "requirements_webkit.txt"
def download(self, dest=None, channel=None): def download(self, dest=None, channel=None, rename=None):
raise NotImplementedError raise NotImplementedError
def install(self, dest=None, channel=None): def install(self, dest=None, channel=None):
@ -1252,7 +1272,7 @@ class Epiphany(Browser):
product = "epiphany" product = "epiphany"
requirements = "requirements_epiphany.txt" requirements = "requirements_epiphany.txt"
def download(self, dest=None, channel=None): def download(self, dest=None, channel=None, rename=None):
raise NotImplementedError raise NotImplementedError
def install(self, dest=None, channel=None): def install(self, dest=None, channel=None):

View file

@ -43,6 +43,9 @@ def get_parser():
'latest browser release on the selected channel.') 'latest browser release on the selected channel.')
parser.add_argument('--download-only', action="store_true", parser.add_argument('--download-only', action="store_true",
help="Download the selected component but don't install it") help="Download the selected component but don't install it")
parser.add_argument('--rename', action="store", default=None,
help="Filename, excluding extension for downloaded archive "
"(only with --download-only)")
parser.add_argument('-d', '--destination', parser.add_argument('-d', '--destination',
help='filesystem directory to place the component') help='filesystem directory to place the component')
return parser return parser
@ -75,10 +78,11 @@ def run(venv, **kwargs):
"No --destination argument, and no default for the environment") "No --destination argument, and no default for the environment")
install(browser, kwargs["component"], destination, channel, install(browser, kwargs["component"], destination, channel,
download_only=kwargs["download_only"]) download_only=kwargs["download_only"], rename=kwargs["rename"])
def install(name, component, destination, channel="nightly", logger=None, download_only=False): def install(name, component, destination, channel="nightly", logger=None, download_only=False,
rename=None):
if logger is None: if logger is None:
import logging import logging
logger = logging.getLogger("install") logger = logging.getLogger("install")
@ -90,6 +94,9 @@ def install(name, component, destination, channel="nightly", logger=None, downlo
subclass = getattr(browser, name.title()) subclass = getattr(browser, name.title())
sys.stdout.write('Now installing %s %s...\n' % (name, component)) sys.stdout.write('Now installing %s %s...\n' % (name, component))
path = getattr(subclass(logger), method)(dest=destination, channel=channel) kwargs = {}
if download_only and rename:
kwargs["rename"] = rename
path = getattr(subclass(logger), method)(dest=destination, channel=channel, **kwargs)
if path: if path:
sys.stdout.write('Binary %s as %s\n' % ("downloaded" if download_only else "installed", path,)) sys.stdout.write('Binary %s as %s\n' % ("downloaded" if download_only else "installed", path,))

View file

@ -207,6 +207,54 @@ promise_test(async t => {
assert_numeric_style_equals(getComputedStyle(div).opacity, 0.4); assert_numeric_style_equals(getComputedStyle(div).opacity, 0.4);
}, 'Commits the intermediate value of an animation in the middle of stack'); }, 'Commits the intermediate value of an animation in the middle of stack');
promise_test(async t => {
const div = createDiv(t);
div.style.opacity = '0.1';
const animA = div.animate(
{ opacity: '0.2', composite: 'add' },
{ duration: 1, fill: 'forwards' }
);
const animB = div.animate(
{ opacity: '0.2', composite: 'add' },
{ duration: 1, fill: 'forwards' }
);
const animC = div.animate(
{ opacity: '0.3', composite: 'add' },
{ duration: 1, fill: 'forwards' }
);
animA.persist();
animB.persist();
await animB.finished;
// The error cases are similar to the above test with one additional case;
// verifying that the animations composite on top of the correct underlying
// base style.
//
// Expected result:
//
// <underlying> + animA + animB = 0.5
//
// Additional error results:
//
// <underlying> + animA + animB + animC + animA + animB = 1.0 (saturates)
// (Added to the computed value instead of underlying value when
// resolving)
//
// animA + animB = 0.4
// Failed to composite on top of underlying value.
//
animB.commitStyles();
animA.cancel();
animB.cancel();
animC.cancel();
assert_numeric_style_equals(getComputedStyle(div).opacity, 0.5);
}, 'Commit composites on top of the underlying value');
promise_test(async t => { promise_test(async t => {
const div = createDiv(t); const div = createDiv(t);
div.style.opacity = '0.1'; div.style.opacity = '0.1';

View file

@ -0,0 +1,58 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>Animation.onremove</title>
<link rel="help" href="https://drafts.csswg.org/web-animations/#dom-animation-onremove">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../../testcommon.js"></script>
<body>
<div id="log"></div>
<script>
'use strict';
async_test(t => {
const div = createDiv(t);
const animA = div.animate({ opacity: 1 }, { duration: 1, fill: 'forwards' });
const animB = div.animate({ opacity: 1 }, { duration: 1, fill: 'forwards' });
let finishedTimelineTime = null;
animB.onfinish = event => {
finishedTimelineTime = event.timelineTime;
};
animA.onremove = t.step_func_done(event => {
assert_equals(animA.replaceState, 'removed');
assert_equals(event.currentTime, 1);
assert_true(finishedTimelineTime != null, 'finished event fired');
assert_true(event.timelineTime == finishedTimelineTime,
'timeline time is set');
});
}, 'onremove event is fired when replaced animation is removed.');
promise_test(async t => {
const div = createDiv(t);
const animA = div.animate({ opacity: 1 }, { duration: 1, fill: 'forwards' });
const animB = div.animate({ opacity: 1 }, { duration: 1, fill: 'forwards' });
const animC = div.animate({ opacity: 1 }, { duration: 1, fill: 'forwards' });
const animD = div.animate({ opacity: 1 }, { duration: 1, fill: 'forwards' });
const removed = [];
animA.onremove = () => { removed.push('A'); };
animB.onremove = () => { removed.push('B'); };
animC.onremove = () => { removed.push('C'); };
animD.onremove = event => {
assert_unreached('onremove event should not be fired');
};
await waitForAnimationFrames(2);
assert_equals(removed.join(''), 'ABC');
}, 'onremove events are fired in the correct order');
</script>
</body>

View file

@ -38,9 +38,6 @@ const fakeDeviceInitParams = {
// |refSpaceName| - XRReferenceSpaceType - either 'local', 'local-floor' or 'viewer'. // |refSpaceName| - XRReferenceSpaceType - either 'local', 'local-floor' or 'viewer'.
let testFunctionGenerator = function(ray, entityTypes, expectedPoses, refSpaceName) { let testFunctionGenerator = function(ray, entityTypes, expectedPoses, refSpaceName) {
const testFunction = function(session, fakeDeviceController, t) { const testFunction = function(session, fakeDeviceController, t) {
assert_equals(session.mode, 'immersive-ar');
assert_not_equals(session.environmentBlendMode, 'opaque');
return Promise.all([ return Promise.all([
session.requestReferenceSpace('local'), session.requestReferenceSpace('local'),
session.requestReferenceSpace('viewer'), session.requestReferenceSpace('viewer'),
@ -109,6 +106,9 @@ const localFloorBasedTestFunctionGenerator = function(ray, entityTypes, expected
return testFunctionGenerator(ray, entityTypes, expectedPoses, 'local-floor'); return testFunctionGenerator(ray, entityTypes, expectedPoses, 'local-floor');
}; };
// All test cases require local-floor and hit-test.
const sessionInit = { 'requiredFeatures': ['local-floor', 'hit-test'] };
// Pose of the first expected hit test result - straight ahead of the viewer, viewer-facing. // Pose of the first expected hit test result - straight ahead of the viewer, viewer-facing.
const pose_1 = { const pose_1 = {
position: {x: 0.0, y: 1.0, z: -2.5, w: 1.0}, position: {x: 0.0, y: 1.0, z: -2.5, w: 1.0},
@ -125,11 +125,11 @@ const pose_1 = {
xr_session_promise_test( xr_session_promise_test(
"Ensures subscription to hit test works with viewer space - straight ahead - plane", "Ensures subscription to hit test works with viewer space - straight ahead - plane",
viewerBasedTestFunctionGenerator(new XRRay(), ["plane"], [pose_1]), viewerBasedTestFunctionGenerator(new XRRay(), ["plane"], [pose_1]),
fakeDeviceInitParams, 'immersive-ar', { 'requiredFeatures': ['local-floor'] }); fakeDeviceInitParams, 'immersive-ar', sessionInit);
xr_session_promise_test("Ensures subscription to hit test works with viewer space - straight up - plane - no results", xr_session_promise_test("Ensures subscription to hit test works with viewer space - straight up - plane - no results",
viewerBasedTestFunctionGenerator(new XRRay({}, {x: 0.0, y: 1.0, z : 0.0}), ["plane"], []), viewerBasedTestFunctionGenerator(new XRRay({}, {x: 0.0, y: 1.0, z : 0.0}), ["plane"], []),
fakeDeviceInitParams, 'immersive-ar', { 'requiredFeatures': ['local-floor'] }); fakeDeviceInitParams, 'immersive-ar', sessionInit);
const pose_2 = { const pose_2 = {
position: {x: 0.0, y: 2.0, z: 0.0, w: 1.0}, position: {x: 0.0, y: 2.0, z: 0.0, w: 1.0},
@ -142,8 +142,7 @@ const pose_2 = {
xr_session_promise_test("Ensures subscription to hit test works with viewer space - straight up - point", xr_session_promise_test("Ensures subscription to hit test works with viewer space - straight up - point",
viewerBasedTestFunctionGenerator(new XRRay({}, {x: 0.0, y: 1.0, z : 0.0}), ["point"], [pose_2]), viewerBasedTestFunctionGenerator(new XRRay({}, {x: 0.0, y: 1.0, z : 0.0}), ["point"], [pose_2]),
fakeDeviceInitParams, fakeDeviceInitParams, 'immersive-ar', sessionInit);
'immersive-ar', { 'requiredFeatures': ['local-floor'] });
const pose_3 = { const pose_3 = {
position: {x: 0.0, y: 0.0, z: -2.5, w: 1.0}, position: {x: 0.0, y: 0.0, z: -2.5, w: 1.0},
@ -156,8 +155,7 @@ const pose_3 = {
xr_session_promise_test("Ensures subscription to hit test works with local space", xr_session_promise_test("Ensures subscription to hit test works with local space",
localBasedTestFunctionGenerator(new XRRay(), ["plane"], [pose_3]), localBasedTestFunctionGenerator(new XRRay(), ["plane"], [pose_3]),
fakeDeviceInitParams, fakeDeviceInitParams, 'immersive-ar', sessionInit);
'immersive-ar', { 'requiredFeatures': ['local-floor'] });
const pose_4 = { const pose_4 = {
position: {x: 0.0, y: 0.25, z: -2.5, w: 1.0}, position: {x: 0.0, y: 0.25, z: -2.5, w: 1.0},
@ -170,7 +168,6 @@ const pose_4 = {
xr_session_promise_test("Ensures subscription to hit test works with local-floor space", xr_session_promise_test("Ensures subscription to hit test works with local-floor space",
localFloorBasedTestFunctionGenerator(new XRRay(), ["plane"], [pose_4]), localFloorBasedTestFunctionGenerator(new XRRay(), ["plane"], [pose_4]),
fakeDeviceInitParams, fakeDeviceInitParams, 'immersive-ar', sessionInit);
'immersive-ar', { 'requiredFeatures': ['local-floor'] });
</script> </script>

View file

@ -0,0 +1,65 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../resources/webxr_util.js"></script>
<script src="../resources/webxr_test_asserts.js"></script>
<script src="../resources/webxr_test_constants.js"></script>
<script src="../resources/webxr_test_constants_fake_world.js"></script>
<canvas />
<script>
const fakeDeviceInitParams = {
supportedModes: ["immersive-ar"],
views: VALID_VIEWS,
supportedFeatures: ALL_FEATURES,
};
// |shouldSucceed| - true if the hit test request is expected to succeed, false otherwise
// |endSession| - true if the test case should call session.end() prior to requesting hit test
const testFunctionGenerator = function(shouldSucceed, endSession) {
const testFunction = function(session, fakeDeviceController, t) {
session.requestReferenceSpace('viewer').then((viewerRefSpace) => {
const hitTestOptionsInit = {
space: viewerRefSpace,
offsetRay: new XRRay(),
};
if(endSession) {
session.end();
}
return session.requestHitTestSource(hitTestOptionsInit).then((hitTestSource) => {
t.step(() => {
assert_true(shouldSucceed,
"`requestHitTestSource` succeeded when it was expected to fail");
});
}).catch((error) => {
t.step(() => {
assert_false(shouldSucceed,
"`requestHitTestSource` failed when it was expected to succeed, error: " + error);
});
});
});
};
return testFunction;
};
xr_session_promise_test("Hit test subscription succeeds if the feature was requested",
testFunctionGenerator(/*shouldSucceed=*/true, /*endSession=*/false),
fakeDeviceInitParams,
'immersive-ar', { 'requiredFeatures': ['hit-test'] });
xr_session_promise_test("Hit test subscription fails if the feature was not requested",
testFunctionGenerator(/*shouldSucceed=*/false, /*endSession=*/false),
fakeDeviceInitParams,
'immersive-ar', {});
xr_session_promise_test("Hit test subscription fails if the feature was requested but the session already ended",
testFunctionGenerator(/*shouldSucceed=*/false, /*endSession=*/true),
fakeDeviceInitParams,
'immersive-ar', { 'requiredFeatures': ['hit-test'] });
</script>

View file

@ -126,6 +126,7 @@ const ALL_FEATURES = [
"local-floor", "local-floor",
"bounded-floor", "bounded-floor",
"unbounded", "unbounded",
"hit-test",
]; ];
const TRACKED_IMMERSIVE_DEVICE = { const TRACKED_IMMERSIVE_DEVICE = {

View file

@ -8,7 +8,7 @@ test(() => {
assert_throws_js(Error, assert_throws_js(Error,
function() { function() {
new SharedWorker({toString:function(){throw new Error()}}, "name") }, new SharedWorker({toString:function(){throw new Error()}}, "name") },
"toString exception not propagagted"); "toString exception not propagated");
}, "Test toString exception propagated correctly."); }, "Test toString exception propagated correctly.");
test(() => { test(() => {

View file

@ -24,7 +24,7 @@ test(() => {
test(() => { test(() => {
assert_throws_js(TypeError, assert_throws_js(TypeError,
function() { new Worker(); }, function() { new Worker(); },
'invoking Worker constructor without arguments should result' + 'invoking Worker constructor without arguments should result ' +
'in an exception.') 'in an exception.')
}, 'Test worker creation with no arguments'); }, 'Test worker creation with no arguments');
@ -39,7 +39,7 @@ async_test(t => {
test(() => { test(() => {
assert_throws_dom("SyntaxError", assert_throws_dom("SyntaxError",
function() { var worker = new Worker('http://invalid:123$'); }, function() { var worker = new Worker('http://invalid:123$'); },
'Invoking Worker constructor with invalid script URL should' + 'Invoking Worker constructor with invalid script URL should ' +
'result in an exception.'); 'result in an exception.');
}, 'Test invalid script URL.'); }, 'Test invalid script URL.');

View file

@ -0,0 +1,24 @@
// META: global=!worker
// META: script=/workers/modules/resources/import-test-cases.js
// Imports |testCase.scriptURL| on a shared worker loaded from a data URL,
// and waits until the list of imported modules is sent from the worker. Passes
// if the list is equal to |testCase.expectation|.
function import_data_url_test(testCase) {
promise_test(async () => {
// The Access-Control-Allow-Origin header is necessary because a worker
// loaded from a data URL has a null origin and import() on the worker
// without the header is blocked.
const importURL = new URL(testCase.scriptURL, location.href) +
'?pipe=header(Access-Control-Allow-Origin, *)';
const dataURL = `data:text/javascript,import "${importURL}";`;
const worker = new SharedWorker(dataURL, { type: 'module'});
worker.port.postMessage('Send message for tests from main script.');
const msgEvent =
await new Promise(resolve => worker.port.onmessage = resolve);
assert_array_equals(msgEvent.data, testCase.expectation);
}, testCase.description);
}
testCases.forEach(import_data_url_test);