import sharp from 'sharp'; import { closeElectronApp, expect, getStableWindow, test, } from './fixtures/electron'; test.describe('OpenCode image compression composer', () => { test('preprocesses a 4K image and lets the user switch variants', async ({ launchElectronApp, }) => { const app = await launchElectronApp({ skipSetup: true }); try { await app.evaluate(async () => { const { ipcMain } = process.mainModule!.require('electron') as typeof import('electron'); const activeProject = { id: 'prj_e2e_compression', path: 'D:/e2e/image-compression', name: 'image-compression', createdAt: '2026-07-18T00:00:00.000Z', updatedAt: '2026-07-18T00:00:00.000Z', lastOpenedAt: '2026-07-18T00:00:00.000Z', }; const respond = (json: unknown, status = 200) => ({ ok: true, data: { status, ok: status >= 200 && status < 300, json, }, }); ipcMain.removeHandler('hostapi:fetch'); ipcMain.handle('hostapi:fetch', async ( _event: unknown, request: { path?: string; method?: string }, ) => { const path = request.path ?? ''; const method = request.method ?? 'GET'; if (path === '/api/opencode/status') { return respond({ state: 'running', port: 4096, url: 'http://127.0.0.1:4096', }); } if (path.startsWith('/api/opencode/projects')) { return respond({ projects: [activeProject], activeProject }); } if (path === '/api/opencode/config-summary') { return respond({ model: 'niancode-user-models/qwen3.7-plus', smallModel: null, providerIds: ['niancode-user-models'], providerCount: 1, }); } if (path === '/api/opencode/sessions') { return respond({ sessions: [{ id: 'ses_e2e_compression', title: 'Image compression', updatedAt: '2026-07-18T00:00:00.000Z', }], }); } if (path === '/api/opencode/sessions/status') { return respond({ statuses: { ses_e2e_compression: { type: 'idle' } }, }); } if ( path === '/api/opencode/sessions/ses_e2e_compression/messages' && method === 'GET' ) { return respond({ messages: [] }); } if (path.endsWith('/todos')) return respond({ todos: [] }); if (path === '/api/provider-accounts') return respond([]); if (path === '/api/provider-accounts/key-info') return respond([]); if (path === '/api/provider-vendors') return respond([]); if (path === '/api/provider-accounts/default') { return respond({ accountId: null }); } return respond({}); }); }); const page = await getStableWindow(app); await page.reload(); await expect(page.getByTestId('sidebar-nav-agent-chat')).toBeVisible(); await page.getByTestId('sidebar-nav-agent-chat').click(); await expect(page.getByTestId('opencode-message-composer')).toBeVisible(); const png = await sharp({ create: { width: 3840, height: 2160, channels: 4, background: { r: 64, g: 210, b: 200, alpha: 1 }, }, }).png().toBuffer(); await page.getByTestId('opencode-file-attachment-input').setInputFiles({ name: 'four-k.png', mimeType: 'image/png', buffer: png, }); const card = page.getByTestId('opencode-composer-attachment'); await expect(card).toContainText('3840×2160'); await expect(card).toContainText('1930×1086'); await expect(page.getByTestId('opencode-attachment-use-compressed')) .toHaveAttribute('aria-pressed', 'true'); await expect(page.getByTestId('opencode-attachment-token-estimate')) .toContainText('约2049 Token'); await page.getByTestId('opencode-attachment-use-original').click(); await expect(page.getByTestId('opencode-attachment-use-original')) .toHaveAttribute('aria-pressed', 'true'); await expect(page.getByTestId('opencode-attachment-token-estimate')) .toContainText('约8102 Token'); await page.getByTestId('opencode-attachment-use-compressed').click(); await expect(page.getByTestId('opencode-attachment-use-compressed')) .toHaveAttribute('aria-pressed', 'true'); await page.getByRole('button', { name: '移除附件 four-k.png' }).click(); await expect(card).toHaveCount(0); } finally { await closeElectronApp(app); } }); });