mirror of
https://github.com/linshenkx/prompt-optimizer.git
synced 2026-05-06 21:50:27 +08:00
619 lines
20 KiB
TypeScript
619 lines
20 KiB
TypeScript
import { test, expect } from './fixtures';
|
||
|
||
/**
|
||
* 导入导出完整流程 E2E 测试
|
||
*
|
||
* 测试导入导出功能的完整场景:
|
||
* - 导入有效JSON数据
|
||
* - 导入无效JSON处理
|
||
* - 导入数据合并策略
|
||
* - 导入结果统计显示
|
||
* - 导出数据完整性
|
||
*/
|
||
test.describe('导入导出完整流程', () => {
|
||
test.beforeEach(async ({ page }) => {
|
||
await page.goto('/');
|
||
await page.waitForLoadState('networkidle');
|
||
});
|
||
|
||
/**
|
||
* 辅助函数:打开收藏管理器
|
||
*/
|
||
async function openFavoriteManager(page: any) {
|
||
const favoriteButton = page.getByRole('button', { name: /收藏|favorite/i });
|
||
if (await favoriteButton.count() === 0) {
|
||
return null;
|
||
}
|
||
await favoriteButton.first().click();
|
||
await page.waitForTimeout(500);
|
||
|
||
const managerDialog = page.locator('[role="dialog"]').filter({ hasText: /收藏|Favorites/i }).first();
|
||
if (await managerDialog.isVisible().catch(() => false)) {
|
||
return managerDialog;
|
||
}
|
||
return null;
|
||
}
|
||
|
||
test('导入有效的JSON数据', async ({ page }) => {
|
||
const managerDialog = await openFavoriteManager(page);
|
||
if (!managerDialog) {
|
||
test.skip();
|
||
return;
|
||
}
|
||
|
||
// 查找导入按钮
|
||
const importButton = managerDialog.getByRole('button', { name: /导入|Import/i });
|
||
if (await importButton.count() === 0) {
|
||
test.skip();
|
||
return;
|
||
}
|
||
|
||
await importButton.click();
|
||
await page.waitForTimeout(500);
|
||
|
||
// 准备导入数据
|
||
const importData = {
|
||
favorites: [
|
||
{
|
||
id: 'import-test-001',
|
||
title: '导入测试收藏1',
|
||
content: '这是通过导入创建的收藏',
|
||
tags: ['导入', '测试'],
|
||
functionMode: 'basic',
|
||
createdAt: new Date().toISOString(),
|
||
updatedAt: new Date().toISOString()
|
||
},
|
||
{
|
||
id: 'import-test-002',
|
||
title: '导入测试收藏2',
|
||
content: '另一个导入的收藏',
|
||
tags: ['导入'],
|
||
functionMode: 'context',
|
||
optimizationMode: 'user',
|
||
createdAt: new Date().toISOString(),
|
||
updatedAt: new Date().toISOString()
|
||
}
|
||
],
|
||
categories: [
|
||
{
|
||
id: 'import-cat-001',
|
||
name: '导入的分类',
|
||
description: '通过导入创建的分类',
|
||
color: '#FF5722'
|
||
}
|
||
],
|
||
tags: ['导入', '测试']
|
||
};
|
||
|
||
// 在导入对话框中输入JSON数据
|
||
const importDialog = page.locator('[role="dialog"]').last();
|
||
|
||
// 查找文本输入区域(可能是textarea或文件上传)
|
||
const jsonInput = importDialog.locator('textarea').first();
|
||
|
||
if (await jsonInput.count() > 0) {
|
||
await jsonInput.fill(JSON.stringify(importData, null, 2));
|
||
|
||
// 点击确认导入按钮
|
||
const confirmButton = importDialog.getByRole('button', { name: /确定|确认|导入|ok|import/i });
|
||
if (await confirmButton.count() > 0) {
|
||
await confirmButton.click();
|
||
await page.waitForTimeout(1500);
|
||
|
||
// 验证导入成功消息
|
||
const successMessage = page.locator('.n-message, .n-notification').filter({
|
||
hasText: /成功|success|导入/i
|
||
});
|
||
|
||
if (await successMessage.count() > 0) {
|
||
await expect(successMessage.first()).toBeVisible();
|
||
}
|
||
|
||
// 验证导入的收藏显示在列表中
|
||
const importedFavorite = managerDialog.locator('text=导入测试收藏1');
|
||
if (await importedFavorite.count() > 0) {
|
||
await expect(importedFavorite.first()).toBeVisible();
|
||
}
|
||
}
|
||
} else {
|
||
// 可能是文件上传模式
|
||
// 创建临时JSON文件并上传
|
||
const fileInput = importDialog.locator('input[type="file"]');
|
||
if (await fileInput.count() > 0) {
|
||
// 在实际环境中,这里需要创建真实文件
|
||
// Playwright支持通过setInputFiles上传文件
|
||
test.skip(); // 文件上传模式需要额外处理
|
||
}
|
||
}
|
||
});
|
||
|
||
test('导入无效JSON数据处理', async ({ page }) => {
|
||
const managerDialog = await openFavoriteManager(page);
|
||
if (!managerDialog) {
|
||
test.skip();
|
||
return;
|
||
}
|
||
|
||
const importButton = managerDialog.getByRole('button', { name: /导入|Import/i });
|
||
if (await importButton.count() === 0) {
|
||
test.skip();
|
||
return;
|
||
}
|
||
|
||
await importButton.click();
|
||
await page.waitForTimeout(500);
|
||
|
||
const importDialog = page.locator('[role="dialog"]').last();
|
||
const jsonInput = importDialog.locator('textarea').first();
|
||
|
||
if (await jsonInput.count() > 0) {
|
||
// 输入无效的JSON
|
||
await jsonInput.fill('{ 这不是有效的JSON }');
|
||
|
||
const confirmButton = importDialog.getByRole('button', { name: /确定|确认|导入|ok|import/i });
|
||
if (await confirmButton.count() > 0) {
|
||
await confirmButton.click();
|
||
await page.waitForTimeout(500);
|
||
|
||
// 应该显示错误消息
|
||
const errorMessage = page.locator('.n-message, .n-notification').filter({
|
||
hasText: /错误|失败|error|invalid|格式/i
|
||
});
|
||
|
||
if (await errorMessage.count() > 0) {
|
||
await expect(errorMessage.first()).toBeVisible();
|
||
}
|
||
|
||
// 对话框应该仍然打开(未成功导入)
|
||
const stillOpen = await importDialog.isVisible().catch(() => false);
|
||
if (stillOpen) {
|
||
expect(stillOpen).toBe(true);
|
||
}
|
||
}
|
||
}
|
||
});
|
||
|
||
test('导入数据后统计信息更新', async ({ page }) => {
|
||
const managerDialog = await openFavoriteManager(page);
|
||
if (!managerDialog) {
|
||
test.skip();
|
||
return;
|
||
}
|
||
|
||
// 记录导入前的收藏数量(如果有显示)
|
||
const initialFavorites = await managerDialog.locator('.n-card, [class*="favorite"]').count();
|
||
|
||
const importButton = managerDialog.getByRole('button', { name: /导入|Import/i });
|
||
if (await importButton.count() === 0) {
|
||
test.skip();
|
||
return;
|
||
}
|
||
|
||
await importButton.click();
|
||
await page.waitForTimeout(500);
|
||
|
||
const importData = {
|
||
favorites: [
|
||
{
|
||
title: '统计测试收藏',
|
||
content: '用于测试统计更新',
|
||
tags: ['统计'],
|
||
functionMode: 'basic',
|
||
createdAt: new Date().toISOString(),
|
||
updatedAt: new Date().toISOString()
|
||
}
|
||
],
|
||
categories: [],
|
||
tags: ['统计']
|
||
};
|
||
|
||
const importDialog = page.locator('[role="dialog"]').last();
|
||
const jsonInput = importDialog.locator('textarea').first();
|
||
|
||
if (await jsonInput.count() > 0) {
|
||
await jsonInput.fill(JSON.stringify(importData));
|
||
|
||
const confirmButton = importDialog.getByRole('button', { name: /确定|确认|导入|ok|import/i });
|
||
if (await confirmButton.count() > 0) {
|
||
await confirmButton.click();
|
||
await page.waitForTimeout(1500);
|
||
|
||
// 验证收藏数量增加
|
||
const finalFavorites = await managerDialog.locator('.n-card, [class*="favorite"]').count();
|
||
expect(finalFavorites).toBeGreaterThan(initialFavorites);
|
||
}
|
||
}
|
||
});
|
||
|
||
test('导入包含分类的数据', async ({ page }) => {
|
||
const managerDialog = await openFavoriteManager(page);
|
||
if (!managerDialog) {
|
||
test.skip();
|
||
return;
|
||
}
|
||
|
||
const importButton = managerDialog.getByRole('button', { name: /导入|Import/i });
|
||
if (await importButton.count() === 0) {
|
||
test.skip();
|
||
return;
|
||
}
|
||
|
||
await importButton.click();
|
||
await page.waitForTimeout(500);
|
||
|
||
const importData = {
|
||
favorites: [
|
||
{
|
||
title: '分类测试收藏',
|
||
content: '属于导入分类的收藏',
|
||
tags: ['分类测试'],
|
||
category: 'import-category-001',
|
||
functionMode: 'basic',
|
||
createdAt: new Date().toISOString(),
|
||
updatedAt: new Date().toISOString()
|
||
}
|
||
],
|
||
categories: [
|
||
{
|
||
id: 'import-category-001',
|
||
name: '导入的测试分类',
|
||
description: '通过导入创建的分类',
|
||
color: '#4CAF50'
|
||
}
|
||
],
|
||
tags: ['分类测试']
|
||
};
|
||
|
||
const importDialog = page.locator('[role="dialog"]').last();
|
||
const jsonInput = importDialog.locator('textarea').first();
|
||
|
||
if (await jsonInput.count() > 0) {
|
||
await jsonInput.fill(JSON.stringify(importData));
|
||
|
||
const confirmButton = importDialog.getByRole('button', { name: /确定|确认|导入|ok|import/i });
|
||
if (await confirmButton.count() > 0) {
|
||
await confirmButton.click();
|
||
await page.waitForTimeout(1500);
|
||
|
||
// 验证收藏已导入
|
||
const importedFavorite = managerDialog.locator('text=分类测试收藏');
|
||
if (await importedFavorite.count() > 0) {
|
||
await expect(importedFavorite.first()).toBeVisible();
|
||
}
|
||
|
||
// 可以通过打开分类管理器验证分类也被导入
|
||
// 这里简化处理,只验证收藏导入成功
|
||
}
|
||
}
|
||
});
|
||
|
||
test('导入数据合并策略(相同ID处理)', async ({ page }) => {
|
||
const managerDialog = await openFavoriteManager(page);
|
||
if (!managerDialog) {
|
||
test.skip();
|
||
return;
|
||
}
|
||
|
||
// 第一次导入
|
||
const importButton = managerDialog.getByRole('button', { name: /导入|Import/i });
|
||
if (await importButton.count() === 0) {
|
||
test.skip();
|
||
return;
|
||
}
|
||
|
||
await importButton.click();
|
||
await page.waitForTimeout(500);
|
||
|
||
const importData = {
|
||
favorites: [
|
||
{
|
||
id: 'duplicate-test-001',
|
||
title: '重复ID测试收藏',
|
||
content: '第一次导入',
|
||
tags: ['重复测试'],
|
||
functionMode: 'basic',
|
||
createdAt: new Date().toISOString(),
|
||
updatedAt: new Date().toISOString()
|
||
}
|
||
],
|
||
categories: [],
|
||
tags: ['重复测试']
|
||
};
|
||
|
||
const importDialog = page.locator('[role="dialog"]').last();
|
||
const jsonInput = importDialog.locator('textarea').first();
|
||
|
||
if (await jsonInput.count() > 0) {
|
||
await jsonInput.fill(JSON.stringify(importData));
|
||
|
||
const confirmButton = importDialog.getByRole('button', { name: /确定|确认|导入|ok|import/i });
|
||
if (await confirmButton.count() > 0) {
|
||
await confirmButton.click();
|
||
await page.waitForTimeout(1500);
|
||
|
||
// 第二次导入相同ID的数据
|
||
const importButton2 = managerDialog.getByRole('button', { name: /导入|Import/i });
|
||
if (await importButton2.count() > 0) {
|
||
await importButton2.click();
|
||
await page.waitForTimeout(500);
|
||
|
||
const importData2 = {
|
||
favorites: [
|
||
{
|
||
id: 'duplicate-test-001', // 相同ID
|
||
title: '重复ID测试收藏-修改版',
|
||
content: '第二次导入',
|
||
tags: ['重复测试', '修改'],
|
||
functionMode: 'basic',
|
||
createdAt: new Date().toISOString(),
|
||
updatedAt: new Date().toISOString()
|
||
}
|
||
],
|
||
categories: [],
|
||
tags: ['重复测试', '修改']
|
||
};
|
||
|
||
const importDialog2 = page.locator('[role="dialog"]').last();
|
||
const jsonInput2 = importDialog2.locator('textarea').first();
|
||
|
||
if (await jsonInput2.count() > 0) {
|
||
await jsonInput2.fill(JSON.stringify(importData2));
|
||
|
||
const confirmButton2 = importDialog2.getByRole('button', { name: /确定|确认|导入|ok|import/i });
|
||
if (await confirmButton2.count() > 0) {
|
||
await confirmButton2.click();
|
||
await page.waitForTimeout(1500);
|
||
|
||
// 验证两个收藏都存在(ID冲突应该生成新ID)
|
||
const favorites = managerDialog.locator('.n-card, [class*="favorite"]').filter({
|
||
hasText: /重复ID测试收藏/
|
||
});
|
||
|
||
const count = await favorites.count();
|
||
// 应该有2个收藏(系统重新生成了ID以避免冲突)
|
||
expect(count).toBeGreaterThanOrEqual(1);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
});
|
||
|
||
test('导出功能生成有效JSON', async ({ page }) => {
|
||
const managerDialog = await openFavoriteManager(page);
|
||
if (!managerDialog) {
|
||
test.skip();
|
||
return;
|
||
}
|
||
|
||
// 先创建一个收藏,确保有数据可导出
|
||
const addButton = managerDialog.getByRole('button', { name: /添加|创建|新建|add|create/i }).first();
|
||
if (await addButton.count() > 0) {
|
||
await addButton.click();
|
||
await page.waitForTimeout(500);
|
||
|
||
const createDialog = page.locator('[role="dialog"]').last();
|
||
const titleInput = createDialog.getByPlaceholder(/标题|title/i);
|
||
|
||
if (await titleInput.count() > 0) {
|
||
await titleInput.fill('导出测试收藏');
|
||
|
||
const contentInput = createDialog.locator('textarea').first();
|
||
if (await contentInput.count() > 0) {
|
||
await contentInput.fill('用于测试导出功能');
|
||
}
|
||
|
||
const saveButton = createDialog.getByRole('button', { name: /保存|save|确定|ok/i });
|
||
if (await saveButton.count() > 0) {
|
||
await saveButton.click();
|
||
await page.waitForTimeout(1000);
|
||
|
||
// 等待创建对话框的遮罩层消失
|
||
await page.waitForSelector('.n-modal-mask', { state: 'hidden', timeout: 3000 }).catch(() => {});
|
||
}
|
||
}
|
||
}
|
||
|
||
// 等待创建对话框完全关闭后再打开更多菜单
|
||
await page.keyboard.press('Escape');
|
||
await page.waitForTimeout(300);
|
||
|
||
// 打开更多菜单导出
|
||
const moreButton = managerDialog.getByRole('button').filter({
|
||
has: page.locator('svg, .n-icon')
|
||
}).first();
|
||
|
||
if (await moreButton.count() > 0) {
|
||
await moreButton.click();
|
||
await page.waitForTimeout(300);
|
||
|
||
const exportOption = page.locator('text=/导出|Export/i');
|
||
if (await exportOption.count() > 0) {
|
||
// 监听下载事件
|
||
const downloadPromise = page.waitForEvent('download', { timeout: 5000 }).catch(() => null);
|
||
|
||
await exportOption.click();
|
||
|
||
const download = await downloadPromise;
|
||
if (download) {
|
||
// 验证下载的文件
|
||
const path = await download.path();
|
||
if (path) {
|
||
const fs = await import('fs');
|
||
const content = fs.readFileSync(path, 'utf-8');
|
||
|
||
// 验证是有效的JSON
|
||
expect(() => JSON.parse(content)).not.toThrow();
|
||
|
||
const data = JSON.parse(content);
|
||
|
||
// 验证包含必要的字段
|
||
expect(data).toHaveProperty('favorites');
|
||
expect(Array.isArray(data.favorites)).toBe(true);
|
||
expect(data.favorites.length).toBeGreaterThan(0);
|
||
|
||
// 验证收藏数据结构
|
||
const firstFavorite = data.favorites[0];
|
||
expect(firstFavorite).toHaveProperty('id');
|
||
expect(firstFavorite).toHaveProperty('title');
|
||
expect(firstFavorite).toHaveProperty('content');
|
||
expect(firstFavorite).toHaveProperty('tags');
|
||
expect(firstFavorite).toHaveProperty('functionMode');
|
||
}
|
||
}
|
||
}
|
||
}
|
||
});
|
||
|
||
test('导入后数据可以正常编辑', async ({ page }) => {
|
||
const managerDialog = await openFavoriteManager(page);
|
||
if (!managerDialog) {
|
||
test.skip();
|
||
return;
|
||
}
|
||
|
||
// 导入数据
|
||
const importButton = managerDialog.getByRole('button', { name: /导入|Import/i });
|
||
if (await importButton.count() === 0) {
|
||
test.skip();
|
||
return;
|
||
}
|
||
|
||
await importButton.click();
|
||
await page.waitForTimeout(500);
|
||
|
||
const importData = {
|
||
favorites: [
|
||
{
|
||
title: '可编辑导入收藏',
|
||
content: '原始内容',
|
||
tags: ['可编辑'],
|
||
functionMode: 'basic',
|
||
createdAt: new Date().toISOString(),
|
||
updatedAt: new Date().toISOString()
|
||
}
|
||
],
|
||
categories: [],
|
||
tags: ['可编辑']
|
||
};
|
||
|
||
const importDialog = page.locator('[role="dialog"]').last();
|
||
const jsonInput = importDialog.locator('textarea').first();
|
||
|
||
if (await jsonInput.count() > 0) {
|
||
await jsonInput.fill(JSON.stringify(importData));
|
||
|
||
const confirmButton = importDialog.getByRole('button', { name: /确定|确认|导入|ok|import/i });
|
||
if (await confirmButton.count() > 0) {
|
||
await confirmButton.click();
|
||
await page.waitForTimeout(1500);
|
||
|
||
// 查找并编辑导入的收藏
|
||
const favoriteCard = managerDialog.locator('text=可编辑导入收藏').locator('..').locator('..');
|
||
if (await favoriteCard.count() > 0) {
|
||
// 查找编辑按钮
|
||
const editButton = favoriteCard.locator('button').filter({
|
||
hasText: /编辑|edit/i
|
||
}).first();
|
||
|
||
if (await editButton.count() > 0) {
|
||
await editButton.click();
|
||
await page.waitForTimeout(500);
|
||
|
||
// 修改标题
|
||
const editDialog = page.locator('[role="dialog"]').last();
|
||
const titleInput = editDialog.getByPlaceholder(/标题|title/i);
|
||
|
||
if (await titleInput.count() > 0) {
|
||
await titleInput.clear();
|
||
await titleInput.fill('编辑后的导入收藏');
|
||
|
||
const saveButton = editDialog.getByRole('button', { name: /保存|save|确定|ok/i });
|
||
if (await saveButton.count() > 0) {
|
||
await saveButton.click();
|
||
await page.waitForTimeout(1000);
|
||
|
||
// 验证修改成功
|
||
const updatedCard = managerDialog.locator('text=编辑后的导入收藏');
|
||
if (await updatedCard.count() > 0) {
|
||
await expect(updatedCard.first()).toBeVisible();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
});
|
||
|
||
test('导入后数据可以正常删除', async ({ page }) => {
|
||
const managerDialog = await openFavoriteManager(page);
|
||
if (!managerDialog) {
|
||
test.skip();
|
||
return;
|
||
}
|
||
|
||
// 导入数据
|
||
const importButton = managerDialog.getByRole('button', { name: /导入|Import/i });
|
||
if (await importButton.count() === 0) {
|
||
test.skip();
|
||
return;
|
||
}
|
||
|
||
await importButton.click();
|
||
await page.waitForTimeout(500);
|
||
|
||
const importData = {
|
||
favorites: [
|
||
{
|
||
title: '可删除导入收藏',
|
||
content: '将被删除的内容',
|
||
tags: ['可删除'],
|
||
functionMode: 'basic',
|
||
createdAt: new Date().toISOString(),
|
||
updatedAt: new Date().toISOString()
|
||
}
|
||
],
|
||
categories: [],
|
||
tags: ['可删除']
|
||
};
|
||
|
||
const importDialog = page.locator('[role="dialog"]').last();
|
||
const jsonInput = importDialog.locator('textarea').first();
|
||
|
||
if (await jsonInput.count() > 0) {
|
||
await jsonInput.fill(JSON.stringify(importData));
|
||
|
||
const confirmButton = importDialog.getByRole('button', { name: /确定|确认|导入|ok|import/i });
|
||
if (await confirmButton.count() > 0) {
|
||
await confirmButton.click();
|
||
await page.waitForTimeout(1500);
|
||
|
||
// 查找并删除导入的收藏
|
||
const favoriteCard = managerDialog.locator('text=可删除导入收藏').locator('..').locator('..');
|
||
if (await favoriteCard.count() > 0) {
|
||
const deleteButton = favoriteCard.locator('button').filter({
|
||
hasText: /删除|delete/i
|
||
}).first();
|
||
|
||
if (await deleteButton.count() > 0) {
|
||
await deleteButton.click();
|
||
await page.waitForTimeout(300);
|
||
|
||
// 确认删除
|
||
const confirmDeleteButton = page.getByRole('button', { name: /确定|确认|ok|confirm/i }).last();
|
||
if (await confirmDeleteButton.count() > 0) {
|
||
await confirmDeleteButton.click();
|
||
await page.waitForTimeout(1000);
|
||
|
||
// 验证已删除
|
||
const deletedCard = managerDialog.locator('text=可删除导入收藏');
|
||
expect(await deletedCard.count()).toBe(0);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
});
|
||
});
|