Skip to content

Commit 06794f3

Browse files
radium-vCopilot
andcommitted
feat: enhance documentation with detailed SSR flow and CLI commands
Co-authored-by: Copilot <copilot@github.com>
1 parent ad60e32 commit 06794f3

2 files changed

Lines changed: 72 additions & 49 deletions

File tree

packages/fast-test-harness/DESIGN.md

Lines changed: 51 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -34,24 +34,28 @@ This document describes the internal architecture of the `@microsoft/fast-test-h
3434

3535
The mode is selected per test via `test.use({ ssr: true })` or globally via the `PLAYWRIGHT_TEST_SSR=true` environment variable.
3636

37-
```
37+
```ts
3838
test("renders element", async ({ fastPage }) => {
3939
await fastPage.setTemplate({ attributes: { label: "Hello" } });
4040
await expect(fastPage.element).toBeVisible();
4141
});
42-
43-
├── CSR path ──────────────────────────────────────────┐
44-
│ page.goto("/") │
45-
│ page.evaluate() → inject HTML into <body> │
46-
│ waitForCustomElement() + waitForStability() │
47-
│ │
48-
└── SSR path ──────────────────────────────────────────┐
49-
POST /generate-fixture { tagName, attributes, … } │
50-
server: vite.ssrLoadModule("entry-server.js") │
51-
server: render(queryObj) → { template, fixture } │
52-
server: inject into ssr.html → write to temp/ │
53-
page.goto("/ssr-<testId>.html") │
54-
waitForStability() │
42+
```
43+
44+
Both modes use the same test API. The fixture handles routing internally:
45+
46+
```mermaid
47+
flowchart TD
48+
A["setTemplate(options)"] --> B{ssr?}
49+
B -- CSR --> C["page.goto('/')"]
50+
C --> D["page.evaluate() — inject HTML into body"]
51+
D --> E["waitForCustomElement()"]
52+
E --> F["waitForStability()"]
53+
B -- SSR --> G["POST /generate-fixture"]
54+
G --> H["Server: vite.ssrLoadModule('entry-server.js')"]
55+
H --> I["Server: render(queryObj)"]
56+
I --> J["Server: assemble ssr.html, cache in memory"]
57+
J --> K["page.goto('/ssr-testId.html')"]
58+
K --> F
5559
```
5660

