From 2fdb59a90584f3112dcee839c9e0dc65f7e20b51 Mon Sep 17 00:00:00 2001 From: Alaister Young Date: Mon, 22 Jun 2026 21:37:04 +0800 Subject: [PATCH] test(e2e/studio): drop racy post-action waits in database specs (from #46424) (#47106) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow-up to #47077, extracted from the TanStack Start migration (#46424). Three `waitForResponse` waits in `database.spec.ts` were registered *after* their triggering action, so the response could resolve before the listener attached and the wait would time out (this surfaced under TanStack, where the data is SSR-streamed, but the waits are redundant on Next too). **Removed:** - Schema Visualizer *actions*: `waitForSchemaVisualizerToLoad(...'auth')` registered after the schema-selector click — the `focusTableInVisualizer` loop immediately below already auto-waits for the auth schema's tables. - table update / duplicate: `waitForDatabaseToLoad(...)` after the save mutation — the `toBeVisible` assertion right after each already waits for the list to refetch. - the now-unused `waitForDatabaseToLoad` / `waitForSchemaVisualizerToLoad` imports. The UI assertions are the real synchronization points, so behaviour is unchanged on Next. ## To test - Studio E2E `database.spec.ts` passes (the Schema Visualizer + Tables groups). ## Summary by CodeRabbit * **Tests** * Improved database e2e test reliability by optimizing synchronization logic and eliminating timing-sensitive helpers that could introduce flakiness during schema and table operations. Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com> --- e2e/studio/features/database.spec.ts | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/e2e/studio/features/database.spec.ts b/e2e/studio/features/database.spec.ts index 87c17866d32..597ff6a213b 100644 --- a/e2e/studio/features/database.spec.ts +++ b/e2e/studio/features/database.spec.ts @@ -6,12 +6,7 @@ import { createTable, dropTable, query } from '../utils/db/index.js' import { dismissToastsIfAny } from '../utils/dismiss-toast.js' import { test, withSetupCleanup } from '../utils/test.js' import { toUrl } from '../utils/to-url.js' -import { - createApiResponseWaiter, - waitForApiResponse, - waitForDatabaseToLoad, - waitForSchemaVisualizerToLoad, -} from '../utils/wait-for-response.js' +import { createApiResponseWaiter, waitForApiResponse } from '../utils/wait-for-response.js' async function focusTableInVisualizer(page: Page, tableName: string) { await page.getByTestId('find-table-selector').click() @@ -88,8 +83,12 @@ test.describe('Database', () => { // changing schema -> auth await page.getByTestId('schema-selector').click() await page.getByRole('option', { name: 'auth' }).click() - await waitForSchemaVisualizerToLoad(page, ref, 'auth') + // No waitForResponse for auth-infinite_tables here: it fires on the + // schema switch above and can resolve before a listener registered now + // attaches (and is SSR-streamed under TanStack) — the same race that + // flaked this test. focusTableInVisualizer below already auto-waits for + // the auth schema's tables to load. for (const tableName of ['users', 'sso_providers', 'saml_providers']) { await focusTableInVisualizer(page, tableName) await expect(page.getByText(tableName, { exact: true })).toBeVisible() @@ -340,9 +339,9 @@ test.describe('Database', () => { ) await page.getByRole('button', { name: 'Save' }).click() - // validate table update + // validate table update — the toBeVisible assertion below already waits + // for the list to refetch, so no racy post-mutation waitForResponse here. await updateTableWait - await waitForDatabaseToLoad(page, ref) await expect(page.getByText(databaseTableNameUpdated, { exact: true })).toBeVisible() await expect( page.getByText(`Successfully updated ${databaseTableNameUpdated}!`) @@ -362,9 +361,9 @@ test.describe('Database', () => { const duplicateTableWait = createApiResponseWaiter(page, 'pg-meta', ref, 'query?key=') await page.getByRole('button', { name: 'Save' }).click() - // validate table duplicate + // validate table duplicate — the toBeVisible assertion below already + // waits for the list to refetch, so no racy post-mutation wait here. await duplicateTableWait - await waitForDatabaseToLoad(page, ref) await expect(page.getByText(databaseTableNameDuplicate, { exact: true })).toBeVisible() await expect( page.getByText(