# Testing

> Use this skill when running or writing tests in the FAST monorepo — local test execution, CI workflows, Playwright fixtures, and WebUI integration testing.

- Skill: `microsoft/testing-2` (Agent Skill)
- Install (CLI): `npx skillmds@latest add microsoft/testing-2`
- Raw SKILL.md: https://api.skillmd.com/api/skills/microsoft/testing-2/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Integrations & APIs
- Author: Microsoft (https://skillmd.com/u/microsoft)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/microsoft/testing-2

---


# Testing Patterns for FAST

Use this guide when running or writing tests in the FAST monorepo. FAST uses [Playwright](https://playwright.dev/) for integration testing with a [Vite](https://vitejs.dev/) dev server.

## Running tests

### Locally

#### First-time setup

After cloning and installing dependencies (`npm ci`), install Playwright browsers:

```bash
npx playwright install --with-deps
```

#### Commands

All commands are run from the **monorepo root**. Use `-w` to target a specific package.

| Task | Command |
|---|---|
| Run all tests (all browsers) | `npm run test` |
| Run all tests (Chromium only) | `npm run test:chromium` |
| Test a single package (all browsers) | `npm run test -w @microsoft/fast-element` |
| Test a single package (Chromium only) | `npm run test:chromium -w @microsoft/fast-element` |
| Test changed packages only | `npx lage test:node test:chromium --since origin/main` |

#### Interactive / debug workflows

For FAST declarative tests in `@microsoft/fast-element`, these additional scripts are available:

| Task | Command |
|---|---|
| Playwright UI mode | `npm run test:ui:declarative -w @microsoft/fast-element` |
| Start declarative source server | `npm run test-server:declarative -w @microsoft/fast-element` |
| Rebuild fixtures | `npm run build:fixtures -w @microsoft/fast-element` |
| Build fixtures with webui | `npm run build:fixtures:webui -w @microsoft/fast-element` |
| Run webui integration tests | `npm run test:webui-integration -w @microsoft/fast-element` |

**Playwright UI mode** (`test:ui`) starts a visual test runner where you can select and debug individual tests, view traces, and inspect DOM snapshots.

**Declarative browser workflows** resolve `@microsoft/fast-element` package imports directly to `src` and let Vite transpile TypeScript on demand. Vite does not type-check these modules; the package build remains responsible for type checking, while `test:exports` imports every emitted package export.

### Through GitHub Actions

The repository uses several CI workflows to validate changes.

#### PR validation (ci-validate-pr.yml)

Runs on every pull request targeting `main`, `releases/*`, or `features/*` branches. Tests run on **Ubuntu with Chromium only** for fast feedback.

Key steps:
- Checks for change files (`npm run checkchange`)
- Biome lint/format check
- Builds affected packages (incremental with `--since`)
- Runs `test:node` and `test:chromium` for affected packages

#### Cross-platform validation (ci-validate-platforms.yml)

Runs on pushes to `main`, PRs targeting `main`, and on a weekly schedule. Tests run on **Ubuntu, Windows, and macOS** with **Chromium, Firefox, and Safari**.

This ensures cross-platform and cross-browser compatibility.

#### WebUI integration testing (ci-webui-integration.yml)

A dedicated workflow for validating FAST's integration with `@microsoft/webui`. This workflow runs on:

- **Manual dispatch** (`workflow_dispatch`)
- **Pushes to `webui/*` branches**

> **Note:** This workflow does _not_ run on regular pull requests. It is scoped to `webui/*` branches to test integration changes in isolation before they land on `main`.

The workflow builds all packages, installs Playwright Chromium, and runs:

```bash
npm run test:webui-integration -w @microsoft/fast-element
```

This builds each fixture with `webui build --plugin=fast`, renders the protocol with the fixture's `state.json`, and runs the same Playwright specs against the webui-rendered output.

To trigger WebUI integration tests for your changes:

1. Create a branch with the `webui/` prefix (e.g., `webui/my-integration-change`).
2. Push the branch — the workflow runs automatically.
3. Alternatively, trigger the workflow manually from the Actions tab using `workflow_dispatch`.

#### Azure Pipelines (azure-pipelines-ci.yml)

The repository also has an Azure DevOps pipeline that runs on PRs to `main`. This pipeline runs in a 1ES-managed environment and includes SDL compliance checks in addition to building and testing.

## Writing tests

FAST tests are [Playwright](https://playwright.dev/) integration tests that run against fixture pages served by Vite.

### Test file conventions

- Test files use the `*.spec.ts` suffix (specifically `*.pw.spec.ts` for package `src/` tests).
- Tests for developer-authored declarative markup and directives live in the matching
  `test/declarative/fixtures/<category>/<feature>/<feature>.spec.ts` fixture.
- Tests for implementation APIs and lifecycle behavior are co-located with their source as
  `src/<feature>/<feature>.pw.spec.ts`.

### Writing declarative fixture tests

Fixture tests in `@microsoft/fast-element/test/declarative/fixtures` are the primary way to verify declarative template features. Each fixture is a self-contained test case with its own HTML, state, templates, and component definitions.

When changing declarative syntax, directive parsing, template generation, hydration behavior, or other user-authored template behavior, add or update a declarative fixture and exercise it in browser. Source-level parser tests may supplement narrow parsing edge cases, but they should not be the only coverage for syntax that users write in `entry.html` or `templates.html`. Use the local README files under `packages/fast-element/test/declarative/fixtures/` and each fixture category to choose the right fixture type and follow category-specific examples.

For a complete guide on creating fixtures — including how to write `entry.html`, `state.json`, `templates.html`, `main.ts`, and spec files — see:

📄 **[Writing Fixtures](../../../packages/fast-element/test/declarative/fixtures/WRITING_FIXTURES.md)**

### Quick example

```typescript
import { expect, test } from "@playwright/test";

test.describe("my-feature", async () => {
    test("renders correctly", async ({ page }) => {
        await page.goto("/fixtures/bindings/my-feature/");

        const element = page.locator("my-element");
        await expect(element).toHaveText("Hello");
    });
});
```

