78 lines
3.9 KiB
TypeScript
78 lines
3.9 KiB
TypeScript
import { mkdtemp, readFile, rm, writeFile } from 'node:fs/promises';
|
|
import { tmpdir } from 'node:os';
|
|
import path from 'node:path';
|
|
import { closeElectronApp, expect, getStableWindow, test } from './fixtures/electron';
|
|
|
|
const CANONICAL_PROJECT_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/u;
|
|
|
|
async function readProjectConfig(projectPath: string): Promise<Record<string, unknown>> {
|
|
return JSON.parse(await readFile(path.join(projectPath, '.makelore', 'project.json'), 'utf8')) as Record<string, unknown>;
|
|
}
|
|
|
|
async function selectProgrammingProjectFolder(
|
|
app: Parameters<typeof closeElectronApp>[0],
|
|
projectPath: string,
|
|
) {
|
|
await app.evaluate(({ ipcMain }, selectedPath) => {
|
|
ipcMain.removeHandler('dialog:open');
|
|
ipcMain.handle('dialog:open', async () => ({ canceled: false, filePaths: [selectedPath] }));
|
|
}, projectPath);
|
|
const page = await getStableWindow(app);
|
|
await expect(page.getByTestId('ai-module-selection-page')).toBeVisible();
|
|
await page.getByTestId('ai-module-option-programming').click();
|
|
await expect(page.getByTestId('main-layout')).toBeVisible();
|
|
return page;
|
|
}
|
|
|
|
test.describe('Coding project identity UX', () => {
|
|
test('keeps the service identity automatic and invisible to young users', async ({ launchElectronApp }) => {
|
|
const projectPath = await mkdtemp(path.join(tmpdir(), 'makelore-identity-e2e-'));
|
|
const app = await launchElectronApp({ skipSetup: true });
|
|
|
|
try {
|
|
const page = await selectProgrammingProjectFolder(app, projectPath);
|
|
await page.getByTestId('sidebar-create-project').click();
|
|
const createDialog = page.getByRole('dialog', { name: '新建项目' });
|
|
|
|
await expect(createDialog.getByText(/项目 ID|项目身份|独立副本/u)).toHaveCount(0);
|
|
await expect(createDialog.getByRole('radio', { name: '创建新的项目 ID' })).toHaveCount(0);
|
|
await expect(createDialog.getByRole('radio', { name: '绑定已有项目 ID' })).toHaveCount(0);
|
|
await createDialog.getByRole('button', { name: '选择路径' }).click();
|
|
await expect(createDialog.getByLabel('项目路径')).toHaveValue(projectPath);
|
|
await createDialog.getByRole('button', { name: '确认创建' }).click();
|
|
|
|
await expect(page.getByTestId('coding-chat-empty-agent')).toBeVisible();
|
|
const createdConfig = await readProjectConfig(projectPath);
|
|
const generatedProjectId = String(createdConfig.projectId);
|
|
expect(generatedProjectId).toMatch(CANONICAL_PROJECT_ID);
|
|
|
|
await page.getByRole('button', { name: '创建项目智能体' }).click();
|
|
await expect(page.getByTestId('project-configuration-page')).toBeVisible();
|
|
await expect(page.getByTestId('project-identity-card')).toHaveCount(0);
|
|
await expect(page.getByTestId('legacy-project-identity-card')).toHaveCount(0);
|
|
await expect(page.getByTestId('independent-copy-button')).toHaveCount(0);
|
|
await expect(page.getByText(/项目 ID|项目身份|独立副本/u)).toHaveCount(0);
|
|
|
|
const legacyConfig = await readProjectConfig(projectPath);
|
|
delete legacyConfig.projectId;
|
|
await writeFile(
|
|
path.join(projectPath, '.makelore', 'project.json'),
|
|
JSON.stringify(legacyConfig, null, 2),
|
|
);
|
|
await page.reload();
|
|
|
|
await expect(page.getByTestId('project-configuration-page')).toBeVisible();
|
|
const repairedConfig = await readProjectConfig(projectPath);
|
|
const repairedProjectId = String(repairedConfig.projectId);
|
|
expect(repairedProjectId).toMatch(CANONICAL_PROJECT_ID);
|
|
expect(repairedProjectId).not.toBe(generatedProjectId);
|
|
await expect(page.getByTestId('project-identity-card')).toHaveCount(0);
|
|
await expect(page.getByTestId('legacy-project-identity-card')).toHaveCount(0);
|
|
await expect(page.getByText(/项目 ID|项目身份|独立副本/u)).toHaveCount(0);
|
|
} finally {
|
|
await closeElectronApp(app);
|
|
await rm(projectPath, { recursive: true, force: true });
|
|
}
|
|
});
|
|
});
|