feat: 改造云智能体桌面编辑与试用工作区
This commit is contained in:
@@ -8,7 +8,8 @@ test('personal cloud Agent creation, draft save and leave protection in Electron
|
||||
const applicationUrl = page.url();
|
||||
await page.goto('about:blank');
|
||||
// This UI test owns the Host API boundary; real cloud HTTP/PG is tested separately.
|
||||
await app.evaluate(({ ipcMain }) => {
|
||||
await app.evaluate(({ ipcMain, BrowserWindow }) => {
|
||||
BrowserWindow.getAllWindows()[0].setSize(1366, 768);
|
||||
let draft: Record<string, unknown> | null = null;
|
||||
let recent: unknown = null;
|
||||
let limits: { request_limit_points: string | null; daily_limit_points: string | null } = { request_limit_points: null, daily_limit_points: null };
|
||||
@@ -52,7 +53,7 @@ test('personal cloud Agent creation, draft save and leave protection in Electron
|
||||
if (body.operation === 'submit' || body.operation === 'preview') return result({ request_id: input.request_id, thread_id: 'thread-1', run_id: 'run-1', version: '1', status: 'dispatched' });
|
||||
if (body.operation === 'history') return result({ thread_id: 'thread-1', next_offset: null,
|
||||
queued_requests: [], schedule_proposals: [{ id: 'proposal', name: '每天整理选题', prompt: '每天给我三个适合个人创作的选题', cron_expression: '30 8 * * *', timezone: 'Asia/Shanghai' }],
|
||||
messages: [{ id: 1, role: 'assistant', content: '## 创作建议\n先从一个真实的观察开始。' }],
|
||||
messages: [{ id: 1, role: 'assistant', content: '## 创作建议\n先从一个真实的观察开始。\n\n' + '记录今天的一次观察,把具体场景、你的感受和想分享的发现写下来。\n\n'.repeat(22) }],
|
||||
run: { agent_run_id: 'run-1', request_id: 'request-1', thread_id: 'thread-1', status: 'completed', version: '1' } });
|
||||
if (body.operation === 'viewed') return result({ viewed: true });
|
||||
if (body.operation === 'attachments') return result({ attachments: [] });
|
||||
@@ -64,7 +65,7 @@ test('personal cloud Agent creation, draft save and leave protection in Electron
|
||||
draft_revision: 1, updated_at: '2026-09-10T00:00:00Z',
|
||||
configuration, published_version: null, enabled: true,
|
||||
};
|
||||
if (method === 'PATCH') draft = { ...draft, name: body.name, purpose: body.purpose, system_prompt: body.system_prompt, configuration: body.configuration, draft_revision: 2 };
|
||||
if (method === 'PATCH') draft = { ...draft, name: body.name, purpose: body.purpose, system_prompt: body.system_prompt, configuration: body.configuration, draft_revision: Number(draft?.draft_revision ?? 1) + 1 };
|
||||
if (method === 'GET' && (path.endsWith('/agents') || path.endsWith('/bootstrap'))) return result({ agents: draft ? [draft] : [], next_cursor: null });
|
||||
return result(draft);
|
||||
}
|
||||
@@ -81,29 +82,87 @@ test('personal cloud Agent creation, draft save and leave protection in Electron
|
||||
await page.getByRole('button', { name: '创建草稿', exact: true }).click();
|
||||
await expect(page.getByTestId('cloud-agent-editor')).toBeVisible();
|
||||
await page.getByLabel('角色与指令').fill('使用简洁自然的中文。先理解我的目的,再协助梳理结构。');
|
||||
await page.getByRole('button', { name: '能力', exact: true }).click();
|
||||
await page.getByLabel('模型', { exact: true }).selectOption('test-model');
|
||||
await page.getByTestId('sidebar-module-switcher-trigger').click();
|
||||
await expect(page.getByRole('dialog', { name: '未保存的修改' })).toBeVisible();
|
||||
await page.getByRole('button', { name: '继续编辑', exact: true }).click();
|
||||
await page.getByRole('button', { name: '保存草稿', exact: true }).click();
|
||||
await expect(page.getByRole('button', { name: '已保存', exact: true })).toBeVisible();
|
||||
await expect(page.getByTestId('titlebar-page-title')).toHaveText('智能体工作区');
|
||||
await page.getByRole('button', { name: '指令', exact: true }).click();
|
||||
const preview = page.getByRole('region', { name: '草稿预览', exact: true });
|
||||
await preview.getByLabel('消息').fill('先给我一些创作建议');
|
||||
await preview.getByLabel('消息').press('Enter');
|
||||
await expect(preview.getByRole('heading', { name: '创作建议' })).toBeAttached();
|
||||
const composer = preview.getByTestId('cloud-chat-composer');
|
||||
const beforeScroll = await composer.boundingBox();
|
||||
await preview.getByTestId('cloud-chat-messages').evaluate(el => { el.scrollTop = 0; });
|
||||
await expect.poll(async () => (await composer.boundingBox())?.y).toBe(beforeScroll?.y);
|
||||
await expect.poll(() => page.getByTestId('main-content').evaluate(el => el.scrollHeight - el.clientHeight)).toBeLessThanOrEqual(1);
|
||||
expect(beforeScroll!.y + beforeScroll!.height).toBeLessThanOrEqual(await page.evaluate(() => innerHeight));
|
||||
await preview.getByLabel('消息').fill('保存后继续的问题');
|
||||
await preview.getByLabel('消息').press('F6');
|
||||
await expect(page.getByRole('region', { name: '草稿配置', exact: true }).getByRole('button', { name: '展开配置' })).toBeFocused();
|
||||
await page.getByLabel('角色与指令').fill('使用简洁自然的中文。先理解我的目的,再协助梳理结构。补充具体例子。');
|
||||
await page.getByLabel('角色与指令').press('Control+s');
|
||||
await expect(page.getByText('云端已保存', { exact: true })).toBeVisible();
|
||||
await expect(preview.getByLabel('消息')).toHaveValue('保存后继续的问题');
|
||||
await expect(preview.getByRole('heading', { name: '创作建议' })).toBeAttached();
|
||||
await expect(preview.getByText('草稿预览 · 修订 2')).toBeVisible();
|
||||
const divider = page.getByRole('separator', { name: '调整配置与试用宽度' });
|
||||
await divider.focus();
|
||||
const previousRatio = Number(await divider.getAttribute('aria-valuenow'));
|
||||
await divider.press('ArrowRight');
|
||||
await expect(divider).toHaveAttribute('aria-valuenow', String(previousRatio + 2));
|
||||
const handle = await divider.boundingBox();
|
||||
await page.mouse.move(handle!.x + 4, handle!.y + 80);
|
||||
await page.mouse.down();
|
||||
await page.mouse.move(handle!.x - 35, handle!.y + 80);
|
||||
await page.mouse.up();
|
||||
expect(Number(await divider.getAttribute('aria-valuenow'))).toBeLessThan(previousRatio + 2);
|
||||
await page.getByRole('button', { name: '展开试用', exact: true }).click();
|
||||
await expect(page.getByRole('region', { name: '草稿配置', exact: true })).toBeHidden();
|
||||
await page.keyboard.press('Escape');
|
||||
await expect(page.getByRole('region', { name: '草稿配置', exact: true })).toBeVisible();
|
||||
await page.screenshot({ path: testInfo.outputPath('cloud-agent-editor.png') });
|
||||
await app.evaluate(({ BrowserWindow }) => { const win = BrowserWindow.getAllWindows()[0]; win.setMinimumSize(800, 600); win.setSize(980, 680); });
|
||||
await expect(divider).toBeHidden();
|
||||
await page.getByRole('button', { name: '试用', exact: true }).click();
|
||||
await expect(preview.getByLabel('消息')).toHaveValue('保存后继续的问题');
|
||||
await expect.poll(async () => {
|
||||
const bounds = await composer.boundingBox();
|
||||
return bounds!.y + bounds!.height - await page.evaluate(() => innerHeight);
|
||||
}).toBeLessThanOrEqual(0);
|
||||
await page.screenshot({ path: testInfo.outputPath('cloud-agent-compact.png') });
|
||||
await app.evaluate(({ BrowserWindow }) => BrowserWindow.getAllWindows()[0].setSize(1366, 768));
|
||||
for (const factor of [1.25, 1.5]) {
|
||||
await app.evaluate(({ BrowserWindow }, zoom) => BrowserWindow.getAllWindows()[0].webContents.setZoomFactor(zoom), factor);
|
||||
if (await page.getByRole('button', { name: '试用', exact: true }).isVisible()) await page.getByRole('button', { name: '试用', exact: true }).click();
|
||||
await expect.poll(async () => { const bounds = await composer.boundingBox(); return bounds!.y + bounds!.height - await page.evaluate(() => innerHeight); }).toBeLessThanOrEqual(0);
|
||||
}
|
||||
await app.evaluate(({ BrowserWindow }) => BrowserWindow.getAllWindows()[0].webContents.setZoomFactor(1));
|
||||
await preview.getByRole('button', { name: '用最新草稿试用' }).click();
|
||||
await expect(preview.getByText('草稿预览 · 修订 3')).toBeVisible();
|
||||
await expect(preview.getByLabel('消息')).toHaveValue('保存后继续的问题');
|
||||
await preview.getByLabel('消息').fill('');
|
||||
await page.getByTestId('sidebar-module-switcher-trigger').click();
|
||||
await expect(page.getByTestId('ai-module-selection-page')).toBeVisible();
|
||||
await page.getByTestId('ai-module-option-cloud_agents').click();
|
||||
await expect(page.getByTestId('cloud-agent-editor')).toBeVisible();
|
||||
await expect(page.getByLabel('角色与指令')).toHaveValue('使用简洁自然的中文。先理解我的目的,再协助梳理结构。');
|
||||
await page.getByRole('button', { name: '发布与访问', exact: true }).click();
|
||||
await expect(page.getByLabel('角色与指令')).toHaveValue('使用简洁自然的中文。先理解我的目的,再协助梳理结构。补充具体例子。');
|
||||
await page.getByRole('button', { name: '限制', exact: true }).click();
|
||||
await page.getByLabel('每次任务上限(词元点数)').fill('2.50');
|
||||
await page.getByLabel('每日上限(词元点数)').fill('10.00');
|
||||
await page.getByRole('button', { name: '保存费用上限' }).click();
|
||||
await expect(page.getByRole('button', { name: '保存费用上限' })).toBeDisabled();
|
||||
await page.getByRole('button', { name: '发布与访问', exact: true }).click();
|
||||
await page.getByRole('button', { name: '发布当前草稿' }).click();
|
||||
await expect(page.getByText('当前发布版本 1')).toBeVisible();
|
||||
await page.getByRole('button', { name: '对话', exact: true }).click();
|
||||
await page.getByLabel('消息', { exact: true }).fill('每天早上八点半给我三个创作方向');
|
||||
await page.getByRole('button', { name: '发送', exact: true }).click();
|
||||
await expect(page.getByRole('heading', { name: '创作建议' })).toBeVisible();
|
||||
await page.getByRole('region', { name: '智能体对话', exact: true }).getByLabel('消息', { exact: true }).fill('每天早上八点半给我三个创作方向');
|
||||
await page.getByRole('region', { name: '智能体对话', exact: true }).getByRole('button', { name: '发送', exact: true }).click();
|
||||
await expect(page.getByRole('region', { name: '智能体对话', exact: true }).getByRole('heading', { name: '创作建议' })).toBeAttached();
|
||||
await page.getByRole('button', { name: '查看并配置自动任务' }).click();
|
||||
await expect(page.getByLabel('任务名称')).toHaveValue('每天整理选题');
|
||||
await expect(page.getByLabel('执行时间')).toHaveValue('08:30');
|
||||
@@ -118,6 +177,7 @@ test('personal cloud Agent creation, draft save and leave protection in Electron
|
||||
await page.getByRole('button', { name: '取消', exact: true }).click();
|
||||
await page.screenshot({ path: testInfo.outputPath('cloud-agent-schedules.png') });
|
||||
} finally {
|
||||
await app.evaluate(({ BrowserWindow }) => { for (const win of BrowserWindow.getAllWindows()) win.destroy(); }).catch(() => undefined);
|
||||
await closeElectronApp(app);
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user