104 lines
3.8 KiB
TypeScript
104 lines
3.8 KiB
TypeScript
import { test, expect } from '@playwright/test';
|
|
|
|
test.describe('基础UI功能测试', () => {
|
|
test('前端应用基本功能验证', async ({ page }) => {
|
|
// 测试1: 应用首页加载
|
|
await test.step('加载应用首页', async () => {
|
|
await page.goto('/');
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
// 验证页面标题(无论是否重定向,标题都包含 Novalon)
|
|
const title = await page.title();
|
|
expect(title).toContain('Novalon');
|
|
});
|
|
|
|
// 测试2: 登录页面渲染
|
|
await test.step('验证登录页面元素', async () => {
|
|
await page.goto('/login');
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
// 验证登录表单元素 - 使用更宽松的选择器
|
|
const usernameField = page.locator('input[type="text"], input[placeholder*="用户名"], input[placeholder*="账号"]');
|
|
const passwordField = page.locator('input[type="password"]');
|
|
const loginButton = page.locator('button:has-text("登录")');
|
|
|
|
// 登录页面至少应该有输入框和按钮
|
|
await expect(usernameField.first()).toBeVisible({ timeout: 10000 });
|
|
await expect(passwordField.first()).toBeVisible({ timeout: 10000 });
|
|
await expect(loginButton.first()).toBeVisible({ timeout: 10000 });
|
|
});
|
|
|
|
// 测试3: 登录后页面导航
|
|
await test.step('登录后验证导航功能', async () => {
|
|
// 填写登录表单并提交
|
|
const usernameInput = page.locator('input[type="text"], input[placeholder*="用户名"], input[placeholder*="账号"]').first();
|
|
const passwordInput = page.locator('input[type="password"]').first();
|
|
const loginButton = page.locator('button:has-text("登录")').first();
|
|
|
|
await usernameInput.fill('admin');
|
|
await passwordInput.fill('Test@123');
|
|
await loginButton.click();
|
|
|
|
// 等待跳转到 Dashboard
|
|
await page.waitForURL('**/dashboard', { timeout: 30000 });
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
// 登录后检查导航元素
|
|
const navigationSelectors = [
|
|
'nav', '.navbar', '.menu', '.el-menu', '.el-header',
|
|
'.layout-header', '.app-header', '[class*="header"]',
|
|
'[class*="nav"]', '[class*="menu"]', '.sidebar', '.aside'
|
|
];
|
|
|
|
let hasNavigation = false;
|
|
for (const selector of navigationSelectors) {
|
|
const count = await page.locator(selector).count();
|
|
if (count > 0) {
|
|
hasNavigation = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// 如果找不到传统导航元素,检查是否有其他页面结构
|
|
if (!hasNavigation) {
|
|
const hasAppContainer = await page.locator('#app, .app, .container').count() > 0;
|
|
const hasBodyContent = await page.locator('body').textContent() !== '';
|
|
hasNavigation = hasAppContainer && hasBodyContent;
|
|
}
|
|
|
|
expect(hasNavigation).toBeTruthy();
|
|
});
|
|
|
|
// 测试4: 响应式设计验证
|
|
await test.step('验证响应式设计', async () => {
|
|
// 设置移动端视口
|
|
await page.setViewportSize({ width: 375, height: 667 });
|
|
await page.waitForTimeout(500);
|
|
|
|
// 验证页面在移动端仍然可访问
|
|
await expect(page.locator('body')).toBeVisible();
|
|
});
|
|
});
|
|
|
|
test('应用静态资源加载', async ({ page }) => {
|
|
await page.goto('/login');
|
|
|
|
// 验证CSS加载
|
|
const cssLoaded = await page.evaluate(() => {
|
|
return document.styleSheets.length > 0;
|
|
});
|
|
expect(cssLoaded).toBeTruthy();
|
|
|
|
// 验证JavaScript加载
|
|
const jsLoaded = await page.evaluate(() => {
|
|
return typeof window !== 'undefined';
|
|
});
|
|
expect(jsLoaded).toBeTruthy();
|
|
|
|
// 验证Vue应用挂载
|
|
const vueMounted = await page.evaluate(() => {
|
|
return !!document.querySelector('#app');
|
|
});
|
|
expect(vueMounted).toBeTruthy();
|
|
});
|
|
}); |