mirror of
https://github.com/stablyai/orca.git
synced 2026-10-21 16:03:26 +00:00
fix(win-e2e): keep overlay retries inside composer
This commit is contained in:
@@ -275,19 +275,30 @@ async function createWorkspaceFromSeededRepo(page, timeoutMs) {
|
||||
// timeout by another full click attempt.
|
||||
await newWorkspace.click({ timeout: 1 })
|
||||
}
|
||||
// Choose the plain-terminal mode (best-effort — if it is already the default
|
||||
// or the label differs, the create below still produces a worktree).
|
||||
await tryClickWithKnownOverlayRetry(
|
||||
page,
|
||||
page.getByRole('button', { name: 'Blank Terminal' }).first(),
|
||||
15_000
|
||||
)
|
||||
const composer = page.getByRole('dialog', { name: 'Create worktree' }).last()
|
||||
await composer.waitFor({ state: 'visible', timeout: 15_000 })
|
||||
const agentPicker = composer
|
||||
.locator('[data-agent-combobox-root="true"] button[role="combobox"]')
|
||||
.first()
|
||||
const selectedAgent = await agentPicker.innerText({ timeout: 15_000 }).catch(() => '')
|
||||
if (!selectedAgent.includes('Blank Terminal')) {
|
||||
if (!(await tryClickWithKnownOverlayRetry(page, agentPicker, 15_000))) {
|
||||
await agentPicker.click({ timeout: 1 })
|
||||
}
|
||||
const blankTerminalOption = page
|
||||
.locator('[data-agent-combobox-root="true"] [data-slot="command-item"]:visible')
|
||||
.filter({ hasText: 'Blank Terminal' })
|
||||
.first()
|
||||
if (!(await tryClickWithKnownOverlayRetry(page, blankTerminalOption, 15_000))) {
|
||||
await blankTerminalOption.click({ timeout: 1 })
|
||||
}
|
||||
}
|
||||
// Submit. The create button's accessible name carries the shortcut hint
|
||||
// ("Create worktreeCtrl"), so match by prefix; fall back to the documented
|
||||
// Ctrl+Enter shortcut if the button is not directly clickable.
|
||||
const created = await tryClickWithKnownOverlayRetry(
|
||||
page,
|
||||
page.getByRole('button', { name: /^Create worktree/ }).last(),
|
||||
composer.getByRole('button', { name: /^Create worktree/ }).last(),
|
||||
15_000
|
||||
)
|
||||
if (!created) {
|
||||
@@ -296,18 +307,21 @@ async function createWorkspaceFromSeededRepo(page, timeoutMs) {
|
||||
}
|
||||
|
||||
const OVERLAY_DISMISS_LABELS = ['Got it', 'Dismiss setup scripts', 'Dismiss tip', 'Dismiss update']
|
||||
const DIALOG_CLOSE_BUTTON = '[data-slot="dialog-content"]:visible [data-slot="dialog-close"]'
|
||||
const CLI_FEATURE_TIP_TITLE = 'Let agents drive Orca with the Orca CLI'
|
||||
|
||||
async function dismissKnownOverlays(page) {
|
||||
let acted = false
|
||||
// Why: a global "Close" role also matches the Windows/Linux title-bar button.
|
||||
const dialogClose = page.locator(DIALOG_CLOSE_BUTTON).first()
|
||||
if (await dialogClose.isVisible().catch(() => false)) {
|
||||
const clicked = await dialogClose
|
||||
.click({ timeout: 3_000 })
|
||||
.then(() => true)
|
||||
.catch(() => false)
|
||||
acted ||= clicked
|
||||
const cliFeatureTip = page.getByRole('dialog', { name: CLI_FEATURE_TIP_TITLE }).first()
|
||||
if (await cliFeatureTip.isVisible().catch(() => false)) {
|
||||
// Why: a global "Close" role also matches the Windows/Linux title-bar button.
|
||||
const dialogClose = cliFeatureTip.locator('[data-slot="dialog-close"]').first()
|
||||
if (await dialogClose.isVisible().catch(() => false)) {
|
||||
const clicked = await dialogClose
|
||||
.click({ timeout: 3_000 })
|
||||
.then(() => true)
|
||||
.catch(() => false)
|
||||
acted ||= clicked
|
||||
}
|
||||
}
|
||||
for (const name of OVERLAY_DISMISS_LABELS) {
|
||||
const btn = page.getByRole('button', { name }).first()
|
||||
|
||||
@@ -23,10 +23,20 @@ describe('dismissOverlays', () => {
|
||||
click: vi.fn().mockRejectedValue(new Error('window closed'))
|
||||
}
|
||||
windowClose.first.mockReturnValue(windowClose)
|
||||
const featureTipDialog = {
|
||||
first: vi.fn(),
|
||||
isVisible: vi.fn().mockResolvedValue(true),
|
||||
locator: vi.fn().mockReturnValue(dialogClose)
|
||||
}
|
||||
featureTipDialog.first.mockReturnValue(featureTipDialog)
|
||||
|
||||
const page = {
|
||||
locator: vi.fn().mockReturnValue(dialogClose),
|
||||
getByRole: vi.fn((_role, { name }) => (name === 'Close' ? windowClose : hiddenButton())),
|
||||
getByRole: vi.fn((role, { name }) => {
|
||||
if (role === 'dialog') {
|
||||
return featureTipDialog
|
||||
}
|
||||
return name === 'Close' ? windowClose : hiddenButton()
|
||||
}),
|
||||
keyboard: { press: vi.fn().mockResolvedValue(undefined) },
|
||||
waitForTimeout: vi.fn().mockResolvedValue(undefined)
|
||||
}
|
||||
@@ -35,9 +45,9 @@ describe('dismissOverlays', () => {
|
||||
|
||||
expect(dialogClose.click).toHaveBeenCalledOnce()
|
||||
expect(windowClose.click).not.toHaveBeenCalled()
|
||||
expect(page.locator).toHaveBeenCalledWith(
|
||||
'[data-slot="dialog-content"]:visible [data-slot="dialog-close"]'
|
||||
)
|
||||
expect(page.getByRole).toHaveBeenCalledWith('dialog', {
|
||||
name: 'Let agents drive Orca with the Orca CLI'
|
||||
})
|
||||
})
|
||||
|
||||
it('keeps overlay retries within the caller timeout budget', async () => {
|
||||
@@ -53,9 +63,12 @@ describe('dismissOverlays', () => {
|
||||
newWorkspace.first.mockReturnValue(newWorkspace)
|
||||
const page = {
|
||||
locator: vi.fn().mockImplementation(() => hiddenButton()),
|
||||
getByRole: vi.fn((_role, { name }) =>
|
||||
name === 'New workspace' ? newWorkspace : hiddenButton()
|
||||
),
|
||||
getByRole: vi.fn((role, { name }) => {
|
||||
if (role === 'dialog') {
|
||||
return hiddenButton()
|
||||
}
|
||||
return name === 'New workspace' ? newWorkspace : hiddenButton()
|
||||
}),
|
||||
keyboard: { press: vi.fn().mockResolvedValue(undefined) },
|
||||
isClosed: vi.fn().mockReturnValue(false)
|
||||
}
|
||||
@@ -71,4 +84,71 @@ describe('dismissOverlays', () => {
|
||||
vi.useRealTimers()
|
||||
}
|
||||
})
|
||||
|
||||
it('submits within the composer without reopening the selected Blank Terminal picker', async () => {
|
||||
const newWorkspace = {
|
||||
first: vi.fn(),
|
||||
click: vi.fn().mockResolvedValue(undefined)
|
||||
}
|
||||
newWorkspace.first.mockReturnValue(newWorkspace)
|
||||
const agentPicker = {
|
||||
first: vi.fn(),
|
||||
innerText: vi.fn().mockResolvedValue('Blank Terminal'),
|
||||
click: vi.fn()
|
||||
}
|
||||
agentPicker.first.mockReturnValue(agentPicker)
|
||||
const createWorktree = {
|
||||
last: vi.fn(),
|
||||
click: vi
|
||||
.fn()
|
||||
.mockRejectedValueOnce(new Error('submit was briefly intercepted'))
|
||||
.mockResolvedValueOnce(undefined)
|
||||
}
|
||||
createWorktree.last.mockReturnValue(createWorktree)
|
||||
const composer = {
|
||||
last: vi.fn(),
|
||||
waitFor: vi.fn().mockResolvedValue(undefined),
|
||||
locator: vi.fn().mockReturnValue(agentPicker),
|
||||
getByRole: vi.fn().mockReturnValue(createWorktree)
|
||||
}
|
||||
composer.last.mockReturnValue(composer)
|
||||
const xterm = {
|
||||
first: vi.fn(),
|
||||
waitFor: vi.fn().mockResolvedValue(undefined)
|
||||
}
|
||||
xterm.first.mockReturnValue(xterm)
|
||||
const terminalSurface = {
|
||||
first: vi.fn(),
|
||||
isVisible: vi.fn().mockResolvedValue(false),
|
||||
waitFor: vi.fn().mockResolvedValue(undefined),
|
||||
locator: vi.fn().mockReturnValue(xterm)
|
||||
}
|
||||
terminalSurface.first.mockReturnValue(terminalSurface)
|
||||
const unintendedDialogClose = {
|
||||
first: vi.fn(),
|
||||
isVisible: vi.fn().mockResolvedValue(true),
|
||||
click: vi.fn().mockResolvedValue(undefined)
|
||||
}
|
||||
unintendedDialogClose.first.mockReturnValue(unintendedDialogClose)
|
||||
const page = {
|
||||
locator: vi.fn((selector) =>
|
||||
selector.includes('dialog-close') ? unintendedDialogClose : terminalSurface
|
||||
),
|
||||
getByRole: vi.fn((role, { name }) => {
|
||||
if (role === 'dialog') {
|
||||
return name === 'Create worktree' ? composer : hiddenButton()
|
||||
}
|
||||
return name === 'New workspace' ? newWorkspace : hiddenButton()
|
||||
}),
|
||||
keyboard: { press: vi.fn().mockResolvedValue(undefined) },
|
||||
isClosed: vi.fn().mockReturnValue(false)
|
||||
}
|
||||
|
||||
await ensureTerminal(page)
|
||||
|
||||
expect(agentPicker.click).not.toHaveBeenCalled()
|
||||
expect(composer.getByRole).toHaveBeenCalledWith('button', { name: /^Create worktree/ })
|
||||
expect(unintendedDialogClose.click).not.toHaveBeenCalled()
|
||||
expect(createWorktree.click).toHaveBeenCalledTimes(2)
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user