mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
chore: e2e tests reliability (#46496)
## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES/NO ## What kind of change does this PR introduce? Bug fix, feature, docs update, ... ## What is the current behavior? Please link any relevant issues here. ## What is the new behavior? Feel free to include screenshots if it includes visual changes. ## Additional context Add any other context or screenshots. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Accessibility** * Improved screen-reader label for table row action menus so table controls are clearer for assistive‑technology users. * **Tests** * Enhanced end-to-end test reliability: tightened selectors, added dialog/toast visibility and API-wait synchronization, scoped lookup fixes, removed redundant cleanup helper, and updated test setup to mark a terms-of-service dismissal to reduce flakiness. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
1 parent
d691073f02
commit
ac59de1f9e
6 files changed
+56
-50
No files matched your search
@@ -400,8 +400,10 @@ test.describe('Cron Jobs', () => {
|
||||
// The test job should still be visible in the grid (minimal mode shows jobs without last run)
|
||||
await expect(page.getByRole('row', { name: new RegExp(testJobName) })).toBeVisible()
|
||||
|
||||
// The "Learn more" button should be visible
|
||||
await expect(page.getByRole('button', { name: 'Learn more' })).toBeVisible()
|
||||
// An alert about high query costs should be visible and contain a "Learn more" button
|
||||
await expect(
|
||||
page.getByRole('alert').getByRole('button', { name: 'Learn more' })
|
||||
).toBeVisible()
|
||||
|
||||
// Remove the route mock for subsequent tests
|
||||
await page.unroute('**/pg-meta/*/query**')
|
||||
@@ -441,8 +443,8 @@ test.describe('Cron Jobs', () => {
|
||||
timeout: 15000,
|
||||
})
|
||||
|
||||
// Click the "Learn more" button to open the dialog
|
||||
await page.getByRole('button', { name: 'Learn more' }).click()
|
||||
// Click the "Learn more" button in the alert to open the dialog
|
||||
await page.getByRole('alert').getByRole('button', { name: 'Learn more' }).click()
|
||||
|
||||
// The dialog should open with the explanation
|
||||
await expect(
|
||||
@@ -504,7 +506,7 @@ test.describe('Cron Jobs', () => {
|
||||
).toBeVisible({
|
||||
timeout: 15000,
|
||||
})
|
||||
await page.getByRole('button', { name: 'Learn more' }).click()
|
||||
await page.getByRole('alert').getByRole('button', { name: 'Learn more' }).click()
|
||||
|
||||
// Wait for dialog to open
|
||||
await expect(
|
||||
|
||||
@@ -301,6 +301,7 @@ test.describe('Database', () => {
|
||||
|
||||
// create a new table
|
||||
await page.getByRole('button', { name: 'New table' }).click()
|
||||
await expect(page.getByRole('dialog')).toBeVisible()
|
||||
await page.getByLabel('Name', { exact: true }).fill(databaseTableNameNew)
|
||||
const createTableWait = createApiResponseWaiter(
|
||||
page,
|
||||
@@ -313,12 +314,23 @@ test.describe('Database', () => {
|
||||
// validate table creation
|
||||
await createTableWait
|
||||
await waitForDatabaseToLoad(page, ref)
|
||||
await expect(page.getByRole('dialog')).not.toBeVisible()
|
||||
|
||||
await expect(page.getByText(databaseTableNameNew, { exact: true })).toBeVisible()
|
||||
await expect(page.getByText('Table pw_database_table_crud_new is good to go!')).toBeVisible()
|
||||
await page.getByRole('button', { name: 'Close toast' }).click()
|
||||
|
||||
// edit a new table
|
||||
await page.getByRole('row', { name: databaseTableNameNew }).getByRole('button').last().click()
|
||||
await page
|
||||
.getByRole('row', { name: databaseTableNameNew })
|
||||
.getByRole('button', { name: `Table ${databaseTableNameNew} actions` })
|
||||
.click()
|
||||
await page.getByRole('menuitem', { name: 'Edit table' }).click()
|
||||
await page.getByTestId('table-name-input').fill(databaseTableNameUpdated)
|
||||
await expect(page.getByRole('dialog')).toBeVisible()
|
||||
await expect(page.getByText(`Update table ${databaseTableNameNew}`)).toBeVisible()
|
||||
// Ensure table data is loaded
|
||||
await expect(page.getByLabel('Name', { exact: true })).toHaveValue(databaseTableNameNew)
|
||||
await page.getByLabel('Name', { exact: true }).fill(databaseTableNameUpdated)
|
||||
const updateTableWait = createApiResponseWaiter(
|
||||
page,
|
||||
'pg-meta',
|
||||
@@ -331,14 +343,19 @@ test.describe('Database', () => {
|
||||
await updateTableWait
|
||||
await waitForDatabaseToLoad(page, ref)
|
||||
await expect(page.getByText(databaseTableNameUpdated, { exact: true })).toBeVisible()
|
||||
await expect(
|
||||
page.getByText(`Successfully updated ${databaseTableNameUpdated}!`)
|
||||
).toBeVisible()
|
||||
await page.getByRole('button', { name: 'Close toast' }).click()
|
||||
await expect(page.getByRole('dialog')).not.toBeVisible()
|
||||
|
||||
// duplicate table
|
||||
await page
|
||||
.getByRole('row', { name: databaseTableNameUpdated })
|
||||
.getByRole('button')
|
||||
.last()
|
||||
.getByRole('button', { name: `Table ${databaseTableNameUpdated} actions` })
|
||||
.click()
|
||||
await page.getByRole('menuitem', { name: 'Duplicate Table' }).click()
|
||||
await expect(page.getByRole('dialog')).toBeVisible()
|
||||
await page.getByLabel('Name').fill(databaseTableNameDuplicate)
|
||||
await page.getByLabel('Description').fill('')
|
||||
const duplicateTableWait = createApiResponseWaiter(page, 'pg-meta', ref, 'query?key=')
|
||||
@@ -348,14 +365,21 @@ test.describe('Database', () => {
|
||||
await duplicateTableWait
|
||||
await waitForDatabaseToLoad(page, ref)
|
||||
await expect(page.getByText(databaseTableNameDuplicate, { exact: true })).toBeVisible()
|
||||
await expect(
|
||||
page.getByText(
|
||||
`Table ${databaseTableNameUpdated} has been successfully duplicated into ${databaseTableNameDuplicate}!`
|
||||
)
|
||||
).toBeVisible()
|
||||
await page.getByRole('button', { name: 'Close toast' }).click()
|
||||
await expect(page.getByRole('dialog')).not.toBeVisible()
|
||||
|
||||
// delete tables
|
||||
await page
|
||||
.getByRole('row', { name: `${databaseTableNameDuplicate}` })
|
||||
.getByRole('button')
|
||||
.last()
|
||||
.getByRole('row', { name: databaseTableNameUpdated })
|
||||
.getByRole('button', { name: `Table ${databaseTableNameUpdated} actions` })
|
||||
.click()
|
||||
await page.getByRole('menuitem', { name: 'Delete table' }).click()
|
||||
await expect(page.getByRole('dialog')).toBeVisible()
|
||||
await page.getByRole('checkbox', { name: 'Drop table with cascade?' }).check()
|
||||
const deleteDuplicateWait = createApiResponseWaiter(
|
||||
page,
|
||||
@@ -365,13 +389,14 @@ test.describe('Database', () => {
|
||||
)
|
||||
await page.getByRole('button', { name: 'Delete' }).click()
|
||||
await deleteDuplicateWait
|
||||
await expect(page.getByRole('dialog')).not.toBeVisible()
|
||||
|
||||
await page
|
||||
.getByRole('row', { name: `${databaseTableNameUpdated}` })
|
||||
.getByRole('button')
|
||||
.last()
|
||||
.getByRole('row', { name: databaseTableNameDuplicate })
|
||||
.getByRole('button', { name: `Table ${databaseTableNameDuplicate} actions` })
|
||||
.click()
|
||||
await page.getByRole('menuitem', { name: 'Delete table' }).click()
|
||||
await expect(page.getByRole('dialog')).toBeVisible()
|
||||
await page.getByRole('checkbox', { name: 'Drop table with cascade?' }).check()
|
||||
const deleteUpdatedWait = createApiResponseWaiter(
|
||||
page,
|
||||
@@ -381,6 +406,7 @@ test.describe('Database', () => {
|
||||
)
|
||||
await page.getByRole('button', { name: 'Delete' }).click()
|
||||
await deleteUpdatedWait
|
||||
await expect(page.getByRole('dialog')).not.toBeVisible()
|
||||
|
||||
// validate navigating to table editor from database table page
|
||||
await page.getByRole('row', { name: databaseTableName }).getByRole('button').last().click()
|
||||
@@ -449,12 +475,15 @@ test.describe('Database', () => {
|
||||
// wait for response + validate
|
||||
await columnCreateWait
|
||||
await columnCreateRefreshWait
|
||||
await expect(page.getByRole('dialog')).not.toBeVisible()
|
||||
|
||||
const columnDatabase2Row = page.getByRole('row', { name: databaseColumnName2 })
|
||||
await expect(columnDatabase2Row).toContainText(databaseColumnName2)
|
||||
await expect(columnDatabase2Row).toContainText('numeric')
|
||||
|
||||
// update table column
|
||||
await columnDatabase2Row.getByRole('button', { name: 'Edit' }).click()
|
||||
await expect(page.getByRole('dialog')).toBeVisible()
|
||||
await page.getByLabel('name').fill(databaseColumnName3)
|
||||
const columnUpdateWait = createApiResponseWaiter(
|
||||
page,
|
||||
@@ -473,6 +502,7 @@ test.describe('Database', () => {
|
||||
// wait for response + validate
|
||||
await columnUpdateWait
|
||||
await columnUpdateRefreshWait
|
||||
await expect(page.getByRole('dialog')).not.toBeVisible()
|
||||
|
||||
// delete table column
|
||||
const columnDatabase3Row = page.getByRole('row', { name: databaseColumnName3 })
|
||||
|
||||
@@ -15,6 +15,7 @@ import { test } from '../utils/test.js'
|
||||
test.describe('Realtime Inspector', () => {
|
||||
test.beforeEach(async ({ page, ref }) => {
|
||||
await navigateToRealtimeInspector(page, ref)
|
||||
await page.waitForResponse(new RegExp(`/platform/projects/${ref}/settings`))
|
||||
})
|
||||
|
||||
test.describe('Basic Inspector UI', () => {
|
||||
|
||||
@@ -3,7 +3,7 @@ import { expect, Page } from '@playwright/test'
|
||||
import { createTableWithRLS, dropTable } from '../utils/db/queries.js'
|
||||
import { test, withSetupCleanup } from '../utils/test.js'
|
||||
import { toUrl } from '../utils/to-url.js'
|
||||
import { createApiResponseWaiter, waitForApiResponse } from '../utils/wait-for-response.js'
|
||||
import { createApiResponseWaiter } from '../utils/wait-for-response.js'
|
||||
|
||||
/**
|
||||
* Helper function to navigate to policies page and wait for it to load
|
||||
@@ -15,39 +15,6 @@ const navigateToPoliciesPage = async (page: Page, ref: string) => {
|
||||
await page.waitForTimeout(500)
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to delete a policy if it exists
|
||||
*/
|
||||
const deletePolicyIfExists = async (page: Page, ref: string, policyNameToDelete: string) => {
|
||||
// Look for the policy in the table
|
||||
const policyButton = page.getByRole('button', { name: policyNameToDelete })
|
||||
const policyExists = (await policyButton.count()) > 0
|
||||
|
||||
if (policyExists) {
|
||||
// Click the policy row actions button
|
||||
await page.getByTestId(`policy-${policyNameToDelete}-actions-button`).click()
|
||||
await page.waitForTimeout(200)
|
||||
|
||||
// Click delete
|
||||
await page.getByText('Delete', { exact: true }).click()
|
||||
await page.waitForTimeout(200)
|
||||
|
||||
const waitForDeletion = waitForApiResponse(page, 'pg-meta', ref, 'query?key=')
|
||||
// Confirm deletion
|
||||
await page.getByRole('button', { name: 'Delete' }).click()
|
||||
|
||||
// Wait for deletion to complete
|
||||
await waitForDeletion
|
||||
|
||||
await expect(
|
||||
page.getByText('Successfully removed policy'),
|
||||
'Policy deletion confirmation should be visible'
|
||||
).toBeVisible({ timeout: 50000 })
|
||||
|
||||
await page.waitForTimeout(500)
|
||||
}
|
||||
}
|
||||
|
||||
test.describe('RLS Policies', () => {
|
||||
test.describe('Policies Page', () => {
|
||||
test('should display policies page correctly', async ({ page, ref }) => {
|
||||
|
||||
@@ -26,6 +26,7 @@ export const test = base.extend<TestOptions>({
|
||||
`table-editor-queue-operations-banner-dismissed-${ref}`,
|
||||
JSON.stringify(true)
|
||||
)
|
||||
localStorage.setItem(`terms-of-service-update-2026-06-06`, JSON.stringify(true))
|
||||
}, ref)
|
||||
await use(page)
|
||||
},
|
||||
|
||||
Reference in new issue
Block a user