Extract add-project navigation into reusable helper with UI transition f

Sidebar navigation is transitioning to a new composer-based entry point. Extract
openAddProjectDialog() helper to support both legacy and new patterns:
- Legacy: direct "Add Project" button click
- New: "New workspace" → "Add project" menu flow

Updates all test files that open the add project dialog to use the helper,
ensuring tests continue working through the UI transition. Also fixes the agents
sidebar button selector to target the activity toggle button instead of a radio.
This commit is contained in:
Jinjing
2026-09-03 11:35:23 -07:00
parent f2ddf7779f
commit 8dea573cf9
10 changed files with 35 additions and 41 deletions
@@ -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(
@@ -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()
@@ -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()
+3 -8
View File
@@ -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()
+2 -4
View File
@@ -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<void> {
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()
+16
View File
@@ -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<void> {
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()
}
+2 -4
View File
@@ -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<void> {
/** Add Project → Host → Add remote host → Add SSH host → form dialog. */
export async function openAddSshHostDialog(page: Page): Promise<Locator> {
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 })
@@ -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')
@@ -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<void> {
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')
@@ -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<Locator> {
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')