Simplify WeChat binding cards and guided setup

This commit is contained in:
鲨鱼辣椒 committed 2026-10-12 21:20:28 +08:00
1 parent ad1d2f261d
commit d823ddb8fa
5 files changed
+768 -303

No files matched your search

+53 -35
View File
@@ -47,6 +47,11 @@ test('own WeChat conversation approval and generated PPT delivery in the desktop
if (operation === 'budget') return result({ request_limit_points: '2.50', daily_limit_points: '10.00', daily_committed_points: '0.20' });
if (operation === 'costs') return result({ items: [], next_offset: null, summary: { count: 0, settled_points: '0', pending_points: '0' } });
if (operation === 'channelAccounts') return result({ items: channelAccounts });
if (operation === 'createChannelAccount') {
const created = { ...spare, id: 'wechat-created', display_name: input.display_name, binding_id: 'binding-created' };
channelAccounts.push(created);
return result({ channel: created });
}
if (operation === 'routeChannelAccount') {
const target = input.target_agent_slug === secondSlug ? secondDraft : input.target_agent_slug === slug ? draft : null;
channelAccounts = channelAccounts.map(item => item.id !== input.channel_account_id ? item : { ...item, revision: item.revision + 1, enabled: input.enabled,
@@ -60,7 +65,10 @@ test('own WeChat conversation approval and generated PPT delivery in the desktop
channelAccounts = channelAccounts.map(item => item.id !== input.channel_account_id ? item : { ...item, revision: item.revision + 1, enabled, desired_state: enabled ? 'enabled' : 'disabled' });
return result({ channel: channelAccounts.find(item => item.id === input.channel_account_id) });
}
if (operation === 'disconnectChannelAccount') return result({ channel: { ...channelAccounts.find(item => item.id === input.channel_account_id), health: 'login_required', enabled: false }, disconnected: true });
if (operation === 'disconnectChannelAccount') {
channelAccounts = channelAccounts.map(item => item.id === input.channel_account_id ? { ...item, health: 'login_required', enabled: false, revision: item.revision + 1 } : item);
return result({ channel: channelAccounts.find(item => item.id === input.channel_account_id), disconnected: true });
}
if (operation === 'channelBindings') return result({ items: channelAccounts.filter(item => item.target_agent_slug === input.slug), available_accounts: [] });
if (operation === 'channelConversations') return result({ items: [session], next_offset: null });
if (operation === 'channelSelfCallers') return result({ items: [{ ...session, paired_ws_account_id: 'creator', revoked_at: null }] });
@@ -97,48 +105,58 @@ test('own WeChat conversation approval and generated PPT delivery in the desktop
expect(calls.some(call => call.operation === 'resume' || call.operation === 'submit')).toBe(false);
await page.getByTestId('cloud-agent-editor').getByRole('button', { name: '我的智能体', exact: true }).click();
await page.getByRole('button', { name: '渠道', exact: true }).click();
await expect(page.getByRole('heading', { name: '微信', exact: true })).toBeVisible();
await expect(page.getByRole('button', { name: /创作微信.*我的创作助手/ })).toBeVisible();
await expect(page.getByRole('button', { name: /备用微信.*未分配智能体/ })).toBeVisible();
await page.screenshot({ path: testInfo.outputPath('wechat-account-list.png'), fullPage: true });
await page.getByRole('button', { name: /备用微信.*未分配智能体/ }).click();
const spareDetail = page.getByRole('article', { name: '备用微信账号详情', exact: true });
await spareDetail.getByRole('button', { name: '扫码连接', exact: true }).click();
await expect(page.getByRole('img', { name: '个人微信登录二维码', exact: true })).toHaveAttribute('src', /^data:image\//);
await page.getByLabel('微信验证码', { exact: true }).scrollIntoViewIfNeeded();
await page.screenshot({ path: testInfo.outputPath('wechat-unassigned-qr-and-target.png'), fullPage: true });
await page.getByLabel('微信验证码', { exact: true }).fill('123456');
await page.getByRole('button', { name: '提交验证码', exact: true }).click();
await expect.poll(async () => app.evaluate(() => (globalThis as typeof globalThis & { cloudChannelFixtureCalls: { operation: string; input: unknown }[] }).cloudChannelFixtureCalls.some(call => call.operation === 'channelAccountWechatBindVerification'))).toBe(true);
await expect(page.getByRole('img', { name: '个人微信登录二维码', exact: true })).toHaveCount(0);
await expect(page.getByLabel('微信验证码', { exact: true })).toHaveCount(0);
await expect(spareDetail.getByRole('status')).toContainText('微信已连接');
await expect(spareDetail.getByRole('status')).toContainText('选择目标智能体');
await spareDetail.getByRole('status').scrollIntoViewIfNeeded();
await page.screenshot({ path: testInfo.outputPath('wechat-binding-completed.png'), fullPage: true });
await spareDetail.getByLabel('目标智能体', { exact: true }).selectOption(agentSlug);
await spareDetail.getByRole('button', { name: '保存目标', exact: true }).click();
await expect(page.getByRole('heading', { name: '连接到微信', exact: true })).toBeVisible();
const legacyCard = page.getByRole('article', { name: '创作微信微信', exact: true });
const spareCard = page.getByRole('article', { name: '备用微信微信', exact: true });
await expect(legacyCard.getByText('我的创作助手', { exact: true })).toBeVisible();
await expect(spareCard.getByRole('button', { name: '继续绑定', exact: true })).toBeVisible();
await expect(page.getByRole('dialog')).toHaveCount(0);
await expect(page.getByText('活动记录', { exact: true })).toHaveCount(0);
await expect(page.getByRole('button', { name: '微信对话', exact: true })).toHaveCount(0);
const callsBeforeConfig = await app.evaluate(() => (globalThis as typeof globalThis & { cloudChannelFixtureCalls: { operation: string }[] }).cloudChannelFixtureCalls.length);
await page.screenshot({ path: testInfo.outputPath('wechat-binding-cards.png'), fullPage: true });
await page.getByRole('button', { name: '添加微信', exact: true }).click();
const adding = page.getByRole('dialog', { name: '添加微信', exact: true });
await adding.getByLabel('选择智能体', { exact: true }).selectOption(agentSlug);
await adding.getByLabel('微信备注(可选)', { exact: true }).fill('新创作微信');
await adding.getByRole('button', { name: '下一步:扫码连接', exact: true }).click();
await expect(adding.getByRole('img', { name: '个人微信登录二维码', exact: true })).toHaveAttribute('src', /^data:image\//);
await expect.poll(async () => app.evaluate(() => (globalThis as typeof globalThis & { cloudChannelFixtureCalls: { operation: string; input: Record<string, unknown> }[] }).cloudChannelFixtureCalls
.filter(call => call.operation === 'routeChannelAccount').some(call => call.input.channel_account_id === 'wechat-b' && call.input.target_agent_slug === 'ml-' + 'a'.repeat(32)))).toBe(true);
await expect(page.getByRole('button', { name: /备用微信.*我的创作助手/ })).toBeVisible();
await expect(spareDetail.getByRole('status')).toContainText('点击“启用”');
await spareDetail.getByRole('button', { name: '启用', exact: true }).click();
await expect(spareDetail.getByRole('status')).toContainText('返回微信与智能体对话');
await page.getByRole('button', { name: /创作微信.*我的创作助手/ }).click();
const legacyDetail = page.getByRole('article', { name: '创作微信账号详情', exact: true });
.filter(call => call.operation === 'routeChannelAccount').some(call => call.input.channel_account_id === 'wechat-created' && call.input.target_agent_slug === 'ml-' + 'a'.repeat(32) && call.input.enabled === false))).toBe(true);
await expect(adding.getByRole('button', { name: '完成绑定并启用', exact: true })).toBeDisabled();
await adding.getByLabel('微信验证码', { exact: true }).fill('123456');
await adding.getByRole('button', { name: '提交验证码', exact: true }).click();
await expect(adding.getByRole('img', { name: '个人微信登录二维码', exact: true })).toHaveCount(0);
await expect(adding.getByLabel('微信验证码', { exact: true })).toHaveCount(0);
await expect(adding.getByText('微信已连接', { exact: true })).toBeVisible();
expect(await app.evaluate(() => (globalThis as typeof globalThis & { cloudChannelFixtureCalls: { operation: string }[] }).cloudChannelFixtureCalls.some(call => call.operation === 'enableChannelAccount'))).toBe(false);
await page.screenshot({ path: testInfo.outputPath('wechat-connection-confirmed.png'), fullPage: true });
await adding.getByRole('button', { name: '完成绑定并启用', exact: true }).click();
await expect(adding.getByRole('button', { name: '完成', exact: true })).toBeVisible();
await adding.getByRole('button', { name: '完成', exact: true }).click();
await expect(page.getByRole('article', { name: '新创作微信微信', exact: true }).getByText('我的创作助手', { exact: true })).toBeVisible();
await legacyCard.getByRole('button', { name: '管理绑定', exact: true }).click();
const managing = page.getByRole('dialog', { name: '管理微信绑定', exact: true });
const qrStartsBeforeSwitch = await app.evaluate(() => (globalThis as typeof globalThis & { cloudChannelFixtureCalls: { operation: string }[] }).cloudChannelFixtureCalls.filter(call => call.operation === 'channelAccountWechatBindStart').length);
await legacyDetail.getByLabel('目标智能体', { exact: true }).selectOption(secondAgentSlug);
await legacyDetail.getByRole('button', { name: '保存目标', exact: true }).click();
await managing.getByLabel('绑定的智能体', { exact: true }).selectOption(secondAgentSlug);
await managing.getByRole('button', { name: '保存更换', exact: true }).click();
const switching = page.getByRole('dialog', { name: '更换绑定的智能体', exact: true });
await switching.getByRole('button', { name: /确认更换/ }).click();
await expect.poll(async () => app.evaluate(() => (globalThis as typeof globalThis & { cloudChannelFixtureCalls: { operation: string; input: Record<string, unknown> }[] }).cloudChannelFixtureCalls
.filter(call => call.operation === 'routeChannelAccount').some(call => call.input.channel_account_id === 'wechat-a' && call.input.target_agent_slug === 'ml-' + 'b'.repeat(32) && call.input.enabled === true))).toBe(true);
expect(await app.evaluate(() => (globalThis as typeof globalThis & { cloudChannelFixtureCalls: { operation: string }[] }).cloudChannelFixtureCalls.filter(call => call.operation === 'channelAccountWechatBindStart').length)).toBe(qrStartsBeforeSwitch);
await expect(page.getByRole('button', { name: '活动记录', exact: true })).toBeVisible();
await expect(page.getByRole('button', { name: '微信对话', exact: true })).toBeVisible();
await expect(page.getByText('活动记录', { exact: true })).toHaveCount(0);
await expect(page.getByRole('button', { name: '微信对话', exact: true })).toHaveCount(0);
await expect(page.getByText(/本人|受邀|邀请|使用范围|使用权限|授权调用者/)).toHaveCount(0);
await app.evaluate(({ BrowserWindow }) => { const win = BrowserWindow.getAllWindows()[0]; win.setMinimumSize(800, 600); win.setSize(980, 680); });
await expect.poll(() => page.getByTestId('main-content').evaluate(element => element.scrollWidth - element.clientWidth)).toBeLessThanOrEqual(1);
await page.screenshot({ path: testInfo.outputPath('wechat-account-detail-compact.png'), fullPage: true });
expect(await app.evaluate(() => (globalThis as typeof globalThis & { cloudChannelFixtureCalls: { operation: string }[] }).cloudChannelFixtureCalls.some(call => ['channelPolicy', 'createChannelPairing', 'channelCallers', 'revokeChannelCaller'].includes(call.operation)))).toBe(false);
await page.screenshot({ path: testInfo.outputPath('wechat-manage-binding-compact.png'), fullPage: true });
const finalCalls = await app.evaluate(() => (globalThis as typeof globalThis & { cloudChannelFixtureCalls: { operation: string }[] }).cloudChannelFixtureCalls);
expect(finalCalls.slice(callsBeforeConfig).some(call => ['channelActivity', 'channelConversations', 'channelConversation', 'channelPolicy', 'createChannelPairing', 'channelCallers', 'revokeChannelCaller'].includes(call.operation))).toBe(false);
expect(finalCalls.filter(call => call.operation === 'createChannelAccount')).toHaveLength(1);
} finally {
await app.evaluate(({ BrowserWindow }) => { for (const window of BrowserWindow.getAllWindows()) window.destroy(); }).catch(() => undefined);
await closeElectronApp(app);