diff --git a/packages/twenty-e2e-testing/playwright.config.ts b/packages/twenty-e2e-testing/playwright.config.ts index 8ce700ec11..a57098b377 100644 --- a/packages/twenty-e2e-testing/playwright.config.ts +++ b/packages/twenty-e2e-testing/playwright.config.ts @@ -23,7 +23,7 @@ export default defineConfig({ forbidOnly: !!process.env.CI, retries: process.env.CI ? 2 : 0, workers: 1, // 1 worker = 1 test at the time, tests can't be parallelized - timeout: 30 * 1000, // timeout can be changed + timeout: process.env.CI ? 60_000 : 30 * 1000, // timeout can be changed use: { baseURL: process.env.FRONTEND_BASE_URL || 'http://localhost:3001', trace: 'retain-on-failure', // trace takes EVERYTHING from page source, records every single step, should be used only when normal debugging won't work @@ -32,7 +32,9 @@ export default defineConfig({ testIdAttribute: 'data-testid', // taken from Twenty source }, expect: { - timeout: 5000, + // CI runners are slow enough that post-mutation UI transitions routinely + // exceed 5s; locally keep the tight budget. + timeout: process.env.CI ? 15_000 : 5000, }, reporter: [ [process.env.CI ? 'github' : 'list'], diff --git a/packages/twenty-e2e-testing/tests/create-kanban-view.spec.ts b/packages/twenty-e2e-testing/tests/create-kanban-view.spec.ts index 31122f071a..0a8a1530e1 100644 --- a/packages/twenty-e2e-testing/tests/create-kanban-view.spec.ts +++ b/packages/twenty-e2e-testing/tests/create-kanban-view.spec.ts @@ -1,5 +1,8 @@ import { expect, test } from '../lib/fixtures/screenshot'; test.describe.serial('Create Kanban View', () => { +// Unique per run: retries of this serial group re-run field creation against +// the same database, and a duplicate label makes the form unsubmittable. +const industryLabel = `Industry ${Date.now()}`; test('Create Industry Select Field', async ({ page }) => { await page.getByTestId('workspace-dropdown').click(); await page.getByRole('link', { name: 'Settings' }).click(); @@ -9,7 +12,7 @@ test('Create Industry Select Field', async ({ page }) => { await page.getByRole('button', { name: 'New Field' }).click(); await page.getByRole('link', { name: 'Select', exact: true }).click(); await page.getByRole('textbox', { name: 'Employees' }).click(); - await page.getByRole('textbox', { name: 'Employees' }).fill('Industry'); + await page.getByRole('textbox', { name: 'Employees' }).fill(industryLabel); await page.getByRole('textbox').nth(1).click(); await page.getByRole('textbox').nth(1).press('ControlOrMeta+a'); await page.getByRole('textbox').nth(1).fill('Food'); @@ -19,8 +22,8 @@ test('Create Industry Select Field', async ({ page }) => { await page.getByRole('button', { name: 'Option 3' }).getByRole('textbox').fill('Travel'); await page.getByRole('button', { name: 'Save' }).click(); await page.waitForURL('**/objects/opportunities'); - await page.waitForSelector('text=Industry'); - await expect(page.getByText('Industry')).toBeVisible(); + await page.waitForSelector(`text=${industryLabel}`); + await expect(page.getByText(industryLabel)).toBeVisible(); }); test('Create Kanban View from Industry Select Field', async ({ page }) => { @@ -32,7 +35,7 @@ test('Create Kanban View from Industry Select Field', async ({ page }) => { await page.getByRole('button', { name: 'Table', exact: true }).click(); await page.getByText('Kanban').click(); await page.locator('[aria-controls="view-picker-kanban-field-options"]').click(); - await page.getByRole('option', { name: 'Industry' }).click(); + await page.getByRole('option', { name: industryLabel }).click(); await page.getByRole('button', { name: 'Create new view' }).click(); await expect(page.getByText('Food')).toBeVisible({ timeout: 30000 }); await expect(page.getByText('Tech')).toBeVisible();