diff --git a/.github/workflows/tests-linux.yml b/.github/workflows/tests-linux.yml index de4c0b02e..1390539e1 100644 --- a/.github/workflows/tests-linux.yml +++ b/.github/workflows/tests-linux.yml @@ -49,7 +49,7 @@ jobs: e2e-test: name: Playwright E2E Tests (Linux) - timeout-minutes: 120 + timeout-minutes: 180 runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v6 diff --git a/.github/workflows/tests-macos.yml b/.github/workflows/tests-macos.yml index 143d47480..6677adfb1 100644 --- a/.github/workflows/tests-macos.yml +++ b/.github/workflows/tests-macos.yml @@ -49,7 +49,7 @@ jobs: e2e-test: name: Playwright E2E Tests (macOS) - timeout-minutes: 150 + timeout-minutes: 180 runs-on: macos-latest steps: - uses: actions/checkout@v6 diff --git a/.github/workflows/tests-windows.yml b/.github/workflows/tests-windows.yml index 69862de97..d774f65c4 100644 --- a/.github/workflows/tests-windows.yml +++ b/.github/workflows/tests-windows.yml @@ -58,7 +58,7 @@ jobs: e2e-test: name: Playwright E2E Tests (Windows) - timeout-minutes: 120 + timeout-minutes: 180 runs-on: windows-latest steps: - uses: actions/checkout@v6 diff --git a/playwright.config.ts b/playwright.config.ts index bee024111..ec7d9cba1 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -7,10 +7,10 @@ if (process.env.CI) { } export default defineConfig({ - fullyParallel: false, + fullyParallel: true, forbidOnly: !!process.env.CI, - retries: process.env.CI ? 2 : 0, - workers: process.env.CI ? undefined : 1, + retries: process.env.CI ? 2 : 1, + workers: undefined, reporter, use: { diff --git a/playwright/index.ts b/playwright/index.ts index aae5a8c2b..a94118ca4 100644 --- a/playwright/index.ts +++ b/playwright/index.ts @@ -2,6 +2,7 @@ import { test as baseTest, BrowserContext, ElectronApplication, Page, TestInfo } import * as path from 'path'; import * as os from 'os'; import * as fs from 'fs'; +import { version } from '../packages/bruno-app/package.json'; const electronAppPath = path.join(__dirname, '../packages/bruno-electron'); @@ -246,7 +247,8 @@ export const test = baseTest.extend< preferences: { onboarding: { hasLaunchedBefore: true, - hasSeenWelcomeModal: true + hasSeenWelcomeModal: true, + lastSeenVersion: version } } }; diff --git a/tests/asserts/add-assertions.spec.ts b/tests/asserts/add-assertions.spec.ts index fd8681171..309b039bc 100644 --- a/tests/asserts/add-assertions.spec.ts +++ b/tests/asserts/add-assertions.spec.ts @@ -13,7 +13,7 @@ import { } from '../utils/page'; import { buildCommonLocators } from '../utils/page/locators'; -test.describe('Assertions - BRU Collection', () => { +test.describe.serial('Assertions - BRU Collection', () => { test.beforeAll(async ({ pageWithUserData: page }) => { await page.locator('[data-app-state="loaded"]').waitFor({ timeout: 30000 }); diff --git a/tests/auth/oauth1/oauth1.spec.ts b/tests/auth/oauth1/oauth1.spec.ts index 0a88fc8a0..a4f6ffbdc 100644 --- a/tests/auth/oauth1/oauth1.spec.ts +++ b/tests/auth/oauth1/oauth1.spec.ts @@ -20,7 +20,7 @@ const selectAuthMode = async (page) => { await dropdownItem(page, 'OAuth 1.0').click(); }; -test.describe('OAuth 1.0 Authentication', () => { +test.describe.serial('OAuth 1.0 Authentication', () => { test.afterAll(async ({ page }) => { await closeAllCollections(page); }); diff --git a/tests/collection/draft/draft-indicator.spec.ts b/tests/collection/draft/draft-indicator.spec.ts index 69c2f18cd..48ccc96e1 100644 --- a/tests/collection/draft/draft-indicator.spec.ts +++ b/tests/collection/draft/draft-indicator.spec.ts @@ -1,7 +1,7 @@ import { test, expect } from '../../../playwright'; import { closeAllCollections, createCollection } from '../../utils/page'; -test.describe('Draft indicator in collection and folder settings', () => { +test.describe.serial('Draft indicator in collection and folder settings', () => { test.afterAll(async ({ page }) => { // cleanup: close all collections await closeAllCollections(page); diff --git a/tests/environments/color-picker/color-picker.spec.ts b/tests/environments/color-picker/color-picker.spec.ts index b74b105b3..cb3a31e9d 100644 --- a/tests/environments/color-picker/color-picker.spec.ts +++ b/tests/environments/color-picker/color-picker.spec.ts @@ -20,7 +20,7 @@ const hexToRgb = (hex: string): string => { return `rgb(${r}, ${g}, ${b})`; }; -test.describe('Color Picker Tests', () => { +test.describe.serial('Color Picker Tests', () => { test.afterAll(async ({ pageWithUserData: page }) => { await closeAllCollections(page); }); diff --git a/tests/graphql/query-builder/query-builder.spec.ts b/tests/graphql/query-builder/query-builder.spec.ts index 80df9ba67..cc02482df 100644 --- a/tests/graphql/query-builder/query-builder.spec.ts +++ b/tests/graphql/query-builder/query-builder.spec.ts @@ -23,7 +23,7 @@ const getVariablesEditorContent = async (page: Page) => { return await editor.evaluate((el) => (el as any).CodeMirror?.getValue() || '') as string; }; -test.describe('GraphQL Query Builder', () => { +test.describe.serial('GraphQL Query Builder', () => { test.afterAll(async ({ pageWithUserData: page }) => { await closeAllCollections(page); }); diff --git a/tests/import/insomnia/import-insomnia-v5-date-types.spec.ts b/tests/import/insomnia/import-insomnia-v5-date-types.spec.ts index 97ef02379..8445d2fff 100644 --- a/tests/import/insomnia/import-insomnia-v5-date-types.spec.ts +++ b/tests/import/insomnia/import-insomnia-v5-date-types.spec.ts @@ -3,7 +3,7 @@ import * as path from 'path'; import * as fs from 'fs'; import { closeAllCollections, importCollection } from '../../utils/page'; -test.describe('Import Insomnia Collection - date types preserved', () => { +test.describe.serial('Import Insomnia Collection - date types preserved', () => { test.afterEach(async ({ page }) => { await closeAllCollections(page); }); diff --git a/tests/proxy/pac/pac-proxy.spec.ts b/tests/proxy/pac/pac-proxy.spec.ts index bae84bc36..33b8be507 100644 --- a/tests/proxy/pac/pac-proxy.spec.ts +++ b/tests/proxy/pac/pac-proxy.spec.ts @@ -4,7 +4,7 @@ import { test } from '../../../playwright'; import { setSandboxMode, runCollection, validateRunnerResults, waitForReadyPage } from '../../utils/page'; import { startServers, stopServers, PAC_PORT, type TestServers } from './server'; -test.describe('PAC Proxy', () => { +test.describe.serial('PAC Proxy', () => { let servers: TestServers; test.beforeAll(async () => { diff --git a/tests/request/copy-request/copy-folder.spec.ts b/tests/request/copy-request/copy-folder.spec.ts index 2030fb17b..cfdcbad0f 100644 --- a/tests/request/copy-request/copy-folder.spec.ts +++ b/tests/request/copy-request/copy-folder.spec.ts @@ -1,7 +1,7 @@ import { test, expect } from '../../../playwright'; import { closeAllCollections, createCollection } from '../../utils/page'; -test.describe('Copy and Paste Folders', () => { +test.describe.serial('Copy and Paste Folders', () => { test.afterAll(async ({ page }) => { await closeAllCollections(page); }); diff --git a/tests/request/copy-request/copy-request.spec.ts b/tests/request/copy-request/copy-request.spec.ts index aa580ffdd..b99294194 100644 --- a/tests/request/copy-request/copy-request.spec.ts +++ b/tests/request/copy-request/copy-request.spec.ts @@ -1,7 +1,7 @@ import { test, expect } from '../../../playwright'; import { closeAllCollections, createCollection, createRequest } from '../../utils/page'; -test.describe('Copy and Paste Requests', () => { +test.describe.serial('Copy and Paste Requests', () => { test.afterAll(async ({ page }) => { await closeAllCollections(page); }); diff --git a/tests/request/copy-request/keyboard-shortcuts.spec.ts b/tests/request/copy-request/keyboard-shortcuts.spec.ts index cff366254..6384013f2 100644 --- a/tests/request/copy-request/keyboard-shortcuts.spec.ts +++ b/tests/request/copy-request/keyboard-shortcuts.spec.ts @@ -1,7 +1,7 @@ import { test, expect } from '../../../playwright'; import { closeAllCollections, createCollection } from '../../utils/page'; -test.describe('Copy and Paste with Keyboard Shortcuts', () => { +test.describe.serial('Copy and Paste with Keyboard Shortcuts', () => { test.afterAll(async ({ page }) => { await closeAllCollections(page); }); diff --git a/tests/shortcuts/bound-actions.spec.ts b/tests/shortcuts/bound-actions.spec.ts index d0c873815..aea6caa65 100644 --- a/tests/shortcuts/bound-actions.spec.ts +++ b/tests/shortcuts/bound-actions.spec.ts @@ -147,7 +147,7 @@ test.describe('Shortcut Keys - BOUND_ACTIONS', () => { }); test.describe('TABS', () => { - test.describe('SHORTCUT: Close Tab', () => { + test.describe.serial('SHORTCUT: Close Tab', () => { test('default Cmd/Ctrl+W closes the active tab', async ({ page, createTmpDir }) => { await openRequest(page, collectionName, 'req-1', { persist: true }); const reqTab = page.locator('.request-tab').filter({ hasText: 'req-1' }); @@ -189,7 +189,7 @@ test.describe('Shortcut Keys - BOUND_ACTIONS', () => { }); }); - test.describe('SHORTCUT: Close All Tabs', () => { + test.describe.serial('SHORTCUT: Close All Tabs', () => { test('default Cmd/Ctrl+Shift+W closes all tabs', async ({ page }) => { await openRequest(page, collectionName, 'req-1', { persist: true }); await openRequest(page, collectionName, 'req-2', { persist: true }); @@ -240,7 +240,7 @@ test.describe('Shortcut Keys - BOUND_ACTIONS', () => { }); }); - test.describe('SHORTCUT: Save', () => { + test.describe.serial('SHORTCUT: Save', () => { test('default Cmd/Ctrl+S save tab', async ({ page, createTmpDir }) => { await page.getByTestId('collections').locator('.collection-name').filter({ hasText: 'kb-collection' }).dblclick(); await expect(page.locator('.request-tab').filter({ hasText: 'collection' })).toBeVisible({ timeout: 2000 }); @@ -334,7 +334,7 @@ test.describe('Shortcut Keys - BOUND_ACTIONS', () => { }); }); - test.describe('SHORTCUT: Save All Tabs', () => { + test.describe.serial('SHORTCUT: Save All Tabs', () => { test('default Cmd/Ctrl+Shift+S save all tabs', async ({ page }) => { await page.getByTestId('collections').locator('.collection-name').filter({ hasText: 'kb-collection' }).dblclick(); await expect(page.locator('.request-tab').filter({ hasText: 'collection' })).toBeVisible({ timeout: 2000 }); @@ -495,7 +495,7 @@ test.describe('Shortcut Keys - BOUND_ACTIONS', () => { }); }); - test.describe('SHORTCUT: Switch to Previous Tab', () => { + test.describe.serial('SHORTCUT: Switch to Previous Tab', () => { test('default Cmd/Ctrl+Shift+[ switches to previous tab', async ({ page }) => { await openRequest(page, collectionName, 'req-4', { persist: true }); await openRequest(page, collectionName, 'req-5', { persist: true }); @@ -543,7 +543,7 @@ test.describe('Shortcut Keys - BOUND_ACTIONS', () => { }); }); - test.describe('SHORTCUT: Switch to Next Tab', () => { + test.describe.serial('SHORTCUT: Switch to Next Tab', () => { test('default Cmd/Ctrl+Shift+] switches to next tab', async ({ page }) => { await openRequest(page, collectionName, 'req-4', { persist: true }); await openRequest(page, collectionName, 'req-5', { persist: true }); @@ -596,7 +596,7 @@ test.describe('Shortcut Keys - BOUND_ACTIONS', () => { }); }); - test.describe('SHORTCUT: Move Tab Left', () => { + test.describe.serial('SHORTCUT: Move Tab Left', () => { test('default Cmd/Ctrl+[ moves active tab left', async ({ page }) => { await openRequest(page, collectionName, 'req-7', { persist: true }); await openRequest(page, collectionName, 'req-8', { persist: true }); @@ -660,7 +660,7 @@ test.describe('Shortcut Keys - BOUND_ACTIONS', () => { }); }); - test.describe('SHORTCUT: Move Tab Right', () => { + test.describe.serial('SHORTCUT: Move Tab Right', () => { test('default Cmd/Ctrl+] moves active tab right', async ({ page }) => { await openRequest(page, collectionName, 'req-6', { persist: true }); await openRequest(page, collectionName, 'req-7', { persist: true }); @@ -785,7 +785,7 @@ test.describe('Shortcut Keys - BOUND_ACTIONS', () => { }); }); - test.describe('SHORTCUT: Reopen Last Closed Tab', () => { + test.describe.serial('SHORTCUT: Reopen Last Closed Tab', () => { test('default Cmd/Ctrl+Shift+T reopens last closed request tab', async ({ page }) => { await openRequest(page, collectionName, 'req-2', { persist: true }); await openRequest(page, collectionName, 'req-1', { persist: true }); @@ -849,7 +849,7 @@ test.describe('Shortcut Keys - BOUND_ACTIONS', () => { }); test.describe('SIDEBAR', () => { - test.describe('SHORTCUT: Sidebar search', () => { + test.describe.serial('SHORTCUT: Sidebar search', () => { test('default Cmd/Ctrl+F open sidebar search', async ({ page, createTmpDir }) => { await page.keyboard.down('Alt'); await page.keyboard.down('KeyY'); @@ -889,7 +889,7 @@ test.describe('Shortcut Keys - BOUND_ACTIONS', () => { }); }); - test.describe('SHORTCUT: New request', () => { + test.describe.serial('SHORTCUT: New request', () => { test('default Cmd/Ctrl+N open new request modal', async ({ page, createTmpDir }) => { await page.keyboard.down('Alt'); await page.keyboard.down('KeyY'); @@ -939,7 +939,7 @@ test.describe('Shortcut Keys - BOUND_ACTIONS', () => { }); }); - test.describe('SHORTCUT: Rename Item', () => { + test.describe.serial('SHORTCUT: Rename Item', () => { test('default Cmd/Ctrl+R open rename item modal for request', async ({ page, createTmpDir }) => { await page.keyboard.down('Alt'); await page.keyboard.down('KeyY'); @@ -1119,7 +1119,7 @@ test.describe('Shortcut Keys - BOUND_ACTIONS', () => { }); }); - test.describe('SHORTCUT: Clone Item', () => { + test.describe.serial('SHORTCUT: Clone Item', () => { test('default Cmd/Ctrl+D open clone item modal for request', async ({ page, createTmpDir }) => { await page.keyboard.down('Alt'); await page.keyboard.down('KeyY'); @@ -1240,7 +1240,7 @@ test.describe('Shortcut Keys - BOUND_ACTIONS', () => { }); }); - test.describe('SHORTCUT: Copy Paste Item', () => { + test.describe.serial('SHORTCUT: Copy Paste Item', () => { test('default Cmd/Ctrl+C/V copy paste item for request', async ({ page, createTmpDir }) => { await page.keyboard.down('Alt'); await page.keyboard.down('KeyY'); @@ -1348,7 +1348,7 @@ test.describe('Shortcut Keys - BOUND_ACTIONS', () => { }); }); - test.describe('SHORTCUT: Collapse Sidebar', () => { + test.describe.serial('SHORTCUT: Collapse Sidebar', () => { test('default collapse sidebar using default Cmd/Ctrl+\\', async ({ page, createTmpDir }) => { await expect(page.getByTestId('collections')).toBeVisible(); await page.locator('body').click({ position: { x: 1, y: 1 } }); @@ -1414,7 +1414,7 @@ test.describe('Shortcut Keys - BOUND_ACTIONS', () => { }); test.describe('DEVELOPER TOOLS', () => { - test.describe('SHORTCUT: Open Terminal', () => { + test.describe.serial('SHORTCUT: Open Terminal', () => { test('default Cmd/Ctrl+T opens terminal', async ({ page, createTmpDir }) => { // Open Collection-Settings tab (double-click collection name) await page.getByTestId('collections').locator('.collection-name').filter({ hasText: 'kb-collection' }).click(); @@ -1509,7 +1509,7 @@ test.describe('Shortcut Keys - BOUND_ACTIONS', () => { }); test.describe('LAYOUT', () => { - test.describe('SHORTCUT: Change Layout', () => { + test.describe.serial('SHORTCUT: Change Layout', () => { test('default Cmd/Ctrl+J change layout orientation', async ({ page, createTmpDir }) => { await openRequest(page, 'kb-collection', 'req-5', { persist: true }); @@ -1596,7 +1596,7 @@ test.describe('Shortcut Keys - BOUND_ACTIONS', () => { }); }); - test.describe('SHORTCUT: Open Preferences', () => { + test.describe.serial('SHORTCUT: Open Preferences', () => { test('default Cmd/Ctrl+, open preferences', async ({ page }) => { await page.keyboard.down('Alt'); await page.keyboard.down('KeyY'); @@ -1644,7 +1644,7 @@ test.describe('Shortcut Keys - BOUND_ACTIONS', () => { }); test.describe('SEARCH', () => { - test.describe('SHORTCUT: Global Search', () => { + test.describe.serial('SHORTCUT: Global Search', () => { test('default Cmd/Ctrl+K Global Search Modal', async ({ page, createTmpDir }) => { // Press Cmd/Ctrl+K to global search modal await page.keyboard.press(`${modifier}+KeyK`); @@ -1691,7 +1691,7 @@ test.describe('Shortcut Keys - BOUND_ACTIONS', () => { }); }); - test.describe('SHORTCUT: Edit Environment', () => { + test.describe.serial('SHORTCUT: Edit Environment', () => { test('open environment tab of collection Cmd/Ctrl+E', async ({ page, createTmpDir }) => { await page.keyboard.down('Alt'); await page.keyboard.down('KeyY'); @@ -1744,7 +1744,7 @@ test.describe('Shortcut Keys - BOUND_ACTIONS', () => { }); test.describe('REQUESTS', () => { - test.describe('SHORTCUT: Send Request from CodeEditor (Cmd/Ctrl+Enter)', () => { + test.describe.serial('SHORTCUT: Send Request from CodeEditor (Cmd/Ctrl+Enter)', () => { test('sends request when cursor is in JSON body editor', async ({ page }) => { // Close existing tabs await page.keyboard.down('Alt'); @@ -1854,7 +1854,7 @@ test.describe('Shortcut Keys - BOUND_ACTIONS', () => { }); }); - test.describe('SHORTCUT: Send Request from CodeEditor (customized Shift+Enter)', () => { + test.describe.serial('SHORTCUT: Send Request from CodeEditor (customized Shift+Enter)', () => { test('customized Shift+Enter sends request when cursor is in JSON body editor', async ({ page }) => { // Close existing tabs await page.keyboard.down('Alt'); diff --git a/tests/websockets/multi-message-bru/multi-message.spec.ts b/tests/websockets/multi-message-bru/multi-message.spec.ts index fbc41d983..490a55505 100644 --- a/tests/websockets/multi-message-bru/multi-message.spec.ts +++ b/tests/websockets/multi-message-bru/multi-message.spec.ts @@ -11,7 +11,7 @@ const MULTI_MSG_BRU_PATH = join(__dirname, 'fixtures/collection/ws-multi-msg.bru const SINGLE_MSG_BRU_PATH = join(__dirname, 'fixtures/collection/ws-single-msg.bru'); const MAX_CONNECTION_TIME = 3000; -test.describe('websocket multi-message (bru format)', () => { +test.describe.serial('websocket multi-message (bru format)', () => { let originalMultiMsgData = ''; let originalSingleMsgData = ''; diff --git a/tests/websockets/multi-message-yml/multi-message.spec.ts b/tests/websockets/multi-message-yml/multi-message.spec.ts index 5fdaab951..a883712a5 100644 --- a/tests/websockets/multi-message-yml/multi-message.spec.ts +++ b/tests/websockets/multi-message-yml/multi-message.spec.ts @@ -11,7 +11,7 @@ const MULTI_MSG_YML_PATH = join(__dirname, 'fixtures/collection/ws-multi-msg.yml const SINGLE_MSG_YML_PATH = join(__dirname, 'fixtures/collection/ws-single-msg.yml'); const MAX_CONNECTION_TIME = 3000; -test.describe('websocket multi-message (yml format)', () => { +test.describe.serial('websocket multi-message (yml format)', () => { let originalMultiMsgData = ''; let originalSingleMsgData = '';