diff --git a/apps/ui/tests/spec-editor-persistence.spec.ts b/apps/ui/tests/spec-editor-persistence.spec.ts index 9369ccad..16a3254e 100644 --- a/apps/ui/tests/spec-editor-persistence.spec.ts +++ b/apps/ui/tests/spec-editor-persistence.spec.ts @@ -77,8 +77,28 @@ test.describe("Spec Editor Persistence", () => { const specEditorAfterReload = await getByTestId(page, "spec-editor"); await specEditorAfterReload.locator(".cm-content").waitFor({ state: "visible", timeout: 10000 }); - // Small delay to ensure editor content is loaded - await page.waitForTimeout(500); + // Wait for the spec to finish loading (check that loading state is gone) + await page.waitForFunction( + () => { + const loadingView = document.querySelector('[data-testid="spec-view-loading"]'); + return loadingView === null; + }, + { timeout: 10000 } + ); + + // Wait for CodeMirror content to update with the loaded spec + // CodeMirror might need a moment to update its DOM after the value prop changes + await page.waitForFunction( + (expectedContent) => { + const contentElement = document.querySelector('[data-testid="spec-editor"] .cm-content'); + if (!contentElement) return false; + const text = (contentElement.textContent || "").trim(); + // Wait until content matches what we saved + return text === expectedContent; + }, + "hello world", + { timeout: 10000 } + ); // Step 11: Verify the content was persisted const persistedContent = await getEditorContent(page); diff --git a/apps/ui/tests/utils/views/spec-editor.ts b/apps/ui/tests/utils/views/spec-editor.ts index e8f86dd1..551b46a5 100644 --- a/apps/ui/tests/utils/views/spec-editor.ts +++ b/apps/ui/tests/utils/views/spec-editor.ts @@ -60,12 +60,16 @@ export async function navigateToSpecEditor(page: Page): Promise { /** * Get the CodeMirror editor content + * Waits for CodeMirror to be ready and returns the content */ export async function getEditorContent(page: Page): Promise { // CodeMirror uses a contenteditable div with class .cm-content - const content = await page - .locator('[data-testid="spec-editor"] .cm-content') - .textContent(); + // Wait for it to be visible and then read its textContent + const contentElement = page.locator('[data-testid="spec-editor"] .cm-content'); + await contentElement.waitFor({ state: "visible", timeout: 10000 }); + + // Read the content - CodeMirror should have updated its DOM by now + const content = await contentElement.textContent(); return content || ""; } diff --git a/apps/ui/tests/worktree-integration.spec.ts b/apps/ui/tests/worktree-integration.spec.ts index d59d0a1f..a78df49e 100644 --- a/apps/ui/tests/worktree-integration.spec.ts +++ b/apps/ui/tests/worktree-integration.spec.ts @@ -874,27 +874,28 @@ test.describe("Worktree Integration Tests", () => { await confirmAddFeature(page); // Wait for feature to be saved and worktree to be created + // Also wait for the worktree to appear in the UI and be auto-selected await page.waitForTimeout(2000); - // Verify the new worktree is auto-selected (highlighted/active in the worktree panel) - // The worktree button should now be in a selected state (indicated by data-selected or similar class) - const worktreeButton = page.getByRole("button", { - name: new RegExp(branchName.replace("/", "\\/"), "i"), - }); - await expect(worktreeButton).toBeVisible({ timeout: 5000 }); + // Wait for the worktree button to appear in the UI + // Worktree buttons are actual