150 lines
4.6 KiB
TypeScript
150 lines
4.6 KiB
TypeScript
|
|
import { test, expect } from '@playwright/test';
|
||
|
|
|
||
|
|
test.describe('核心业务流程', () => {
|
||
|
|
test.beforeEach(async ({ page }) => {
|
||
|
|
// 每个测试前导航到登录页
|
||
|
|
await page.goto('/login');
|
||
|
|
});
|
||
|
|
|
||
|
|
test('采购商登录并查看仪表盘', async ({ page }) => {
|
||
|
|
// 验证登录页面加载
|
||
|
|
await expect(page).toHaveURL(/.*login/);
|
||
|
|
await expect(page.locator('h1')).toContainText('登录');
|
||
|
|
|
||
|
|
// 由于需要真实账号,这里只验证页面结构
|
||
|
|
await expect(page.locator('input[name="username"]')).toBeVisible();
|
||
|
|
await expect(page.locator('input[name="password"]')).toBeVisible();
|
||
|
|
await expect(page.locator('button[type="submit"]')).toBeVisible();
|
||
|
|
});
|
||
|
|
|
||
|
|
test('角色选择页面', async ({ page }) => {
|
||
|
|
await page.goto('/role-select');
|
||
|
|
|
||
|
|
// 验证角色选择页面
|
||
|
|
await expect(page.locator('h1')).toContainText('选择角色');
|
||
|
|
await expect(page.locator('text=采购商/布行')).toBeVisible();
|
||
|
|
await expect(page.locator('text=纺织厂')).toBeVisible();
|
||
|
|
await expect(page.locator('text=水洗厂')).toBeVisible();
|
||
|
|
});
|
||
|
|
|
||
|
|
test('注册页面表单验证', async ({ page }) => {
|
||
|
|
await page.goto('/register');
|
||
|
|
|
||
|
|
// 验证注册页面
|
||
|
|
await expect(page.locator('h1')).toContainText('注册');
|
||
|
|
|
||
|
|
// 尝试提交空表单
|
||
|
|
await page.click('button[type="submit"]');
|
||
|
|
|
||
|
|
// 验证表单验证(假设有必填验证)
|
||
|
|
await expect(page.locator('input[name="username"]')).toBeVisible();
|
||
|
|
await expect(page.locator('input[name="password"]')).toBeVisible();
|
||
|
|
await expect(page.locator('input[name="confirmPassword"]')).toBeVisible();
|
||
|
|
});
|
||
|
|
|
||
|
|
test('页面导航和路由', async ({ page }) => {
|
||
|
|
// 测试路由导航
|
||
|
|
await page.goto('/login');
|
||
|
|
await expect(page).toHaveURL(/.*login/);
|
||
|
|
|
||
|
|
// 测试 404 回退
|
||
|
|
await page.goto('/non-existent-page');
|
||
|
|
// 应该显示登录页或 404
|
||
|
|
await expect(page.locator('body')).toBeVisible();
|
||
|
|
});
|
||
|
|
|
||
|
|
test('响应式布局 - 移动端适配', async ({ page }) => {
|
||
|
|
// 设置移动端视口
|
||
|
|
await page.setViewportSize({ width: 375, height: 667 });
|
||
|
|
await page.goto('/login');
|
||
|
|
|
||
|
|
// 验证移动端布局
|
||
|
|
await expect(page.locator('body')).toBeVisible();
|
||
|
|
|
||
|
|
// 检查是否有移动端特定的样式或元素
|
||
|
|
const body = page.locator('body');
|
||
|
|
await expect(body).toBeVisible();
|
||
|
|
});
|
||
|
|
|
||
|
|
test('网络状态提示组件', async ({ page }) => {
|
||
|
|
await page.goto('/login');
|
||
|
|
|
||
|
|
// 模拟离线状态
|
||
|
|
await page.context().setOffline(true);
|
||
|
|
|
||
|
|
// 等待离线提示出现
|
||
|
|
await page.waitForTimeout(500);
|
||
|
|
|
||
|
|
// 恢复网络
|
||
|
|
await page.context().setOffline(false);
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
test.describe('页面加载性能', () => {
|
||
|
|
test('首页加载时间', async ({ page }) => {
|
||
|
|
const startTime = Date.now();
|
||
|
|
await page.goto('/login');
|
||
|
|
const loadTime = Date.now() - startTime;
|
||
|
|
|
||
|
|
// 验证页面在合理时间内加载
|
||
|
|
expect(loadTime).toBeLessThan(5000);
|
||
|
|
|
||
|
|
// 验证关键元素渲染
|
||
|
|
await expect(page.locator('h1')).toBeVisible();
|
||
|
|
});
|
||
|
|
|
||
|
|
test('资源加载无错误', async ({ page }) => {
|
||
|
|
const errors: string[] = [];
|
||
|
|
|
||
|
|
page.on('console', (msg) => {
|
||
|
|
if (msg.type() === 'error') {
|
||
|
|
errors.push(msg.text());
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
page.on('pageerror', (error) => {
|
||
|
|
errors.push(error.message);
|
||
|
|
});
|
||
|
|
|
||
|
|
await page.goto('/login');
|
||
|
|
await page.waitForLoadState('networkidle');
|
||
|
|
|
||
|
|
// 允许一些预期的错误(如 API 调用)
|
||
|
|
const unexpectedErrors = errors.filter(e =>
|
||
|
|
!e.includes('supabase') &&
|
||
|
|
!e.includes('api') &&
|
||
|
|
!e.includes('favicon')
|
||
|
|
);
|
||
|
|
|
||
|
|
expect(unexpectedErrors).toHaveLength(0);
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
test.describe('无障碍测试', () => {
|
||
|
|
test('登录页表单可访问性', async ({ page }) => {
|
||
|
|
await page.goto('/login');
|
||
|
|
|
||
|
|
// 检查表单元素是否有正确的标签
|
||
|
|
const usernameInput = page.locator('input[name="username"]');
|
||
|
|
const passwordInput = page.locator('input[name="password"]');
|
||
|
|
|
||
|
|
await expect(usernameInput).toHaveAttribute('placeholder');
|
||
|
|
await expect(passwordInput).toHaveAttribute('placeholder');
|
||
|
|
|
||
|
|
// 检查按钮可点击
|
||
|
|
const submitButton = page.locator('button[type="submit"]');
|
||
|
|
await expect(submitButton).toBeEnabled();
|
||
|
|
});
|
||
|
|
|
||
|
|
test('键盘导航', async ({ page }) => {
|
||
|
|
await page.goto('/login');
|
||
|
|
|
||
|
|
// 使用 Tab 键导航
|
||
|
|
await page.keyboard.press('Tab');
|
||
|
|
await expect(page.locator('input[name="username"]"]')).toBeFocused();
|
||
|
|
|
||
|
|
await page.keyboard.press('Tab');
|
||
|
|
await expect(page.locator('input[name="password"]"]')).toBeFocused();
|
||
|
|
});
|
||
|
|
});
|