Update web-platform-tests to revision f0cb9071aea5ce5b641fcba5f362a0796bdc70bc

This commit is contained in:
WPT Sync Bot 2019-11-23 08:37:37 +00:00
parent 0d549e8146
commit 7289e837fd
558 changed files with 8627 additions and 6619 deletions

View file

@ -0,0 +1,128 @@
<!DOCTYPE html>
<link rel="help" href="https://drafts.csswg.org/css-scroll-snap-1" />
<title>Arrow key scroll snapping</title>
<meta name="flags" content="should">
<meta name="assert"
content="Test passes if keyboard scrolling correctly snaps on a snap
container">
<link rel="stylesheet" href="../support/common.css">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/resources/testdriver-actions.js"></script>
<script src="../support/common.js"></script>
<div id="scroller">
<div id="space"></div>
<div class="snap left top" id="top-left"></div>
<div class="snap right top" id="top-right"></div>
<div class="snap left bottom" id="bottom-left"></div>
</div>
<script>
const scroller = document.getElementById("scroller");
const topLeft = document.getElementById("top-left");
const topRight = document.getElementById("top-right");
scrollLeft = () => scroller.scrollLeft;
scrollTop = () => scroller.scrollTop;
promise_test(async t => {
scroller.scrollTo(0, 0);
assert_equals(scroller.scrollTop, 0, "verify test pre-condition");
await keyPress(scroller, "ArrowDown");
await waitForAnimationEnd(scrollTop);
assert_equals(scroller.scrollTop, 400);
}, "Snaps to bottom-left after pressing ArrowDown");
promise_test(async t => {
scroller.scrollTo(0, 400);
assert_equals(scroller.scrollTop, 400, "verify test pre-condition");
await keyPress(scroller, "ArrowUp");
await waitForAnimationEnd(scrollTop);
assert_equals(scroller.scrollTop, 0);
}, "Snaps to top-left after pressing ArrowUp");
promise_test(async t => {
scroller.scrollTo(0, 0);
assert_equals(scroller.scrollTop, 0, "verify test pre-condition");
await keyPress(scroller, "ArrowRight");
await waitForAnimationEnd(scrollLeft);
assert_equals(scroller.scrollLeft, 400);
}, "Snaps to top-right after pressing ArrowRight");
promise_test(async t => {
scroller.scrollTo(400, 0);
assert_equals(scroller.scrollLeft, 400, "verify test pre-condition");
await keyPress(scroller, "ArrowLeft");
await waitForAnimationEnd(scrollLeft);
assert_equals(scroller.scrollLeft, 0);
}, "Snaps to top-left after pressing ArrowLeft");
promise_test(async t => {
t.add_cleanup(function() {
topLeft.style.width = "";
topRight.style.left = "400px";
});
// Make the snap area cover the snapport.
topLeft.style.width = "800px";
// Make the distance between the previous and the next snap position larger
// than snapport.
topRight.style.left = "500px";
scroller.scrollTo(0, 0);
assert_equals(scroller.scrollLeft, 0, "verify test pre-condition");
await keyPress(scroller, "ArrowRight");
await waitForAnimationEnd(scrollLeft);
assert_between_exclusive(scroller.scrollLeft, 0, 500);
}, "If the original intended offset is valid as making a snap area cover the"
+ "snapport, and there's no other snap offset in between, use the original"
+ "intended offset");
promise_test(async t => {
t.add_cleanup(function() {
topLeft.style.width = "";
topRight.style.left = "400px";
});
// Make the snap area cover the snapport.
topLeft.style.width = "800px";
// Make the next snap offset closer than the original intended offset.
topRight.style.left = "20px";
scroller.scrollTo(0, 0);
assert_equals(scroller.scrollLeft, 0, "verify test pre-condition");
await keyPress(scroller, "ArrowRight");
await waitForAnimationEnd(scrollLeft);
assert_equals(scroller.scrollLeft, 20);
}, "If the original intended offset is valid as making a snap area cover the "
+ "snapport, but there's a defined snap offset in between, use the defined snap"
+ " offset.");
promise_test(async t => {
scroller.scrollTo(400, 0);
await keyPress(scroller, "ArrowRight");
await waitForAnimationEnd(scrollLeft);
assert_equals(scroller.scrollLeft, 400);
}, "If there is no valid snap offset on the arrow key's direction other than "
+ "the current offset, and the scroll-snap-type is mandatory, stay at the "
+ "current offset.");
promise_test(async t => {
t.add_cleanup(function() {
scroller.style.scrollSnapType = "both mandatory";
});
scroller.style.scrollSnapType = "both proximity";
scroller.scrollTo(400, 0);
assert_equals(scroller.scrollLeft, 400, "verify test pre-condition");
await keyPress(scroller, "ArrowRight");
await waitForAnimationEnd(scrollLeft);
assert_greater_than(scroller.scrollLeft, 400);
}, "If there is no valid snap offset on the arrow key's direction other than "
+ "the current offset, and the scroll-snap-type is proximity, go to the "
+ "original intended offset");
</script>

