test(e2e): block WebSocket in SuperSync tests to prevent sync race conditions

The WebSocket push feature (7fa8f12132) introduced background downloads
via WsTriggeredDownloadService that race with E2E test assertions.
Tests assume controlled, sequential sync via syncAndWait() but WS push
causes data to arrive before tests expect it, breaking conflict scenarios
and route interception.

Block the /api/sync/ws endpoint by default in setupSuperSync() and
opt-in only for the realtime-push test that specifically verifies WS.
This commit is contained in:
Johannes Millan 2026-03-30 23:14:01 +02:00
parent 139494599e
commit 2f2f861b9f
2 changed files with 15 additions and 2 deletions

View file

@ -23,6 +23,13 @@ export interface SuperSyncConfig {
* The password is entered and "Retry Decrypt" is clicked to proceed.
*/
decryptionFailedPassword?: string;
/**
* If true, allows the WebSocket connection for real-time push notifications.
* Default is false: the WS endpoint is blocked so tests have controlled,
* sequential sync via syncAndWait(). Set to true only for tests that
* specifically verify the WebSocket push flow.
*/
enableWebSocket?: boolean;
}
/**
@ -169,6 +176,12 @@ export class SuperSyncPage extends BasePage {
* @param config - SuperSync configuration (includes optional waitForInitialSync flag)
*/
async setupSuperSync(config: SuperSyncConfig): Promise<void> {
// Block WebSocket connections by default so tests have controlled, sequential sync.
// Only the realtime-push test opts in with enableWebSocket: true.
if (!config.enableWebSocket) {
await this.page.route('**/api/sync/ws**', (route) => route.abort());
}
// Extract waitForInitialSync from config, defaulting to true
const waitForInitialSync = config.waitForInitialSync ?? true;
// Auto-accept native browser confirm dialogs (window.confirm used for fresh client sync confirmation)

View file

@ -35,7 +35,7 @@ test.describe('@supersync Realtime Push', () => {
const syncConfig = getSuperSyncConfig(user);
clientA = await createSimulatedClient(browser, appUrl, 'A', testRunId);
await clientA.sync.setupSuperSync(syncConfig);
await clientA.sync.setupSuperSync({ ...syncConfig, enableWebSocket: true });
const baselineTask = `Realtime-Baseline-${testRunId}`;
await clientA.workView.addTask(baselineTask);
@ -43,7 +43,7 @@ test.describe('@supersync Realtime Push', () => {
await waitForTask(clientA.page, baselineTask);
clientB = await createSimulatedClient(browser, appUrl, 'B', testRunId);
await clientB.sync.setupSuperSync(syncConfig);
await clientB.sync.setupSuperSync({ ...syncConfig, enableWebSocket: true });
await clientB.sync.syncAndWait();
await waitForTask(clientB.page, baselineTask);