test: remove low-value sidebar and prompt disclosure suites

This commit is contained in:
OrcaWin
2026-11-12 16:54:05 -08:00
parent 56f8bf5f01
commit df7daeb41d
3 changed files with 0 additions and 352 deletions
@@ -1,144 +0,0 @@
// @vitest-environment happy-dom
import { act, cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { TooltipProvider } from '@/components/ui/tooltip'
import { AutomationPromptDisclosure } from './AutomationPromptDisclosure'
const END_MARKER = 'SYNTHETIC-END-MARKER'
const LONG_PROMPT = [
'Synthetic prompt preview validation only.',
'',
...Array.from(
{ length: 20 },
(_, index) =>
`Synthetic step ${index + 1}: inspect placeholder input and summarize placeholder output.`
),
'',
END_MARKER
].join('\n')
// Why: happy-dom has no layout, so the clamped paragraph's overflow is driven by these values.
const layout = { scrollHeight: 0, clientHeight: 0 }
const resizeCallbacks = new Set<() => void>()
class ResizeObserverStub {
private readonly callback: () => void
constructor(callback: () => void) {
this.callback = callback
}
observe(): void {
resizeCallbacks.add(this.callback)
}
unobserve(): void {}
disconnect(): void {
resizeCallbacks.delete(this.callback)
}
}
const writeClipboardText = vi.fn<(text: string) => Promise<void>>()
beforeEach(() => {
layout.scrollHeight = 0
layout.clientHeight = 0
vi.spyOn(HTMLElement.prototype, 'scrollHeight', 'get').mockImplementation(
() => layout.scrollHeight
)
vi.spyOn(HTMLElement.prototype, 'clientHeight', 'get').mockImplementation(
() => layout.clientHeight
)
vi.stubGlobal('ResizeObserver', ResizeObserverStub)
writeClipboardText.mockReset().mockResolvedValue(undefined)
Object.assign(window, { api: { ui: { writeClipboardText } } })
})
afterEach(() => {
cleanup()
resizeCallbacks.clear()
vi.restoreAllMocks()
vi.unstubAllGlobals()
})
function renderPrompt(prompt: string): void {
render(
<TooltipProvider>
<AutomationPromptDisclosure prompt={prompt} />
</TooltipProvider>
)
}
function promptFor(toggle: HTMLElement): HTMLElement {
const id = toggle.getAttribute('aria-controls')
const element = id ? document.getElementById(id) : null
if (!element) {
throw new Error('Toggle does not control a prompt element')
}
return element
}
describe('AutomationPromptDisclosure', () => {
it('shows a short prompt in full without an expand control', () => {
layout.scrollHeight = 40
layout.clientHeight = 40
renderPrompt('Synthetic short prompt.')
expect(screen.getByText('Synthetic short prompt.')).toBeTruthy()
expect(screen.queryByRole('button', { name: 'Show more' })).toBeNull()
})
it('collapses a long prompt behind Show more and reveals all of it on expand', () => {
layout.scrollHeight = 600
layout.clientHeight = 160
renderPrompt(LONG_PROMPT)
const showMore = screen.getByRole('button', { name: 'Show more' })
expect(showMore.getAttribute('aria-expanded')).toBe('false')
const prompt = promptFor(showMore)
expect(prompt.textContent).toBe(LONG_PROMPT)
showMore.focus()
fireEvent.click(showMore)
const showLess = screen.getByRole('button', { name: 'Show less' })
expect(showLess.getAttribute('aria-expanded')).toBe('true')
expect(document.activeElement).toBe(showLess)
expect(promptFor(showLess)).toBe(prompt)
expect(prompt.textContent).toContain(END_MARKER)
fireEvent.click(showLess)
expect(screen.getByRole('button', { name: 'Show more' }).getAttribute('aria-expanded')).toBe(
'false'
)
})
it('drops the expand control and keeps focus on the prompt when it stops overflowing', () => {
layout.scrollHeight = 300
layout.clientHeight = 160
renderPrompt(`Synthetic resize focus validation. ${'placeholder '.repeat(48)}`)
const showMore = screen.getByRole('button', { name: 'Show more' })
const prompt = promptFor(showMore)
showMore.focus()
layout.scrollHeight = 160
act(() => {
for (const callback of resizeCallbacks) {
callback()
}
})
expect(screen.queryByRole('button', { name: 'Show more' })).toBeNull()
expect(document.activeElement).toBe(prompt)
})
it('copies the full prompt text', async () => {
layout.scrollHeight = 600
layout.clientHeight = 160
renderPrompt(LONG_PROMPT)
fireEvent.click(screen.getByRole('button', { name: 'Copy prompt' }))
expect(writeClipboardText).toHaveBeenCalledTimes(1)
expect(writeClipboardText).toHaveBeenCalledWith(LONG_PROMPT)
await waitFor(() => expect(screen.getByRole('button', { name: 'Copied' })).toBeTruthy())
})
})
@@ -1,72 +0,0 @@
// @vitest-environment happy-dom
import { act } from 'react'
import { createRoot } from 'react-dom/client'
import { expect, it, vi } from 'vitest'
import { createUIStore } from '@/store/slices/ui/ui-slice-test-harness'
import { useSidebarWorkspaceDeleteKeyboard } from './use-sidebar-workspace-delete-keyboard'
import { resolveSidebarWorkspaceDeleteIntent } from './sidebar-workspace-delete'
import { repo, worktree } from '../grouping/worktree-list-groups-test-fixtures'
const store = createUIStore()
vi.mock('@/store', () => ({ useAppStore: { getState: () => store.getState() } }))
vi.mock('../../workspace-actions/deletion/delete-worktree-flow', () => ({
runWorktreeDelete: vi.fn(),
runWorktreeBatchDelete: vi.fn()
}))
vi.mock('../../workspace-actions/deletion/folder-workspace-delete', () => ({
deleteFolderWorkspaceUnlessUnsaved: vi.fn()
}))
Object.assign(globalThis, { IS_REACT_ACT_ENVIRONMENT: true })
it('resolves the initial delete gesture once and never resolves held repeats at fleet scale', () => {
store.setState({ repos: [repo], deleteStateByWorktreeId: {} })
for (const size of [750, 7500]) {
const selectedWorktrees = Array.from({ length: size }, (_, index) => ({
...worktree,
id: `primary-${index}`,
isMainWorktree: true
}))
const resolve = vi.fn(() =>
resolveSidebarWorkspaceDeleteIntent({
selectedWorktrees,
focusedWorktree: selectedWorktrees[0],
repoMap: new Map([[repo.id, repo]])
})
)
function Probe() {
const keyboard = useSidebarWorkspaceDeleteKeyboard({
keybindings: {},
resolveDeleteIntent: resolve,
dropPreview: () => {}
})
return <div tabIndex={0} onKeyDown={keyboard.handleDeleteKeyDown} />
}
const container = document.createElement('div')
document.body.append(container)
const root = createRoot(container)
try {
act(() => root.render(<Probe />))
const target = container.firstElementChild!
for (let index = 0; index < 21; index++) {
act(() =>
target.dispatchEvent(
new KeyboardEvent('keydown', {
bubbles: true,
cancelable: true,
key: 'Backspace',
code: 'Backspace',
shiftKey: true,
metaKey: navigator.userAgent.includes('Mac'),
ctrlKey: !navigator.userAgent.includes('Mac'),
repeat: index > 0
})
)
)
}
expect(resolve).toHaveBeenCalledTimes(1)
} finally {
act(() => root.unmount())
container.remove()
}
}
})
@@ -1,136 +0,0 @@
// @vitest-environment happy-dom
import type { ComponentProps } from 'react'
import { act, cleanup, fireEvent, render } from '@testing-library/react'
import { afterEach, expect, it, vi } from 'vitest'
import { useAppStore } from '@/store'
import { TooltipProvider } from '@/components/ui/tooltip'
import WorktreeContextMenu from '../../workspace-actions/context-menu/WorktreeContextMenu'
import type WorktreeCard from '../../workspace-card/surface/WorktreeCard'
import { renderFolderWorkspaceOption, type FolderWorkspaceRowContext } from './folder-row'
import type { FolderWorkspaceItemRow } from '../listing/renderable-rows'
import { WORKTREE_ROW_DRAG_INITIAL_STATE } from '../drag/row-state'
import { folderWorkspaceToWorktree } from '../../../../../../shared/folder-workspaces/folder-workspace-worktree'
import type { Worktree } from '../../../../../../shared/worktree/types'
import { worktree } from '../grouping/worktree-list-groups-test-fixtures'
// Keep the real menu model/view at the card prop seam; omit unrelated card presentation.
vi.mock('../../workspace-card/surface/WorktreeCard', () => ({
default: (props: ComponentProps<typeof WorktreeCard>) => (
<WorktreeContextMenu
worktree={props.worktree}
selectedWorktrees={props.selectedWorktrees}
onContextMenuSelect={(event) =>
props.onContextMenuSelect?.(event, props.worktree) ?? [props.worktree]
}
>
<span>{props.worktree.displayName}</span>
</WorktreeContextMenu>
)
}))
afterEach(() => {
cleanup()
useAppStore.setState(useAppStore.getInitialState(), true)
})
it.each([750, 7500])(
'does no aggregate selection work for closed folder menus at %i selected rows',
(size) => {
const folders: FolderWorkspaceItemRow[] = Array.from({ length: 10 }, (_, index) => ({
type: 'folder-workspace',
key: `folder-${index}`,
depth: 0,
groupDepth: 0,
projectGroup: {
id: 'group',
name: 'Folders',
parentPath: null,
parentGroupId: null,
createdFrom: 'manual',
tabOrder: 0,
isCollapsed: false,
color: null,
createdAt: 0,
updatedAt: 0
},
folderWorkspace: {
id: `folder-${index}`,
projectGroupId: 'group',
name: `Folder ${index}`,
folderPath: `/tmp/tri35-folder-${index}`,
linkedTask: null,
comment: '',
isArchived: false,
isUnread: false,
isPinned: false,
sortOrder: index,
lastActivityAt: 0,
createdAt: 0,
updatedAt: 0
}
}))
let selectedOwnerReads = 0
const selection = Array.from({ length: size }, (_, index): Worktree => {
const item =
index < folders.length
? folderWorkspaceToWorktree(folders[index].folderWorkspace)
: { ...worktree, id: `worktree-${index}` }
Object.defineProperty(item, 'runtimeOwnerEnvironmentId', {
get: () => {
selectedOwnerReads += 1
return undefined
}
})
return item
})
// The list owns this collection; unopened folder menus must not traverse it.
const ctx: FolderWorkspaceRowContext & { selectedWorktrees: readonly Worktree[] } = {
groupBy: 'none',
newCardStyle: false,
settings: null,
activeWorktreeId: null,
activeWorkspaceExecutionHostId: null,
currentWorktreeId: null,
selectedWorktreeIds: new Set(folders.map((row) => `local|folder:${row.folderWorkspace.id}`)),
selectedWorktrees: selection,
repoMap: new Map(),
worktreeMap: new Map(),
worktreeLineageById: {},
workspaceLineageByChildKey: {},
crossStoreChildrenByFolderId: new Map(),
prCache: null,
hostedReviewCache: null,
getCachedFolderWorkspacePathStatus: () => null,
onSelectionGesture: () => false,
onContextMenuSelect: () => selection,
onImmediateActivate: () => {},
onRowClickCapture: () => {},
onRowPointerDown: () => {},
worktreeDragState: WORKTREE_ROW_DRAG_INITIAL_STATE,
nativeLineageDropTargetIdentity: null
}
const view = render(
<TooltipProvider>
{folders.map((row) => renderFolderWorkspaceOption({ ctx, row }))}
</TooltipProvider>
)
expect(selectedOwnerReads).toBe(0)
view.rerender(
<TooltipProvider>
{folders.map((row) =>
renderFolderWorkspaceOption({
ctx: { ...ctx, selectedWorktreeIds: new Set(ctx.selectedWorktreeIds) },
row
})
)}
</TooltipProvider>
)
// Ten mounted folders require zero selected-row owner lookups until a menu opens, at either fleet size.
expect(selectedOwnerReads).toBe(0)
const first = view.container.querySelector('[data-worktree-context-menu-scope]')
if (!(first instanceof HTMLElement)) {
throw new Error('Missing folder menu scope')
}
act(() => fireEvent.contextMenu(first))
expect(selectedOwnerReads).toBeGreaterThan(0)
}
)