Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .github/workflows/validate-skill.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: Validate AI Skill

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
agnix:
name: Agnix Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Validate agent configs
uses: agent-sh/agnix@12a1917d13e7c804bc91768c30dd4159f536c5c6
4 changes: 2 additions & 2 deletions SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: playwright-best-practices
description: Writing Playwright tests, fixing flaky tests, debugging failures, implementing Page Object Model, configuring CI/CD, optimizing performance, mocking APIs, handling authentication or OAuth, testing accessibility (axe-core), file uploads/downloads, date/time mocking, WebSockets, geolocation, permissions, multi-tab/popup flows, mobile/responsive layouts, touch gestures, GraphQL, error handling, offline mode, multi-user collaboration, third-party services (payments, email verification), console error monitoring, global setup/teardown, test annotations (skip, fixme, slow), test tags (@smoke, @fast, @critical, filtering with --grep), project dependencies, security testing (XSS, CSRF, auth), performance budgets (Web Vitals, Lighthouse), iframes, component testing, canvas/WebGL, service workers/PWA, test coverage, i18n/localization, Electron apps, or browser extension testing. Covers E2E, component, API, visual, accessibility, security, Electron, and extension testing.
name: playwright-best-practices-skill
description: Use when writing Playwright tests, fixing flaky tests, debugging failures, implementing Page Object Model, configuring CI/CD, optimizing performance, mocking APIs, handling authentication or OAuth, testing accessibility (axe-core), file uploads/downloads, date/time mocking, WebSockets, geolocation, permissions, multi-tab/popup flows, mobile/responsive layouts, touch gestures, GraphQL, error handling, offline mode, multi-user collaboration, third-party services (payments, email verification), console error monitoring, global setup/teardown, test annotations (skip, fixme, slow), test tags (@smoke, @fast, @critical, filtering with --grep), project dependencies, security testing (XSS, CSRF, auth), performance budgets (Web Vitals, Lighthouse), iframes, component testing, canvas/WebGL, service workers/PWA, test coverage, i18n/localization, Electron apps, or browser extension testing. Covers E2E, component, API, visual, accessibility, security, Electron, and extension testing.
license: MIT
metadata:
author: currents.dev
Expand Down
18 changes: 10 additions & 8 deletions testing-patterns/forms-validation.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ test("complete a multi-step booking wizard", async ({ page }) => {

await test.step("enter guest information", async () => {
await expect(
page.getByRole("heading", { name: "Guest Info" })
page.getByRole("heading", { name: "Guest Info" }),
).toBeVisible();

await page.getByLabel("Full name").fill("Alice Smith");
Expand All @@ -162,7 +162,7 @@ test("complete a multi-step booking wizard", async ({ page }) => {

await test.step("select room options", async () => {
await expect(
page.getByRole("heading", { name: "Room Selection" })
page.getByRole("heading", { name: "Room Selection" }),
).toBeVisible();

await page.getByLabel("Room type").selectOption("suite");
Expand All @@ -174,7 +174,7 @@ test("complete a multi-step booking wizard", async ({ page }) => {

await test.step("confirm booking", async () => {
await expect(
page.getByRole("heading", { name: "Confirmation" })
page.getByRole("heading", { name: "Confirmation" }),
).toBeVisible();

await expect(page.getByText("Alice Smith")).toBeVisible();
Expand All @@ -184,7 +184,7 @@ test("complete a multi-step booking wizard", async ({ page }) => {
});

await expect(
page.getByRole("heading", { name: "Booking complete" })
page.getByRole("heading", { name: "Booking complete" }),
).toBeVisible();
});

Expand Down Expand Up @@ -242,7 +242,7 @@ test("form submission shows server-side validation errors", async ({
await page.getByRole("button", { name: "Sign up" }).click();

await expect(
page.getByText("Email address already registered")
page.getByText("Email address already registered"),
).toBeVisible();
});

Expand All @@ -253,7 +253,9 @@ test("form shows loading state during submission", async ({ page }) => {
await page.getByLabel("Email").fill("user@test.com");
await page.getByLabel("Details").fill("Found an issue");

const submit = page.getByRole("button", { name: /Submit feedback|Submitting/ });
const submit = page.getByRole("button", {
name: /Submit feedback|Submitting/,
});
await submit.click();

await expect(submit).toHaveText(/Submitting/);
Expand Down Expand Up @@ -371,7 +373,7 @@ test("native HTML5 validation with required attribute", async ({ page }) => {

const emailInput = page.getByLabel("Email");
const validationMessage = await emailInput.evaluate(
(el: HTMLInputElement) => el.validationMessage
(el: HTMLInputElement) => el.validationMessage,
);
expect(validationMessage).toBeTruthy();
});
Expand Down Expand Up @@ -536,7 +538,7 @@ await page.getByLabel("Date").fill("2025-06-15");
await page.getByLabel("Date").dispatchEvent("change");
```

### `selectOption()` throws "not a <select> element"
### `selectOption()` throws "not a select element"

**Cause**: The dropdown is a custom component (ARIA listbox), not a native `<select>`.

Expand Down
Loading