合并 AI 设计多会话客户端
Some checks failed
Electron E2E / Electron E2E (macos-latest) (push) Has been cancelled
Electron E2E / Electron E2E (ubuntu-latest) (push) Has been cancelled
Electron E2E / Electron E2E (windows-latest) (push) Has been cancelled

整合 Enter 发送与多会话交互,保留服务端持久 Conversation Session,并补齐迁移、回归、Electron E2E 与 canonical 文档。
This commit is contained in:
2026-08-11 16:18:52 +08:00
32 changed files with 2417 additions and 804 deletions

View File

@@ -12,6 +12,7 @@ import { tmpdir } from 'node:os';
import { basename, join, resolve } from 'node:path';
export type LaunchElectronOptions = {
imageWorkspaceMode?: 'local';
skipSetup?: boolean;
};
@@ -79,6 +80,7 @@ function buildElectronEnvironment(
resources: ElectronTestResources,
skipSetup: boolean,
hostApiPort: number,
imageWorkspaceMode?: 'local',
): Record<string, string> {
const env: Record<string, string> = {};
for (const key of PASSTHROUGH_ENVIRONMENT_KEYS) {
@@ -103,6 +105,9 @@ function buildElectronEnvironment(
if (skipSetup) {
env.NIANCODE_E2E_SKIP_SETUP = '1';
}
if (imageWorkspaceMode) {
env.NIANCODE_IMAGE_WORKSPACE_MODE = imageWorkspaceMode;
}
if (process.platform === 'linux') {
env.ELECTRON_DISABLE_SANDBOX = '1';
}
@@ -112,13 +117,19 @@ function buildElectronEnvironment(
async function launchMakeloreElectron(
resources: ElectronTestResources,
skipSetup: boolean,
options: LaunchElectronOptions,
): Promise<ElectronApplication> {
const hostApiPort = await allocatePort();
const skipSetup = options.skipSetup ?? resources.defaultSkipSetup;
const app = await electron.launch({
executablePath: electronBinaryPath as unknown as string,
args: [electronEntry],
env: buildElectronEnvironment(resources, skipSetup, hostApiPort),
env: buildElectronEnvironment(
resources,
skipSetup,
hostApiPort,
options.imageWorkspaceMode,
),
timeout: 90_000,
});
@@ -248,8 +259,7 @@ export const test = base.extend<ElectronFixtures>({
launchElectronApp: async ({ electronTestResources }, provideLauncher) => {
await provideLauncher(async (options = {}) => {
const skipSetup = options.skipSetup ?? electronTestResources.defaultSkipSetup;
return await launchMakeloreElectron(electronTestResources, skipSetup);
return await launchMakeloreElectron(electronTestResources, options);
});
},

View File

@@ -0,0 +1,52 @@
import { closeElectronApp, expect, getStableWindow, test } from './fixtures/electron';
test.describe('AI Design conversations', () => {
test('keeps generation tasks visible while conversations stay independent', async ({ launchElectronApp }) => {
const app = await launchElectronApp({
imageWorkspaceMode: 'local',
skipSetup: true,
});
try {
const page = await getStableWindow(app);
await page.getByTestId('sidebar-module-switcher-trigger').click();
await page.getByTestId('sidebar-module-painting').click();
await page.getByTestId('sidebar-create-image-project').click();
await page.getByLabel('项目名称').fill('多会话验收项目');
await page.getByRole('button', { name: '创建项目' }).click();
const conversationSelect = page.getByTestId('image-canvas-conversation-select');
await expect(conversationSelect).toBeVisible();
await expect(conversationSelect.locator('option')).toHaveCount(1);
const firstConversationId = await conversationSelect.inputValue();
const firstPrompt = '为项目设计一张蓝色星空海报';
await page.getByLabel('设计需求').fill(firstPrompt);
await page.getByRole('button', { name: '发送给设计 Agent' }).click();
await expect(page.getByTestId('image-workspace-conversation')).toContainText(firstPrompt);
await page.getByRole('button', { name: '确认并开始生成' }).click();
const task = page.locator('[data-testid^="design-task-"]').first();
await expect(task).toContainText(firstPrompt);
await page.getByRole('button', { name: '新建设计会话' }).first().click();
await expect(conversationSelect.locator('option')).toHaveCount(2);
await expect(conversationSelect).not.toHaveValue(firstConversationId);
await expect(page.getByTestId('image-workspace-conversation')).not.toContainText(firstPrompt);
await expect(task).toContainText(firstPrompt);
const secondPrompt = '这一条会话只讨论红色角色立绘';
await page.getByLabel('设计需求').fill(secondPrompt);
await page.getByRole('button', { name: '发送给设计 Agent' }).click();
await expect(page.getByTestId('image-workspace-conversation')).toContainText(secondPrompt);
await conversationSelect.selectOption(firstConversationId);
await expect(page.getByTestId('image-workspace-conversation')).toContainText(firstPrompt);
await expect(page.getByTestId('image-workspace-conversation')).not.toContainText(secondPrompt);
await expect(task).toContainText(firstPrompt);
} finally {
await closeElectronApp(app);
}
});
});