Skip to content

Commit 00f763b

Browse files
authored
test: fix flaky drawer open and column sort timing issues (#15677)
### What Fixed three flaky list view e2e tests: "should persist per-page limit in list drawer", "should sort", and "should sort without resetting column preferences". <img width="1200" height="224" alt="Screenshot 2026-02-18 at 2 47 24 PM" src="https://github.com/user-attachments/assets/ac4e2147-8925-4626-ab1f-8e33ab6c1a3e" /> ### Why The `drawer--is-open` and `sort-column--active` classes weren't applied immediately after clicking buttons. Tests were checking visibility before React finished re-rendering, causing intermittent timeouts in CI. ### How Added explicit waits for drawer and sort button states before running assertions. The drawer now waits for `state: 'visible'` after clicking "Select posts", and the sortColumn helper waits for the active state on sort buttons before checking the URL.
1 parent a66e844 commit 00f763b

File tree

3 files changed

+29
-9
lines changed

3 files changed

+29
-9
lines changed

test/__helpers/e2e/columns/sortColumn.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,18 @@ export const sortColumn = async (
2525
const downChevron = columnHeading.locator('button.sort-column__desc')
2626

2727
if (options.targetState === 'asc') {
28+
await upChevron.waitFor({ state: 'visible' })
2829
await upChevron.click()
29-
await expect(columnHeading.locator('button.sort-column__asc.sort-column--active')).toBeVisible()
30+
const activeButton = columnHeading.locator('button.sort-column__asc.sort-column--active')
31+
await activeButton.waitFor({ state: 'visible' })
32+
await expect(activeButton).toBeVisible()
3033
await page.waitForURL(() => page.url().includes(`sort=${options.fieldPath}`))
3134
} else if (options.targetState === 'desc') {
35+
await downChevron.waitFor({ state: 'visible' })
3236
await downChevron.click()
33-
await expect(
34-
columnHeading.locator('button.sort-column__desc.sort-column--active'),
35-
).toBeVisible()
37+
const activeButton = columnHeading.locator('button.sort-column__desc.sort-column--active')
38+
await activeButton.waitFor({ state: 'visible' })
39+
await expect(activeButton).toBeVisible()
3640
await page.waitForURL(() => page.url().includes(`sort=-${options.fieldPath}`))
3741
}
3842
}

test/__helpers/e2e/goToNextPage.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ export const goToNextPage = async (
1515
} = { targetPage: 2, affectsURL: true },
1616
) => {
1717
const pageControls = (options.scope || page).locator('.paginator')
18-
await pageControls.locator('button').nth(1).click()
18+
const nextButton = pageControls.locator('button').nth(1)
19+
await nextButton.waitFor({ state: 'visible' })
20+
await nextButton.click()
1921

2022
if (options.affectsURL) {
2123
const regex = new RegExp(`page=${options.targetPage}(?:&|$)`)
@@ -40,7 +42,9 @@ export const goToPreviousPage = async (
4042
},
4143
) => {
4244
const pageControls = (options.scope || page).locator('.paginator')
43-
await pageControls.locator('button').nth(0).click()
45+
const prevButton = pageControls.locator('button').nth(0)
46+
await prevButton.waitFor({ state: 'visible' })
47+
await prevButton.click()
4448

4549
if (options.affectsURL) {
4650
const regex = new RegExp(`page=${options.targetPage}(?:&|$)`)

test/admin/e2e/list-view/e2e.spec.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1628,9 +1628,12 @@ describe('List View', () => {
16281628
await page.goto(withListViewUrl.list)
16291629

16301630
// Open the list drawer via the "Select posts" button
1631-
await page.locator('button:has-text("Select posts")').click()
1631+
const selectButton = page.locator('button:has-text("Select posts")')
1632+
await selectButton.waitFor({ state: 'visible' })
1633+
await selectButton.click()
16321634

16331635
const listDrawer = page.locator('.list-drawer.drawer--is-open')
1636+
await listDrawer.waitFor({ state: 'visible' })
16341637
await expect(listDrawer).toBeVisible()
16351638

16361639
await expect(page.locator('.list-drawer .per-page')).toContainText('Per Page: 10')
@@ -1647,7 +1650,9 @@ describe('List View', () => {
16471650
await expect(listDrawer).toBeHidden()
16481651

16491652
// Reopen the drawer
1650-
await page.locator('button:has-text("Select posts")').click()
1653+
await selectButton.waitFor({ state: 'visible' })
1654+
await selectButton.click()
1655+
await listDrawer.waitFor({ state: 'visible' })
16511656
await expect(listDrawer).toBeVisible()
16521657

16531658
await expect(page.locator('.list-drawer .per-page')).toContainText('Per Page: 5')
@@ -1670,6 +1675,7 @@ describe('List View', () => {
16701675

16711676
test('should sort', async () => {
16721677
await page.reload()
1678+
await expect(page.locator(tableRowLocator)).toHaveCount(2)
16731679

16741680
await sortColumn(page, { fieldPath: 'number', targetState: 'asc' })
16751681

@@ -1783,9 +1789,15 @@ describe('List View', () => {
17831789
})
17841790

17851791
await page.goto(postsUrl.list)
1792+
await expect(page.locator(tableRowLocator).first()).toBeVisible()
17861793

17871794
// sort by title
1788-
await page.locator('#heading-title button.sort-column__asc').click()
1795+
const sortButton = page.locator('#heading-title button.sort-column__asc')
1796+
await sortButton.waitFor({ state: 'visible' })
1797+
await sortButton.click()
1798+
await page
1799+
.locator('#heading-title button.sort-column__asc.sort-column--active')
1800+
.waitFor({ state: 'visible' })
17891801
await page.waitForURL(/sort=title/)
17901802

17911803
// enable a column that is _not_ part of this collection's default columns

0 commit comments

Comments
 (0)