diff --git a/tests/e2e/activity-agent-pane-isolation.spec.ts b/tests/e2e/activity-agent-pane-isolation.spec.ts index 12ac2f68dc6..54152407c0d 100644 --- a/tests/e2e/activity-agent-pane-isolation.spec.ts +++ b/tests/e2e/activity-agent-pane-isolation.spec.ts @@ -32,7 +32,7 @@ type SplitGroupTerminal = { } function agentsSidebarButton(page: Page) { - return page.getByRole('radio', { name: /^Agents$/ }).first() + return page.getByRole('button', { name: /View activity|Turn off activity view/i }).first() } async function seedActivityThread( diff --git a/tests/e2e/add-project-default-checkout.spec.ts b/tests/e2e/add-project-default-checkout.spec.ts index 0077fa6ff34..71c167697fc 100644 --- a/tests/e2e/add-project-default-checkout.spec.ts +++ b/tests/e2e/add-project-default-checkout.spec.ts @@ -4,6 +4,7 @@ import { mkdtemp } from 'node:fs/promises' import os from 'node:os' import path from 'node:path' import { test, expect } from './helpers/orca-app' +import { openAddProjectDialog } from './helpers/sidebar-navigation' import { waitForSessionReady } from './helpers/store' const tempRoots: string[] = [] @@ -86,10 +87,7 @@ test.describe('Add project default checkout', () => { await waitForSessionReady(orcaPage) const fixture = await createCloneFixture() - await orcaPage - .getByRole('button', { name: /Add Project/i }) - .first() - .click() + await openAddProjectDialog(orcaPage) const addDialog = orcaPage.getByRole('dialog', { name: /Add a project/i }) await expect(addDialog).toBeVisible() await addDialog.getByRole('button', { name: /Clone from URL/i }).click() diff --git a/tests/e2e/folder-setup-shallow-priority.spec.ts b/tests/e2e/folder-setup-shallow-priority.spec.ts index 15bccef63ee..abd0853b153 100644 --- a/tests/e2e/folder-setup-shallow-priority.spec.ts +++ b/tests/e2e/folder-setup-shallow-priority.spec.ts @@ -5,6 +5,7 @@ import os from 'node:os' import path from 'node:path' import type { ElectronApplication, Locator } from '@stablyai/playwright-test' import { test, expect } from './helpers/orca-app' +import { openAddProjectDialog } from './helpers/sidebar-navigation' import { waitForSessionReady } from './helpers/store' const tempRoots: string[] = [] @@ -166,10 +167,7 @@ test('prioritizes shallow sibling repositories in a bounded nested scan', async const fixture = await createShallowPriorityTruncationFixture() await chooseFolderInNativeDialog(electronApp, fixture.parentPath) - await orcaPage - .getByRole('button', { name: /Add Project/i }) - .first() - .click() + await openAddProjectDialog(orcaPage) const dialog = orcaPage.getByRole('dialog', { name: /Add a project/i }) await expect(dialog).toBeVisible() await dialog.getByRole('button', { name: /Browse folder/i }).click() @@ -256,10 +254,7 @@ test('can stop a nested repo scan and import repositories found so far', async ( }) await chooseFolderInNativeDialog(electronApp, fixture.parentPath) - await orcaPage - .getByRole('button', { name: /Add Project/i }) - .first() - .click() + await openAddProjectDialog(orcaPage) const dialog = orcaPage.getByRole('dialog', { name: /Add a project/i }) await dialog.getByRole('button', { name: /Browse folder/i }).click() diff --git a/tests/e2e/folder-setup.spec.ts b/tests/e2e/folder-setup.spec.ts index fc0f27824cc..8524b108165 100644 --- a/tests/e2e/folder-setup.spec.ts +++ b/tests/e2e/folder-setup.spec.ts @@ -4,6 +4,7 @@ import { mkdtemp } from 'node:fs/promises' import os from 'node:os' import path from 'node:path' import { test, expect } from './helpers/orca-app' +import { openAddProjectDialog } from './helpers/sidebar-navigation' import { waitForSessionReady } from './helpers/store' import type { ElectronApplication, Locator } from '@stablyai/playwright-test' @@ -122,10 +123,7 @@ test.describe('Folder setup', () => { const fixture = await createNestedRepoFixture() await chooseFolderInNativeDialog(electronApp, fixture.parentPath) - await orcaPage - .getByRole('button', { name: /Add Project/i }) - .first() - .click() + await openAddProjectDialog(orcaPage) const dialog = orcaPage.getByRole('dialog', { name: /Add a project/i }) await expect(dialog).toBeVisible() await dialog.getByRole('button', { name: /Browse folder/i }).click() @@ -190,10 +188,7 @@ test.describe('Folder setup', () => { const fixture = await createLargeNestedRepoFixture() await chooseFolderInNativeDialog(electronApp, fixture.parentPath) - await orcaPage - .getByRole('button', { name: /Add Project/i }) - .first() - .click() + await openAddProjectDialog(orcaPage) const dialog = orcaPage.getByRole('dialog', { name: /Add a project/i }) await expect(dialog).toBeVisible() await dialog.getByRole('button', { name: /Browse folder/i }).click() diff --git a/tests/e2e/golden-core-flows.spec.ts b/tests/e2e/golden-core-flows.spec.ts index 96863251081..4ab85d7644d 100644 --- a/tests/e2e/golden-core-flows.spec.ts +++ b/tests/e2e/golden-core-flows.spec.ts @@ -5,6 +5,7 @@ import os from 'node:os' import path from 'node:path' import type { ElectronApplication, Page } from '@stablyai/playwright-test' import { test, expect } from './helpers/orca-app' +import { openAddProjectDialog } from './helpers/sidebar-navigation' import { ensureTerminalVisible, waitForActiveWorktree, waitForSessionReady } from './helpers/store' import { countVisibleTerminalPanes, @@ -211,10 +212,7 @@ async function addProjectFromSidebar( repoPath: string ): Promise { await chooseFolderInNativeDialog(electronApp, repoPath) - await page - .getByRole('button', { name: /Add Project/i }) - .first() - .click() + await openAddProjectDialog(page) const addDialog = page.getByRole('dialog', { name: /Add a project/i }) await expect(addDialog).toBeVisible() await addDialog.getByRole('button', { name: /Browse folder/i }).click() diff --git a/tests/e2e/helpers/sidebar-navigation.ts b/tests/e2e/helpers/sidebar-navigation.ts new file mode 100644 index 00000000000..7f3965dde2a --- /dev/null +++ b/tests/e2e/helpers/sidebar-navigation.ts @@ -0,0 +1,16 @@ +import { expect, type Page } from '@stablyai/playwright-test' + +/** Open Add Project through the current sidebar/composer entry point. */ +export async function openAddProjectDialog(page: Page): Promise { + const legacyButton = page.getByRole('button', { name: /Add Project/i }).first() + if (await legacyButton.isVisible().catch(() => false)) { + await legacyButton.click() + } else { + await page + .getByRole('button', { name: /New workspace/i }) + .first() + .click() + await page.getByRole('button', { name: 'Add project', exact: true }).click() + } + await expect(page.getByRole('dialog', { name: /Add a project/i })).toBeVisible() +} diff --git a/tests/e2e/helpers/ssh-config-host-picker.ts b/tests/e2e/helpers/ssh-config-host-picker.ts index 482eb9ed84e..59142937359 100644 --- a/tests/e2e/helpers/ssh-config-host-picker.ts +++ b/tests/e2e/helpers/ssh-config-host-picker.ts @@ -7,6 +7,7 @@ import { mkdirSync, writeFileSync } from 'node:fs' import path from 'node:path' import type { ElectronApplication, Locator, Page } from '@stablyai/playwright-test' import { expect } from '@stablyai/playwright-test' +import { openAddProjectDialog } from './sidebar-navigation' export function makeSshConfigHostPrefix(): string { return `e2e-ssh-cfg-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}` @@ -101,10 +102,7 @@ export async function returnToAppShell(page: Page): Promise { /** Add Project → Host → Add remote host → Add SSH host → form dialog. */ export async function openAddSshHostDialog(page: Page): Promise { await returnToAppShell(page) - await page - .getByRole('button', { name: /Add Project/i }) - .first() - .click() + await openAddProjectDialog(page) const addProjectDialog = page.getByRole('dialog', { name: /Add a project/i }) await expect(addProjectDialog).toBeVisible({ timeout: 10_000 }) diff --git a/tests/e2e/multi-client-navigation-isolation.spec.ts b/tests/e2e/multi-client-navigation-isolation.spec.ts index c8a01eff636..39732835c65 100644 --- a/tests/e2e/multi-client-navigation-isolation.spec.ts +++ b/tests/e2e/multi-client-navigation-isolation.spec.ts @@ -5,6 +5,7 @@ import os from 'node:os' import path from 'node:path' import type { ElectronApplication, Page } from '@stablyai/playwright-test' import { test, expect } from './helpers/orca-app' +import { openAddProjectDialog } from './helpers/sidebar-navigation' import { worktreeRow, worktreeRowSurface } from './worktree-row-locators' type RuntimePairingOffer = { @@ -343,10 +344,7 @@ test('routes Add Project folder browsing through the paired host', async ({ const offer = await createPairingOffer(orcaPage) const client = await openPairedClient(electronApp, offer, visibleWorktreeId) try { - await client - .getByRole('button', { name: /Add Project/i }) - .first() - .click() + await openAddProjectDialog(client) const addDialog = client.getByRole('dialog', { name: /Add a project/i }) await expect(addDialog).toBeVisible() await expect(addDialog).not.toContainText('Local Mac') diff --git a/tests/e2e/paired-web-add-project-unavailable-host.spec.ts b/tests/e2e/paired-web-add-project-unavailable-host.spec.ts index 771feffdde7..20d569c0c9f 100644 --- a/tests/e2e/paired-web-add-project-unavailable-host.spec.ts +++ b/tests/e2e/paired-web-add-project-unavailable-host.spec.ts @@ -1,5 +1,6 @@ import type { ElectronApplication, Page, TestInfo } from '@stablyai/playwright-test' import { expect, test } from './helpers/orca-app' +import { openAddProjectDialog } from './helpers/sidebar-navigation' import { launchHeadlessPairedRuntimeHost, type HeadlessPairedRuntimeHost @@ -61,10 +62,7 @@ async function assertCreationActionsDisabled(args: { testInfo: TestInfo topology: 'headed' | 'headless' }): Promise { - await args.page - .getByRole('button', { name: /Add Project/i }) - .first() - .click() + await openAddProjectDialog(args.page) const dialog = args.page.getByRole('dialog', { name: /Add a project/i }) await expect(dialog).toBeVisible() const hostPicker = dialog.getByRole('combobox') diff --git a/tests/e2e/pr11346-selected-runtime-add.spec.ts b/tests/e2e/pr11346-selected-runtime-add.spec.ts index 93e49d4c4f2..8648589f499 100644 --- a/tests/e2e/pr11346-selected-runtime-add.spec.ts +++ b/tests/e2e/pr11346-selected-runtime-add.spec.ts @@ -6,6 +6,7 @@ import type { FolderWorkspace } from '../../src/shared/folder-workspace-types' import type { ProjectGroup } from '../../src/shared/project-group-types' import type { Repo } from '../../src/shared/repo-types' import { expect, test } from './helpers/orca-app' +import { openAddProjectDialog } from './helpers/sidebar-navigation' import { revealPairedClientWindow } from './helpers/paired-client-window-reveal' import { forwardRendererConsole } from './helpers/renderer-console-forwarding' import { @@ -22,10 +23,7 @@ import { } from './pr11346-selected-runtime-identity-oracle' async function selectRuntimeHost(page: Page, runtimeName: string): Promise { - await page - .getByRole('button', { name: /Add Project/i }) - .first() - .click() + await openAddProjectDialog(page) const dialog = page.getByRole('dialog', { name: /Add a project/i }) await expect(dialog).toBeVisible() const hostPicker = dialog.getByRole('combobox')