diff --git a/tests/e2e/onboarding.spec.ts b/tests/e2e/onboarding.spec.ts index 35f3a3e48..46499791d 100644 --- a/tests/e2e/onboarding.spec.ts +++ b/tests/e2e/onboarding.spec.ts @@ -280,13 +280,15 @@ test.describe('Onboarding flow', () => { await expectSkillSetupTerminalReady(orcaPage) await expect(onboardingFooterButton(orcaPage, /^Continue\b/)).toBeVisible() await continueFromFeatureSetupToRepo(orcaPage) - await expect(orcaPage.getByRole('button', { name: 'Continue' })).toHaveCount(0) await expect(orcaPage.getByRole('button', { name: /Open a folder/i })).toBeVisible() await expect .poll(async () => (await getOnboardingState(orcaPage)).lastCompletedStep, { timeout: 5_000 }) .toBe(6) + // Why: the E2E fixture starts with a seeded project, so the repo step can + // complete onboarding through its existing-project Continue action. + await expect(onboardingFooterButton(orcaPage, /^Continue\b/)).toBeVisible() // Verify the source defaults land without asking users to configure each // source in the onboarding UI. @@ -326,6 +328,28 @@ test.describe('Onboarding flow', () => { { timeout: 5_000 } ) .toEqual({ orchestration: '1', browserUse: '1' }) + + await continueOnboarding(orcaPage) + await expect(orcaPage.getByRole('heading', { name: REPO_STEP_HEADING })).toHaveCount(0) + await expect + .poll( + async () => { + const state = await getOnboardingState(orcaPage) + return { + closedAt: state.closedAt === null ? null : 'set', + outcome: state.outcome, + addedRepo: state.checklist.addedRepo, + lastCompletedStep: state.lastCompletedStep + } + }, + { timeout: 5_000 } + ) + .toEqual({ + closedAt: 'set', + outcome: 'completed', + addedRepo: true, + lastCompletedStep: 7 + }) }) test('Cmd/Ctrl+Enter advances steps like Continue', async ({ orcaPage }) => { @@ -454,7 +478,7 @@ test.describe('Onboarding flow', () => { await expect(orcaPage.getByText('7 of 7')).toBeVisible() }) - test('Skip from theme preserves the immediately saved choice', async ({ orcaPage }) => { + test('Skip from theme restores the entry theme choice', async ({ orcaPage }) => { await expect(orcaPage.getByRole('heading', { name: /Pick your default agent/i })).toBeVisible({ timeout: 15_000 }) @@ -466,6 +490,7 @@ test.describe('Onboarding flow', () => { document.documentElement.classList.contains('dark') || document.documentElement.classList.contains('light') ) + const entryTheme = (await getSettings(orcaPage)).theme const startingTheme = await getDocumentThemeClass(orcaPage) const oppositeTheme: 'dark' | 'light' = startingTheme === 'dark' ? 'light' : 'dark' const oppositeTileName = oppositeTheme === 'light' ? /Bright & crisp/ : /Easy on the eyes/ @@ -479,10 +504,10 @@ test.describe('Onboarding flow', () => { await expect(orcaPage.getByRole('heading', { name: REPO_STEP_HEADING })).toBeVisible() await expect .poll(async () => (await getSettings(orcaPage)).theme, { timeout: 5_000 }) - .toBe(oppositeTheme) + .toBe(entryTheme) await expect .poll(async () => getDocumentThemeClass(orcaPage), { timeout: 5_000 }) - .toBe(oppositeTheme) + .toBe(startingTheme) }) test('Skip preserves runtime server project setup UI', async ({ orcaPage }) => { diff --git a/tests/e2e/worktree.spec.ts b/tests/e2e/worktree.spec.ts index 38eb07dd2..b35941a2e 100644 --- a/tests/e2e/worktree.spec.ts +++ b/tests/e2e/worktree.spec.ts @@ -57,14 +57,11 @@ test.describe('Create Workspace', () => { const workspaceName = `e2e-create-${Date.now()}` try { - // 1. Open the composer. Using the store setter (not clicking the - // sidebar affordance) keeps the spec stable under sidebar refactors; - // the modal open path itself is not what #1186 broke. - await orcaPage.evaluate(() => { - window.__store?.getState().openModal('new-workspace-composer') - }) + // 1. Open the composer through the visible affordance so the lazy modal + // mount path stays covered along with the composer body. + await orcaPage.getByRole('button', { name: 'New workspace', exact: true }).click() - const dialog = orcaPage.getByRole('dialog', { name: /Create Workspace/i }) + const dialog = orcaPage.getByRole('dialog', { name: /Create (Workspace|Worktree)/i }) await expect(dialog).toBeVisible() // Wait for the composer to settle. The card fires several async effects @@ -96,10 +93,10 @@ test.describe('Create Workspace', () => { await expect(nameInput).toBeVisible() await nameInput.fill(workspaceName) - // 4. Click Create Workspace. This fires the full submitQuick path: + // 4. Click Create. This fires the full submitQuick path: // createWorktree IPC, applyWorktreeMeta, activateAndRevealWorktree, // and closeModal via onCreated. - const createButton = dialog.getByRole('button', { name: /Create Workspace/i }) + const createButton = dialog.getByRole('button', { name: /Create (Workspace|Worktree)/i }) await expect(createButton).toBeEnabled() await createButton.click()