Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add test for wheel event groups #37445

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
139 changes: 139 additions & 0 deletions dom/events/scrolling/wheel-event-transactions-basic.html
@@ -0,0 +1,139 @@
<!DOCTYPE HTML>
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1">
<meta name="variant" content="?include=target-basic"/>
<meta name="variant" content="?include=scroll-over-scrollable-child"/>
<meta name="variant" content="?include=transaction-not-bound-to-scroll-frame"/>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-actions.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/common/subset-tests-by-key.js"></script>
<script src="scroll_support.js"></script>
<style>
body {
margin: 0;
padding: 0;
height: 200vh;
}

.spacer {
width: 100%;
height: 25px;
padding: 0;
margin: 0;
}

#scrollableDiv {
width: 100%;
height: 500px;
overflow: scroll;
background: yellow;
}

#innerDiv {
width: 100%;
height: 4000px;
background: red;
}

</style>
<head>
<body onload=runTest()>
<div id="firstRootSpacer" class="spacer" style="background: cyan"></div>
<div id="secondRootSpacer" class="spacer" style="background: magenta"></div>
<div id="scrollableDiv">
<div id="innerDiv">
<div id="firstInnerSpacer" class="spacer" style="background: green">
</div>
<div id="secondInnerSpacer" class="spacer" style="background: blue">
</div>
</div>
</div>
</body>

<script>

let variants = [
// Ensure that the wheel transaction fires all wheel events to the initial
// target.
{
key: 'target-basic',
origin: "viewport",
scrollX: 40,
scrollY: 2,
scrollingElement: document.scrollingElement,
targetElement: firstRootSpacer,
title: 'Wheel events should be captured to one target #1',
},
// Ensure that the wheel transaction fires all wheel events to the initial
// target, even when another scroll frame is under the mouse cursor.
{
key: 'scroll-over-scrollable-child',
origin: "viewport",
scrollX: 40,
scrollY: 27,
scrollingElement: document.scrollingElement,
targetElement: secondRootSpacer,
title: 'Wheel events should be captured to one target #2',
},
// Ensure that the wheel transaction targets the topmost-element, which is
// not the scrollable element.
{
key: 'transaction-not-bound-to-scroll-frame',
origin: innerDiv,
scrollX: 40,
scrollY: 2,
scrollingElement: scrollableDiv,
targetElement: innerDiv,
title: 'The wheel event transactions target may not be a scroll frame',
},
];

function runTest() {
async function testBasic(testInfo, t) {
await waitForCompositorReady();

await waitForCompositorCommit();

let wheelEventTargets = [];
function pushTargetToWheelEventTargets(e) {
wheelEventTargets.push(e.target)
}

window.addEventListener("wheel", pushTargetToWheelEventTargets, {passive: true});

// Scroll past the boundary of the original element to ensure all events in
// transaction have the same target.
await new test_driver.Actions()
.addWheel("wheel1")
.scroll(testInfo.scrollX, testInfo.scrollY, 0, 30, {origin: testInfo.origin})
.pause(1)
.scroll(testInfo.scrollX, testInfo.scrollY, 0, 30, {origin: testInfo.origin})
.pause(1)
.scroll(testInfo.scrollX, testInfo.scrollY, 0, 30, {origin: testInfo.origin})
.send();

// TODO(dlrobertson): Use the scrollend event here to wait for the
// wheel scroll to finish instead of waitForAnimationEnd().
await waitForAnimationEnd(() => { return testInfo.scrollingElement.scrollTop; });
await waitForCompositorCommit();

// Ensure that all the captured wheel events are the expected target.
wheelEventTargets.forEach((wheelEventTarget, i) => {
assert_equals(wheelEventTarget, testInfo.targetElement,
"Wheel event at index `" + i + "` does not have the expected target");
});

assert_greater_than(testInfo.scrollingElement.scrollTop, 0,
"The scrolling element has scrolled");
}

variants.forEach((testInfo) => {
subsetTestByKey(testInfo.key, promise_test, t => testBasic(testInfo, t), testInfo.title);
});
}
</script>
</html>
@@ -0,0 +1,100 @@
<!DOCTYPE HTML>
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-actions.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="scroll_support.js"></script>
<style>
body {
margin: 0;
padding: 0;
height: 200vh;
}

#initial {
background: red;
width: 100%;
height: 25px;
padding: 0;
margin: 0;
}

#second {
background: green;
width: 100%;
height: 200vh;
padding: 0;
margin: 0;
}

</style>
<head>
<body>
<div id="initial"></div>
<div id="second"></div>
</body>

