From dc2060fc7b4f67228523524fa73d587f82ebfc45 Mon Sep 17 00:00:00 2001 From: R Midhun Suresh Date: Wed, 16 Jul 2025 20:40:05 +0530 Subject: [PATCH] Fix flaky scrolling (#30329) There are two potential problems here: 1. mouse.scroll returns before the scroll is completed 2. visibility check does not check if the element is actually in the viewport. I've added a helper function to make it easier to scroll to the end of an infinite list. --- .../room-list-panel/room-list.spec.ts | 11 ++++------ playwright/pages/ElementAppPage.ts | 22 +++++++++++++++++++ 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/playwright/e2e/left-panel/room-list-panel/room-list.spec.ts b/playwright/e2e/left-panel/room-list-panel/room-list.spec.ts index 1f965ffb8f..a91a0c38d0 100644 --- a/playwright/e2e/left-panel/room-list-panel/room-list.spec.ts +++ b/playwright/e2e/left-panel/room-list-panel/room-list.spec.ts @@ -49,8 +49,7 @@ test.describe("Room list", () => { // Put focus on the room list await roomListView.getByRole("gridcell", { name: "Open room room29" }).click(); // Scroll to the end of the room list - await page.mouse.wheel(0, 1000); - await expect(roomListView.getByRole("gridcell", { name: "Open room room0" })).toBeVisible(); + await app.scrollListToBottom(page.locator(".mx_RoomList_List")); await expect(roomListView).toMatchScreenshot("room-list-scrolled.png"); }); @@ -120,10 +119,8 @@ test.describe("Room list", () => { // Put focus on the room list await roomListView.getByRole("gridcell", { name: "Open room room28" }).click(); - while (!(await roomItem.isVisible())) { - // Scroll to the end of the room list - await page.mouse.wheel(0, 1000); - } + // Scroll to the end of the room list + await app.scrollListToBottom(page.locator(".mx_RoomList_List")); // The room decoration should have the muted icon await expect(roomItem.getByTestId("notification-decoration")).toBeVisible(); @@ -144,7 +141,7 @@ test.describe("Room list", () => { // Put focus on the room list await roomListView.getByRole("gridcell", { name: "Open room room29" }).click(); // Scroll to the end of the room list - await page.mouse.wheel(0, 1000); + await app.scrollListToBottom(page.locator(".mx_RoomList_List")); await expect(roomListView.getByRole("gridcell", { name: "Open room room0" })).toBeVisible(); await roomListView.getByRole("gridcell", { name: "Open room room0" }).click(); diff --git a/playwright/pages/ElementAppPage.ts b/playwright/pages/ElementAppPage.ts index afc814b3e1..abddc9c644 100644 --- a/playwright/pages/ElementAppPage.ts +++ b/playwright/pages/ElementAppPage.ts @@ -213,4 +213,26 @@ export class ElementAppPage { .getByRole("button", { name: "Dismiss" }) .click(); } + + /** + * Scroll an infinite list to the bottom. + * @param list The element to scroll + */ + public async scrollListToBottom(list: Locator): Promise { + // First hover the mouse over the element that we want to scroll + await list.hover(); + + const needsScroll = async () => { + // From https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight#determine_if_an_element_has_been_totally_scrolled + const fullyScrolled = await list.evaluate( + (e) => Math.abs(e.scrollHeight - e.clientHeight - e.scrollTop) <= 1, + ); + return !fullyScrolled; + }; + + // Scroll the element until we detect that it is fully scrolled + do { + await this.page.mouse.wheel(0, 1000); + } while (await needsScroll()); + } }