test(e2e): update four stale e2e specs to match intentional product changes (#30115)

* test(e2e): repair specs that missed intentional product changes

Align still-stale e2e expectations with shipped product behavior:
- the Cmd+J placeholder names workspaces and tasks
- the worktree meta dialog is titled "Workspace details"
- OS-opened CSV/TSV files are editable and render as an ARIA grid
- the delayed-save notice carries the app toaster's close button

Fixes #30114

Co-authored-by: Neil <neil@stably.ai>

* test(e2e): stub host Linear status in linear-url-workspace-entry spec

Since #33270, Create worktree reads Linear status from the repo's host
(linear:status IPC) instead of the store, so the store-only fixture left
Linear disconnected in the composer and the pasted URL was never looked up.
Stub the linear:status handler with the same connected status.

---------

Co-authored-by: Neil <neil@stably.ai>
This commit is contained in:
Simon Cho
2026-10-27 10:15:28 -07:00
committed by GitHub
co-authored by Neil
parent 46c0a1f453
commit 13757d773d
4 changed files with 44 additions and 34 deletions
+36 -28
View File
@@ -3,6 +3,7 @@ import type { ElectronApplication, Page } from '@stablyai/playwright-test'
import { test, expect } from './helpers/orca-app'
import { waitForActiveWorktree, waitForSessionReady } from './helpers/store'
import type { LinearIssue } from '../../src/shared/linear/issue-types'
import type { LinearConnectionStatus } from '../../src/shared/linear/workspace-types'
const LINEAR_URL =
'https://linear.app/stably/issue/STA-4084/restore-osc-133-shell-integration-when-an-exec-in-user-rc-files-strips'
@@ -25,6 +26,31 @@ const LINEAR_ISSUE: LinearIssue = {
updatedAt: '2026-08-12T00:00:00.000Z'
}
const LINEAR_STATUS: LinearConnectionStatus = {
connected: true,
viewer: null,
activeWorkspaceId: 'workspace-other',
selectedWorkspaceId: 'workspace-other',
workspaces: [
{
id: 'workspace-other',
displayName: 'Other User',
email: null,
organizationId: 'organization-other',
organizationName: 'Other',
organizationUrlKey: 'other'
},
{
id: 'workspace-1',
displayName: 'Stably User',
email: null,
organizationId: 'organization-stably',
organizationName: 'Stably',
organizationUrlKey: 'stably'
}
]
}
declare global {
// oxlint-disable-next-line typescript-eslint/consistent-type-definitions -- declaration merging requires interface
interface Window {
@@ -43,37 +69,14 @@ async function installLinearFixture(
lookupDelayMs: number | null = 150
): Promise<void> {
await page.evaluate(
({ resolvedIssue, lookupDelayMs }) => {
({ resolvedIssue, lookupDelayMs, status }) => {
Reflect.deleteProperty(window, '__orcaTestReleaseLinearLookup')
const store = window.__store
if (!store) {
throw new Error('window.__store is not available')
}
store.setState({
linearStatus: {
connected: true,
viewer: null,
activeWorkspaceId: 'workspace-other',
selectedWorkspaceId: 'workspace-other',
workspaces: [
{
id: 'workspace-other',
displayName: 'Other User',
email: null,
organizationId: 'organization-other',
organizationName: 'Other',
organizationUrlKey: 'other'
},
{
id: 'workspace-1',
displayName: 'Stably User',
email: null,
organizationId: 'organization-stably',
organizationName: 'Stably',
organizationUrlKey: 'stably'
}
]
},
linearStatus: status,
linearStatusChecked: true,
checkLinearConnection: async () => {},
searchLinearIssues: async () => [],
@@ -88,7 +91,7 @@ async function installLinearFixture(
}
})
},
{ resolvedIssue: issue, lookupDelayMs }
{ resolvedIssue: issue, lookupDelayMs, status: LINEAR_STATUS }
)
}
@@ -121,9 +124,14 @@ async function openJumpPalette(electronApp: ElectronApplication): Promise<void>
}
test.describe('Linear URL workspace entry', () => {
test.beforeEach(async ({ orcaPage }) => {
test.beforeEach(async ({ electronApp, orcaPage }) => {
await waitForSessionReady(orcaPage)
await waitForActiveWorktree(orcaPage)
// Why: Create worktree reads Linear status from its repo's host, not the store.
await electronApp.evaluate(({ ipcMain }, status) => {
ipcMain.removeHandler('linear:status')
ipcMain.handle('linear:status', () => status)
}, LINEAR_STATUS)
await installLinearFixture(orcaPage)
})
@@ -210,7 +218,7 @@ test.describe('Linear URL workspace entry', () => {
await openJumpPalette(electronApp)
const palette = orcaPage.getByRole('dialog', { name: 'Jump to...' })
const input = palette.getByPlaceholder(
'Search chats, terminals, worktrees, settings, and actions...'
'Search chats, terminals, workspaces, tasks, settings, and actions...'
)
await expect(input).toBeVisible()
+4 -3
View File
@@ -36,15 +36,16 @@ for (const extension of ['md', 'csv', 'tsv'] as const) {
try {
launched = await session.launch({ extraArgs: [coldPath, pathToFileURL(coldPath).href] })
const { app, page } = launched
const table = page.getByRole('table')
// OS-opened CSVs are editable, so they render as an ARIA grid rather than a table.
const grid = page.getByRole('grid', { name: 'CSV editor' })
const coldResult =
extension === 'md'
? page.getByRole('heading', { name: 'Cold result' })
: table.getByRole('cell', { name: 'Cold result', exact: true })
: grid.getByRole('gridcell', { name: 'Cold result', exact: true })
const warmResult =
extension === 'md'
? page.getByRole('heading', { name: 'Warm result' })
: table.getByRole('cell', { name: 'Warm result', exact: true })
: grid.getByRole('gridcell', { name: 'Warm result', exact: true })
await expect(coldResult).toBeVisible()
await expect(page.getByText('42', { exact: true })).toBeVisible()
await expect(
+2 -1
View File
@@ -31,7 +31,8 @@ test('shows one delayed-save notice, restores it after reload, and clears on rec
await expect(notice).toHaveCount(1)
await expect(notice).toBeVisible()
await expect(notice).toContainText('Further saves may be delayed while this operation finishes.')
await expect(notice.getByRole('button')).toHaveCount(0)
// The app toaster's close button is the only control; the notice has no action button.
await expect(notice.getByRole('button')).toHaveAttribute('data-close-button')
await expect(notice).toHaveCSS('opacity', '1')
const screenshot = testInfo.outputPath('delayed-save-notice.png')
await orcaPage.screenshot({ path: screenshot })
+2 -2
View File
@@ -56,7 +56,7 @@ test.describe('Workspace emoji picker', () => {
})
})
const detailsDialog = orcaPage.getByRole('dialog', { name: 'Edit Worktree Details' })
const detailsDialog = orcaPage.getByRole('dialog', { name: 'Workspace details' })
const displayNameInput = detailsDialog.getByPlaceholder('Custom display name...')
await expect(displayNameInput).toBeFocused()
await displayNameInput.fill('Details proof')
@@ -72,7 +72,7 @@ test.describe('Workspace emoji picker', () => {
await orcaPage.evaluate(() => window.__store!.getState().openModal('worktree-palette'))
const palette = orcaPage.getByRole('dialog', { name: 'Jump to...' })
const paletteInput = palette.getByPlaceholder(
'Search chats, terminals, worktrees, settings, and actions...'
'Search chats, terminals, workspaces, tasks, settings, and actions...'
)
await expect(paletteInput).toBeFocused()
await captureProof(orcaPage, testInfo, 'cmd-j-before.png')