View file

@ -76,54 +76,54 @@ body {
// its snap areas to the next scrollable ancestor, per spec [1].
// [1] https://drafts.csswg.org/css-scroll-snap/#captures-snap-positions
test(() => {
const innerscroller = document.getElementById("inner-scroller");
const middlescroller = document.getElementById("middle-scroller");
const documentscroller = document.scrollingElement;
const inner_scroller = document.getElementById("inner-scroller");
const middle_scroller = document.getElementById("middle-scroller");
const document_scroller = document.scrollingElement;
// Middle scroller doesn't snap.
// Document scroller should snap to its only captured area.
documentscroller.scrollBy(0, 100);
middlescroller.scrollBy(0, 10);
assert_equals(innerscroller.scrollTop, 0);
assert_equals(middlescroller.scrollTop, 10);
assert_equals(documentscroller.scrollTop, 500);
document_scroller.scrollBy(0, 100);
middle_scroller.scrollBy(0, 10);
assert_equals(inner_scroller.scrollTop, 0);
assert_equals(middle_scroller.scrollTop, 10);
assert_equals(document_scroller.scrollTop, 500);
// Inner scroller snaps.
innerscroller.scrollBy(0, 10);
assert_equals(innerscroller.scrollTop, 300);
assert_equals(middlescroller.scrollTop, 10);
assert_equals(documentscroller.scrollTop, 500);
inner_scroller.scrollBy(0, 10);
assert_equals(inner_scroller.scrollTop, 300);
assert_equals(middle_scroller.scrollTop, 10);
assert_equals(document_scroller.scrollTop, 500);
// Inner scroller is no longer a scroll container.
innerscroller.style.setProperty("overflow", "visible");
assert_equals(innerscroller.scrollTop, 0);
assert_equals(middlescroller.scrollTop, 10);
assert_equals(documentscroller.scrollTop, 500);
inner_scroller.style.setProperty("overflow", "visible");
assert_equals(inner_scroller.scrollTop, 0);
assert_equals(middle_scroller.scrollTop, 10);
assert_equals(document_scroller.scrollTop, 500);
// The new snap container is the middle scroller, which has snap-type 'none'.
// Per spec, the scroll container should capture snap positions even if it has
// snap-type 'none'.
// The middle scroller should not snap.
// The document scroller should still only snap to its captured snap area.
documentscroller.scrollBy(0, 100);
middlescroller.scrollBy(0, 10);
assert_equals(innerscroller.scrollTop, 0);
assert_equals(middlescroller.scrollTop, 20);
assert_equals(documentscroller.scrollTop, 500);
document_scroller.scrollBy(0, 100);
middle_scroller.scrollBy(0, 10);
assert_equals(inner_scroller.scrollTop, 0);
assert_equals(middle_scroller.scrollTop, 20);
assert_equals(document_scroller.scrollTop, 500);
// The scroll container should now be at the document level.
middlescroller.style.setProperty("overflow", "visible");
documentscroller.scrollBy(0, -10);
assert_equals(innerscroller.scrollTop, 0);
assert_equals(middlescroller.scrollTop, 0);
middle_scroller.style.setProperty("overflow", "visible");
document_scroller.scrollBy(0, -10);
assert_equals(inner_scroller.scrollTop, 0);
assert_equals(middle_scroller.scrollTop, 0);
// Check that the existing snap area did not get removed when reassigning
// the inner snap area.
assert_equals(documentscroller.scrollTop, 500);
assert_equals(document_scroller.scrollTop, 500);
// Check that the inner snap area got reassigned to the document.
documentscroller.scrollBy(0, 150);
assert_equals(documentscroller.scrollTop, 600);
document_scroller.scrollBy(0, 150);
assert_equals(document_scroller.scrollTop, 600);
}, 'Making a snap container not scrollable should promote the next scrollable\
ancestor to become a snap container.');
</script>

View file

@ -0,0 +1,149 @@
<!DOCTYPE html>
<title>
Adding a scrollable element should make it start capturing snap points.
</title>
<link rel="help" href="https://drafts.csswg.org/css-scroll-snap/#captures-snap-positions"/>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
div {
position: absolute;
margin: 0px;
}
html {
scroll-snap-type: y mandatory;
}
body {
margin: 0px;
}
#middle-scroller {
top: 100px;
height: 500px;
width: 500px;
overflow: visible;
background-color: rgb(12, 61, 2);
scroll-snap-type: none;
}
#inner-scroller {
top: 200px;
height: 400px;
width: 400px;
overflow: visible;
background-color: rgb(65, 139, 50);
scroll-snap-type: y mandatory;
}
.space {
width: 2000px;
height: 2000px;
}
#inner-snap-area {
top: 300px;
width: 200px;
height: 200px;
background-color: blue;
scroll-snap-align: start;
}
#document-snap-area {
top: 500px;
width: 200px;
height: 200px;
background-color: lightblue;
scroll-snap-align: start;
}
#inserted-snap-container {
top: 400px;
height: 600px;
width: 400px;
overflow: scroll;
scroll-snap-type: y mandatory;
}
</style>
<div class="space"></div>
<div id="middle-scroller">
<div class="space"></div>
<div id="inner-scroller">
<div class="space"></div>
<div id="inner-snap-area"></div>
</div>
</div>
</div>
<div id="document-snap-area"></div>
<script>
const inner_scroller = document.getElementById("inner-scroller");
const middle_scroller = document.getElementById("middle-scroller");
const document_scroller = document.scrollingElement;
// This tests that making an element scrollable will reassign the correct snap
// areas to itself, per spec [1].
// [1] https://drafts.csswg.org/css-scroll-snap/#captures-snap-positions
test(() => {
// Confirm that the document-level scroller is the snap container for all of
// the snap areas.
document_scroller.scrollBy(0, 10);
assert_equals(document_scroller.scrollTop, 500);
// Snaps to the inner snap area.
document_scroller.scrollBy(0, 75);
assert_equals(document_scroller.scrollTop, 600);
// The middle scroller should now have the inner snap area assigned to it.
// Per spec, even if the snap-type is 'none', it should still capture snap
// points.
middle_scroller.style.setProperty("overflow", "scroll");
// The middle scroller has snap-type 'none' so it should not snap.
middle_scroller.scrollBy(0, 10);
assert_equals(middle_scroller.scrollTop, 10);
// The document scroller should only snap to the document-level snap area.
document_scroller.scrollTo(0, 600);
assert_equals(document_scroller.scrollTop, 500);
// The inner scroller should now have the innermost snap area assigned to it.
inner_scroller.style.setProperty("overflow", "scroll");
inner_scroller.scrollBy(0, 10);
assert_equals(inner_scroller.scrollTop, 300);
document_scroller.scrollTo(0, 600);
assert_equals(document_scroller.scrollTop, 500);
}, "Making an element scrollable should make it capture the correct descendant\
snap areas' snap points.");
// Test that attaching a new snap container also properly assigns snap areas.
test(() => {
// Sanity check that the scrollers still snap to the snap areas.
document_scroller.scrollBy(0, 10);
inner_scroller.scrollBy(0,10);
assert_equals(inner_scroller.scrollTop, 300);
assert_equals(document_scroller.scrollTop, 500);
// Create new snap container and append thedocument-level snap area as its
// child.
const inserted_scroller = document.createElement("div");
inserted_scroller.id = "inserted-snap-container";
const space = document.createElement("div");
space.classList.add("space");
inserted_scroller.appendChild(space);
inserted_scroller.appendChild(document.getElementById("document-snap-area"));
document_scroller.appendChild(inserted_scroller);
// Document scroller no longer snaps.
document_scroller.scrollTo(0, 400);
assert_equals(document_scroller.scrollTop, 400);
// Inserted scroller snaps.
inserted_scroller.scrollBy(0, 10);
assert_equals(inserted_scroller.scrollTop, 500);
}, "Attaching a new element that is scrollable should assign the correct snap\
areas to it.");
</script>