5761
---
@@ -68,11 +72,12 @@ test("renders element", async ({ fastPage }) => {
6872
| `src/build/dom-shim.ts` | Minimal DOM shim for running FAST Element's `css` and `html` tagged templates in Node.js |
6973
| `src/build/generate-stylesheets.ts` | Extracts compiled FAST `ElementStyles` JS modules into plain `.css` files |
7074
| `src/build/generate-templates.ts` | Converts compiled FAST `ViewTemplate` JS modules into declarative `<f-template>` HTML files |
75+
| `src/build/generate-webui-templates.ts` | Converts compiled FAST `ViewTemplate` JS modules into WebUI-compatible declarative shadow DOM `<template>` HTML files |
7176
| `src/ssr/render.ts` | `createSSRRenderer` factory — scans for component build artifacts and uses the `@microsoft/fast-build` WASM module to produce SSR output |
7277
| `src/ssr/entry-client.ts` | SSR hydration entry point — defines `<f-template>` for the browser |
7378
| `server.mjs` | Node.js HTTP server with Vite middleware — serves CSR pages and handles SSR fixture generation |
74-
| `start.mjs` | CLI entry point (`fast-test-harness` bin) — parses `--port`, `--base`, `--root`, `--config`, `--debug` flags via `node:util` `parseArgs` and calls `startServer()` |
75-
| `playwright.config.ts` | Shared Playwright configuration (browsers, web server, test matching) |
79+
| `start.mjs` | CLI entry point (`fast-test-harness` bin) — supports subcommands (`serve`, `generate-templates`, `generate-stylesheets`, `generate-webui-templates`) and flags via `node:util` `parseArgs` |
80+
| `playwright.config.mjs` | Shared Playwright configuration (browsers, web server, test matching) |
7681
| `vite.config.mjs` | Shared Vite configuration (port, resolve conditions, build settings) |
7782
| `public/styles.css` | Base CSS reset served as a Vite public asset |
7883

@@ -207,26 +212,31 @@ Browser GET /
207212

208213
The `/generate-fixture` POST endpoint handles SSR fixture generation:
209214

210-
```
211-
Browser POST /generate-fixture { testId, tagName, attributes, … }
212-
→ validate testId (derived from Playwright's testInfo.titlePath, alphanumeric + hyphens/underscores only)
213-
→ JSON.parse attributes and styles (sent as JSON strings within the JSON body)
214-
→ check pendingGenerations deduplication map
215-
→ read ssr.html template
216-
→ vite.ssrLoadModule("/src/entry-server.js")
217-
→ call render(body) → { template, fixture, preloadLinks }
218-
→ replace placeholders in ssr.html:
219-
<!--fixturetitle--> → test title
220-
<!--templates--> → f-template HTML
221-
<!--fixture--> → rendered element HTML
222-
<!--stylespreload--> → preload links + inline styles
223-
→ vite.transformIndexHtml() for module injection
224-
→ cache in fixtureCache Map
225-
→ if debug: write to temp/ssr-<testId>.html (for inspection)
226-
→ respond with { url: "/ssr-<testId>.html" }
215+
```mermaid
216+
sequenceDiagram
217+
participant B as Browser
218+
participant S as Server
219+
participant V as Vite
220+
participant E as entry-server.ts
221+
222+
B->>S: POST /generate-fixture { testId, tagName, … }
223+
S->>S: Validate testId, parse attributes & styles
224+
S->>S: Check pendingGenerations (dedup)
225+
S->>S: Read ssr.html template
226+
S->>V: ssrLoadModule("/src/entry-server.js")
227+
V-->>S: entry-server module
228+
S->>E: render(body)
229+
E-->>S: { template, fixture, preloadLinks }
230+
S->>S: Replace placeholders in ssr.html
231+
S->>V: transformIndexHtml(url, assembled)
232+
V-->>S: Transformed HTML
233+
S->>S: Cache in fixtureCache
234+
S-->>B: { url: "/ssr-testId.html" }
235+
B->>S: GET /ssr-testId.html
236+
S-->>B: Cached fixture HTML
227237
```
228238

229-
A dedicated `GET /ssr-:id.html` handler serves cached fixtures directly from the in-memory `fixtureCache`. The temp file writes (when debug is enabled) are a secondary output for post-mortem inspection.
239+
When `debug` is enabled, the server also writes fixtures to `temp/ssr-<testId>.html` for post-failure inspection.
230240

231241
### Caching and Deduplication
232242

@@ -288,10 +298,10 @@ The `src/ssr/render.ts` module exports `createSSRRenderer`, a factory that scans
288298
| Setting | Value |
289299
|---------|-------|
290300
| `retries` | `3` in CI, `1` locally |
291-
| `timeout` | `30_000` in CI, `10_000` locally |
292-
| `fullyParallel` | `true` |
301+
| `timeout` | `10_000` in CI, `5_000` locally |
302+
| `fullyParallel` | `true` locally, `false` in CI |
293303
| `use.contextOptions.reducedMotion` | `"reduce"` |
294-
| `testMatch` | `src/**/*.pw.spec.ts` |
304+
| `testMatch` | `**/*.pw.spec.ts` |
295305
| `reporter` | `"list"` |
296306
| `webServer.command` | `fast-test-harness` |
297307
| `webServer.port` | `3278` (configurable via `PORT` env var) |
@@ -316,10 +326,10 @@ The `src/ssr/render.ts` module exports `createSSRRenderer`, a factory that scans
316326

317327
| Specifier | Contents |
318328
|-----------|----------|
319-
| `@microsoft/fast-test-harness` | `test`, `expect`, `CSRFixture`, `SSRFixture`, `createSSRRenderer`, `ComponentRegistration`, `RenderResult`, `SSRRendererOptions`, build utilities (`installDomShim`, `generateStylesheets`, `generateFTemplates`) |
329+
| `@microsoft/fast-test-harness` | `test`, `expect`, `CSRFixture`, `SSRFixture`, `createSSRRenderer`, `ComponentRegistration`, `RenderResult`, `SSRRendererOptions`, build utilities (`installDomShim`, `generateStylesheets`, `generateFTemplates`, `generateWebuiTemplates`) |
320330
| `@microsoft/fast-test-harness/server.mjs` | `startServer` |
321-
| `@microsoft/fast-test-harness/ssr/render.js` | `createSSRRenderer`, `ComponentRegistration`, `RenderResult`, `SSRRendererOptions` |
322-
| `@microsoft/fast-test-harness/build/*.js` | Build utilities: `installDomShim`, `generateStylesheets`, `generateFTemplates` |
323-
| `@microsoft/fast-test-harness/playwright.config.ts` | Shared Playwright configuration |
331+
| `@microsoft/fast-test-harness/ssr/render.js` | `createSSRRenderer`, `ComponentRegistration`, `RenderResult`, `SSRRendererOptions`, `renderTemplate`, `buildEntryHtml`, `buildState`, `parseDefaultValue` |
332+
| `@microsoft/fast-test-harness/build/*.js` | Build utilities: `installDomShim`, `generateStylesheets`, `generateFTemplates`, `generateWebuiTemplates` |
333+
| `@microsoft/fast-test-harness/playwright.config.mjs` | Shared Playwright configuration |
324334
| `@microsoft/fast-test-harness/vite.config.mjs` | Shared Vite configuration |
325335
| `@microsoft/fast-test-harness/public/*` | Static assets (base CSS reset) |

packages/fast-test-harness/README.md

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -123,15 +123,17 @@ setTheme(lightTheme);
123123
</html>
124124
```
125125

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

128128
```ts
129-
import { TemplateElement } from "@microsoft/fast-html";
130-
TemplateElement.define({ name: "f-template" });
129+
import { RenderableFASTElement } from "@microsoft/fast-html";
130+
import "@microsoft/fast-test-harness/ssr/entry-client.js";
131+
import { MyButton, definition } from "../../src/button/index.js";
131132

132-
// Load all define-async modules
133-
const modules = import.meta.glob("../../src/*/define-async.{ts,js,mts,mjs}");
134-
Promise.all(Object.values(modules).map(m => m()));
133+
RenderableFASTElement(MyButton).defineAsync({
134+
name: definition.name,
135+
templateOptions: "defer-and-hydrate",
136+
});
135137
```
136138

137139
**`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`:
@@ -212,13 +214,21 @@ await startServer(process.cwd(), "./test", "./test/vite.config.ts", {
212214
### CLI flags
213215

214216
```
215-
fast-test-harness [options]
217+
fast-test-harness [command] [options]
218+
219+
Commands:
220+
serve Start the test harness dev server (default)
221+
generate-templates Generate <f-template> HTML files from compiled templates
222+
generate-stylesheets Generate CSS files from compiled ElementStyles
223+
generate-webui-templates Generate WebUI-compatible DSD templates
216224
225+
Serve options:
217226
-p, --port <number> Server port (default: 3278)
218227
-b, --base <path> Base URL path (default: /)
219228
-r, --root <path> Vite root directory (default: <cwd>/test)
220229
-c, --config <path> Vite config file path (default: <root>/vite.config.ts)
221230
-d, --debug Write SSR fixtures to temp/ for inspection
231+
-v, --version Show version number
222232
-h, --help Show help message
223233
```
224234

@@ -247,7 +257,10 @@ CLI flags take precedence over environment variables.
247257

248258
| Specifier | Contents |
249259
|-----------|----------|
250-
| `@microsoft/fast-test-harness` | `test`, `expect`, `CSRFixture`, `SSRFixture`, `createSSRRenderer` |
260+
| `@microsoft/fast-test-harness` | `test`, `expect`, `CSRFixture`, `SSRFixture`, `createSSRRenderer`, build utilities |
251261
| `@microsoft/fast-test-harness/server.mjs` | `startServer` |
252262
| `@microsoft/fast-test-harness/ssr/render.js` | `createSSRRenderer`, `ComponentRegistration`, `RenderResult`, `SSRRendererOptions` |
263+
| `@microsoft/fast-test-harness/build/*.js` | `installDomShim`, `generateStylesheets`, `generateFTemplates`, `generateWebuiTemplates` |
264+
| `@microsoft/fast-test-harness/playwright.config.mjs` | Shared Playwright configuration |
265+
| `@microsoft/fast-test-harness/vite.config.mjs` | Shared Vite configuration |
253266
| `@microsoft/fast-test-harness/public/*` | Static assets (base CSS) |

0 commit comments

Comments
 (0)