iloom-flatten/e2e/core-workflow.spec.ts

150 lines
4.6 KiB
TypeScript
Raw Normal View History

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();
});
});