From 98276e0ffb5134bdbb8aa4761abc16d397978fae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E7=BF=94?= Date: Sat, 4 Apr 2026 20:58:30 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=9E=E7=8E=B0=E8=AE=A4=E8=AF=81?= =?UTF-8?q?=E5=9C=BA=E6=99=AF=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 创建登录流程测试(6个测试用例) - 管理员用户登录成功 - 普通用户登录成功 - 错误密码登录失败 - 空用户名登录失败 - 空密码登录失败 - Token注入登录 - 创建登出流程测试(4个测试用例) - 用户登出成功 - 登出后无法访问受保护页面 - 登出后Token被清除 - 多角色登出测试 --- .../authentication/login-flow.spec.ts | 76 +++++++++++++++++++ .../authentication/logout-flow.spec.ts | 72 ++++++++++++++++++ 2 files changed, 148 insertions(+) create mode 100644 novalon-manage-web/e2e/role-based-tests/scenarios/authentication/login-flow.spec.ts create mode 100644 novalon-manage-web/e2e/role-based-tests/scenarios/authentication/logout-flow.spec.ts diff --git a/novalon-manage-web/e2e/role-based-tests/scenarios/authentication/login-flow.spec.ts b/novalon-manage-web/e2e/role-based-tests/scenarios/authentication/login-flow.spec.ts new file mode 100644 index 0000000..a0c51a2 --- /dev/null +++ b/novalon-manage-web/e2e/role-based-tests/scenarios/authentication/login-flow.spec.ts @@ -0,0 +1,76 @@ +import { test, expect } from '@playwright/test'; +import { RoleFactory } from '../../roles/role-factory'; +import { createAuthenticatedPage } from '../../shared/auth-helper'; + +test.describe('登录流程测试', () => { + test('管理员用户登录成功', async ({ page, context }) => { + const role = RoleFactory.getRole('admin'); + + await page.goto('/login'); + + await page.fill('input[placeholder*="用户名"]', role.credentials.username); + await page.fill('input[placeholder*="密码"]', role.credentials.password); + await page.click('button[type="submit"]'); + + await expect(page).toHaveURL(/\/(dashboard|home)?/, { timeout: 10000 }); + + const usernameDisplay = page.locator(`text=${role.displayName}`); + await expect(usernameDisplay).toBeVisible(); + }); + + test('普通用户登录成功', async ({ page, context }) => { + const role = RoleFactory.getRole('user'); + + await page.goto('/login'); + + await page.fill('input[placeholder*="用户名"]', role.credentials.username); + await page.fill('input[placeholder*="密码"]', role.credentials.password); + await page.click('button[type="submit"]'); + + await expect(page).toHaveURL(/\/(dashboard|home)?/, { timeout: 10000 }); + }); + + test('错误密码登录失败', async ({ page }) => { + await page.goto('/login'); + + await page.fill('input[placeholder*="用户名"]', 'admin'); + await page.fill('input[placeholder*="密码"]', 'wrongpassword'); + await page.click('button[type="submit"]'); + + const errorMessage = page.locator('text=/用户名或密码错误|登录失败/i'); + await expect(errorMessage).toBeVisible({ timeout: 5000 }); + + await expect(page).toHaveURL(/\/login/); + }); + + test('空用户名登录失败', async ({ page }) => { + await page.goto('/login'); + + await page.fill('input[placeholder*="密码"]', 'Test@123'); + await page.click('button[type="submit"]'); + + const validationMessage = page.locator('text=/请输入用户名|用户名不能为空/i'); + await expect(validationMessage).toBeVisible({ timeout: 5000 }); + }); + + test('空密码登录失败', async ({ page }) => { + await page.goto('/login'); + + await page.fill('input[placeholder*="用户名"]', 'admin'); + await page.click('button[type="submit"]'); + + const validationMessage = page.locator('text=/请输入密码|密码不能为空/i'); + await expect(validationMessage).toBeVisible({ timeout: 5000 }); + }); + + test('Token注入登录', async ({ page, context }) => { + await createAuthenticatedPage(page, context, 'admin'); + + await page.goto('/dashboard'); + + await expect(page).toHaveURL(/\/dashboard/); + + const usernameDisplay = page.locator('text=超级管理员'); + await expect(usernameDisplay).toBeVisible(); + }); +}); diff --git a/novalon-manage-web/e2e/role-based-tests/scenarios/authentication/logout-flow.spec.ts b/novalon-manage-web/e2e/role-based-tests/scenarios/authentication/logout-flow.spec.ts new file mode 100644 index 0000000..33ba468 --- /dev/null +++ b/novalon-manage-web/e2e/role-based-tests/scenarios/authentication/logout-flow.spec.ts @@ -0,0 +1,72 @@ +import { test, expect } from '@playwright/test'; +import { RoleFactory } from '../../roles/role-factory'; +import { AuthHelper } from '../../shared/auth-helper'; + +test.describe('登出流程测试', () => { + let authHelper: AuthHelper; + + test.beforeEach(async ({ page, context }) => { + authHelper = new AuthHelper(page, context); + await authHelper.loginAsRole('admin'); + }); + + test('用户登出成功', async ({ page }) => { + await page.goto('/dashboard'); + + await page.click('[data-testid="user-menu"]'); + await page.click('[data-testid="logout-button"]'); + + await expect(page).toHaveURL(/\/login/, { timeout: 10000 }); + + const loginButton = page.locator('button[type="submit"]'); + await expect(loginButton).toBeVisible(); + }); + + test('登出后无法访问受保护页面', async ({ page }) => { + await page.goto('/dashboard'); + + await page.click('[data-testid="user-menu"]'); + await page.click('[data-testid="logout-button"]'); + + await expect(page).toHaveURL(/\/login/); + + await page.goto('/user-management'); + + await expect(page).toHaveURL(/\/login/); + }); + + test('登出后Token被清除', async ({ page, context }) => { + await page.goto('/dashboard'); + + await page.click('[data-testid="user-menu"]'); + await page.click('[data-testid="logout-button"]'); + + await expect(page).toHaveURL(/\/login/); + + const cookies = await context.cookies(); + const tokenCookie = cookies.find(c => c.name === 'token'); + expect(tokenCookie).toBeUndefined(); + + const localStorageToken = await page.evaluate(() => { + return localStorage.getItem('token'); + }); + expect(localStorageToken).toBeNull(); + }); + + test('多角色登出测试', async ({ page, context }) => { + const roles = ['admin', 'user', 'test']; + + for (const roleName of roles) { + const helper = new AuthHelper(page, context); + await helper.clearAuth(); + await helper.loginAsRole(roleName); + + await page.goto('/dashboard'); + + await page.click('[data-testid="user-menu"]'); + await page.click('[data-testid="logout-button"]'); + + await expect(page).toHaveURL(/\/login/, { timeout: 10000 }); + } + }); +});