From 3164fd6c293bf3501134471b3d4cc492faaf5378 Mon Sep 17 00:00:00 2001 From: lin onetwo Date: Sun, 8 Mar 2026 03:32:02 +0800 Subject: [PATCH] fix(e2e): revert update-workspace-settings to use restartWiki() like master The stop->update->start approach introduced a race condition that caused 'watch-fs did not stabilize after restart' failures in 25 out of 52 scenarios. Reverting to the proven update->restartWiki() approach from master while still supporting enableHTTPAPI restart. --- features/stepDefinitions/wiki.ts | 100 +++++++++++++++++-------------- 1 file changed, 54 insertions(+), 46 deletions(-) diff --git a/features/stepDefinitions/wiki.ts b/features/stepDefinitions/wiki.ts index ddd490d9..17d37827 100644 --- a/features/stepDefinitions/wiki.ts +++ b/features/stepDefinitions/wiki.ts @@ -1175,67 +1175,75 @@ When('I update workspace {string} settings:', async function(this: ApplicationWo watchFsCurrentlyEnabled = currentWorkspace !== null && isWikiWorkspace(currentWorkspace) && currentWorkspace.enableFileSystemWatch; } - // Determine if a wiki restart is needed (enableFileSystemWatch or enableHTTPAPI changed) - const needsRestart = 'enableFileSystemWatch' in settingsUpdate || 'enableHTTPAPI' in settingsUpdate; + // Update workspace settings via main window + await this.app.evaluate(async ({ BrowserWindow }, { workspaceId, updates }: { workspaceId: string; updates: Record }) => { + const windows = BrowserWindow.getAllWindows(); + const mainWindow = windows.find(win => !win.isDestroyed() && win.webContents && win.webContents.getURL().includes('index.html')); + if (!mainWindow) { + throw new Error('Main window not found'); + } + + // Call workspace service to update workspace settings + await mainWindow.webContents.executeJavaScript(` + (async () => { + await window.service.workspace.update(${JSON.stringify(workspaceId)}, ${JSON.stringify(updates)}); + })(); + `); + }, { workspaceId: targetWorkspaceId, updates: settingsUpdate }); + + // Wait for settings to propagate + await this.app.evaluate(async () => { + await new Promise(resolve => setTimeout(resolve, 500)); + }); + + // If enableFileSystemWatch or enableHTTPAPI was changed, we need to restart the wiki + const needsRestart = 'enableFileSystemWatch' in settingsUpdate || 'enableHTTPAPI' in settingsUpdate; if (needsRestart) { - // If watch-fs is currently running, wait for it to be stable before stopping + // Only wait for watch-fs if it was enabled before the update + // If it was disabled, wiki is ready immediately without watch-fs markers if (watchFsCurrentlyEnabled) { await waitForLogMarker(this, '[test-id-WATCH_FS_STABILIZED]', 'watch-fs not ready before restart', LOG_MARKER_WAIT_TIMEOUT); } + + // Clear log markers to ensure we wait for fresh ones after restart await clearLogLinesContaining(this, '[test-id-WATCH_FS_STABILIZED]'); - // Use stop→update→start instead of update→restartWiki to avoid the reactive system - // firing a concurrent startWiki that races with restartWiki for the same port. - const restartResult = await this.app.evaluate( - async ({ BrowserWindow }, { workspaceId, updates }: { workspaceId: string; updates: Record }) => { - const windows = BrowserWindow.getAllWindows(); - const mainWindow = windows.find(win => !win.isDestroyed() && win.webContents && win.webContents.getURL().includes('index.html')); - if (!mainWindow) return { success: false, error: 'Main window not found' }; + // Restart the wiki + const restartResult = await this.app.evaluate(async ({ BrowserWindow }, workspaceId: string) => { + const windows = BrowserWindow.getAllWindows(); + const mainWindow = windows.find(win => !win.isDestroyed() && win.webContents && win.webContents.getURL().includes('index.html')); - return await mainWindow.webContents.executeJavaScript(` - (async () => { - try { - await window.service.wiki.stopWiki(${JSON.stringify(workspaceId)}); - await window.service.workspace.update(${JSON.stringify(workspaceId)}, ${JSON.stringify(updates)}); - await new Promise(resolve => setTimeout(resolve, 500)); - const workspace = await window.service.workspace.get(${JSON.stringify(workspaceId)}); - if (!workspace) return { success: false, error: 'Workspace not found after update' }; - const userName = await window.service.auth.getUserName(workspace); - await window.service.wiki.startWiki(${JSON.stringify(workspaceId)}, userName); - return { success: true }; - } catch (error) { - return { success: false, error: error.message }; - } - })(); - `) as Promise<{ success: boolean; error?: string }>; - }, - { workspaceId: targetWorkspaceId, updates: settingsUpdate }, - ); + if (!mainWindow) { + throw new Error('Main window not found'); + } + + const result = await mainWindow.webContents.executeJavaScript(` + (async () => { + const workspace = await window.service.workspace.get(${JSON.stringify(workspaceId)}); + if (!workspace) { + return { success: false, error: 'Workspace not found' }; + } + try { + await window.service.wiki.restartWiki(workspace); + return { success: true }; + } catch (error) { + return { success: false, error: error.message }; + } + })(); + `) as Promise<{ success: boolean; error?: string }>; + return result; + }, targetWorkspaceId); if (!restartResult.success) { - throw new Error(`Failed to restart wiki after settings update: ${restartResult.error ?? 'Unknown error'}`); + throw new Error(`Failed to restart wiki: ${restartResult.error ?? 'Unknown error'}`); } + // Wait for wiki to restart and watch-fs to stabilize + // Only wait if enableFileSystemWatch was set to true if (settingsUpdate.enableFileSystemWatch === true) { await waitForLogMarker(this, '[test-id-WATCH_FS_STABILIZED]', 'watch-fs did not stabilize after restart', LOG_MARKER_WAIT_TIMEOUT); } - } else { - // No restart needed, just update settings - await this.app.evaluate(async ({ BrowserWindow }, { workspaceId, updates }: { workspaceId: string; updates: Record }) => { - const windows = BrowserWindow.getAllWindows(); - const mainWindow = windows.find(win => !win.isDestroyed() && win.webContents && win.webContents.getURL().includes('index.html')); - if (!mainWindow) throw new Error('Main window not found'); - await mainWindow.webContents.executeJavaScript(` - (async () => { - await window.service.workspace.update(${JSON.stringify(workspaceId)}, ${JSON.stringify(updates)}); - })(); - `); - }, { workspaceId: targetWorkspaceId, updates: settingsUpdate }); - - await this.app.evaluate(async () => { - await new Promise(resolve => setTimeout(resolve, 500)); - }); } });