npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@microsoft/fast-test-harness

v0.3.1

Published

Playwright testing harness for FAST web components

Readme

FAST Test Harness

License: MIT

The fast-test-harness package is a Playwright testing harness for FAST Element web components with CSR and SSR support.

Requirements

  • Node.js 22.18 or later
  • Playwright 1.56 or later

Installation

To install fast-test-harness using npm:

npm install --save-dev @microsoft/fast-test-harness

Test directory setup

The harness serves a Vite dev server from a test/ directory in your project. CSR and SSR modes use different entry points from the same directory.

test/
├── index.html              # CSR: loads main.ts
├── ssr.html                # SSR: template with comment placeholders
├── vite.config.ts          # Vite config (shared by both modes)
└── src/
    ├── main.ts             # CSR: registers components, applies theme
    ├── entry-client.ts     # SSR: registers components for hydration
    └── entry-server.ts     # SSR: exports render() for fixture generation

Writing tests

Import test and expect from the harness. Configure the component tag name with test.use(), then call fastPage.setTemplate() in each test to render it.

import { expect, test } from "@microsoft/fast-test-harness";

test.describe("Button", () => {
    test.use({ tagName: "my-button", innerHTML: "Click me" });

    test("should render", async ({ fastPage }) => {
        await fastPage.setTemplate();
        await expect(fastPage.element).toBeVisible();
    });

    test("should accept attributes", async ({ fastPage }) => {
        await fastPage.setTemplate({
            attributes: { appearance: "primary", disabled: true },
        });
        await expect(fastPage.element).toHaveAttribute("appearance", "primary");
    });

    test("should work inside a form", async ({ fastPage }) => {
        await fastPage.setTemplate(`
            <form>
                <my-button type="submit">Submit</my-button>
            </form>
        `);
        await expect(fastPage.element).toBeVisible();
    });
});

Use updateTemplate() to modify attributes or innerHTML after the initial render without navigating away from the page:

await fastPage.setTemplate();
await fastPage.updateTemplate(fastPage.element, { attributes: { disabled: true } });

The toHaveCustomState assertion checks ElementInternals custom states:

await expect(element).toHaveCustomState("checked");

Fixture options

| Option | Type | Default | Description | |--------|------|---------|-------------| | tagName | string | "" | Custom element tag name | | innerHTML | string | "" | Default inner HTML | | waitFor | string[] | [] | Additional elements to wait for before testing | | ssr | boolean | false | Use SSR mode (or set PLAYWRIGHT_TEST_SSR=true) |

CSR files

index.html loads a script that registers your components:

<!doctype html>
<html lang="en">
    <head><meta charset="UTF-8" /></head>
    <body>
        <script type="module" src="/src/main.ts"></script>
    </body>
</html>

main.ts registers components and applies global config. The body starts empty; setTemplate() injects HTML per test.

import "./define-all.js";
import { setTheme } from "./theme.js";
setTheme(lightTheme);

SSR files

ssr.html contains comment placeholders the server fills in per request:

<!doctype html>
<html lang="en">
    <head>
        <title><!--fixturetitle--></title>
        <!--stylespreload-->
    </head>
    <body>
        <!--fixture-->
        <!--templates-->
        <script type="module" src="/src/entry-client.ts"></script>
    </body>
</html>

entry-client.ts imports the harness SSR entry (which defines the <f-template> element) and registers components for DSD hydration using defineAsync:

import "@microsoft/fast-test-harness/ssr/entry-client.js";

import { RenderableFASTElement } from "@microsoft/fast-html";
import { MyButton, definition } from "../../src/button/index.js";

RenderableFASTElement(MyButton).defineAsync({
    name: definition.name,
    templateOptions: "defer-and-hydrate",
});

entry-server.ts exports a render() function that the server calls for each setTemplate() request. It returns three strings that get injected into ssr.html:

export function render(queryObj: Record<string, string>): {
    template: string;    // <f-template> HTML → <!--templates-->
    fixture: string;     // rendered element HTML → <!--fixture-->
    preloadLinks: string; // <link> tags → <!--stylespreload-->
};

Use createSSRRenderer from the harness to build the render() function. It scans for component build artifacts (f-templates, stylesheets) and uses the @microsoft/fast-build WASM renderer to produce declarative shadow DOM on each request.

Multi-component package (all components in one package):

