ebaa7f3c50
ci/woodpecker/manual/woodpecker Pipeline was successful
- 移除未使用的YAML锚点定义 - 替换commands字段中的锚点引用为实际值 - 移除有问题的通知步骤 - 修复测试文件中的问题 - 添加新的测试用例和配置文件
199 lines
6.7 KiB
TypeScript
199 lines
6.7 KiB
TypeScript
import { test, expect, Page } from '@playwright/test';
|
|
|
|
const BASE_URL = process.env.BASE_URL || 'http://localhost:3000';
|
|
const ADMIN_EMAIL = process.env.ADMIN_EMAIL || 'admin@novalon.cn';
|
|
const ADMIN_PASSWORD = process.env.ADMIN_PASSWORD || 'admin123456';
|
|
|
|
test.describe('后台管理发布功能 - 核心测试', () => {
|
|
test.beforeEach(async ({ page }) => {
|
|
await page.goto(`${BASE_URL}/admin/login`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const emailInput = page.locator('#email');
|
|
const passwordInput = page.locator('#password');
|
|
const submitButton = page.locator('button[type="submit"]');
|
|
|
|
await emailInput.fill(ADMIN_EMAIL);
|
|
await passwordInput.fill(ADMIN_PASSWORD);
|
|
await submitButton.click();
|
|
|
|
await page.waitForURL(/\/admin(?!\/login)/, { timeout: 15000 });
|
|
});
|
|
|
|
test('管理员登录成功', async ({ page }) => {
|
|
expect(page.url()).not.toContain('/admin/login');
|
|
|
|
await page.goto(`${BASE_URL}/admin/content`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
await expect(page.locator('h1, .text-2xl').first()).toContainText('内容管理');
|
|
});
|
|
|
|
test('后台内容列表加载', async ({ page }) => {
|
|
await page.goto(`${BASE_URL}/admin/content`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const table = page.locator('table');
|
|
await expect(table).toBeVisible();
|
|
|
|
const rows = page.locator('tbody tr');
|
|
const count = await rows.count();
|
|
expect(count).toBeGreaterThanOrEqual(0);
|
|
});
|
|
|
|
test('新建内容页面加载', async ({ page }) => {
|
|
await page.goto(`${BASE_URL}/admin/content/new`);
|
|
await page.waitForLoadState('domcontentloaded');
|
|
|
|
await page.waitForSelector('input[placeholder="请输入标题"]', { timeout: 60000 });
|
|
await page.waitForSelector('input[placeholder="url-slug"]', { timeout: 60000 });
|
|
|
|
const heading = page.locator('h1, .text-2xl').first();
|
|
await expect(heading).toBeVisible({ timeout: 10000 });
|
|
|
|
const titleInput = page.locator('input[placeholder="请输入标题"]');
|
|
await expect(titleInput).toBeVisible({ timeout: 10000 });
|
|
|
|
const slugInput = page.locator('input[placeholder="url-slug"]');
|
|
await expect(slugInput).toBeVisible({ timeout: 10000 });
|
|
});
|
|
|
|
test('新建内容页面表单元素可见', async ({ page }) => {
|
|
await page.goto(`${BASE_URL}/admin/content/new`);
|
|
await page.waitForLoadState('domcontentloaded');
|
|
await page.waitForSelector('input[placeholder="请输入标题"]', { timeout: 60000 });
|
|
|
|
const typeSelect = page.locator('select').first();
|
|
await expect(typeSelect).toBeVisible({ timeout: 10000 });
|
|
|
|
const categoryInput = page.locator('input[placeholder="分类名称"]');
|
|
await expect(categoryInput).toBeVisible({ timeout: 10000 });
|
|
|
|
const saveButton = page.locator('button:has-text("保存草稿")');
|
|
await expect(saveButton).toBeVisible({ timeout: 10000 });
|
|
|
|
const publishButton = page.locator('button:has-text("发布")');
|
|
await expect(publishButton).toBeVisible({ timeout: 10000 });
|
|
});
|
|
});
|
|
|
|
test.describe('前端内容展示验证', () => {
|
|
test('首页加载正常', async ({ page }) => {
|
|
await page.goto(BASE_URL);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
await expect(page.locator('header')).toBeVisible();
|
|
await expect(page.locator('footer')).toBeVisible();
|
|
});
|
|
|
|
test('新闻页面加载', async ({ page }) => {
|
|
await page.goto(`${BASE_URL}/news`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
await expect(page).toHaveURL(/\/news/);
|
|
await expect(page.locator('header')).toBeVisible();
|
|
});
|
|
|
|
test('产品页面加载', async ({ page }) => {
|
|
await page.goto(`${BASE_URL}/products`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
await expect(page).toHaveURL(/\/products/);
|
|
await expect(page.locator('header')).toBeVisible();
|
|
});
|
|
|
|
test('服务页面加载', async ({ page }) => {
|
|
await page.goto(`${BASE_URL}/services`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
await expect(page).toHaveURL(/\/services/);
|
|
await expect(page.locator('header')).toBeVisible();
|
|
});
|
|
|
|
test('案例页面加载', async ({ page }) => {
|
|
await page.goto(`${BASE_URL}/cases`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
await expect(page).toHaveURL(/\/cases/);
|
|
await expect(page.locator('header')).toBeVisible();
|
|
});
|
|
});
|
|
|
|
test.describe('权限控制测试', () => {
|
|
test('未登录访问后台重定向到登录页', async ({ browser }) => {
|
|
const context = await browser.newContext();
|
|
const page = await context.newPage();
|
|
|
|
await page.goto(`${BASE_URL}/admin/content`);
|
|
await page.waitForURL(/\/admin\/login/, { timeout: 10000 });
|
|
|
|
expect(page.url()).toContain('/admin/login');
|
|
|
|
await context.close();
|
|
});
|
|
|
|
test('API无权限访问返回403', async ({ request }) => {
|
|
const response = await request.post(`${BASE_URL}/api/admin/content`, {
|
|
data: {
|
|
type: 'news',
|
|
title: '测试',
|
|
slug: 'test',
|
|
content: 'test',
|
|
},
|
|
});
|
|
|
|
expect([401, 403]).toContain(response.status());
|
|
});
|
|
});
|
|
|
|
test.describe('性能测试', () => {
|
|
test('首页加载性能', async ({ page }) => {
|
|
const startTime = Date.now();
|
|
await page.goto(BASE_URL);
|
|
await page.waitForLoadState('networkidle');
|
|
const loadTime = Date.now() - startTime;
|
|
|
|
console.log(`首页加载时间: ${loadTime}ms`);
|
|
expect(loadTime).toBeLessThan(5000);
|
|
});
|
|
|
|
test('新闻页面加载性能', async ({ page }) => {
|
|
const startTime = Date.now();
|
|
await page.goto(`${BASE_URL}/news`);
|
|
await page.waitForLoadState('networkidle');
|
|
const loadTime = Date.now() - startTime;
|
|
|
|
console.log(`新闻页面加载时间: ${loadTime}ms`);
|
|
expect(loadTime).toBeLessThan(5000);
|
|
});
|
|
});
|
|
|
|
test.describe('响应式设计测试', () => {
|
|
test('移动端显示', async ({ page }) => {
|
|
await page.setViewportSize({ width: 375, height: 667 });
|
|
await page.goto(BASE_URL);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
await expect(page.locator('header')).toBeVisible();
|
|
await expect(page.locator('footer')).toBeVisible();
|
|
});
|
|
|
|
test('平板端显示', async ({ page }) => {
|
|
await page.setViewportSize({ width: 768, height: 1024 });
|
|
await page.goto(BASE_URL);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
await expect(page.locator('header')).toBeVisible();
|
|
await expect(page.locator('footer')).toBeVisible();
|
|
});
|
|
|
|
test('桌面端显示', async ({ page }) => {
|
|
await page.setViewportSize({ width: 1920, height: 1080 });
|
|
await page.goto(BASE_URL);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
await expect(page.locator('header')).toBeVisible();
|
|
await expect(page.locator('footer')).toBeVisible();
|
|
});
|
|
});
|