feat(e2e): 添加完整的E2E测试框架和测试用例
添加Playwright测试框架配置和基础页面对象 实现冒烟测试用例覆盖首页和联系页面核心功能 更新导航组件以支持滚动高亮功能 添加BackButton组件统一返回按钮行为 配置Woodpecker CI集成和测试报告生成
This commit is contained in:
@@ -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);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user