feat(e2e): 添加完整的E2E测试框架和测试用例

添加Playwright测试框架配置和基础页面对象
实现冒烟测试用例覆盖首页和联系页面核心功能
更新导航组件以支持滚动高亮功能
添加BackButton组件统一返回按钮行为
配置Woodpecker CI集成和测试报告生成
This commit is contained in:
张翔
2026-02-27 10:30:33 +08:00
parent 4a616fe96e
commit 5d5b7feb0a
50 changed files with 6765 additions and 46 deletions
@@ -0,0 +1,213 @@
import { test, expect } from '../../fixtures/base.fixture';
test.describe('首页回归测试 @regression', () => {
test.beforeEach(async ({ homePage }) => {
await homePage.goto();
await homePage.waitForPageLoad();
});
test('应该正确响应滚动事件', async ({ homePage }) => {
const initialBg = await homePage.getHeaderBackgroundColor();
await homePage.scrollToSection('services');
await homePage.page.waitForTimeout(500);
const scrolledBg = await homePage.getHeaderBackgroundColor();
expect(scrolledBg).not.toBe(initialBg);
});
test('应该显示粘性头部', async ({ homePage }) => {
const isSticky = await homePage.isHeaderSticky();
expect(isSticky).toBe(true);
});
test('滚动后应该显示头部阴影', async ({ homePage }) => {
await homePage.scrollToSection('services');
await homePage.page.waitForTimeout(500);
const hasShadow = await homePage.isHeaderScrolled();
expect(hasShadow).toBe(true);
});
test('应该能够通过导航跳转到各个区块', async ({ homePage }) => {
const labels = await homePage.getAllNavigationLabels();
for (let i = 0; i < Math.min(labels.length, 3); i++) {
await homePage.clickNavigationItem(labels[i]);
await homePage.page.waitForTimeout(1000);
const url = homePage.page.url();
expect(url).toContain('#');
}
});
test('应该正确高亮当前区块的导航项', async ({ homePage }) => {
await homePage.scrollToSection('services');
await homePage.page.waitForTimeout(500);
const activeItem = await homePage.getActiveNavigationItem();
expect(activeItem).toBeTruthy();
});
test('应该能够点击Logo返回首页', async ({ homePage }) => {
await homePage.scrollToSection('services');
await homePage.logo.click();
await homePage.page.waitForTimeout(1000);
const url = homePage.page.url();
expect(url).toMatch(/\/$/);
});
test('应该能够通过立即咨询按钮跳转到联系页面', async ({ homePage }) => {
await homePage.clickContactButton();
await homePage.page.waitForTimeout(1000);
const url = homePage.page.url();
expect(url).toContain('/contact');
});
test('应该能够打开和关闭移动端菜单', async ({ homePage }) => {
await homePage.openMobileMenu();
await expect(homePage.mobileMenu).toBeVisible();
await homePage.closeMobileMenu();
await expect(homePage.mobileMenu).not.toBeVisible();
});
test('移动端菜单应该包含所有导航项', async ({ homePage }) => {
await homePage.openMobileMenu();
const desktopNavItems = await homePage.getAllNavigationLabels();
const mobileNavItems = homePage.mobileMenu.locator('a');
const mobileCount = await mobileNavItems.count();
expect(mobileCount).toBeGreaterThan(0);
expect(mobileCount).toBe(desktopNavItems.length);
});
test('应该能够通过移动端菜单导航', async ({ homePage }) => {
await homePage.openMobileMenu();
const firstLink = homePage.mobileMenu.locator('a').first();
await firstLink.click();
await homePage.page.waitForTimeout(1000);
const isMenuVisible = await homePage.mobileMenu.isVisible();
expect(isMenuVisible).toBe(false);
});
test('应该能够平滑滚动到各个区块', async ({ homePage }) => {
const sections = ['services', 'products', 'cases'];
for (const sectionId of sections) {
await homePage.scrollToSection(sectionId);
const isVisible = await homePage.isSectionVisible(sectionId);
expect(isVisible).toBe(true);
}
});
test('应该正确显示所有区块标题', async ({ homePage }) => {
const titles = [
await homePage.getHeroSectionTitle(),
await homePage.getServicesSectionTitle(),
await homePage.getProductsSectionTitle(),
await homePage.getCasesSectionTitle(),
await homePage.getAboutSectionTitle(),
await homePage.getNewsSectionTitle(),
await homePage.getContactSectionTitle(),
];
titles.forEach(title => {
expect(title).toBeTruthy();
expect(title.length).toBeGreaterThan(0);
});
});
test('应该能够滚动到页面底部并返回顶部', async ({ homePage }) => {
await homePage.scrollToBottom();
const bottomScroll = await homePage.page.evaluate(() => window.scrollY);
expect(bottomScroll).toBeGreaterThan(0);
await homePage.scrollToTop();
const topScroll = await homePage.page.evaluate(() => window.scrollY);
expect(topScroll).toBe(0);
});
test('应该正确处理快速滚动', async ({ homePage }) => {
for (let i = 0; i < 5; i++) {
await homePage.page.evaluate(() => window.scrollBy(0, 500));
await homePage.page.waitForTimeout(100);
}
const scrollPosition = await homePage.page.evaluate(() => window.scrollY);
expect(scrollPosition).toBeGreaterThan(0);
});
test('应该能够截取各个区块的截图', async ({ homePage }) => {
const sections = ['home', 'services'];
for (const sectionId of sections) {
await homePage.scrollToSection(sectionId);
await homePage.page.waitForTimeout(500);
const isVisible = await homePage.isSectionVisible(sectionId);
expect(isVisible).toBe(true);
}
});
test('应该正确响应窗口大小变化', async ({ homePage }) => {
await homePage.page.setViewportSize({ width: 768, height: 1024 });
await homePage.page.waitForTimeout(500);
await expect(homePage.header).toBeVisible();
await homePage.page.setViewportSize({ width: 1280, height: 720 });
await homePage.page.waitForTimeout(500);
await expect(homePage.header).toBeVisible();
});
test('应该能够通过键盘导航', async ({ homePage }) => {
await homePage.page.keyboard.press('Tab');
await homePage.page.waitForTimeout(100);
const focusedElement = await homePage.page.evaluate(() => document.activeElement?.tagName);
expect(focusedElement).toBeTruthy();
});
test('应该正确显示页脚内容', async ({ homePage }) => {
await homePage.scrollToBottom();
const footerText = await homePage.getFooterText();
expect(footerText).toBeTruthy();
expect(footerText.length).toBeGreaterThan(0);
});
test('应该能够重新加载页面', async ({ homePage }) => {
await homePage.reload();
await homePage.waitForPageLoad();
await expect(homePage.header).toBeVisible();
await expect(homePage.heroSection).toBeVisible();
});
test('应该能够使用浏览器后退按钮', async ({ homePage }) => {
await homePage.clickContactButton();
await homePage.page.waitForTimeout(1000);
await homePage.goBack();
await homePage.page.waitForTimeout(1000);
const url = homePage.page.url();
expect(url).toMatch(/\/$/);
});
test('应该能够使用浏览器前进按钮', async ({ homePage }) => {
await homePage.clickContactButton();
await homePage.page.waitForTimeout(1000);
await homePage.goBack();
await homePage.page.waitForTimeout(1000);
await homePage.goForward();
await homePage.page.waitForTimeout(1000);
const url = homePage.page.url();
expect(url).toContain('/contact');
});
test('应该没有JavaScript错误', async ({ homePage, page }) => {
const errors: string[] = [];
page.on('pageerror', error => {
errors.push(error.toString());
});
await homePage.waitForPageLoad();
await homePage.scrollToSection('services');
await homePage.scrollToSection('products');
await homePage.scrollToSection('cases');
expect(errors.length).toBe(0);
});
test('应该正确处理网络请求', async ({ homePage, page }) => {
const failedRequests: string[] = [];
page.on('requestfailed', request => {
failedRequests.push(request.url());
});
await homePage.waitForPageLoad();
await homePage.page.waitForTimeout(2000);
expect(failedRequests.length).toBe(0);
});
});