/** * 认证模块端到端测试 * 测试登录、登出、Token刷新等认证流程 */ import { test, expect, Page } from '@playwright/test'; import { TestLogger } from '../core/test-logger.js'; import { TestDataManager } from '../core/test-data-manager.js'; import { WorkflowExecutor } from '../core/workflow-executor.js'; import { TestReporter } from '../core/test-reporter.js'; import { LoginPage } from '../pages/login-page.js'; import { DashboardPage } from '../pages/dashboard-page.js'; test.describe('认证模块端到端测试', () => { let page: Page; let testLogger: TestLogger; let testDataManager: TestDataManager; let workflowExecutor: WorkflowExecutor; let testReporter: TestReporter; let loginPage: LoginPage; let dashboardPage: DashboardPage; test.beforeAll(async ({ browser }) => { page = await browser.newPage(); testLogger = new TestLogger(); testDataManager = TestDataManager.getInstance(testLogger); workflowExecutor = new WorkflowExecutor(testLogger); testReporter = new TestReporter(testLogger); loginPage = new LoginPage(page, testLogger); dashboardPage = new DashboardPage(page); testReporter.startSuite('认证模块端到端测试'); }); test.afterAll(async () => { testReporter.endSuite(); testReporter.generateHTMLReport('认证模块E2E测试报告'); await page.close(); }); test.afterEach(async ({}, testInfo) => { if (testInfo.status === 'failed') { const screenshotPath = `test-results/screenshots/${testInfo.title}-${Date.now()}.png`; await page.screenshot({ path: screenshotPath, fullPage: true }); testReporter.addScreenshot(screenshotPath); } }); test('应该成功登录并跳转到仪表盘', async () => { testReporter.startTest('成功登录'); try { await loginPage.navigate(); await loginPage.login('admin', 'admin123'); await loginPage.waitForLoginSuccess(); // 验证仪表盘页面 const pageTitle = await dashboardPage.getPageTitle(); expect(pageTitle).toContain('仪表盘'); testReporter.endTest('passed'); } catch (error) { testReporter.endTest('failed', error as Error); throw error; } }); test('应该拒绝错误的用户名', async () => { testReporter.startTest('拒绝错误用户名'); try { await loginPage.navigate(); await loginPage.login('wronguser', 'admin123'); const errorText = await loginPage.waitForError(); expect(errorText).toContain('错误'); testReporter.endTest('passed'); } catch (error) { testReporter.endTest('failed', error as Error); throw error; } }); test('应该拒绝错误的密码', async () => { testReporter.startTest('拒绝错误密码'); try { await loginPage.navigate(); await loginPage.login('admin', 'wrongpassword'); const errorText = await loginPage.waitForError(); expect(errorText).toContain('错误'); testReporter.endTest('passed'); } catch (error) { testReporter.endTest('failed', error as Error); throw error; } }); test('应该验证用户名不能为空', async () => { testReporter.startTest('验证用户名不能为空'); try { await loginPage.navigate(); await loginPage.clickLoginButton(); const hasError = await page.locator('[role="alert"]').isVisible(); expect(hasError).toBe(true); testReporter.endTest('passed'); } catch (error) { testReporter.endTest('failed', error as Error); throw error; } }); test('应该成功登出', async () => { testReporter.startTest('成功登出'); try { // 先登录 await loginPage.navigate(); await loginPage.login('admin', 'admin123'); await loginPage.waitForLoginSuccess(); // 执行登出 await page.click('.ant-dropdown-link'); await page.waitForTimeout(500); await page.click('.ant-dropdown-menu-item:has-text("退出")'); await page.waitForURL(/.*login/, { timeout: 10000 }); // 验证返回登录页面 const isLoginFormVisible = await loginPage.verifyLoginFormExists(); expect(isLoginFormVisible).toBe(true); testReporter.endTest('passed'); } catch (error) { testReporter.endTest('failed', error as Error); throw error; } }); test('应该保持登录状态在页面刷新后', async () => { testReporter.startTest('刷新后保持登录'); try { // 先登录 await loginPage.navigate(); await loginPage.login('admin', 'admin123'); await loginPage.waitForLoginSuccess(); // 刷新页面 await page.reload(); await dashboardPage.waitForLoad(); // 验证仍在仪表盘 const isDashboardVisible = await dashboardPage.isDashboardVisible(); expect(isDashboardVisible).toBe(true); testReporter.endTest('passed'); } catch (error) { testReporter.endTest('failed', error as Error); throw error; } }); test('应该完成完整的登录-操作-登出流程', async () => { testReporter.startTest('完整认证流程'); try { // 步骤1: 登录 testLogger.startStep('用户登录'); await loginPage.navigate(); await loginPage.login('admin', 'admin123'); await loginPage.waitForLoginSuccess(); testLogger.endStep('用户登录', 'passed'); // 步骤2: 访问仪表盘 testLogger.startStep('访问仪表盘'); await dashboardPage.waitForLoad(); const isDashboardVisible = await dashboardPage.isDashboardVisible(); expect(isDashboardVisible).toBe(true); testLogger.endStep('访问仪表盘', 'passed'); // 步骤3: 访问用户管理 testLogger.startStep('访问用户管理'); await page.click('.ant-menu-item:has-text("用户管理")'); await page.waitForURL(/.*users/, { timeout: 10000 }); testLogger.endStep('访问用户管理', 'passed'); // 步骤4: 返回仪表盘 testLogger.startStep('返回仪表盘'); await page.click('.ant-menu-item:has-text("仪表盘")'); await page.waitForURL(/.*dashboard/, { timeout: 10000 }); testLogger.endStep('返回仪表盘', 'passed'); // 步骤5: 登出 testLogger.startStep('用户登出'); await page.click('.ant-dropdown-link'); await page.waitForTimeout(500); await page.click('.ant-dropdown-menu-item:has-text("退出")'); await page.waitForURL(/.*login/, { timeout: 10000 }); testLogger.endStep('用户登出', 'passed'); // 验证返回登录页面 const isLoginFormVisible = await loginPage.verifyLoginFormExists(); expect(isLoginFormVisible).toBe(true); testReporter.endTest('passed'); } catch (error) { testReporter.endTest('failed', error as Error); throw error; } }); });