refactor(test): 重构测试套件结构并优化测试配置

feat(test-suite): 新增测试套件模块,包含API测试客户端和测试配置
fix(api): 修复数据库实体和仓库的删除操作返回值
style(api): 统一数据库表名和字段命名
perf(api): 添加缓存注解提升配置查询性能
test(api): 添加H2测试数据库配置支持
chore: 清理旧的测试文件和脚本
This commit is contained in:
张翔
2026-04-01 20:57:24 +08:00
parent 24422c2c19
commit 1e3dc11d59
180 changed files with 15421 additions and 3797 deletions
@@ -0,0 +1,368 @@
import { test, expect } from '@playwright/test';
import { LoginPage } from './pages/LoginPage';
import { DashboardPage } from './pages/DashboardPage';
import { UserManagementPage } from './pages/UserManagementPage';
import { RoleManagementPage } from './pages/RoleManagementPage';
import { MenuManagementPage } from './pages/MenuManagementPage';
import { SystemConfigPage } from './pages/SystemConfigPage';
// 测试用户配置
const TEST_USERS = {
superAdmin: {
username: 'admin',
password: 'password',
role: '超级管理员'
},
systemAdmin: {
username: 'sysadmin',
password: 'SysAdmin123!',
role: '系统管理员'
},
regularUser: {
username: 'user',
password: 'User123!',
role: '普通用户'
},
guest: {
username: '',
password: '',
role: '访客'
}
};
// 权限验证测试套件
test.describe('系统配置功能权限验证测试', () => {
let loginPage: LoginPage;
let dashboardPage: DashboardPage;
let userManagementPage: UserManagementPage;
let roleManagementPage: RoleManagementPage;
let menuManagementPage: MenuManagementPage;
let systemConfigPage: SystemConfigPage;
test.beforeEach(async ({ page }) => {
loginPage = new LoginPage(page);
dashboardPage = new DashboardPage(page);
userManagementPage = new UserManagementPage(page);
roleManagementPage = new RoleManagementPage(page);
menuManagementPage = new MenuManagementPage(page);
systemConfigPage = new SystemConfigPage(page);
});
// 测试1: 超级管理员权限验证
test('PERM-001: 超级管理员完整权限验证', async ({ page }) => {
const user = TEST_USERS.superAdmin;
const testResults = [];
await test.step(`1. ${user.role}登录系统`, async () => {
await loginPage.goto();
await loginPage.login(user.username, user.password);
await expect(page).toHaveURL(/.*dashboard/);
testResults.push({ step: '登录系统', result: '通过', details: '成功登录到仪表板' });
});
await test.step('2. 验证用户管理权限', async () => {
await dashboardPage.navigateToUserManagement();
// 验证用户管理页面可访问
await expect(page.locator('.user-management-header')).toBeVisible();
// 验证创建用户权限
await userManagementPage.clickCreateUser();
await expect(page.locator('.user-form')).toBeVisible();
testResults.push({ step: '用户管理权限', result: '通过', details: '可访问用户管理页面和创建用户功能' });
});
await test.step('3. 验证角色管理权限', async () => {
await dashboardPage.navigateToRoleManagement();
// 验证角色管理页面可访问
await expect(page.locator('.role-management-header')).toBeVisible();
// 验证创建角色权限
await roleManagementPage.clickCreateRole();
await expect(page.locator('.role-form')).toBeVisible();
testResults.push({ step: '角色管理权限', result: '通过', details: '可访问角色管理页面和创建角色功能' });
});
await test.step('4. 验证菜单管理权限', async () => {
await dashboardPage.navigateToMenuManagement();
// 验证菜单管理页面可访问
await expect(page.locator('.menu-management-header')).toBeVisible();
// 验证创建菜单权限
await menuManagementPage.clickCreateMenu();
await expect(page.locator('.menu-form')).toBeVisible();
testResults.push({ step: '菜单管理权限', result: '通过', details: '可访问菜单管理页面和创建菜单功能' });
});
await test.step('5. 验证系统配置权限', async () => {
await dashboardPage.navigateToSystemConfig();
// 验证系统配置页面可访问
await expect(page.locator('.system-config-header')).toBeVisible();
// 验证配置修改权限
await systemConfigPage.clickEditConfig();
await expect(page.locator('.config-form')).toBeVisible();
testResults.push({ step: '系统配置权限', result: '通过', details: '可访问系统配置页面和修改配置功能' });
});
// 生成测试报告
console.log(`\n=== ${user.role}权限验证报告 ===`);
testResults.forEach(result => {
console.log(`[${result.result}] ${result.step}: ${result.details}`);
});
});
// 测试2: 系统管理员权限验证
test('PERM-002: 系统管理员权限验证', async ({ page }) => {
const user = TEST_USERS.systemAdmin;
const testResults = [];
await test.step(`1. ${user.role}登录系统`, async () => {
await loginPage.goto();
await loginPage.login(user.username, user.password);
await expect(page).toHaveURL(/.*dashboard/);
testResults.push({ step: '登录系统', result: '通过', details: '成功登录到仪表板' });
});
await test.step('2. 验证用户管理权限', async () => {
await dashboardPage.navigateToUserManagement();
// 验证用户管理页面可访问
await expect(page.locator('.user-management-header')).toBeVisible();
// 验证创建用户权限
await userManagementPage.clickCreateUser();
await expect(page.locator('.user-form')).toBeVisible();
testResults.push({ step: '用户管理权限', result: '通过', details: '可访问用户管理页面和创建用户功能' });
});
await test.step('3. 验证角色管理权限', async () => {
await dashboardPage.navigateToRoleManagement();
// 验证角色管理页面可访问
await expect(page.locator('.role-management-header')).toBeVisible();
// 验证创建角色权限
await roleManagementPage.clickCreateRole();
await expect(page.locator('.role-form')).toBeVisible();
testResults.push({ step: '角色管理权限', result: '通过', details: '可访问角色管理页面和创建角色功能' });
});
await test.step('4. 验证菜单管理权限', async () => {
await dashboardPage.navigateToMenuManagement();
// 验证菜单管理页面可访问
await expect(page.locator('.menu-management-header')).toBeVisible();
// 验证创建菜单权限
await menuManagementPage.clickCreateMenu();
await expect(page.locator('.menu-form')).toBeVisible();
testResults.push({ step: '菜单管理权限', result: '通过', details: '可访问菜单管理页面和创建菜单功能' });
});
await test.step('5. 验证系统配置权限限制', async () => {
await dashboardPage.navigateToSystemConfig();
// 验证系统配置页面可访问
await expect(page.locator('.system-config-header')).toBeVisible();
// 验证配置修改权限(可能受限)
try {
await systemConfigPage.clickEditConfig();
await expect(page.locator('.config-form')).toBeVisible();
testResults.push({ step: '系统配置权限', result: '通过', details: '可访问系统配置页面和修改配置功能' });
} catch (error) {
testResults.push({ step: '系统配置权限', result: '受限', details: '系统配置修改功能受限' });
}
});
// 生成测试报告
console.log(`\n=== ${user.role}权限验证报告 ===`);
testResults.forEach(result => {
console.log(`[${result.result}] ${step}: ${result.details}`);
});
});
// 测试3: 普通用户权限验证
test('PERM-003: 普通用户权限验证', async ({ page }) => {
const user = TEST_USERS.regularUser;
const testResults = [];
await test.step(`1. ${user.role}登录系统`, async () => {
await loginPage.goto();
await loginPage.login(user.username, user.password);
await expect(page).toHaveURL(/.*dashboard/);
testResults.push({ step: '登录系统', result: '通过', details: '成功登录到仪表板' });
});
await test.step('2. 验证用户管理权限限制', async () => {
try {
await dashboardPage.navigateToUserManagement();
// 如果能够访问,验证是否有限制
const hasAccess = await page.locator('.user-management-header').isVisible();
if (hasAccess) {
testResults.push({ step: '用户管理权限', result: '受限', details: '可访问但功能受限' });
} else {
testResults.push({ step: '用户管理权限', result: '拒绝', details: '无法访问用户管理页面' });
}
} catch (error) {
testResults.push({ step: '用户管理权限', result: '拒绝', details: '权限不足,无法访问' });
}
});
await test.step('3. 验证角色管理权限限制', async () => {
try {
await dashboardPage.navigateToRoleManagement();
const hasAccess = await page.locator('.role-management-header').isVisible();
if (hasAccess) {
testResults.push({ step: '角色管理权限', result: '受限', details: '可访问但功能受限' });
} else {
testResults.push({ step: '角色管理权限', result: '拒绝', details: '无法访问角色管理页面' });
}
} catch (error) {
testResults.push({ step: '角色管理权限', result: '拒绝', details: '权限不足,无法访问' });
}
});
await test.step('4. 验证菜单管理权限限制', async () => {
try {
await dashboardPage.navigateToMenuManagement();
const hasAccess = await page.locator('.menu-management-header').isVisible();
if (hasAccess) {
testResults.push({ step: '菜单管理权限', result: '受限', details: '可访问但功能受限' });
} else {
testResults.push({ step: '菜单管理权限', result: '拒绝', details: '无法访问菜单管理页面' });
}
} catch (error) {
testResults.push({ step: '菜单管理权限', result: '拒绝', details: '权限不足,无法访问' });
}
});
await test.step('5. 验证系统配置权限限制', async () => {
try {
await dashboardPage.navigateToSystemConfig();
const hasAccess = await page.locator('.system-config-header').isVisible();
if (hasAccess) {
testResults.push({ step: '系统配置权限', result: '受限', details: '可访问但功能受限' });
} else {
testResults.push({ step: '系统配置权限', result: '拒绝', details: '无法访问系统配置页面' });
}
} catch (error) {
testResults.push({ step: '系统配置权限', result: '拒绝', details: '权限不足,无法访问' });
}
});
// 生成测试报告
console.log(`\n=== ${user.role}权限验证报告 ===`);
testResults.forEach(result => {
console.log(`[${result.result}] ${result.step}: ${result.details}`);
});
});
// 测试4: 访客权限验证
test('PERM-004: 访客权限验证', async ({ page }) => {
const user = TEST_USERS.guest;
const testResults = [];
await test.step('1. 直接访问系统管理页面', async () => {
await page.goto('/user-management');
// 验证是否被重定向到登录页面
const currentUrl = page.url();
if (currentUrl.includes('/login')) {
testResults.push({ step: '用户管理页面访问', result: '拒绝', details: '被重定向到登录页面' });
} else {
testResults.push({ step: '用户管理页面访问', result: '异常', details: '未正确重定向' });
}
});
await test.step('2. 直接访问角色管理页面', async () => {
await page.goto('/role-management');
const currentUrl = page.url();
if (currentUrl.includes('/login')) {
testResults.push({ step: '角色管理页面访问', result: '拒绝', details: '被重定向到登录页面' });
} else {
testResults.push({ step: '角色管理页面访问', result: '异常', details: '未正确重定向' });
}
});
await test.step('3. 直接访问菜单管理页面', async () => {
await page.goto('/menu-management');
const currentUrl = page.url();
if (currentUrl.includes('/login')) {
testResults.push({ step: '菜单管理页面访问', result: '拒绝', details: '被重定向到登录页面' });
} else {
testResults.push({ step: '菜单管理页面访问', result: '异常', details: '未正确重定向' });
}
});
await test.step('4. 直接访问系统配置页面', async () => {
await page.goto('/system-config');
const currentUrl = page.url();
if (currentUrl.includes('/login')) {
testResults.push({ step: '系统配置页面访问', result: '拒绝', details: '被重定向到登录页面' });
} else {
testResults.push({ step: '系统配置页面访问', result: '异常', details: '未正确重定向' });
}
});
// 生成测试报告
console.log(`\n=== ${user.role}权限验证报告 ===`);
testResults.forEach(result => {
console.log(`[${result.result}] ${result.step}: ${result.details}`);
});
});
// 测试5: 权限边界测试
test('PERM-005: 权限边界测试', async ({ page }) => {
const testResults = [];
await test.step('1. 测试越权访问', async () => {
// 使用普通用户登录
await loginPage.goto();
await loginPage.login(TEST_USERS.regularUser.username, TEST_USERS.regularUser.password);
await expect(page).toHaveURL(/.*dashboard/);
// 尝试直接访问管理员功能URL
await page.goto('/user-management/create');
// 验证是否被阻止
const isBlocked = await page.locator('.access-denied, .permission-error').isVisible() ||
page.url().includes('/login') ||
page.url().includes('/dashboard');
if (isBlocked) {
testResults.push({ step: '越权访问测试', result: '通过', details: '系统正确阻止了越权访问' });
} else {
testResults.push({ step: '越权访问测试', result: '失败', details: '系统未正确阻止越权访问' });
}
});
await test.step('2. 测试API权限验证', async () => {
// 模拟API调用权限验证
const apiResponse = await page.request.get('/api/users');
if (apiResponse.status() === 401 || apiResponse.status() === 403) {
testResults.push({ step: 'API权限验证', result: '通过', details: 'API权限验证正常工作' });
} else {
testResults.push({ step: 'API权限验证', result: '警告', details: 'API权限验证可能需要加强' });
}
});
// 生成测试报告
console.log('\n=== 权限边界测试报告 ===');
testResults.forEach(result => {
console.log(`[${result.result}] ${result.step}: ${result.details}`);
});
});
});
+123
View File
@@ -48,6 +48,9 @@ importers:
'@vitejs/plugin-vue':
specifier: ^6.0.3
version: 6.0.5(vite@7.3.1(@types/node@20.19.37))(vue@3.5.30(typescript@5.9.3))
'@vitest/coverage-v8':
specifier: ^4.1.1
version: 4.1.2(vitest@4.1.0)
'@vitest/ui':
specifier: ^4.0.16
version: 4.1.0(vitest@4.1.0)
@@ -110,6 +113,10 @@ packages:
resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==}
engines: {node: '>=6.9.0'}
'@bcoe/v8-coverage@1.0.2':
resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==}
engines: {node: '>=18'}
'@csstools/color-helpers@6.0.2':
resolution: {integrity: sha512-LMGQLS9EuADloEFkcTBR3BwV/CGHV7zyDxVRtVDTwdI2Ca4it0CCVTT9wCkxSgokjE5Ho41hEPgb8OEUwoXr6Q==}
engines: {node: '>=20.19.0'}
@@ -371,9 +378,16 @@ packages:
resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
engines: {node: '>=12'}
'@jridgewell/resolve-uri@3.1.2':
resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
engines: {node: '>=6.0.0'}
'@jridgewell/sourcemap-codec@1.5.5':
resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==}
'@jridgewell/trace-mapping@0.3.31':
resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
'@nodelib/fs.scandir@2.1.5':
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
engines: {node: '>= 8'}
@@ -630,6 +644,15 @@ packages:
vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0
vue: ^3.2.25
'@vitest/coverage-v8@4.1.2':
resolution: {integrity: sha512-sPK//PHO+kAkScb8XITeB1bf7fsk85Km7+rt4eeuRR3VS1/crD47cmV5wicisJmjNdfeokTZwjMk4Mj2d58Mgg==}
peerDependencies:
'@vitest/browser': 4.1.2
vitest: 4.1.2
peerDependenciesMeta:
'@vitest/browser':
optional: true
'@vitest/expect@4.1.0':
resolution: {integrity: sha512-EIxG7k4wlWweuCLG9Y5InKFwpMEOyrMb6ZJ1ihYu02LVj/bzUwn2VMU+13PinsjRW75XnITeFrQBMH5+dLvCDA==}
@@ -647,6 +670,9 @@ packages:
'@vitest/pretty-format@4.1.0':
resolution: {integrity: sha512-3RZLZlh88Ib0J7NQTRATfc/3ZPOnSUn2uDBUoGNn5T36+bALixmzphN26OUD3LRXWkJu4H0s5vvUeqBiw+kS0A==}
'@vitest/pretty-format@4.1.2':
resolution: {integrity: sha512-dwQga8aejqeuB+TvXCMzSQemvV9hNEtDDpgUKDzOmNQayl2OG241PSWeJwKRH3CiC+sESrmoFd49rfnq7T4RnA==}
'@vitest/runner@4.1.0':
resolution: {integrity: sha512-Duvx2OzQ7d6OjchL+trw+aSrb9idh7pnNfxrklo14p3zmNL4qPCDeIJAK+eBKYjkIwG96Bc6vYuxhqDXQOWpoQ==}
@@ -664,6 +690,9 @@ packages:
'@vitest/utils@4.1.0':
resolution: {integrity: sha512-XfPXT6a8TZY3dcGY8EdwsBulFCIw+BeeX0RZn2x/BtiY/75YGh8FeWGG8QISN/WhaqSrE2OrlDgtF8q5uhOTmw==}
'@vitest/utils@4.1.2':
resolution: {integrity: sha512-xw2/TiX82lQHA06cgbqRKFb5lCAy3axQ4H4SoUFhUsg+wztiet+co86IAMDtF6Vm1hc7J6j09oh/rgDn+JdKIQ==}
'@volar/language-core@2.4.28':
resolution: {integrity: sha512-w4qhIJ8ZSitgLAkVay6AbcnC7gP3glYM3fYwKV3srj8m494E3xtrCv6E+bWviiK/8hs6e6t1ij1s2Endql7vzQ==}
@@ -780,6 +809,9 @@ packages:
resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==}
engines: {node: '>=12'}
ast-v8-to-istanbul@1.0.0:
resolution: {integrity: sha512-1fSfIwuDICFA4LKkCzRPO7F0hzFf0B7+Xqrl27ynQaa+Rh0e1Es0v6kWHPott3lU10AyAr7oKHa65OppjLn3Rg==}
async-validator@4.2.5:
resolution: {integrity: sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==}
@@ -1164,6 +1196,9 @@ packages:
resolution: {integrity: sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==}
engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
html-escaper@2.0.2:
resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==}
http-proxy-agent@7.0.2:
resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==}
engines: {node: '>= 14'}
@@ -1224,6 +1259,18 @@ packages:
isexe@2.0.0:
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
istanbul-lib-coverage@3.2.2:
resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==}
engines: {node: '>=8'}
istanbul-lib-report@3.0.1:
resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==}
engines: {node: '>=10'}
istanbul-reports@3.2.0:
resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==}
engines: {node: '>=8'}
jackspeak@3.4.3:
resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==}
@@ -1236,6 +1283,9 @@ packages:
resolution: {integrity: sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==}
engines: {node: '>=14'}
js-tokens@10.0.0:
resolution: {integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==}
js-yaml@4.1.1:
resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==}
hasBin: true
@@ -1295,6 +1345,13 @@ packages:
magic-string@0.30.21:
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
magicast@0.5.2:
resolution: {integrity: sha512-E3ZJh4J3S9KfwdjZhe2afj6R9lGIN5Pher1pF39UGrXRqq/VDaGVIGN13BjHd2u8B61hArAGOnso7nBOouW3TQ==}
make-dir@4.0.0:
resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==}
engines: {node: '>=10'}
math-intrinsics@1.1.0:
resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
engines: {node: '>= 0.4'}
@@ -1879,6 +1936,8 @@ snapshots:
'@babel/helper-string-parser': 7.27.1
'@babel/helper-validator-identifier': 7.28.5
'@bcoe/v8-coverage@1.0.2': {}
'@csstools/color-helpers@6.0.2': {}
'@csstools/css-calc@3.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)':
@@ -2054,8 +2113,15 @@ snapshots:
wrap-ansi: 8.1.0
wrap-ansi-cjs: wrap-ansi@7.0.0
'@jridgewell/resolve-uri@3.1.2': {}
'@jridgewell/sourcemap-codec@1.5.5': {}
'@jridgewell/trace-mapping@0.3.31':
dependencies:
'@jridgewell/resolve-uri': 3.1.2
'@jridgewell/sourcemap-codec': 1.5.5
'@nodelib/fs.scandir@2.1.5':
dependencies:
'@nodelib/fs.stat': 2.0.5
@@ -2279,6 +2345,20 @@ snapshots:
vite: 7.3.1(@types/node@20.19.37)
vue: 3.5.30(typescript@5.9.3)
'@vitest/coverage-v8@4.1.2(vitest@4.1.0)':
dependencies:
'@bcoe/v8-coverage': 1.0.2
'@vitest/utils': 4.1.2
ast-v8-to-istanbul: 1.0.0
istanbul-lib-coverage: 3.2.2
istanbul-lib-report: 3.0.1
istanbul-reports: 3.2.0
magicast: 0.5.2
obug: 2.1.1
std-env: 4.0.0
tinyrainbow: 3.1.0
vitest: 4.1.0(@types/node@20.19.37)(@vitest/ui@4.1.0)(jsdom@27.4.0)(vite@7.3.1(@types/node@20.19.37))
'@vitest/expect@4.1.0':
dependencies:
'@standard-schema/spec': 1.1.0
@@ -2300,6 +2380,10 @@ snapshots:
dependencies:
tinyrainbow: 3.1.0
'@vitest/pretty-format@4.1.2':
dependencies:
tinyrainbow: 3.1.0
'@vitest/runner@4.1.0':
dependencies:
'@vitest/utils': 4.1.0
@@ -2331,6 +2415,12 @@ snapshots:
convert-source-map: 2.0.0
tinyrainbow: 3.1.0
'@vitest/utils@4.1.2':
dependencies:
'@vitest/pretty-format': 4.1.2
convert-source-map: 2.0.0
tinyrainbow: 3.1.0
'@volar/language-core@2.4.28':
dependencies:
'@volar/source-map': 2.4.28
@@ -2484,6 +2574,12 @@ snapshots:
assertion-error@2.0.1: {}
ast-v8-to-istanbul@1.0.0:
dependencies:
'@jridgewell/trace-mapping': 0.3.31
estree-walker: 3.0.3
js-tokens: 10.0.0
async-validator@4.2.5: {}
asynckit@0.4.0: {}
@@ -2939,6 +3035,8 @@ snapshots:
transitivePeerDependencies:
- '@noble/hashes'
html-escaper@2.0.2: {}
http-proxy-agent@7.0.2:
dependencies:
agent-base: 7.1.4
@@ -2989,6 +3087,19 @@ snapshots:
isexe@2.0.0: {}
istanbul-lib-coverage@3.2.2: {}
istanbul-lib-report@3.0.1:
dependencies:
istanbul-lib-coverage: 3.2.2
make-dir: 4.0.0
supports-color: 7.2.0
istanbul-reports@3.2.0:
dependencies:
html-escaper: 2.0.2
istanbul-lib-report: 3.0.1
jackspeak@3.4.3:
dependencies:
'@isaacs/cliui': 8.0.2
@@ -3005,6 +3116,8 @@ snapshots:
js-cookie@3.0.5: {}
js-tokens@10.0.0: {}
js-yaml@4.1.1:
dependencies:
argparse: 2.0.1
@@ -3076,6 +3189,16 @@ snapshots:
dependencies:
'@jridgewell/sourcemap-codec': 1.5.5
magicast@0.5.2:
dependencies:
'@babel/parser': 7.29.0
'@babel/types': 7.29.0
source-map-js: 1.2.1
make-dir@4.0.0:
dependencies:
semver: 7.7.4
math-intrinsics@1.1.0: {}
mdn-data@2.27.1: {}
+5 -8
View File
@@ -10,23 +10,20 @@ export default defineConfig({
}
},
server: {
port: 3001,
port: 3002,
host: '0.0.0.0',
strictPort: false,
strictPort: true,
proxy: {
'/api': {
target: 'http://localhost:8084',
changeOrigin: true,
configure: (proxy, options) => {
proxy.on('proxyReq', (proxyReq, req, res) => {
console.log(`[Proxy] ${req.method} ${req.url} -> ${options.target}${req.url}`);
});
}
secure: false
}
},
hmr: {
overlay: false
}
},
cors: true
},
build: {
target: 'esnext',
+11
View File
@@ -8,6 +8,17 @@ export default defineConfig({
globals: true,
environment: 'jsdom',
setupFiles: ['./src/test/setup.ts'],
// 明确指定只包含单元测试文件
include: ['src/test/**/*.{test,spec}.{js,ts,jsx,tsx}'],
// 明确排除E2E测试文件
exclude: [
'node_modules/',
'dist/',
'e2e/**/*',
'**/*.d.ts',
'**/*.config.*',
'**/mockData',
],
coverage: {
provider: 'v8',
reporter: ['text', 'json', 'html', 'lcov'],