// @vitest-environment jsdom import { afterEach, beforeAll, describe, expect, it, vi } from 'vitest' import { cleanup, fireEvent, render, waitFor } from '@testing-library/react' import React from 'react' vi.mock('../src/renderer/src/terminals', () => { let n = 0 return { Terminal: () => null, lid: () => ++n } }) import { App } from '../src/renderer/src/App' import { ProjectProvider } from '../src/renderer/src/project' beforeAll(() => { globalThis.ResizeObserver = class { observe() {} unobserve() {} disconnect() {} } as never if (!Element.prototype.scrollIntoView) Element.prototype.scrollIntoView = () => {} }) afterEach(() => { cleanup(); localStorage.clear() }) function renderApp(): HTMLElement { return render().container } function find(c: HTMLElement, sel: string, text: string): HTMLElement | undefined { return Array.from(c.querySelectorAll(sel)).find((el) => el.textContent?.includes(text)) } describe('Pass on to Agent', () => { it('inserts " " via the agentPaste event', async () => { const received: string[] = [] const handler = (e: Event): void => { received.push((e as CustomEvent).detail) } window.addEventListener('agentPaste', handler) try { const c = renderApp() const treeRow = await waitFor(() => { const r = find(c, '.tree-row', 'store.js') if (!r) throw new Error('tree not ready') return r }) fireEvent.click(treeRow) const ta = await waitFor(() => { const t = c.querySelector('.ce-ta') if (!t) throw new Error('editor not ready') return t }) fireEvent.contextMenu(ta) const pass = await waitFor(() => { const item = find(c, '.ctx-item', 'Pass on to Agent') if (!item) throw new Error('menu not open') return item }) fireEvent.click(pass) const input = await waitFor(() => { const i = c.querySelector('.pass-input') if (!i) throw new Error('popup not open') return i }) fireEvent.change(input, { target: { value: 'look here' } }) fireEvent.keyDown(input, { key: 'Enter' }) await waitFor(() => expect(received.length).toBeGreaterThan(0)) expect(received[0]).toBe('look here public/assets/store.js:1') } finally { window.removeEventListener('agentPaste', handler) } }) }) describe('Stage + commit', () => { it('stages a file and commits via Shift+Enter (no commit button)', async () => { const c = renderApp() const row = await waitFor(() => { const r = find(c, '.git-row', 'UserController.php') if (!r) throw new Error('git not ready') return r }) fireEvent.click(row.querySelector('button[title="Stage changes"]')!) // the commit button is intentionally gone — committing is keyboard-only expect(c.querySelector('.commit-btn')).toBeNull() const msg = c.querySelector('.commit-input')! fireEvent.change(msg, { target: { value: 'wire up balance' } }) fireEvent.keyDown(msg, { key: 'Enter', shiftKey: true }) await waitFor(() => expect(find(c, '.toast', 'Committed')).toBeTruthy()) }) })