View file

@ -0,0 +1,44 @@
body {
margin: 0;
}
#scroller {
position: absolute;
width: 400px;
height: 400px;
overflow: scroll;
padding: 0;
scroll-snap-type: both mandatory;
}
.snap {
position: absolute;
width: 200px;
height: 200px;
background-color: blue;
scroll-snap-align: start;
}
#space {
position: absolute;
width: 1000px;
height: 1000px;
}
.left {
left: 0;
}
.top {
top: 0;
}
.right {
left: 400px;
}
.bottom {
top: 400px;
}

View file

@ -0,0 +1,64 @@
const KEY_CODE_MAP = {
'ArrowLeft': '\uE012',
'ArrowUp': '\uE013',
'ArrowRight': '\uE014',
'ArrowDown': '\uE015',
'PageUp': '\uE00E',
'PageDown': '\uE00F',
'End': '\uE010',
'Home': '\uE011',
'Space': ' ',
};
// Send key event to the target element using test driver. Supports human
// friendly key names for common keyboard scroll operations e.g., arrow keys,
// page keys, etc.
async function keyPress(target, key) {
let code = key;
if (KEY_CODE_MAP.hasOwnProperty(key))
code = KEY_CODE_MAP[key];
// First move pointer on target and click to ensure it receives the key.
let actions = new test_driver.Actions()
.pointerMove(0, 0, {origin: target})
.pointerDown()
.pointerUp()
.keyDown(code)
.keyUp(code);
return actions.send();
}
// Use rAF to wait for the value of the getter function passed to not change for
// at least 15 frames or timeout after 1 second.
//
// Example usage:
// await waitForAnimationEnd(() => scroller.scrollTop);
function waitForAnimationEnd(getValue) {
const TIMEOUT = 1000; // milliseconds
const MAX_UNCHANGED_FRAMES = 15;
const start_time = performance.now();
let last_changed_frame = 0;
let last_value = getValue();
return new Promise((resolve, reject) => {
function tick(frames, time) {
// We requestAnimationFrame either for TIMEOUT milliseconds or until
// MAX_UNCHANGED_FRAMES with no change have been observed.
if (time - start_time > TIMEOUT ||
frames - last_changed_frame >= MAX_UNCHANGED_FRAMES) {
resolve();
} else {
current_value = getValue();
if (last_value != current_value) {
last_changed_frame = frames;
last_value = current_value;
}
requestAnimationFrame(tick.bind(this, frames + 1));
}
}
tick(0, start_time);
});
}