mirror of
https://github.com/johannesjo/super-productivity.git
synced 2026-01-22 18:30:09 +00:00
perf(e2e): cache WebDAV health checks at worker level
Optimize WebDAV E2E test startup by caching health checks at the worker level instead of checking in each test file's beforeAll hook. Changes: - Create webdav.fixture.ts with worker-level health check caching - Update 12 WebDAV test files to use new fixture - Remove redundant beforeAll health check blocks Impact: - Reduces health check overhead from ~8s to ~2s when WebDAV unavailable - Saves ~6 seconds on PR/build CI runs (combined with existing SuperSync optimization) - Tests automatically skip when WebDAV server is not reachable
This commit is contained in:
parent
3a9d35149d
commit
867b708413
13 changed files with 98 additions and 120 deletions
85
e2e/fixtures/webdav.fixture.ts
Normal file
85
e2e/fixtures/webdav.fixture.ts
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
import { test as base } from '@playwright/test';
|
||||
import { isWebDavServerUp } from '../utils/check-webdav';
|
||||
|
||||
/**
|
||||
* Extended test fixture for WebDAV E2E tests.
|
||||
*
|
||||
* Provides:
|
||||
* - Automatic server health check (skips tests if server unavailable)
|
||||
* - Worker-level caching to avoid redundant health checks
|
||||
*
|
||||
* This reduces health check overhead from ~8s to ~2s when WebDAV is unavailable
|
||||
* by checking once per worker instead of once per test file.
|
||||
*
|
||||
* Usage:
|
||||
* ```typescript
|
||||
* import { test, expect } from '../../fixtures/webdav.fixture';
|
||||
*
|
||||
* test.describe('@webdav My Tests', () => {
|
||||
* test('should sync', async ({ page, request }) => {
|
||||
* // Server health already checked, test will skip if unavailable
|
||||
* });
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
|
||||
export interface WebDavFixtures {
|
||||
/** Whether the WebDAV server is reachable and available */
|
||||
webdavServerUp: boolean;
|
||||
}
|
||||
|
||||
// Cache server health check result per worker to avoid repeated checks
|
||||
let serverHealthCache: boolean | null = null;
|
||||
|
||||
export const test = base.extend<WebDavFixtures>({
|
||||
/**
|
||||
* Check WebDAV server health once per worker and cache the result.
|
||||
* Tests are automatically skipped if the server is not reachable.
|
||||
*/
|
||||
webdavServerUp: async ({}, use, testInfo) => {
|
||||
// Only check once per worker
|
||||
if (serverHealthCache === null) {
|
||||
serverHealthCache = await isWebDavServerUp();
|
||||
if (!serverHealthCache) {
|
||||
console.warn(
|
||||
'WebDAV server not reachable at http://127.0.0.1:2345/ - skipping tests',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Skip the test if server is not reachable
|
||||
testInfo.skip(!serverHealthCache, 'WebDAV server not reachable');
|
||||
|
||||
await use(serverHealthCache);
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* Helper to create a describe block that auto-checks WebDAV server health.
|
||||
* Use this instead of manually adding beforeAll health checks.
|
||||
*
|
||||
* @param title - Test suite title (will be prefixed with @webdav)
|
||||
* @param fn - Test suite function
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* webdavDescribe('Archive Sync', () => {
|
||||
* test('should sync archive', async ({ page, webdavServerUp }) => {
|
||||
* // Server health already checked
|
||||
* });
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export const webdavDescribe = (title: string, fn: () => void): void => {
|
||||
test.describe(`@webdav ${title}`, () => {
|
||||
// The webdavServerUp fixture will auto-skip if server unavailable
|
||||
test.beforeEach(async ({ webdavServerUp }) => {
|
||||
// This line ensures the fixture is evaluated and test is skipped if needed
|
||||
void webdavServerUp;
|
||||
});
|
||||
fn();
|
||||
});
|
||||
};
|
||||
|
||||
// Re-export expect for convenience
|
||||
export { expect } from '@playwright/test';
|
||||
|
|
@ -1,8 +1,7 @@
|
|||
import { test, expect } from '../../fixtures/test.fixture';
|
||||
import { test, expect } from '../../fixtures/webdav.fixture';
|
||||
import { SyncPage } from '../../pages/sync.page';
|
||||
import { WorkViewPage } from '../../pages/work-view.page';
|
||||
import { waitForStatePersistence } from '../../utils/waits';
|
||||
import { isWebDavServerUp } from '../../utils/check-webdav';
|
||||
import {
|
||||
WEBDAV_CONFIG_TEMPLATE,
|
||||
setupSyncClient,
|
||||
|
|
@ -24,13 +23,6 @@ import { waitForAppReady } from '../../utils/waits';
|
|||
test.describe('WebDAV First Sync Conflict', () => {
|
||||
test.describe.configure({ mode: 'serial' });
|
||||
|
||||
test.beforeAll(async () => {
|
||||
const isUp = await isWebDavServerUp(WEBDAV_CONFIG_TEMPLATE.baseUrl);
|
||||
if (!isUp) {
|
||||
test.skip(true, 'WebDAV server not reachable');
|
||||
}
|
||||
});
|
||||
|
||||
test('should show conflict dialog and allow USE_LOCAL to upload local data', async ({
|
||||
browser,
|
||||
baseURL,
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
import { test, expect } from '../../fixtures/test.fixture';
|
||||
import { test, expect } from '../../fixtures/webdav.fixture';
|
||||
import { SyncPage } from '../../pages/sync.page';
|
||||
import { WorkViewPage } from '../../pages/work-view.page';
|
||||
import { waitForStatePersistence } from '../../utils/waits';
|
||||
import { isWebDavServerUp } from '../../utils/check-webdav';
|
||||
import {
|
||||
WEBDAV_CONFIG_TEMPLATE,
|
||||
createSyncFolder,
|
||||
|
|
@ -34,14 +33,6 @@ import legacyDataCollisionB from '../../fixtures/legacy-migration-collision-b.js
|
|||
test.describe('@migration WebDAV Legacy Migration Sync', () => {
|
||||
test.describe.configure({ mode: 'serial' });
|
||||
|
||||
test.beforeAll(async () => {
|
||||
const isUp = await isWebDavServerUp(WEBDAV_CONFIG_TEMPLATE.baseUrl);
|
||||
if (!isUp) {
|
||||
console.warn('WebDAV server not reachable. Skipping WebDAV tests.');
|
||||
test.skip(true, 'WebDAV server not reachable');
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Test: Both clients migrated from legacy - Keep local resolution
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
import { test, expect } from '../../fixtures/test.fixture';
|
||||
import { test, expect } from '../../fixtures/webdav.fixture';
|
||||
import { SyncPage } from '../../pages/sync.page';
|
||||
import { WorkViewPage } from '../../pages/work-view.page';
|
||||
import { waitForStatePersistence } from '../../utils/waits';
|
||||
import { isWebDavServerUp } from '../../utils/check-webdav';
|
||||
import {
|
||||
WEBDAV_CONFIG_TEMPLATE,
|
||||
setupSyncClient,
|
||||
|
|
@ -34,14 +33,6 @@ test.describe('@webdav WebDAV Provider Switch', () => {
|
|||
syncFolderPath: `/${SYNC_FOLDER_NAME}`,
|
||||
};
|
||||
|
||||
test.beforeAll(async () => {
|
||||
const isUp = await isWebDavServerUp(WEBDAV_CONFIG_TEMPLATE.baseUrl);
|
||||
if (!isUp) {
|
||||
console.warn('WebDAV server not reachable. Skipping WebDAV tests.');
|
||||
test.skip(true, 'WebDAV server not reachable');
|
||||
}
|
||||
});
|
||||
|
||||
test('should sync tasks when Client B connects to existing WebDAV server (provider switch)', async ({
|
||||
browser,
|
||||
baseURL,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import { test, expect } from '../../fixtures/test.fixture';
|
||||
import { test, expect } from '../../fixtures/webdav.fixture';
|
||||
import { SyncPage } from '../../pages/sync.page';
|
||||
import { WorkViewPage } from '../../pages/work-view.page';
|
||||
import { isWebDavServerUp } from '../../utils/check-webdav';
|
||||
import {
|
||||
WEBDAV_CONFIG_TEMPLATE,
|
||||
setupSyncClient,
|
||||
|
|
@ -14,14 +13,6 @@ test.describe('WebDAV Sync Advanced Features', () => {
|
|||
// Run sync tests serially to avoid WebDAV server contention
|
||||
test.describe.configure({ mode: 'serial' });
|
||||
|
||||
test.beforeAll(async () => {
|
||||
const isUp = await isWebDavServerUp(WEBDAV_CONFIG_TEMPLATE.baseUrl);
|
||||
if (!isUp) {
|
||||
console.warn('WebDAV server not reachable. Skipping WebDAV tests.');
|
||||
test.skip(true, 'WebDAV server not reachable');
|
||||
}
|
||||
});
|
||||
|
||||
test('should sync sub-tasks correctly', async ({ browser, baseURL, request }) => {
|
||||
const SYNC_FOLDER_NAME = generateSyncFolderName('e2e-advanced-sub');
|
||||
await createSyncFolder(request, SYNC_FOLDER_NAME);
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
import { expect, Page } from '@playwright/test';
|
||||
import { test } from '../../fixtures/test.fixture';
|
||||
import { Page } from '@playwright/test';
|
||||
import { test, expect } from '../../fixtures/webdav.fixture';
|
||||
import { SyncPage } from '../../pages/sync.page';
|
||||
import { WorkViewPage } from '../../pages/work-view.page';
|
||||
import { TaskPage } from '../../pages/task.page';
|
||||
import { waitForStatePersistence } from '../../utils/waits';
|
||||
import { isWebDavServerUp } from '../../utils/check-webdav';
|
||||
import {
|
||||
WEBDAV_CONFIG_TEMPLATE,
|
||||
setupSyncClient,
|
||||
|
|
@ -57,14 +56,6 @@ test.describe('@webdav WebDAV Archive Sync', () => {
|
|||
// Run sync tests serially to avoid WebDAV server contention
|
||||
test.describe.configure({ mode: 'serial' });
|
||||
|
||||
test.beforeAll(async () => {
|
||||
const isUp = await isWebDavServerUp(WEBDAV_CONFIG_TEMPLATE.baseUrl);
|
||||
if (!isUp) {
|
||||
console.warn('WebDAV server not reachable. Skipping WebDAV archive tests.');
|
||||
test.skip(true, 'WebDAV server not reachable');
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Scenario 1: Two clients archive different tasks
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
import { expect } from '@playwright/test';
|
||||
import { test } from '../../fixtures/test.fixture';
|
||||
import { test } from '../../fixtures/webdav.fixture';
|
||||
import { SyncPage } from '../../pages/sync.page';
|
||||
import { WorkViewPage } from '../../pages/work-view.page';
|
||||
import { TaskPage } from '../../pages/task.page';
|
||||
import { TagPage } from '../../pages/tag.page';
|
||||
import { ProjectPage } from '../../pages/project.page';
|
||||
import { waitForStatePersistence, waitForAppReady } from '../../utils/waits';
|
||||
import { isWebDavServerUp } from '../../utils/check-webdav';
|
||||
import {
|
||||
WEBDAV_CONFIG_TEMPLATE,
|
||||
setupSyncClient,
|
||||
|
|
@ -51,14 +50,6 @@ const archiveDoneTasks = async (page: Page): Promise<void> => {
|
|||
test.describe('@webdav WebDAV Delete Cascade Sync', () => {
|
||||
test.describe.configure({ mode: 'serial' });
|
||||
|
||||
test.beforeAll(async () => {
|
||||
const isUp = await isWebDavServerUp(WEBDAV_CONFIG_TEMPLATE.baseUrl);
|
||||
if (!isUp) {
|
||||
console.warn('WebDAV server not reachable. Skipping WebDAV delete cascade tests.');
|
||||
test.skip(true, 'WebDAV server not reachable');
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Test 1.1: Delete tag with archived tasks syncs to other client
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import { test, expect } from '../../fixtures/test.fixture';
|
||||
import { test, expect } from '../../fixtures/webdav.fixture';
|
||||
import { SyncPage } from '../../pages/sync.page';
|
||||
import { WorkViewPage } from '../../pages/work-view.page';
|
||||
import { isWebDavServerUp } from '../../utils/check-webdav';
|
||||
import {
|
||||
WEBDAV_CONFIG_TEMPLATE,
|
||||
createUniqueSyncFolder,
|
||||
|
|
@ -17,14 +16,6 @@ test.describe('WebDAV Sync Error Handling', () => {
|
|||
// Run sync tests serially to avoid WebDAV server contention
|
||||
test.describe.configure({ mode: 'serial' });
|
||||
|
||||
test.beforeAll(async () => {
|
||||
const isUp = await isWebDavServerUp(WEBDAV_CONFIG_TEMPLATE.baseUrl);
|
||||
if (!isUp) {
|
||||
console.warn('WebDAV server not reachable. Skipping WebDAV tests.');
|
||||
test.skip(true, 'WebDAV server not reachable');
|
||||
}
|
||||
});
|
||||
|
||||
test('should handle server unavailable during sync', async ({
|
||||
browser,
|
||||
baseURL,
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
import { expect, test } from '../../fixtures/test.fixture';
|
||||
import { expect, test } from '../../fixtures/webdav.fixture';
|
||||
import { SyncPage } from '../../pages/sync.page';
|
||||
import { WorkViewPage } from '../../pages/work-view.page';
|
||||
import { ProjectPage } from '../../pages/project.page';
|
||||
import { waitForStatePersistence } from '../../utils/waits';
|
||||
import { isWebDavServerUp } from '../../utils/check-webdav';
|
||||
import {
|
||||
createSyncFolder,
|
||||
generateSyncFolderName,
|
||||
|
|
@ -20,14 +19,6 @@ test.describe('WebDAV Sync Expansion', () => {
|
|||
// Run sync tests serially to avoid WebDAV server contention
|
||||
test.describe.configure({ mode: 'serial' });
|
||||
|
||||
test.beforeAll(async () => {
|
||||
const isUp = await isWebDavServerUp(WEBDAV_CONFIG_TEMPLATE.baseUrl);
|
||||
if (!isUp) {
|
||||
console.warn('WebDAV server not reachable. Skipping WebDAV tests.');
|
||||
test.skip(true, 'WebDAV server not reachable');
|
||||
}
|
||||
});
|
||||
|
||||
test('should sync projects', async ({ browser, baseURL, request }) => {
|
||||
test.slow();
|
||||
const SYNC_FOLDER_NAME = generateSyncFolderName('e2e-expansion-proj');
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
import { test, expect } from '../../fixtures/test.fixture';
|
||||
import { test, expect } from '../../fixtures/webdav.fixture';
|
||||
import { SyncPage } from '../../pages/sync.page';
|
||||
import { WorkViewPage } from '../../pages/work-view.page';
|
||||
import { waitForAppReady, waitForStatePersistence } from '../../utils/waits';
|
||||
import { isWebDavServerUp } from '../../utils/check-webdav';
|
||||
import {
|
||||
WEBDAV_CONFIG_TEMPLATE,
|
||||
setupSyncClient,
|
||||
|
|
@ -24,14 +23,6 @@ test.describe('WebDAV Sync Full Flow', () => {
|
|||
syncFolderPath: `/${SYNC_FOLDER_NAME}`,
|
||||
};
|
||||
|
||||
test.beforeAll(async () => {
|
||||
const isUp = await isWebDavServerUp(WEBDAV_CONFIG_TEMPLATE.baseUrl);
|
||||
if (!isUp) {
|
||||
console.warn('WebDAV server not reachable. Skipping WebDAV tests.');
|
||||
test.skip(true, 'WebDAV server not reachable');
|
||||
}
|
||||
});
|
||||
|
||||
test('should sync data between two clients', async ({ browser, baseURL, request }) => {
|
||||
test.slow(); // Sync tests might take longer
|
||||
console.log('Using baseURL:', baseURL);
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
import { test, expect } from '../../fixtures/test.fixture';
|
||||
import { test, expect } from '../../fixtures/webdav.fixture';
|
||||
import { SyncPage } from '../../pages/sync.page';
|
||||
import { WorkViewPage } from '../../pages/work-view.page';
|
||||
import { TagPage } from '../../pages/tag.page';
|
||||
import { isWebDavServerUp } from '../../utils/check-webdav';
|
||||
import {
|
||||
WEBDAV_CONFIG_TEMPLATE,
|
||||
createUniqueSyncFolder,
|
||||
|
|
@ -15,14 +14,6 @@ test.describe('WebDAV Sync Tags', () => {
|
|||
// Run sync tests serially to avoid WebDAV server contention
|
||||
test.describe.configure({ mode: 'serial' });
|
||||
|
||||
test.beforeAll(async () => {
|
||||
const isUp = await isWebDavServerUp(WEBDAV_CONFIG_TEMPLATE.baseUrl);
|
||||
if (!isUp) {
|
||||
console.warn('WebDAV server not reachable. Skipping WebDAV tests.');
|
||||
test.skip(true, 'WebDAV server not reachable');
|
||||
}
|
||||
});
|
||||
|
||||
test('should sync tag creation between clients', async ({
|
||||
browser,
|
||||
baseURL,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import { test, expect } from '../../fixtures/test.fixture';
|
||||
import { test, expect } from '../../fixtures/webdav.fixture';
|
||||
import { SyncPage } from '../../pages/sync.page';
|
||||
import { WorkViewPage } from '../../pages/work-view.page';
|
||||
import { isWebDavServerUp } from '../../utils/check-webdav';
|
||||
import {
|
||||
WEBDAV_CONFIG_TEMPLATE,
|
||||
createUniqueSyncFolder,
|
||||
|
|
@ -14,14 +13,6 @@ test.describe('WebDAV Sync Task Order', () => {
|
|||
// Run sync tests serially to avoid WebDAV server contention
|
||||
test.describe.configure({ mode: 'serial' });
|
||||
|
||||
test.beforeAll(async () => {
|
||||
const isUp = await isWebDavServerUp(WEBDAV_CONFIG_TEMPLATE.baseUrl);
|
||||
if (!isUp) {
|
||||
console.warn('WebDAV server not reachable. Skipping WebDAV tests.');
|
||||
test.skip(true, 'WebDAV server not reachable');
|
||||
}
|
||||
});
|
||||
|
||||
test('should preserve task order after sync', async ({ browser, baseURL, request }) => {
|
||||
test.slow();
|
||||
const SYNC_FOLDER_NAME = createUniqueSyncFolder('task-order');
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
import { expect } from '@playwright/test';
|
||||
import { test } from '../../fixtures/test.fixture';
|
||||
import { test } from '../../fixtures/webdav.fixture';
|
||||
import { SyncPage } from '../../pages/sync.page';
|
||||
import { WorkViewPage } from '../../pages/work-view.page';
|
||||
import { TaskPage } from '../../pages/task.page';
|
||||
import { waitForStatePersistence, waitForAppReady } from '../../utils/waits';
|
||||
import { isWebDavServerUp } from '../../utils/check-webdav';
|
||||
import {
|
||||
WEBDAV_CONFIG_TEMPLATE,
|
||||
setupSyncClient,
|
||||
|
|
@ -28,14 +27,6 @@ import {
|
|||
test.describe('@webdav WebDAV TODAY Tag Sync', () => {
|
||||
test.describe.configure({ mode: 'serial' });
|
||||
|
||||
test.beforeAll(async () => {
|
||||
const isUp = await isWebDavServerUp(WEBDAV_CONFIG_TEMPLATE.baseUrl);
|
||||
if (!isUp) {
|
||||
console.warn('WebDAV server not reachable. Skipping WebDAV TODAY tag tests.');
|
||||
test.skip(true, 'WebDAV server not reachable');
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Test 2.1: Concurrent task reordering in TODAY view
|
||||
*
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue