Fix recent-input.html Flaky Test (#43131)
- Fix the flakiness
- Refactor/flatten the test for better readability
- Rename clickHandler to pointerdownHandler
Previous Undesired Outcome:
- assert_greater_than_equal(timeAfterClick, entry.lastInputTime)
sometimes fail.
Root Cause:
- The variable timeAfterClick is really a time after pointerdown and can
possibly happen before the click event processingStart.
- LastInputTime is the timestamp of the event comes in. And when a new
event show up later, it will get refreshed.
- Thus, if we try to compare pointdown's processingEnd with
lastInputTime of (for example) click event, then there's no guarantee
of one is greater the other.
This CL address it by:
- Remove timeAfterClick, which is not a very meaningful timestamp, since
we should never assume no more events coming in after.
- Compare lastInputTime with the layout shift startTime instead, for
which the sequence is always guaranteed.
Bug: 1441125
Change-Id: Id5fd368db78afd16df4b2a1e7b8924b32fa6a0f8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5026199
Reviewed-by: Michal Mocny <mmocny@chromium.org>
Commit-Queue: Aoyuan Zuo <zuoaoyuan@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1224360}
Co-authored-by: Aoyuan Zuo <zuoaoyuan@chromium.org>
diff --git a/event-timing/resources/event-timing-test-utils.js b/event-timing/resources/event-timing-test-utils.js
index 66aa05a..ddbaafb 100644
--- a/event-timing/resources/event-timing-test-utils.js
+++ b/event-timing/resources/event-timing-test-utils.js
@@ -3,15 +3,15 @@
// event handler if |callback| is provided.
async function clickOnElementAndDelay(id, delay, callback) {
const element = document.getElementById(id);
- const clickHandler = () => {
+ const pointerdownHandler = () => {
mainThreadBusy(delay);
if (callback) {
callback();
}
- element.removeEventListener("pointerdown", clickHandler);
+ element.removeEventListener("pointerdown", pointerdownHandler);
};
- element.addEventListener("pointerdown", clickHandler);
+ element.addEventListener("pointerdown", pointerdownHandler);
await test_driver.click(element);
}
diff --git a/layout-instability/recent-input.html b/layout-instability/recent-input.html
index 2779d4f..1aa9dfe 100644
--- a/layout-instability/recent-input.html
+++ b/layout-instability/recent-input.html
@@ -25,36 +25,42 @@
assert_implements(window.LayoutShift, 'Layout Instability is not supported.');
// Wait for the initial render to complete.
await waitForAnimationFrames(2);
-
const startTime = performance.now();
- return new Promise(resolve => {
+
+ const observerPromise = new Promise(resolve => {
const observer = new PerformanceObserver(
- t.step_func(entryList => {
- const endTime = performance.now();
- assert_equals(entryList.getEntries().length, 1);
- const entry = entryList.getEntries()[0];
- assert_equals(entry.entryType, "layout-shift");
- assert_equals(entry.name, "");
- assert_greater_than_equal(entry.startTime, startTime);
- assert_less_than_equal(entry.startTime, endTime);
- assert_equals(entry.duration, 0.0);
- // The layout shift value should be:
- // 300 * (100 + 60) * (60 / maxDimension) / viewport size.
- assert_equals(entry.value, computeExpectedScore(300 * (100 + 60), 60));
- // We should see that there was a click input entry.
- assert_equals(entry.hadRecentInput, true);
- assert_greater_than_equal(timeAfterClick, entry.lastInputTime);
- resolve();
- })
- );
- observer.observe({entryTypes: ['layout-shift']});
- // User input event
- clickAndBlockMain('button').then(() => {
- timeAfterClick = performance.now();
- // Modify the position of the div.
- document.getElementById('myDiv').style = "top: 60px";
- });
+ entryList => {
+ resolve(entryList);
+ }
+ ).observe({ entryTypes: ['layout-shift'] });
});
+
+ // User input event
+ await clickAndBlockMain('button');
+
+ // Modify the position of the div to trigger layout shift.
+ document.getElementById('myDiv').style = "top: 60px";
+
+ const layoutShiftEntryList = await observerPromise;
+ const endTime = performance.now();
+
+ assert_equals(layoutShiftEntryList.getEntries().length, 1);
+ const entry = layoutShiftEntryList.getEntries()[0];
+ assert_equals(entry.entryType, "layout-shift");
+ assert_equals(entry.name, "");
+ assert_greater_than(entry.startTime, startTime,
+ "The layout shift entry startTime should be greater than the test startTime.");
+ assert_less_than(entry.startTime, endTime,
+ "The layout shift entry startTime should be less than the test endTime.");
+ assert_equals(entry.duration, 0.0);
+ // The layout shift value should be:
+ // 300 * (100 + 60) * (60 / maxDimension) / viewport size.
+ assert_equals(entry.value, computeExpectedScore(300 * (100 + 60), 60));
+ // We should see that there was a click input entry.
+ assert_equals(entry.hadRecentInput, true);
+ assert_less_than(entry.lastInputTime, entry.startTime,
+ "The lastInputTime should be less than the layout shift startTime.");
+
}, 'Layout shift right after user input is observable via PerformanceObserver.');
</script>