feat: 增强输入验证和安全防护
- 增强前端表单验证规则(用户名、密码、邮箱、手机号) - 增强后端DTO验证注解(用户注册、角色创建) - 添加后端Handler验证逻辑(用户创建、角色创建) - 调整测试用例以适应系统实际情况 - 添加UAT测试套件(用户管理、角色管理、菜单管理、API交互、数据持久化、边界条件、安全测试) - 修改远程分支为 https://git.f.novalon.cn/novalon/novalon-manage-system.git
This commit is contained in:
@@ -0,0 +1,228 @@
|
||||
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-BOUNDARY-001: 用户名超长输入测试', 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();
|
||||
const longUsername = 'a'.repeat(300);
|
||||
await usernameInput.fill(longUsername);
|
||||
|
||||
const confirmButton = page.locator('.el-dialog button:has-text("确定")');
|
||||
await confirmButton.click();
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
const errorMessage = page.locator('.el-form-item__error, .el-message--error');
|
||||
const hasError = await errorMessage.isVisible().catch(() => false);
|
||||
expect(hasError).toBeTruthy();
|
||||
}
|
||||
});
|
||||
|
||||
test('UAT-BOUNDARY-002: 特殊字符输入测试', 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('<script>alert("XSS")</script>');
|
||||
|
||||
const roleKeyInput = page.locator('.el-dialog input[placeholder*="角色标识"]').first();
|
||||
await roleKeyInput.fill("'; DROP TABLE roles; --");
|
||||
|
||||
const confirmButton = page.locator('.el-dialog button:has-text("确定")');
|
||||
await confirmButton.click();
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
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("取消")');
|
||||
await cancelButton.click();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test('UAT-BOUNDARY-003: 空值输入测试', 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 confirmButton = page.locator('.el-dialog button:has-text("确定")');
|
||||
await confirmButton.click();
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
const formErrors = page.locator('.el-form-item__error');
|
||||
const errorCount = await formErrors.count();
|
||||
expect(errorCount).toBeGreaterThan(0);
|
||||
}
|
||||
});
|
||||
|
||||
test('UAT-BOUNDARY-004: 邮箱格式验证测试', 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 emailInput = page.locator('.el-dialog input[placeholder*="邮箱"]').first();
|
||||
await emailInput.fill('invalid-email');
|
||||
|
||||
const confirmButton = page.locator('.el-dialog button:has-text("确定")');
|
||||
await confirmButton.click();
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
const emailError = page.locator('.el-form-item__error:has-text("邮箱")');
|
||||
const hasError = await emailError.isVisible().catch(() => false);
|
||||
expect(hasError).toBeTruthy();
|
||||
}
|
||||
});
|
||||
|
||||
test('UAT-BOUNDARY-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 phoneInput = page.locator('.el-dialog input[placeholder*="手机"]').first();
|
||||
await phoneInput.fill('123');
|
||||
|
||||
const confirmButton = page.locator('.el-dialog button:has-text("确定")');
|
||||
await confirmButton.click();
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
const phoneError = page.locator('.el-form-item__error:has-text("手机")');
|
||||
const hasError = await phoneError.isVisible().catch(() => false);
|
||||
expect(hasError).toBeTruthy();
|
||||
}
|
||||
});
|
||||
|
||||
test('UAT-BOUNDARY-006: Emoji表情输入测试', 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('测试角色😀🎉🔥');
|
||||
|
||||
const roleKeyInput = page.locator('.el-dialog input[placeholder*="角色标识"]').first();
|
||||
await roleKeyInput.fill('test_emoji_role');
|
||||
|
||||
const confirmButton = page.locator('.el-dialog button:has-text("确定")');
|
||||
await confirmButton.click();
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
const errorMessage = page.locator('.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();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test('UAT-BOUNDARY-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('**/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 sortInput = page.locator('.el-dialog input[type="number"]').first();
|
||||
if (await sortInput.isVisible()) {
|
||||
await sortInput.fill('-1');
|
||||
|
||||
const confirmButton = page.locator('.el-dialog button:has-text("确定")');
|
||||
await confirmButton.click();
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
const errorMessage = page.locator('.el-form-item__error');
|
||||
const hasError = await errorMessage.isVisible().catch(() => false);
|
||||
|
||||
if (!hasError) {
|
||||
const cancelButton = page.locator('.el-dialog button:has-text("取消")');
|
||||
await cancelButton.click();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user