From bc765b636fd62c71d17ac693b2aadf61292b224f Mon Sep 17 00:00:00 2001 From: Diego Imbert Date: Fri, 9 Jan 2026 12:37:43 +0100 Subject: [PATCH] nit test uid fix --- frontend/e2e/datatable.setup.ts | 82 ------------------------- frontend/e2e/datatable.spec.ts | 76 ++++++++++++++++++++++- frontend/e2e/resource-dbmanager.spec.ts | 3 +- frontend/playwright.config.ts | 13 +--- 4 files changed, 79 insertions(+), 95 deletions(-) delete mode 100644 frontend/e2e/datatable.setup.ts diff --git a/frontend/e2e/datatable.setup.ts b/frontend/e2e/datatable.setup.ts deleted file mode 100644 index 5a5c67c9b5..0000000000 --- a/frontend/e2e/datatable.setup.ts +++ /dev/null @@ -1,82 +0,0 @@ -import test, { expect, Page } from '@playwright/test' -import { Toast } from './utils' - -test('setup a datatable', async ({ page }) => { - if (!process.env.TEST_UNIQUE_ID) throw new Error('TEST_UNIQUE_ID was not generated') - await setupNewDataTable(page, `datatable_${process.env.TEST_UNIQUE_ID}`) -}) - -// This saves the datatable settings which will create race conditions with other tests -async function setupNewDataTable(page: Page, datatableId: string) { - // Navigate to workspace settings data tables tab - await page.goto('/workspace_settings?tab=windmill_data_tables') - - // Check if datatable already exists - let table = page.locator('table') - await table.waitFor({ state: 'visible' }) - let rows = await table.locator('tr:has(input[id="name"])').all() - for (const row of rows) { - const val = await row.locator('input[id="name"]').inputValue() - if (val === datatableId) return // Don't setup again if it already exists - } - - // Click on 'New Data Table' button - const newDataTableButton = page.locator('button:has-text("New Data Table")') - await newDataTableButton.click() - - // Find the second-to-last row in the table (last row contains the button) - const lastRow = table.locator('tr').nth(-2) - - // Fill the name input with generated ID - const nameInput = lastRow.locator('input[id="name"]') - await nameInput.fill(datatableId) - - // Verify database type is 'Instance' - const databaseTypeSelect = lastRow.locator('input[id="database-type-select"]') - await expect(databaseTypeSelect).toHaveValue('Instance') - - // Click on custom instance DB select and add new database - const customInstanceDbSelect = lastRow.locator('input[id="custom-instance-db-select"]') - await customInstanceDbSelect.waitFor({ state: 'visible' }) - await customInstanceDbSelect.click() - await customInstanceDbSelect.fill(datatableId) - - // Click on the "Add new:" button - const addNewButton = page.locator(`button:has-text("Add new: ")`) - await addNewButton.waitFor({ state: 'visible' }) - await addNewButton.click() - - // Click on Setup button - const setupButton = lastRow.locator('button:has-text("Setup")') - await setupButton.waitFor({ state: 'visible' }) - await setupButton.click() - - // Wait for popover to appear and click run setup button - const runSetupButton = page.locator('button[id="run-custom-instance-db-setup-button"]') - await runSetupButton.waitFor({ state: 'visible' }) - await runSetupButton.click() - - const confirmBtn = page.locator('button:has-text("Setup database")') - await confirmBtn.waitFor({ state: 'visible' }) - await confirmBtn.click() - - // Verify success toast appears - await Toast.expectSuccess(page, 'Setup successful') - - const closeModalBtn = page.locator('button[id="modal-close-button"]') - await closeModalBtn.click() - - const saveBtn = page.locator('button:has-text("Save")') - await saveBtn.click() - - if (await page.locator('text=Some databases are not setup').isVisible()) { - await page.locator('button:has-text("Save anyway")').click() - } - - // Verify success toast appears - await Toast.expectSuccess(page, 'saved successfully') - - return { datatableId } -} - -declare const process: any // ignore TS errors diff --git a/frontend/e2e/datatable.spec.ts b/frontend/e2e/datatable.spec.ts index 253c47a707..b514932b43 100644 --- a/frontend/e2e/datatable.spec.ts +++ b/frontend/e2e/datatable.spec.ts @@ -1,5 +1,6 @@ -import { test, Page } from '@playwright/test' +import { test, Page, expect } from '@playwright/test' import { runDbManagerAlterTableTest, runDbManagerSimpleCRUDTest } from './DbManagerPage' +import { Toast } from './utils' test.describe('Data tables', () => { test('simple CRUD with DB Manager', async ({ page }) => { @@ -14,6 +15,7 @@ test.describe('Data tables', () => { async function openDataTableDbManager(page: Page) { await page.goto('/workspace_settings?tab=windmill_data_tables') + await setupNewDataTable(page, `datatable_${process.env.TEST_UNIQUE_ID}`) const datatableId = `datatable_${process.env.TEST_UNIQUE_ID}` let table = page.locator('table') await table.waitFor({ state: 'visible' }) @@ -29,3 +31,75 @@ async function openDataTableDbManager(page: Page) { } declare const process: any // ignore TS errors + +async function setupNewDataTable(page: Page, datatableId: string) { + // Check if datatable already exists + let table = page.locator('table') + await table.waitFor({ state: 'visible' }) + let rows = await table.locator('tr:has(input[id="name"])').all() + for (const row of rows) { + const val = await row.locator('input[id="name"]').inputValue() + // Don't setup again if it already exists. + // The reason we do not use a unique datatable per test is that saving + // the settings create a race condition when multiple tests run in parallel. + if (val === datatableId) return + } + + // Click on 'New Data Table' button + const newDataTableButton = page.locator('button:has-text("New Data Table")') + await newDataTableButton.click() + + // Find the second-to-last row in the table (last row contains the button) + const lastRow = table.locator('tr').nth(-2) + + // Fill the name input with generated ID + const nameInput = lastRow.locator('input[id="name"]') + await nameInput.fill(datatableId) + + // Verify database type is 'Instance' + const databaseTypeSelect = lastRow.locator('input[id="database-type-select"]') + await expect(databaseTypeSelect).toHaveValue('Instance') + + // Click on custom instance DB select and add new database + const customInstanceDbSelect = lastRow.locator('input[id="custom-instance-db-select"]') + await customInstanceDbSelect.waitFor({ state: 'visible' }) + await customInstanceDbSelect.click() + await customInstanceDbSelect.fill(datatableId) + + // Click on the "Add new:" button + const addNewButton = page.locator(`button:has-text("Add new: ")`) + await addNewButton.waitFor({ state: 'visible' }) + await addNewButton.click() + + // Click on Setup button + const setupButton = lastRow.locator('button:has-text("Setup")') + await setupButton.waitFor({ state: 'visible' }) + await setupButton.click() + + // Wait for popover to appear and click run setup button + const runSetupButton = page.locator('button[id="run-custom-instance-db-setup-button"]') + await runSetupButton.waitFor({ state: 'visible' }) + await runSetupButton.click() + + const confirmBtn = page.locator('button:has-text("Setup database")') + await confirmBtn.waitFor({ state: 'visible' }) + await confirmBtn.click() + + // Verify success toast appears + await Toast.expectSuccess(page, 'Setup successful') + + const closeModalBtn = page.locator('button[id="modal-close-button"]') + await closeModalBtn.click() + + const saveBtn = page.locator('button:has-text("Save")') + await saveBtn.click() + + if (await page.locator('text=Some databases are not setup').isVisible()) { + await page.locator('button:has-text("Save anyway")').click() + } + + // Verify success toast appears + await Toast.expectSuccess(page, 'saved successfully') + + return { datatableId } +} diff --git a/frontend/e2e/resource-dbmanager.spec.ts b/frontend/e2e/resource-dbmanager.spec.ts index ead320acbe..6d021add04 100644 --- a/frontend/e2e/resource-dbmanager.spec.ts +++ b/frontend/e2e/resource-dbmanager.spec.ts @@ -54,7 +54,7 @@ async function setupNewResource( resourceType: DbType ): Promise<{ resourceName: string }> { // Generate unique ID with timestamp - const resourceName = `${resourceType}_${process.env.TEST_UNIQUE_ID}` + const resourceName = `${resourceType}_${Date.now()}` await page.goto('/resources') @@ -99,4 +99,3 @@ async function setupNewResourceAndOpenDbManager(page: Page, dbType: DbType) { const manageButton = resourceRow.locator('button:has-text("Manage")') await manageButton.click() } -declare const process: any // avoid TS errors diff --git a/frontend/playwright.config.ts b/frontend/playwright.config.ts index 269bf4d5a7..6aaec234c4 100644 --- a/frontend/playwright.config.ts +++ b/frontend/playwright.config.ts @@ -44,24 +44,17 @@ export default defineConfig({ testMatch: /.*\.spec\.ts/, /* Configure projects for major browsers */ projects: [ - { - name: 'setup', - testMatch: /.*\.setup\.ts/ - }, { name: 'chromium', - use: { ...devices['Desktop Chrome'] }, - dependencies: ['setup'] + use: { ...devices['Desktop Chrome'] } }, { name: 'firefox', - use: { ...devices['Desktop Firefox'] }, - dependencies: ['setup'] + use: { ...devices['Desktop Firefox'] } }, { name: 'webkit', - use: { ...devices['Desktop Safari'] }, - dependencies: ['setup'] + use: { ...devices['Desktop Safari'] } } ]