From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- .../css/css-scroll-snap-2/resources/common.js | 106 +++++++++++++++++++++ .../resources/user-scroll-common.js | 71 ++++++++++++++ 2 files changed, 177 insertions(+) create mode 100644 testing/web-platform/tests/css/css-scroll-snap-2/resources/common.js create mode 100644 testing/web-platform/tests/css/css-scroll-snap-2/resources/user-scroll-common.js (limited to 'testing/web-platform/tests/css/css-scroll-snap-2/resources') diff --git a/testing/web-platform/tests/css/css-scroll-snap-2/resources/common.js b/testing/web-platform/tests/css/css-scroll-snap-2/resources/common.js new file mode 100644 index 0000000000..1a2edab90b --- /dev/null +++ b/testing/web-platform/tests/css/css-scroll-snap-2/resources/common.js @@ -0,0 +1,106 @@ +function checkSnapEventSupport(event_type) { + if (event_type == "snapchanged") { + assert_true(window.onsnapchanged !== undefined, "snapchanged not supported"); + } else if (event_type == "snapchanging") { + assert_true(window.onsnapchanging !== undefined, "snapchanging not supported"); + } else { + assert_unreached(`Unknown snap event type selected: ${event_type}`); + } +} + +function assertSnapEvent(evt, expected_ids) { + assert_equals(evt.bubbles, false, "snap events don't bubble"); + assert_false(evt.cancelable, "snap events are not cancelable."); + const actual = Array.from(evt.snapTargets, el => el.id).join(","); + const expected = expected_ids.join(","); + assert_equals(actual, expected, "snap event supplied expected targets"); +} + +// This function holds logic intended to be used by tests for scroll snap +// events. +// |test_data| should contain: +// - |scroller|: the snap container being scrolled (or +// document.scrollingElement) +// - |scrolling_function|: this function should trigger the desired snap event +// when executed. +// - |expected_snap_targets|: a list of element ids which the triggered snap +// event should supply in SnapEvent.snapTargets. +// - |expected_scroll_offsets|: the scroll offsets at which the snap container +// should be after scrolling function has been +// executed. +// |event_type|: should be "snapchanged" or "snapchanging". +async function test_snap_event(test, test_data, event_type) { + checkSnapEventSupport(event_type); + await waitForScrollReset(test, test_data.scroller); + + let listener = test_data.scroller == + document.scrollingElement ? document : test_data.scroller; + + const event_promise = waitForSnapEvent(listener, event_type); + await test_data.scrolling_function(); + let evt = await event_promise; + + assertSnapEvent(evt, test_data.expected_snap_targets); + assert_approx_equals(test_data.scroller.scrollTop, + test_data.expected_scroll_offsets.y, 1, + "vertical scroll offset mismatch."); + assert_approx_equals(test_data.scroller.scrollLeft, + test_data.expected_scroll_offsets.x, 1, + "horizontal scroll offset mismatch."); +} + +async function test_snapchanged(test, test_data) { + await test_snap_event(test, test_data, "snapchanged"); +} + +function waitForEventUntil(event_target, event_type, wait_until) { + return new Promise(resolve => { + let result = null; + const listener = (evt) => { + result = evt; + }; + event_target.addEventListener(event_type, listener); + wait_until.then(() => { + event_target.removeEventListener(event_type, listener); + resolve(result); + }); + }); +} + +function waitForEventsUntil(event_target, event_type, wait_until) { + return new Promise(resolve => { + let result = []; + const listener = (evt) => { + result.push(evt); + }; + event_target.addEventListener(event_type, listener); + wait_until.then(() => { + event_target.removeEventListener(event_type, listener); + resolve(result); + }); + }); +} + +// Proxy a wait for a snap event. We want to avoid having a test +// timeout in the event of an expected snap event not firing in a particular +// test case as that would cause the entire file to fail. +// Snap events should fire before scrollend, so if a scroll should happen, wait +// for a scrollend event. Otherwise, just do a rAF-based wait. +function waitForSnapEvent(event_target, event_type, scroll_happens = true) { + return scroll_happens ? waitForEventUntil(event_target, event_type, + waitForScrollendEventNoTimeout(event_target)) + : waitForEventUntil(event_target, event_type, + waitForAnimationFrames(2)); +} + +function waitForSnapChangedEvent(event_target, scroll_happens = true) { + return waitForSnapEvent(event_target, "snapchanged", scroll_happens); +} + +function getScrollbarToScrollerRatio(scroller) { + // Ideally we'd subtract the length of the scrollbar thumb from + // the dividend but there isn't currently a way to get the + // scrollbar thumb length. + return scroller.clientHeight / + (scroller.scrollHeight - scroller.clientHeight); +} diff --git a/testing/web-platform/tests/css/css-scroll-snap-2/resources/user-scroll-common.js b/testing/web-platform/tests/css/css-scroll-snap-2/resources/user-scroll-common.js new file mode 100644 index 0000000000..6587aebd92 --- /dev/null +++ b/testing/web-platform/tests/css/css-scroll-snap-2/resources/user-scroll-common.js @@ -0,0 +1,71 @@ +// Helper functions for snapchanged-on-user-* tests. + +// This performs a touch scroll on |scroller| using the coordinates provided +// in |start_pos| and |end_pos|. +// It is meant for use in snapchanged & snapchanging tests for triggering snap +// events when touch scrolling from |start_pos| to |end_pos|. +function snap_event_touch_scroll_helper(start_pos, end_pos) { + return new test_driver.Actions() + .addPointer("TestPointer", "touch") + .pointerMove(Math.round(start_pos.x), Math.round(start_pos.y)) + .pointerDown() + .addTick() + .pause(200) + .pointerMove(Math.round(end_pos.x), Math.round(end_pos.y)) + .addTick() + .pointerUp() + .send(); +} + +// This drags the provided |scroller|'s scrollbar vertically by |drag_amt|. +// Snap event tests should provide a |drag_amt| that would result in a +// the desired snap event being triggered. +const vertical_offset_into_scrollbar = 30; +function snap_event_scrollbar_drag_helper(scroller, scrollbar_width, drag_amt) { + let x, y, bounds; + if (scroller == document.scrollingElement) { + bounds = document.documentElement.getBoundingClientRect(); + x = Math.round(window.innerWidth - scrollbar_width / 2); + } else { + bounds = scroller.getBoundingClientRect(); + x = Math.round(bounds.right - Math.round(scrollbar_width / 2)); + } + y = Math.round(bounds.top + vertical_offset_into_scrollbar); + return new test_driver.Actions() + .addPointer('TestPointer', 'mouse') + .pointerMove(x, y) + .pointerDown() + .pointerMove(x, Math.round(y + drag_amt)) + .addTick() + .pointerUp() + .send(); +} + +// This tests that snap event of type |event_type| don't fire for a user (wheel) +// scroll that snaps back to the same element. Snap events tests should provide +// a |delta| small enough that no change in |scroller|'s snap targets occurs at +// the end of the scroll. +async function test_no_snap_event(test, scroller, delta, event_type) { + const listening_element = scroller == document.scrollingElement + ? document : scroller; + checkSnapEventSupport(event_type); + await waitForScrollReset(test, scroller); + await waitForCompositorCommit(); + let snap_event_promise = waitForSnapEvent(listening_element, event_type); + // Set the scroll destination to just a little off (0, 0) top so we snap + // back to the top box. + await new test_driver.Actions().scroll(0, 0, delta, delta, + { origin: scroller }).send(); + let evt = await snap_event_promise; + assert_equals(evt, null, "no snap event since scroller is back to top"); + assert_equals(scroller.scrollTop, 0, "scroller snaps back to the top"); + assert_equals(scroller.scrollLeft, 0, "scroller snaps back to the left"); +} + +async function test_no_snapchanged(t, scroller, delta) { + await test_no_snap_event(t, scroller, delta, "snapchanged"); +} + +async function test_no_snapchanging(t, scroller, delta) { + await test_no_snap_event(t, scroller, delta, "snapchanging"); +} \ No newline at end of file -- cgit v1.2.3