Agent skill
e2e-testing
Use this skill when writing or running end-to-end browser tests with Playwright. Covers Page Object Model patterns, selector strategies (data-testid, getByRole, getByLabel), fixtures, and accessibility audits with axe-playwright. Apply when adding E2E test coverage, debugging flaky tests, or testing user flows through the browser.
Install this agent skill to your Project
npx add-skill https://github.com/exceptionless/Exceptionless/tree/main/.agents/skills/e2e-testing
SKILL.md
E2E Testing (Frontend)
Note: E2E test coverage is currently limited. This is an area for improvement.
Running Tests
npx playwright install # First time only
npm run test:e2e
Page Object Model
Create page objects for reusable page interactions:
// 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);
}
}
Using Page Objects in Tests
// 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("user@example.com", "password123");
await expect(page).toHaveURL("/");
});
test("invalid credentials shows error", async ({ page }) => {
const loginPage = new LoginPage(page);
await loginPage.goto();
await loginPage.login("wrong@example.com", "wrongpassword");
await loginPage.expectError("Invalid email or password");
});
});
Selector Priority
-
Semantic selectors first:
typescriptpage.getByRole("button", { name: /submit/i }); page.getByLabel("Email address"); page.getByText("Welcome back"); -
Fallback to test IDs:
typescriptpage.getByTestId("stack-trace"); -
Avoid implementation details:
typescript// ❌ Avoid CSS classes and IDs page.locator(".btn-primary");
Backend Data Setup
E2E tests run against the full Aspire stack. The backend uses the same AppWebHostFactory infrastructure from backend-testing.
For tests requiring specific data, consider:
- API calls in beforeEach — Use Playwright's request context to set up data
- Test-specific endpoints — Create
/api/test/*endpoints for test data management - Database seeding — Seed required data before test runs
- Aspire orchestration — Tests start with Elasticsearch and Redis pre-configured
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");
});
Note: Backend services use in-memory implementations during tests. See AppWebHostFactory for how test infrastructure is configured.
Accessibility Audits
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([]);
});
See accessibility for WCAG guidelines.
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
foundatio-repositories
releasenotes
Generate formatted changelogs from git history since the last release tag. Use when preparing release notes that categorize changes into breaking changes, features, fixes, and other sections.
tanstack-query
Use this skill when fetching data, managing server state, or handling API mutations in the Svelte frontend. Covers createQuery, createMutation, query keys, cache invalidation, optimistic updates, and WebSocket-driven refetching. Apply when adding API calls, managing loading/error states, or coordinating cache updates after mutations.
dogfood
Systematically explore and test a web application to find bugs, UX issues, and other problems. Use when asked to "dogfood", "QA", "exploratory test", "find issues", "bug hunt", "test this app/site/platform", or review the quality of a web application. Produces a structured report with full reproduction evidence -- step-by-step screenshots, repro videos, and detailed repro steps for every issue -- so findings can be handed directly to the responsible teams.
storybook
Use this skill when creating or updating Storybook stories for Svelte components. Covers Svelte CSF story format, defineMeta, argTypes, snippet-based customization, and autodocs. Apply when adding visual documentation for components, setting up story files, or running Storybook for development.
frontend-testing
Use this skill when writing or running frontend unit and component tests with Vitest and Testing Library. Covers render/screen/fireEvent patterns, vi.mock for mocking, and the AAA (Arrange-Act-Assert) test structure. Apply when adding test coverage for Svelte components, debugging test failures, or setting up test utilities.
Didn't find tool you were looking for?