24422c2c19
- 增强前端表单验证规则(用户名、密码、邮箱、手机号) - 增强后端DTO验证注解(用户注册、角色创建) - 添加后端Handler验证逻辑(用户创建、角色创建) - 调整测试用例以适应系统实际情况 - 添加UAT测试套件(用户管理、角色管理、菜单管理、API交互、数据持久化、边界条件、安全测试) - 修改远程分支为 https://git.f.novalon.cn/novalon/novalon-manage-system.git
196 lines
7.1 KiB
TypeScript
196 lines
7.1 KiB
TypeScript
import { test, expect } from '@playwright/test';
|
|
|
|
test.describe('UAT阶段八:安全测试', () => {
|
|
test.beforeEach(async ({ page }) => {
|
|
await page.goto('/');
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const usernameInput = page.locator('input[type="text"]').first();
|
|
const passwordInput = page.locator('input[type="password"]').first();
|
|
const loginButton = page.locator('button:has-text("登录")');
|
|
|
|
await usernameInput.fill('admin');
|
|
await passwordInput.fill('admin123');
|
|
await loginButton.click();
|
|
|
|
await page.waitForURL('**/dashboard', { timeout: 30000 });
|
|
await page.waitForLoadState('networkidle');
|
|
});
|
|
|
|
test('UAT-SECURITY-001: XSS攻击防护测试', async ({ page }) => {
|
|
const systemMenu = page.locator('.el-sub-menu__title:has-text("系统管理")');
|
|
await systemMenu.click();
|
|
await page.waitForTimeout(1000);
|
|
|
|
await page.click('text=角色管理');
|
|
await page.waitForURL('**/roles', { timeout: 30000 });
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const addButton = page.locator('button:has-text("新增")').first();
|
|
if (await addButton.isVisible()) {
|
|
await addButton.click();
|
|
await page.waitForTimeout(500);
|
|
|
|
const roleNameInput = page.locator('.el-dialog input[placeholder*="角色名称"]').first();
|
|
const xssPayload = '<img src=x onerror=alert("XSS")>';
|
|
await roleNameInput.fill(xssPayload);
|
|
|
|
const roleKeyInput = page.locator('.el-dialog input[placeholder*="角色标识"]').first();
|
|
await roleKeyInput.fill('xss_test');
|
|
|
|
const confirmButton = page.locator('.el-dialog button:has-text("确定")');
|
|
await confirmButton.click();
|
|
await page.waitForTimeout(1000);
|
|
|
|
const errorMessage = page.locator('.el-form-item__error, .el-message--error');
|
|
const hasError = await errorMessage.isVisible().catch(() => false);
|
|
|
|
if (!hasError) {
|
|
const cancelButton = page.locator('.el-dialog button:has-text("取消")');
|
|
if (await cancelButton.isVisible()) {
|
|
await cancelButton.click();
|
|
}
|
|
}
|
|
|
|
expect(hasError).toBeTruthy();
|
|
}
|
|
});
|
|
|
|
test('UAT-SECURITY-002: SQL注入防护测试', async ({ page }) => {
|
|
const systemMenu = page.locator('.el-sub-menu__title:has-text("系统管理")');
|
|
await systemMenu.click();
|
|
await page.waitForTimeout(1000);
|
|
|
|
await page.click('text=用户管理');
|
|
await page.waitForURL('**/users', { timeout: 30000 });
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const searchInput = page.locator('input[placeholder*="搜索"]').first();
|
|
if (await searchInput.isVisible()) {
|
|
await searchInput.fill("admin' OR '1'='1");
|
|
await page.waitForTimeout(1000);
|
|
|
|
await expect(page.locator('.el-table')).toBeVisible();
|
|
|
|
const allRows = await page.locator('.el-table__row').count();
|
|
expect(allRows).toBeLessThan(100);
|
|
}
|
|
});
|
|
|
|
test('UAT-SECURITY-003: 未授权访问测试', async ({ page }) => {
|
|
await page.evaluate(() => {
|
|
localStorage.removeItem('token');
|
|
});
|
|
|
|
await page.goto('/users');
|
|
await page.waitForTimeout(2000);
|
|
|
|
const currentUrl = page.url();
|
|
expect(currentUrl).toContain('/login');
|
|
});
|
|
|
|
test('UAT-SECURITY-004: CSRF防护测试', async ({ page }) => {
|
|
const systemMenu = page.locator('.el-sub-menu__title:has-text("系统管理")');
|
|
await systemMenu.click();
|
|
await page.waitForTimeout(1000);
|
|
|
|
await page.click('text=角色管理');
|
|
await page.waitForURL('**/roles', { timeout: 30000 });
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const addButton = page.locator('button:has-text("新增")').first();
|
|
if (await addButton.isVisible()) {
|
|
await addButton.click();
|
|
await page.waitForTimeout(500);
|
|
|
|
const roleNameInput = page.locator('.el-dialog input[placeholder*="角色名称"]').first();
|
|
await roleNameInput.fill('CSRF测试角色');
|
|
|
|
const roleKeyInput = page.locator('.el-dialog input[placeholder*="角色标识"]').first();
|
|
await roleKeyInput.fill('csrf_test');
|
|
|
|
const confirmButton = page.locator('.el-dialog button:has-text("确定")');
|
|
await confirmButton.click();
|
|
await page.waitForTimeout(1000);
|
|
|
|
const successMessage = page.locator('.el-message--success');
|
|
const errorMessage = page.locator('.el-message--error');
|
|
|
|
const hasSuccess = await successMessage.isVisible().catch(() => false);
|
|
const hasError = await errorMessage.isVisible().catch(() => false);
|
|
|
|
expect(hasSuccess || hasError).toBeTruthy();
|
|
}
|
|
});
|
|
|
|
test('UAT-SECURITY-005: 密码强度验证测试', async ({ page }) => {
|
|
const systemMenu = page.locator('.el-sub-menu__title:has-text("系统管理")');
|
|
await systemMenu.click();
|
|
await page.waitForTimeout(1000);
|
|
|
|
await page.click('text=用户管理');
|
|
await page.waitForURL('**/users', { timeout: 30000 });
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const addButton = page.locator('button:has-text("新增用户")').first();
|
|
if (await addButton.isVisible()) {
|
|
await addButton.click();
|
|
await page.waitForTimeout(500);
|
|
|
|
const usernameInput = page.locator('.el-dialog input[placeholder*="用户名"]').first();
|
|
await usernameInput.fill('testuser');
|
|
|
|
const passwordInput = page.locator('.el-dialog input[placeholder*="密码"]').first();
|
|
await passwordInput.fill('123');
|
|
|
|
const confirmButton = page.locator('.el-dialog button:has-text("确定")');
|
|
await confirmButton.click();
|
|
await page.waitForTimeout(500);
|
|
|
|
const passwordError = page.locator('.el-form-item__error');
|
|
const hasError = await passwordError.isVisible().catch(() => false);
|
|
|
|
expect(hasError).toBeTruthy();
|
|
}
|
|
});
|
|
|
|
test('UAT-SECURITY-006: 敏感信息泄露测试', async ({ page }) => {
|
|
await page.goto('/');
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const pageContent = await page.content();
|
|
|
|
expect(pageContent).not.toContain('password');
|
|
expect(pageContent).not.toContain('secret');
|
|
expect(pageContent).not.toContain('api_key');
|
|
expect(pageContent).not.toContain('private_key');
|
|
});
|
|
|
|
test('UAT-SECURITY-007: 会话超时测试', async ({ page }) => {
|
|
const systemMenu = page.locator('.el-sub-menu__title:has-text("系统管理")');
|
|
await systemMenu.click();
|
|
await page.waitForTimeout(1000);
|
|
|
|
await page.click('text=用户管理');
|
|
await page.waitForURL('**/users', { timeout: 30000 });
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
await page.evaluate(() => {
|
|
const token = localStorage.getItem('token');
|
|
if (token) {
|
|
const expiredToken = token.replace(/\.(.*?)\./, '.expired.');
|
|
localStorage.setItem('token', expiredToken);
|
|
}
|
|
});
|
|
|
|
await page.reload();
|
|
await page.waitForTimeout(2000);
|
|
|
|
const currentUrl = page.url();
|
|
const isLoginPage = currentUrl.includes('/login');
|
|
const hasError = await page.locator('.el-message--error').isVisible().catch(() => false);
|
|
|
|
expect(isLoginPage || hasError).toBeTruthy();
|
|
});
|
|
});
|