Merge branch 'codex/20260907-project-config-plugin-panel-c84e71a2-project-config-plugin-panel'
# Conflicts: # README.md
This commit is contained in:
@@ -93,17 +93,20 @@ test.describe('Unified plugin workspace', () => {
|
||||
await expect(page.getByTestId('project-plugins-sheet')).toBeVisible();
|
||||
await expect(page.getByTestId('plugins-page')).toBeVisible();
|
||||
await expect(page).toHaveURL(/\/project-config\/plugins\?scope=all/);
|
||||
await expect(page.getByTestId('plugins-page').getByText('尚未获取')).toBeVisible();
|
||||
await expect(page.getByText('为你的智能体添加插件,拓展更多能力。')).toBeVisible();
|
||||
await expect(page.getByRole('button', { name: /刷新/ })).toHaveCount(0);
|
||||
await expect(page.getByRole('searchbox')).toHaveCount(0);
|
||||
await expect(page.getByRole('combobox')).toHaveCount(0);
|
||||
await expect(page.getByRole('button', { name: '添加灵感笔记' })).toBeVisible();
|
||||
await page.getByRole('button', { name: '查看灵感笔记详情' }).click();
|
||||
await expect(page.getByRole('dialog', { name: '灵感笔记' })).toContainText('详细介绍');
|
||||
await page.getByRole('button', { name: '免费获取灵感笔记' }).click();
|
||||
await expect(page.getByRole('button', { name: '从账号移除灵感笔记' })).toBeVisible();
|
||||
await expect(page.getByRole('dialog', { name: '灵感笔记' })).not.toContainText('读取项目名称');
|
||||
await page.getByRole('button', { name: '添加灵感笔记' }).click();
|
||||
await expect(page.getByRole('button', { name: '从插件库移除灵感笔记' })).toBeVisible();
|
||||
|
||||
await page.getByRole('button', { name: '关闭插件详情' }).click();
|
||||
await page.getByRole('combobox', { name: '状态', exact: true }).selectOption('mine');
|
||||
await expect(page).toHaveURL(/state=mine/);
|
||||
await expect(page.getByRole('heading', { name: '灵感笔记' })).toBeVisible();
|
||||
await expect(page.getByText('不适用项目启用')).toBeVisible();
|
||||
await expect(page.getByRole('button', { name: '安装灵感笔记' })).toBeVisible();
|
||||
const requests = await app.evaluate(() => (
|
||||
(globalThis as typeof globalThis & { __pluginsE2E?: { requests: string[] } }).__pluginsE2E?.requests ?? []
|
||||
));
|
||||
@@ -157,17 +160,21 @@ test.describe('Unified plugin workspace', () => {
|
||||
await expect(page.getByTestId('project-configuration-empty-state')).toBeVisible();
|
||||
await expect(page.getByTestId('project-plugins-sheet')).toBeVisible();
|
||||
await expect(page.getByTestId('plugins-page')).toBeVisible();
|
||||
await expect(page.getByRole('alert')).toContainText('官方目录刷新失败');
|
||||
await expect(page.getByRole('alert')).toContainText('官方目录加载失败');
|
||||
await expect(page.getByRole('heading', { name: 'Local Search' })).toBeVisible();
|
||||
await expect(page.getByText('本机全局已启用')).toBeVisible();
|
||||
await expect(page.getByText(/仅通过对话安装/)).toBeVisible();
|
||||
await expect(page.getByRole('button', { name: 'Local Search:已安装' })).toBeDisabled();
|
||||
await expect(page.getByRole('button', { name: /刷新/ })).toHaveCount(0);
|
||||
await expect(page.getByRole('searchbox')).toHaveCount(0);
|
||||
await expect(page.getByRole('combobox')).toHaveCount(0);
|
||||
await expect(page.getByRole('textbox', { name: /包|路径|source/i })).toHaveCount(0);
|
||||
await page.getByRole('button', { name: '查看Local Search详情' }).click();
|
||||
await expect(page.getByText(/完整桌面权限/)).toBeVisible();
|
||||
await page.getByRole('button', { name: '本机全局停用Local Search' }).click();
|
||||
await expect(page.getByRole('button', { name: '本机全局启用Local Search' })).toBeVisible();
|
||||
await page.getByRole('button', { name: '本机全局启用Local Search' }).click();
|
||||
await expect(page.getByRole('button', { name: '本机全局停用Local Search' })).toBeVisible();
|
||||
await expect(page.getByText('为智能体提供可在本机使用的扩展能力。')).toBeVisible();
|
||||
await expect(page.getByText(/完整桌面权限/)).toHaveCount(0);
|
||||
await expect(page.getByText(/Pi extension|Skill 脚本/)).toHaveCount(0);
|
||||
await page.getByRole('button', { name: '停用Local Search' }).click();
|
||||
await expect(page.getByRole('button', { name: '启用Local Search' })).toBeVisible();
|
||||
await page.getByRole('button', { name: '启用Local Search' }).click();
|
||||
await expect(page.getByRole('button', { name: '停用Local Search' })).toBeVisible();
|
||||
|
||||
const requests = await app.evaluate(() => (
|
||||
(globalThis as typeof globalThis & { __pluginsE2E?: { requests: string[] } }).__pluginsE2E?.requests ?? []
|
||||
@@ -291,24 +298,23 @@ test.describe('Unified plugin workspace', () => {
|
||||
await expect.poll(async () => app.evaluate(() => (
|
||||
(globalThis as typeof globalThis & { __pluginsE2E?: { requests: string[] } }).__pluginsE2E?.requests ?? []
|
||||
))).toContain('GET /api/coding/plugin-marketplace/library');
|
||||
const bundledCard = page.getByRole('heading', { name: '游戏资源生成' }).locator('..');
|
||||
await expect(bundledCard).toContainText('账号已获取');
|
||||
await expect(page.getByRole('button', { name: '游戏资源生成:随应用提供' })).toBeDisabled();
|
||||
|
||||
await page.getByRole('button', { name: '查看开发数据服务详情' }).click();
|
||||
await expect(page.getByText('当前状态没有可执行操作。')).toBeVisible();
|
||||
await expect(page.getByText('当前无需进行其他操作。')).toBeVisible();
|
||||
await page.getByRole('button', { name: '关闭插件详情' }).click();
|
||||
|
||||
await page.getByRole('button', { name: '查看游戏资源生成详情' }).click();
|
||||
await expect(page.getByRole('button', { name: '从账号移除游戏资源生成' })).toBeVisible();
|
||||
await expect(page.getByRole('button', { name: /下载.*游戏资源生成|删除.*游戏资源生成.*官方设备包/ })).toHaveCount(0);
|
||||
await page.getByRole('button', { name: '从账号移除游戏资源生成' }).click();
|
||||
await page.getByRole('button', { name: '确认从账号移除' }).click();
|
||||
await expect(page.getByRole('button', { name: '从插件库移除游戏资源生成' })).toBeVisible();
|
||||
await expect(page.getByRole('button', { name: /安装.*游戏资源生成|从本机卸载.*游戏资源生成/ })).toHaveCount(0);
|
||||
await page.getByRole('button', { name: '从插件库移除游戏资源生成' }).click();
|
||||
await page.getByRole('button', { name: '确认移除' }).click();
|
||||
await page.getByRole('button', { name: '关闭插件详情' }).click();
|
||||
|
||||
await page.getByRole('button', { name: '查看Local Tool详情' }).click();
|
||||
await expect(page.getByRole('button', { name: '本机全局停用Local Tool' })).toBeVisible();
|
||||
await expect(page.getByRole('button', { name: /账号.*Local Tool|下载.*Local Tool/ })).toHaveCount(0);
|
||||
await page.getByRole('button', { name: '本机全局停用Local Tool' }).click();
|
||||
await expect(page.getByRole('button', { name: '停用Local Tool' })).toBeVisible();
|
||||
await expect(page.getByRole('button', { name: /插件库.*Local Tool|安装.*Local Tool/ })).toHaveCount(0);
|
||||
await page.getByRole('button', { name: '停用Local Tool' }).click();
|
||||
|
||||
const requests = await app.evaluate(() => (
|
||||
(globalThis as typeof globalThis & { __pluginsE2E?: { requests: string[] } }).__pluginsE2E?.requests ?? []
|
||||
|
||||
@@ -48,18 +48,40 @@ test.describe('Project configuration skills', () => {
|
||||
expect(actionBarBottomGap).toBeLessThan(40);
|
||||
await expect(page.getByRole('button', { name: '创建智能体' })).toBeVisible();
|
||||
|
||||
const resourceCardGeometry = await page.getByTestId('project-resource-row').locator(':scope > button').evaluateAll((cards) => cards.map((card) => {
|
||||
const rect = card.getBoundingClientRect();
|
||||
return { left: rect.left, top: rect.top, width: rect.width };
|
||||
}));
|
||||
expect(resourceCardGeometry).toHaveLength(4);
|
||||
expect(Math.max(...resourceCardGeometry.map(({ top }) => top)) - Math.min(...resourceCardGeometry.map(({ top }) => top))).toBeLessThanOrEqual(1);
|
||||
expect(resourceCardGeometry.every(({ width }) => width > 0)).toBe(true);
|
||||
expect(resourceCardGeometry.map(({ left }) => left)).toEqual([...resourceCardGeometry.map(({ left }) => left)].sort((a, b) => a - b));
|
||||
|
||||
const drawerWidths: number[] = [];
|
||||
for (const [resourceId, title] of [
|
||||
['resource-card-models', '可用模型'],
|
||||
['resource-card-knowledge', '知识文件'],
|
||||
['resource-card-skills', '可用技能'],
|
||||
['resource-card-knowledge', '知识文件'],
|
||||
['resource-card-plugins', '插件'],
|
||||
] as const) {
|
||||
await page.getByTestId(resourceId).click();
|
||||
const drawer = page.getByRole('dialog', { name: title });
|
||||
await expect(drawer).toBeVisible();
|
||||
const drawerBox = await drawer.boundingBox();
|
||||
if (!drawerBox) throw new Error(`未能读取 ${title} 抽屉的布局区域`);
|
||||
drawerWidths.push(drawerBox.width);
|
||||
if (resourceId === 'resource-card-models') {
|
||||
await expect(drawer.getByRole('combobox')).toHaveCount(0);
|
||||
await expect(drawer.locator('[data-testid="project-model-list"], [data-testid="project-model-empty-state"]')).toHaveCount(1);
|
||||
}
|
||||
if (resourceId === 'resource-card-plugins') {
|
||||
await expect(page.getByTestId('project-plugins-sheet')).toBeVisible();
|
||||
await expect(drawer.getByTestId('plugins-page')).toBeVisible();
|
||||
await expect(drawer.getByText('为你的智能体添加插件,拓展更多能力。')).toBeVisible();
|
||||
await expect(drawer.getByRole('button', { name: /刷新/ })).toHaveCount(0);
|
||||
await expect(drawer.getByRole('searchbox')).toHaveCount(0);
|
||||
await expect(drawer.getByRole('combobox')).toHaveCount(0);
|
||||
}
|
||||
const closeButton = drawer.getByRole('button', { name: '关闭' });
|
||||
const closeGeometry = await closeButton.evaluate((button) => {
|
||||
const icon = button.querySelector('svg');
|
||||
@@ -81,6 +103,8 @@ test.describe('Project configuration skills', () => {
|
||||
await closeButton.locator('svg').click();
|
||||
await expect(page.getByRole('dialog', { name: title })).toHaveCount(0);
|
||||
}
|
||||
expect(Math.max(...drawerWidths) - Math.min(...drawerWidths)).toBeLessThanOrEqual(1);
|
||||
expect(Math.max(...drawerWidths)).toBeLessThanOrEqual(430);
|
||||
|
||||
const now = new Date().toISOString();
|
||||
await mkdir(path.join(parentPath, '.makelore'), { recursive: true });
|
||||
|
||||
@@ -103,10 +103,11 @@ test.describe('Unified project plugin workspace', () => {
|
||||
includeHidden: true,
|
||||
})).toBeAttached();
|
||||
await page.getByRole('button', { name: '查看开发数据服务详情' }).click();
|
||||
await expect(page.getByText('按平台包含,不按单次插件调用扣点。')).toBeVisible();
|
||||
await expect(page.getByRole('heading', { name: '生效范围' })).toBeVisible();
|
||||
await expect(page.getByText(/启用当前项目后.*无需单独分配/)).toBeVisible();
|
||||
await expect(page.getByRole('button', { name: '分配开发数据服务给伙伴' })).toHaveCount(0);
|
||||
const pluginDialog = page.getByRole('dialog', { name: '开发数据服务' });
|
||||
await expect(pluginDialog).toContainText('为当前项目提供数据。');
|
||||
await expect(pluginDialog).not.toContainText('Token Point');
|
||||
await expect(pluginDialog).not.toContainText('data-service.control');
|
||||
await expect(page.getByRole('button', { name: '将开发数据服务分配给智能体' })).toHaveCount(0);
|
||||
const localProjectId = await app.evaluate(() => (
|
||||
(globalThis as typeof globalThis & { __projectPluginE2E?: { localProjectId: string } }).__projectPluginE2E?.localProjectId
|
||||
));
|
||||
@@ -114,15 +115,15 @@ test.describe('Unified project plugin workspace', () => {
|
||||
await expect(page.getByText(localProjectId as string)).toHaveCount(0);
|
||||
await expect(page.getByText('11111111-1111-4111-8111-111111111111')).toHaveCount(0);
|
||||
|
||||
await page.getByRole('button', { name: '启用开发数据服务到当前项目' }).click();
|
||||
await expect(page.getByRole('button', { name: '从当前项目禁用开发数据服务' })).toBeVisible();
|
||||
await expect(page.getByText('插件专属设置')).toBeVisible();
|
||||
await page.getByRole('button', { name: '将开发数据服务添加到项目' }).click();
|
||||
await expect(page.getByRole('button', { name: '从项目移除开发数据服务' })).toBeVisible();
|
||||
await expect(page.getByText('使用设置')).toBeVisible();
|
||||
await expect(page.getByRole('button', { name: '创建开发数据空间' })).toBeDisabled();
|
||||
|
||||
await page.getByRole('button', { name: '从当前项目禁用开发数据服务' }).click();
|
||||
await expect(page.getByRole('alertdialog')).toContainText('从当前项目禁用开发数据服务');
|
||||
await page.getByRole('button', { name: '确认从当前项目禁用' }).click();
|
||||
await expect(page.getByRole('button', { name: '启用开发数据服务到当前项目' })).toBeVisible();
|
||||
await page.getByRole('button', { name: '从项目移除开发数据服务' }).click();
|
||||
await expect(page.getByRole('alertdialog')).toContainText('从当前项目移除开发数据服务');
|
||||
await page.getByRole('button', { name: '确认从项目移除' }).click();
|
||||
await expect(page.getByRole('button', { name: '将开发数据服务添加到项目' })).toBeVisible();
|
||||
|
||||
const state = await app.evaluate(() => (
|
||||
(globalThis as typeof globalThis & {
|
||||
|
||||
Reference in New Issue
Block a user