From f37c5892763b395b9d68fddad2e32b1046dfb3c1 Mon Sep 17 00:00:00 2001 From: Elliot DeNolf Date: Mon, 1 Jun 2026 14:41:16 -0400 Subject: [PATCH] test: harden openListFilters against filter-toggle race in CI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The group-by E2E suite failed deterministically on CI (every recent main run) at openListFilters: `#list-controls-where.rah-static--height-auto` never became visible. CI traces show the Filters toggle ended with aria-expanded="false" — the open click was dropped. openListFilters decided whether to open the drawer from a point-in-time `filterContainer.isVisible()` reading, then clicked once and asserted. The container flickers visible mid-animation, and a preceding re-render (the group-by change applied just before in the failing test) can swallow the toggle's React state update on slower CI hardware, so the single click is lost and the drawer never opens. Drive the open state off the toggler's authoritative `aria-expanded` attribute and retry the toggle via expect().toPass() until it reports open, making the helper idempotent and resilient to the race. Does not reproduce locally (passes in every local config incl. 8x CPU throttle); root cause and fix are derived from the CI Playwright trace. --- test/__helpers/e2e/filters/openListFilters.ts | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/test/__helpers/e2e/filters/openListFilters.ts b/test/__helpers/e2e/filters/openListFilters.ts index ebd698ef4ed..37292cf9053 100644 --- a/test/__helpers/e2e/filters/openListFilters.ts +++ b/test/__helpers/e2e/filters/openListFilters.ts @@ -18,16 +18,23 @@ export const openListFilters = async ( ): Promise<{ filterContainer: Locator }> => { - await expect(page.locator(togglerSelector)).toBeVisible() - const filterContainer = page.locator(filterContainerSelector).first() + const toggler = page.locator(togglerSelector).first() + await expect(toggler).toBeVisible() - const isAlreadyOpen = await filterContainer.isVisible() + // Drive the drawer open off the toggler's `aria-expanded` state (the source of truth) + // rather than a point-in-time visibility check of the container. The container flickers + // visible mid-animation, and a preceding re-render (e.g. a group-by/sort change) can drop + // the open click before it updates React state. Retrying the toggle until `aria-expanded` + // reports open makes this idempotent and resilient to that race. + await expect(async () => { + if ((await toggler.getAttribute('aria-expanded')) !== 'true') { + await toggler.click() + } - if (!isAlreadyOpen) { - await page.locator(togglerSelector).first().click() - } + await expect(toggler).toHaveAttribute('aria-expanded', 'true') + }).toPass() await expect(page.locator(`${filterContainerSelector}.rah-static--height-auto`)).toBeVisible() - return { filterContainer } + return { filterContainer: page.locator(filterContainerSelector).first() } }