133 lines
4.8 KiB
TypeScript
133 lines
4.8 KiB
TypeScript
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);
|
||
}
|
||
});
|
||
});
|