<script>

promise_test(async (t) => {
await new Promise(resolve => addEventListener("load", resolve, {once: true}));

await waitForCompositorReady();

await waitForCompositorCommit();

let firstEventTargets = [];
let secondEventTargets = [];
let isFirstGroup = true;
window.addEventListener("wheel", (e) => {
if (isFirstGroup) {
firstEventTargets.push(e.target);
} else {
secondEventTargets.push(e.target);
}
}, {passive: true});

await waitForCompositorCommit();

// The first action chain should target the initial element
await new test_driver.Actions()
.addWheel("wheel1")
.scroll(40, 2, 0, 30, {origin: "viewport"})
.send();

// Start logging event targets in the second transaction
isFirstGroup = false;

// The second chain should target the second element and the prior wheel event
// group should have no impact on this action chain.
await new test_driver.Actions()
.addWheel("wheel1")
.scroll(40, 30, 0, 30, {origin: "viewport"})
.send();

// TODO(dlrobertson): Use the scrollend event here to wait for the
// wheel scroll to finish instead of waitForAnimationEnd().
await waitForAnimationEnd(() => { return document.scrollingElement.scrollTop; });
await waitForCompositorCommit();

assert_greater_than(firstEventTargets.length, 0,
"There should be at least one event in the first transaction");
assert_greater_than(secondEventTargets.length, 0,
"There should be at least one event in the second transaction");

firstEventTargets.forEach((wheelEventTarget, i) => {
assert_equals(wheelEventTarget, initial,
"Wheel event at index `" + i + "` did not target the initial element");
});

secondEventTargets.forEach((wheelEventTarget, i) => {
assert_equals(wheelEventTarget, second,
"Wheel event at index `" + i + "` did not target the second element");
});
}, "Two separate webdriver action chains should have different wheel event transactions");
</script>
</html>
@@ -0,0 +1,99 @@
<!DOCTYPE HTML>
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1">
<meta name="variant" content="?include=none"/>
<meta name="variant" content="?include=contents"/>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-actions.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/common/subset-tests-by-key.js"></script>
<script src="scroll_support.js"></script>
<style>
body {
margin: 0;
padding: 0;
height: 200vh;
}

.spacer {
width: 100%;
height: 25px;
padding: 0;
margin: 0;
}

</style>
<head>
<body onload=runTest()>
<div id="initialTarget" class="spacer" style="background: red"></div>
<div id="firstRootSpacer" class="spacer" style="background: green"></div>
<div id="secondRootSpacer" class="spacer" style="background: blue"></div>
</body>

<script>

let variants = [
"none",
"contents",
]

function runTest() {
async function testDisplayChange(display, t) {
await waitForCompositorReady();

await waitForCompositorCommit();

let wheelEventTargets = [];
let makeInitialTargetNone = false;

// Modify the initial element the wheel event is targetted at to
// display: <variant> once we fire the first wheel event, then log
// the subsequent wheel event targets.
function makeInitialElementNone(e) {
wheelEventTargets.push(e.target);
if (!makeInitialTargetNone) {
makeInitialTargetNone = true;
e.target.style.display = display;
}
}
window.addEventListener("wheel", makeInitialElementNone, {passive: true});

await waitForCompositorCommit();

await new test_driver.Actions()
.addWheel("wheel1")
.scroll(40, 2, 0, 30, {origin: "viewport"})
.pause(1)
.scroll(40, 2, 0, 30, {origin: "viewport"})
.send();

// TODO(dlrobertson): Use the scrollend event here to wait for the
// wheel scroll to finish instead of waitForAnimationEnd().
await waitForAnimationEnd(() => { return document.scrollingElement.scrollTop; });
await waitForCompositorCommit();

// The first wheel event should be targetted at the modified element.
assert_equals(wheelEventTargets.shift(), initialTarget,
"Initial wheel event is has the modified element as the target");

wheelEventTargets.forEach((wheelEventTarget, i) => {
// TODO(dlrobertson): This assertion is pretty weak, but browsers seem to disagree
// on what element the event should target. Find out what the target should be here
// and make this assertion more restrictive.
assert_not_equals(wheelEventTarget, initialTarget,
"Wheel event at index `" + i + "` targetted the initial element");
});

assert_greater_than(document.scrollingElement.scrollTop, 0, "The document has scrolled");
}

variants.forEach((variant) => {
subsetTestByKey(variant, promise_test, t => testDisplayChange(variant, t),
"Modify the initial wheel event target to display:" + variant);
});
}
</script>
</html>