Files
张翔 08ea5fbe98 feat(admin): 添加用户管理相关文件
添加用户管理视图、API和状态管理文件
2026-03-28 14:37:29 +08:00

259 lines
9.8 KiB
TypeScript

import { test, expect } from '@playwright/test';
test.describe('关键词搜索功能E2E测试', () => {
let baseUrl: string;
test.beforeAll(async () => {
baseUrl = 'http://localhost:8081';
});
test.describe('TC-KEYWORD-001: 首页搜索入口', () => {
test.beforeEach(async ({ page }) => {
await page.goto(`${baseUrl}/#/pages/index/index`);
await page.waitForLoadState('networkidle');
});
test('应该显示搜索入口', async ({ page }) => {
const searchEntry = page.locator('.search-entry, [class*="search-entry"], .search-box');
expect(await searchEntry.isVisible()).toBe(true);
});
test('点击搜索入口应该打开搜索面板', async ({ page }) => {
const searchEntry = page.locator('.search-entry, [class*="search-entry"], .search-box');
await searchEntry.click();
await page.waitForTimeout(500);
const searchPanel = page.locator('.search-condition-panel, [class*="SearchConditionPanel"]');
expect(await searchPanel.isVisible()).toBe(true);
});
test('搜索面板应该包含关键词输入框', async ({ page }) => {
const searchEntry = page.locator('.search-entry, [class*="search-entry"], .search-box');
await searchEntry.click();
await page.waitForTimeout(500);
const keywordInput = page.locator('.keyword-input, input[placeholder*="关键词"], input[placeholder*="搜索"]');
expect(await keywordInput.isVisible()).toBe(true);
});
});
test.describe('TC-KEYWORD-002: 关键词搜索流程', () => {
test.beforeEach(async ({ page }) => {
await page.goto(`${baseUrl}/#/pages/index/index`);
await page.waitForLoadState('networkidle');
});
test('应该能够输入关键词进行搜索', async ({ page }) => {
const searchEntry = page.locator('.search-entry, [class*="search-entry"], .search-box');
await searchEntry.click();
await page.waitForTimeout(500);
const keywordInput = page.locator('.keyword-input, input[placeholder*="关键词"], input[placeholder*="搜索"]');
await keywordInput.fill('祭祀');
await page.waitForTimeout(300);
const searchButton = page.locator('.search-btn, button:has-text("搜索")');
if (await searchButton.isVisible()) {
await searchButton.click();
await page.waitForTimeout(1000);
await page.waitForURL(/almanac-search/, { timeout: 5000 });
}
});
test('空关键词不应该触发搜索', async ({ page }) => {
const searchEntry = page.locator('.search-entry, [class*="search-entry"], .search-box');
await searchEntry.click();
await page.waitForTimeout(500);
const keywordInput = page.locator('.keyword-input, input[placeholder*="关键词"], input[placeholder*="搜索"]');
await keywordInput.fill('');
await page.waitForTimeout(300);
const searchButton = page.locator('.search-btn, button:has-text("搜索")');
if (await searchButton.isVisible()) {
await searchButton.click();
await page.waitForTimeout(500);
const currentUrl = page.url();
expect(currentUrl).not.toContain('keyword=');
}
});
test('应该能够清除关键词', async ({ page }) => {
const searchEntry = page.locator('.search-entry, [class*="search-entry"], .search-box');
await searchEntry.click();
await page.waitForTimeout(500);
const keywordInput = page.locator('.keyword-input, input[placeholder*="关键词"], input[placeholder*="搜索"]');
await keywordInput.fill('测试关键词');
await page.waitForTimeout(300);
const clearButton = page.locator('.clear-btn, [class*="clear"]');
if (await clearButton.isVisible()) {
await clearButton.click();
await page.waitForTimeout(300);
const inputValue = await keywordInput.inputValue();
expect(inputValue).toBe('');
}
});
});
test.describe('TC-KEYWORD-003: 搜索历史', () => {
test.beforeEach(async ({ page }) => {
await page.goto(`${baseUrl}/#/pages/index/index`);
await page.waitForLoadState('networkidle');
});
test('应该保存搜索历史', async ({ page }) => {
const searchEntry = page.locator('.search-entry, [class*="search-entry"], .search-box');
await searchEntry.click();
await page.waitForTimeout(500);
const keywordInput = page.locator('.keyword-input, input[placeholder*="关键词"], input[placeholder*="搜索"]');
await keywordInput.fill('历史测试');
const searchButton = page.locator('.search-btn, button:has-text("搜索")');
if (await searchButton.isVisible()) {
await searchButton.click();
await page.waitForTimeout(1000);
}
await page.goto(`${baseUrl}/#/pages/index/index`);
await page.waitForLoadState('networkidle');
await searchEntry.click();
await page.waitForTimeout(500);
const historyItem = page.locator('.history-item:has-text("历史测试"), [class*="history"]:has-text("历史测试")');
const historyVisible = await historyItem.isVisible().catch(() => false);
if (historyVisible) {
expect(historyVisible).toBe(true);
}
});
test('应该能够清除搜索历史', async ({ page }) => {
const searchEntry = page.locator('.search-entry, [class*="search-entry"], .search-box');
await searchEntry.click();
await page.waitForTimeout(500);
const clearHistoryBtn = page.locator('.clear-history, button:has-text("清除历史")');
if (await clearHistoryBtn.isVisible()) {
await clearHistoryBtn.click();
await page.waitForTimeout(500);
const historyItems = page.locator('.history-item, [class*="history-item"]');
const count = await historyItems.count();
expect(count).toBe(0);
}
});
});
test.describe('TC-KEYWORD-004: 搜索结果页', () => {
test.beforeEach(async ({ page }) => {
await page.goto(`${baseUrl}/#/pages/almanac-search/index?keyword=%E7%A5%AD%E7%A5%80`);
await page.waitForLoadState('networkidle');
});
test('应该显示搜索结果', async ({ page }) => {
await page.waitForTimeout(2000);
const results = page.locator('.search-result-card, [class*="SearchResultCard"], .result-item');
const count = await results.count();
if (count > 0) {
expect(await results.first().isVisible()).toBe(true);
}
});
test('应该显示加载状态', async ({ page }) => {
const loadingIndicator = page.locator('.loading-indicator, [class*="loading"]');
const loadingVisible = await loadingIndicator.isVisible().catch(() => false);
if (loadingVisible) {
expect(loadingVisible).toBe(true);
}
});
test('无结果时应该显示空状态', async ({ page }) => {
await page.goto(`${baseUrl}/#/pages/almanac-search/index?keyword=xyz123notexist`);
await page.waitForLoadState('networkidle');
await page.waitForTimeout(2000);
const results = page.locator('.search-result-card, [class*="SearchResultCard"]');
const count = await results.count();
if (count === 0) {
const emptyState = page.locator('.empty-state, [class*="EmptyState"], .no-result');
const emptyVisible = await emptyState.isVisible().catch(() => false);
expect(emptyVisible).toBe(true);
}
});
});
test.describe('TC-KEYWORD-005: 高级搜索与关键词搜索切换', () => {
test.beforeEach(async ({ page }) => {
await page.goto(`${baseUrl}/#/pages/index/index`);
await page.waitForLoadState('networkidle');
});
test('应该能够切换到高级搜索', async ({ page }) => {
const searchEntry = page.locator('.search-entry, [class*="search-entry"], .search-box');
await searchEntry.click();
await page.waitForTimeout(500);
const advancedTab = page.locator('.tab:has-text("高级"), [class*="tab"]:has-text("高级")');
if (await advancedTab.isVisible()) {
await advancedTab.click();
await page.waitForTimeout(300);
const conditionPanel = page.locator('.condition-list, [class*="condition"]');
expect(await conditionPanel.isVisible()).toBe(true);
}
});
test('应该能够切换回关键词搜索', async ({ page }) => {
const searchEntry = page.locator('.search-entry, [class*="search-entry"], .search-box');
await searchEntry.click();
await page.waitForTimeout(500);
const advancedTab = page.locator('.tab:has-text("高级"), [class*="tab"]:has-text("高级")');
if (await advancedTab.isVisible()) {
await advancedTab.click();
await page.waitForTimeout(300);
const keywordTab = page.locator('.tab:has-text("关键词"), [class*="tab"]:has-text("关键词")');
if (await keywordTab.isVisible()) {
await keywordTab.click();
await page.waitForTimeout(300);
const keywordInput = page.locator('.keyword-input, input[placeholder*="关键词"]');
expect(await keywordInput.isVisible()).toBe(true);
}
}
});
});
test.describe('TC-KEYWORD-006: 响应式设计', () => {
test('移动端应该正常显示搜索入口', async ({ page }) => {
await page.setViewportSize({ width: 375, height: 667 });
await page.goto(`${baseUrl}/#/pages/index/index`);
await page.waitForLoadState('networkidle');
const searchEntry = page.locator('.search-entry, [class*="search-entry"], .search-box');
expect(await searchEntry.isVisible()).toBe(true);
});
test('桌面端应该正常显示搜索入口', async ({ page }) => {
await page.setViewportSize({ width: 1920, height: 1080 });
await page.goto(`${baseUrl}/#/pages/index/index`);
await page.waitForLoadState('networkidle');
const searchEntry = page.locator('.search-entry, [class*="search-entry"], .search-box');
expect(await searchEntry.isVisible()).toBe(true);
});
});
});