import { createSSRRenderer } from "@microsoft/fast-test-harness/ssr/render.js";

const { render } = createSSRRenderer({
    packageName: "@my-scope/web-components",
    tagPrefix: "my",
});

export { render };

Per-component packages (each component is a separate npm package):

import { createSSRRenderer } from "@microsoft/fast-test-harness/ssr/render.js";

const { render } = createSSRRenderer({
    tagPrefix: "my",
    components: [
        { name: "button", packageName: "@my-scope/button" },
        { name: "checkbox", packageName: "@my-scope/checkbox" },
    ],
});

export { render };

Server

The package includes a Node.js HTTP server with Vite middleware that handles both CSR page serving and SSR fixture generation. Run it directly or let Playwright manage it via webServer:

// playwright.config.ts
export default defineConfig({
    webServer: {
        command: "fast-test-harness",
        port: 3278,
        reuseExistingServer: true,
    },
});

For custom setup, import startServer:

import { startServer } from "@microsoft/fast-test-harness/server.mjs";
await startServer(process.cwd(), "./test", "./test/vite.config.ts", {
    port: 4000,
    debug: true,
});

| Parameter | Default | Description | | --------- | ------- | ----------- | | cwd | process.cwd() | Static file serving root | | root | <cwd>/test | Vite root (contains index.html, ssr.html) | | configFile | Vite auto-discovery | Vite config path | | options.port | 3278 | Server port | | options.base | / | Base URL path | | options.debug | false | Write SSR fixtures to temp/ for inspection |

CLI flags

fast-test-harness [command] [options]

Commands:
  serve                    Start the test harness dev server (default)
  generate-templates       Generate <f-template> HTML files from compiled templates
  generate-stylesheets     Generate CSS files from compiled ElementStyles
  generate-webui-templates Generate WebUI-compatible DSD templates

Serve options:
  -p, --port <number>    Server port (default: 3278)
  -b, --base <path>      Base URL path (default: /)
  -r, --root <path>      Vite root directory (default: <cwd>/test)
  -c, --config <path>    Vite config file path (default: Vite auto-discovery)
  -d, --debug            Write SSR fixtures to temp/ for inspection
  -v, --version          Show version number
  -h, --help             Show help message

CLI flags take precedence over environment variables.

| Environment variable | Default | Description | | -------------------- | ------- | ----------- | | PORT | 3278 | Server port (overridden by --port) | | BASE | / | Base URL path (overridden by --base) | | FAST_DEBUG | — | Set "true" to enable debug mode (overridden by --debug) | | PLAYWRIGHT_TEST_SSR | — | Set "true" for SSR mode |

SSR renderer

createSSRRenderer(options) scans for component build artifacts and returns a { render } object compatible with the server's entry-server.ts contract. It uses the @microsoft/fast-build WASM module to render f-templates into declarative shadow DOM.

| Option | Type | Description | |--------|------|-------------| | tagPrefix | string | Tag name prefix for custom elements (e.g., "fluent", "contoso") | | packageName | string? | Monolithic package name — scans subdirectories for component artifacts. Mutually exclusive with components. | | components | ComponentRegistration[]? | Explicit list of per-component packages. Mutually exclusive with packageName. | | distDir | string? | Artifact directory relative to the package root (default: "dist/esm"). Only used with packageName. | | themeStylesheet | string? | URL or package specifier for a global theme stylesheet. |

Exports

| Specifier | Contents | |-----------|----------| | @microsoft/fast-test-harness | test, expect, CSRFixture, SSRFixture, toHaveCustomState, installDomShim, createSSRRenderer | | @microsoft/fast-test-harness/build/*.js | installDomShim, generateStylesheets, generateFTemplates, generateWebuiTemplates, definitionAsyncResolver, shadowOptionsToAttributes, ShadowOptionsResolver | | @microsoft/fast-test-harness/fixtures/*.js | CSRFixture, SSRFixture, toHaveCustomState, extended test and expect | | @microsoft/fast-test-harness/ssr/render.js | createSSRRenderer, renderTemplate, buildEntryHtml, buildState | | @microsoft/fast-test-harness/server.mjs | startServer | | @microsoft/fast-test-harness/playwright.config.mjs | Shared Playwright configuration | | @microsoft/fast-test-harness/vite.config.mjs | Shared Vite configuration | | @microsoft/fast-test-harness/public/* | Static assets (base CSS) |