mcpField
E
E2E Testing (Frontend)

E2E Testing (Frontend)

github.com/exceptionless测试与质量2.5k37 次安装1 天前更新
代码仓库

关于 E2E Testing (Frontend)

面向使用 Playwright 的项目的前端端到端测试技能,涵盖页面对象、选择器、后端测试数据准备和无障碍审计。README 指出当前测试覆盖有限。

主要功能

  1. 01使用 Playwright 运行测试
  2. 02组织可复用的页面对象
  3. 03优先使用语义选择器
  4. 04通过 API 或数据播种准备后端数据
  5. 05使用 axe-core 检查无障碍问题

适用场景

  1. 01测试登录等前端流程
  2. 02为浏览器测试准备后端数据
  3. 03检查页面的无障碍违规项

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/exceptionless/exceptionless --skill e2e-testing-(frontend)

安装后在 Claude Code 中输入/e2e-testing-(frontend)确认已加载。

详细介绍

E2E 测试(前端)

**注意:**目前 E2E 测试的覆盖范围有限,这是一个有待改进的方面。

运行测试

npx playwright install  # First time only
npm run test:e2e

页面对象模型

为可复用的页面交互创建页面对象:

// e2e/pages/login-page.ts
import { type Page, type Locator, expect } from '@playwright/test';

export class LoginPage {
    readonly page: Page;
    readonly emailInput: Locator;
    readonly passwordInput: Locator;
    readonly submitButton: Locator;
    readonly errorMessage: Locator;

    constructor(page: Page) {
        this.page = page;
        this.emailInput = page.getByLabel('Email');
        this.passwordInput = page.getByLabel('Password');
        this.submitButton = page.getByRole('button', { name: /log in/i });
        this.errorMessage = page.getByRole('alert');
    }

    async goto() {
        await this.page.goto('/login');
    }

    async login(email: string, password: string) {
        await this.emailInput.fill(email);
        await this.passwordInput.fill(password);
        await this.submitButton.click();
    }

    async expectError(message: string) {
        await expect(this.errorMessage).toContainText(message);
    }
}

在测试中使用页面对象

// e2e/auth/login.spec.ts
import { test, expect } from '@playwright/test';
import { LoginPage } from '../pages/login-page';

test.describe('Login', () => {
    test('successful login redirects to dashboard', async ({ page }) => {
        const loginPage = new LoginPage(page);

        await loginPage.goto();
        await loginPage.login('[email protected]', 'password123');

        await expect(page).toHaveURL('/');
    });

    test('invalid credentials shows error', async ({ page }) => {
        const loginPage = new LoginPage(page);

        await loginPage.goto();
        await loginPage.login('[email protected]', 'wrongpassword');

        await loginPage.expectError('Invalid email or password');
    });
});

选择器优先级

  1. 优先使用语义选择器:

    page.getByRole('button', { name: /submit/i });
    page.getByLabel('Email address');
    page.getByText('Welcome back');
    
  2. 回退到测试 ID:

    page.getByTestId('stack-trace');
    
  3. 避免依赖实现细节:

    // ❌ Avoid CSS classes and IDs
    page.locator('.btn-primary');
    

后端数据设置

E2E 测试针对完整的 Aspire 堆栈运行。后端使用与 backend-testing 相同的 AppWebHostFactory 基础设施。

对于需要特定数据的测试,请考虑:

  1. 在 beforeEach 中调用 API — 使用 Playwright 的请求上下文设置数据
  2. 测试专用端点 — 创建 /api/test/* 端点来管理测试数据
  3. 数据库播种 — 在运行测试前填充所需数据
  4. Aspire 编排 — 测试启动时,Elasticsearch 和 Redis 已完成预配置
test.beforeEach(async ({ request }) => {
    // Set up test data via API
    await request.post('/api/test/seed', {
        data: { scenario: 'events-with-errors' }
    });
});

test.afterEach(async ({ request }) => {
    await request.delete('/api/test/cleanup');
});

**注意:**测试期间,后端服务使用内存实现。有关测试基础设施的配置方式,请参阅 AppWebHostFactory。

无障碍审计

import { test, expect } from '@playwright/test';
import AxeBuilder from '@axe-core/playwright';

test('login page has no accessibility violations', async ({ page }) => {
    await page.goto('/login');

    const results = await new AxeBuilder({ page }).analyze();
    expect(results.violations).toEqual([]);
});

请参阅 accessibility 了解 WCAG 指南。

评论

支持 Markdown