@microsoft/fast-test-harness 0.3.0 → 0.4.0-fast-element-v3-rc-20260615

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -128,17 +128,17 @@ setTheme(lightTheme);
128
128
  </html>
129
129
  ```
130
130
 
131
- **`entry-client.ts`** imports the harness SSR entry (which defines the `<f-template>` element) and registers components for DSD hydration using `defineAsync`:
131
+ **`entry-client.ts`** imports the harness SSR entry (which enables hydration) and registers components. Component definition modules should use `template: declarativeTemplate()`; this automatically defines FAST's internal `<f-template>` publisher.
132
132
 
133
133
  ```ts
134
134
  import "@microsoft/fast-test-harness/ssr/entry-client.js";
135
+ import { declarativeTemplate } from "@microsoft/fast-element/declarative.js";
135
136
 
136
- import { RenderableFASTElement } from "@microsoft/fast-html";
137
137
  import { MyButton, definition } from "../../src/button/index.js";
138
138
 
139
- RenderableFASTElement(MyButton).defineAsync({
139
+ MyButton.define({
140
140
  name: definition.name,
141
- templateOptions: "defer-and-hydrate",
141
+ template: declarativeTemplate(),
142
142
  });
143
143
  ```
144
144
 
@@ -240,6 +240,10 @@ Serve options:
240
240
 
241
241
  CLI flags take precedence over environment variables.
242
242
 
243
+ `generate-templates` preserves browser-valid `<template>` wrappers and strips
244
+ static wrappers even when the opening or closing tag includes ASCII whitespace
245
+ before `>`.
246
+
243
247
  | Environment variable | Default | Description |
244
248
  | -------------------- | ------- | ----------- |
245
249
  | `PORT` | `3278` | Server port (overridden by `--port`) |
@@ -249,7 +253,7 @@ CLI flags take precedence over environment variables.
249
253
 
250
254
  ## SSR renderer
251
255
 
252
- **`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.
256
+ **`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 parse f-templates and render them into declarative shadow DOM, including wrapper tags whose opening or closing `>` is preceded by ASCII whitespace.
253
257
 
254
258
  | Option | Type | Description |
255
259
  |--------|------|-------------|
@@ -267,6 +271,7 @@ CLI flags take precedence over environment variables.
267
271
  | `@microsoft/fast-test-harness/build/*.js` | `installDomShim`, `generateStylesheets`, `generateFTemplates`, `generateWebuiTemplates`, `definitionAsyncResolver`, `shadowOptionsToAttributes`, `ShadowOptionsResolver` |
268
272
  | `@microsoft/fast-test-harness/fixtures/*.js` | `CSRFixture`, `SSRFixture`, `toHaveCustomState`, extended `test` and `expect` |
269
273
  | `@microsoft/fast-test-harness/ssr/render.js` | `createSSRRenderer`, `renderTemplate`, `buildEntryHtml`, `buildState` |
274
+ | `@microsoft/fast-test-harness/ssr/entry-client.js` | Enables FAST Element hydration for SSR pages |
270
275
  | `@microsoft/fast-test-harness/server.mjs` | `startServer` |
271
276
  | `@microsoft/fast-test-harness/playwright.config.mjs` | Shared Playwright configuration |
272
277
  | `@microsoft/fast-test-harness/vite.config.mjs` | Shared Vite configuration |
@@ -1 +1 @@
1
- {"version":3,"file":"generate-stylesheets.d.ts","sourceRoot":"","sources":["../../../src/build/generate-stylesheets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAQH,MAAM,WAAW,0BAA0B;IACvC;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;;;;;;;;;;;;;OAeG;IACH,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACxE;AAiBD,wBAAsB,mBAAmB,CACrC,OAAO,GAAE,0BAA+B,GACzC,OAAO,CAAC,IAAI,CAAC,CAuDf"}
1
+ {"version":3,"file":"generate-stylesheets.d.ts","sourceRoot":"","sources":["../../../src/build/generate-stylesheets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAQH,MAAM,WAAW,0BAA0B;IACvC;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;;;;;;;;;;;;;OAeG;IACH,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACxE;AAiBD,wBAAsB,mBAAmB,CACrC,OAAO,GAAE,0BAA+B,GACzC,OAAO,CAAC,IAAI,CAAC,CAwDf"}
@@ -1 +1 @@
1
- {"version":3,"file":"generate-templates.d.ts","sourceRoot":"","sources":["../../../src/build/generate-templates.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AA8BH,MAAM,WAAW,yBAAyB;IACtC;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEtE;;;;;;;;;;OAUG;IACH,oBAAoB,CAAC,EAAE,qBAAqB,GAAG,IAAI,CAAC;CACvD;AAED;;;;GAIG;AACH,MAAM,MAAM,qBAAqB,GAAG,CAChC,cAAc,EAAE,MAAM,KACrB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,CAAC;AAExF;;;;;;;;;;GAUG;AACH,wBAAsB,uBAAuB,CACzC,cAAc,EAAE,MAAM,GACvB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,CAY9C;AAED,MAAM,WAAW,YAAY;IACzB,IAAI,EAAE,MAAM,GAAG,mBAAmB,CAAC;IACnC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,UAAU,OAAO;IACb,WAAW,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9B,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,WAAW,CAAC,EAAE;QACV,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC;KACrC,CAAC;CACL;AAmFD;;;GAGG;AACH,wBAAgB,eAAe,CAC3B,YAAY,EAAE,YAAY,EAC1B,aAAa,EAAE,MAAM,GACtB,MAAM,GAAG,IAAI,CA4Hf;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CACrC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GACnD,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAmBxB;AAED,wBAAsB,kBAAkB,CACpC,OAAO,GAAE,yBAA8B,GACxC,OAAO,CAAC,IAAI,CAAC,CAgFf"}
1
+ {"version":3,"file":"generate-templates.d.ts","sourceRoot":"","sources":["../../../src/build/generate-templates.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAgCH,MAAM,WAAW,yBAAyB;IACtC;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEtE;;;;;;;;;;OAUG;IACH,oBAAoB,CAAC,EAAE,qBAAqB,GAAG,IAAI,CAAC;CACvD;AAED;;;;GAIG;AACH,MAAM,MAAM,qBAAqB,GAAG,CAChC,cAAc,EAAE,MAAM,KACrB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,CAAC;AAExF;;;;;;;;;;GAUG;AACH,wBAAsB,uBAAuB,CACzC,cAAc,EAAE,MAAM,GACvB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,CAY9C;AAED,MAAM,WAAW,YAAY;IACzB,IAAI,EAAE,MAAM,GAAG,mBAAmB,CAAC;IACnC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,UAAU,OAAO;IACb,WAAW,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9B,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,WAAW,CAAC,EAAE;QACV,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC;KACrC,CAAC;CACL;AAmFD;;;GAGG;AACH,wBAAgB,eAAe,CAC3B,YAAY,EAAE,YAAY,EAC1B,aAAa,EAAE,MAAM,GACtB,MAAM,GAAG,IAAI,CA4Hf;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CACrC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GACnD,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAmBxB;AAED,wBAAsB,kBAAkB,CACpC,OAAO,GAAE,yBAA8B,GACxC,OAAO,CAAC,IAAI,CAAC,CAgFf"}
@@ -1 +1 @@
1
- {"version":3,"file":"generate-webui-templates.d.ts","sourceRoot":"","sources":["../../../src/build/generate-webui-templates.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAQH,OAAO,EAGH,KAAK,qBAAqB,EAG7B,MAAM,yBAAyB,CAAC;AAQjC,MAAM,WAAW,6BAA6B;IAC1C;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEtE;;;;;;;;;;OAUG;IACH,oBAAoB,CAAC,EAAE,qBAAqB,GAAG,IAAI,CAAC;CACvD;AA4CD,wBAAsB,sBAAsB,CACxC,OAAO,GAAE,6BAAkC,GAC5C,OAAO,CAAC,IAAI,CAAC,CA6Ef"}
1
+ {"version":3,"file":"generate-webui-templates.d.ts","sourceRoot":"","sources":["../../../src/build/generate-webui-templates.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAWH,OAAO,EAGH,KAAK,qBAAqB,EAG7B,MAAM,yBAAyB,CAAC;AAQjC,MAAM,WAAW,6BAA6B;IAC1C;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEtE;;;;;;;;;;OAUG;IACH,oBAAoB,CAAC,EAAE,qBAAqB,GAAG,IAAI,CAAC;CACvD;AA4CD,wBAAsB,sBAAsB,CACxC,OAAO,GAAE,6BAAkC,GAC5C,OAAO,CAAC,IAAI,CAAC,CA6Ef"}
@@ -41,8 +41,9 @@ export async function generateStylesheets(options = {}) {
41
41
  for await (const jsFile of glob(pattern, { cwd: distDir })) {
42
42
  const jsFilePath = path.resolve(distDir, jsFile);
43
43
  const baseName = path.basename(jsFile, ".js") + ".css";
44
+ const relativeDir = path.relative(distDir, path.dirname(jsFilePath));
44
45
  const cssFilePath = outDir
45
- ? path.resolve(outDir, baseName)
46
+ ? path.resolve(outDir, relativeDir, baseName)
46
47
  : path.resolve(path.dirname(jsFilePath), baseName);
47
48
  try {
48
49
  const mod = await import(pathToFileURL(jsFilePath).href);
@@ -17,9 +17,11 @@ import { glob, mkdir, writeFile } from "node:fs/promises";
17
17
  import path from "node:path";
18
18
  import { pathToFileURL } from "node:url";
19
19
  import { styleText } from "node:util";
20
- import { attributeDirectivePrefix, clientSideCloseExpression, clientSideOpenExpression, closeExpression, eventArgAccessor, openExpression, } from "@microsoft/fast-html/syntax.js";
20
+ import { attributeDirectivePrefix, clientSideCloseExpression, clientSideOpenExpression, closeExpression, eventArgAccessor, openExpression, } from "@microsoft/fast-element/declarative-utilities.js";
21
21
  import { installDomShim } from "./dom-shim.js";
22
22
  const stylesMarker = `${openExpression}styles${closeExpression}`;
23
+ const templateOpenTagPattern = /<template(?:\s[^>]*)?\s*\/?>/i;
24
+ const templateWrapperTagPattern = /<template(?:\s[^>]*)?\s*\/?>|<\/template\s*>/gi;
23
25
  function wrapClientExpression(expression) {
24
26
  return `${clientSideOpenExpression}${expression}${clientSideCloseExpression}`;
25
27
  }
@@ -136,7 +138,7 @@ export function convertTemplate(viewTemplate, componentName) {
136
138
  const factoryEntries = Object.entries(factories);
137
139
  if (factoryEntries.length === 0) {
138
140
  // No factories — pure static template.
139
- const content = html.replace(/<\/?template[^>]*>/g, "").trim();
141
+ const content = html.replace(templateWrapperTagPattern, "").trim();
140
142
  return `<f-template name="${componentName}" shadowrootmode="open"><template>${stylesMarker}${content}</template></f-template>\n`;
141
143
  }
142
144
  // Derive the binding marker prefix from the first factory key.
@@ -212,15 +214,15 @@ export function convertTemplate(viewTemplate, componentName) {
212
214
  return wrapDefaultExpression(evalStr);
213
215
  });
214
216
  let fInner = fContent.trim();
215
- if (!/<template[^>]*>/.test(fInner)) {
217
+ if (!templateOpenTagPattern.test(fInner)) {
216
218
  fInner = `<template>${fInner}</template>`;
217
219
  }
218
220
  // Inject the {{styles}} marker immediately after the opening <template> tag
219
221
  // so the test harness can substitute it with a <link rel="stylesheet"> at
220
222
  // render time. Harness fallback auto-injects if the marker is missing, but
221
223
  // emitting it explicitly keeps generated output consistent with hand-authored
222
- // f-templates.
223
- fInner = fInner.replace(/(<template[^>]*>)/, `$1${stylesMarker}`);
224
+ // f-templates, including browser-valid template tags with whitespace.
225
+ fInner = fInner.replace(templateOpenTagPattern, match => `${match}${stylesMarker}`);
224
226
  return `<f-template name="${componentName}" shadowrootmode="open">\n${fInner}\n</f-template>\n`;
225
227
  }
226
228
  /**
@@ -21,7 +21,7 @@ import { glob, mkdir, writeFile } from "node:fs/promises";
21
21
  import path from "node:path";
22
22
  import { pathToFileURL } from "node:url";
23
23
  import { styleText } from "node:util";
24
- import { closeExpression, openExpression } from "@microsoft/fast-html/syntax.js";
24
+ import { closeExpression, openExpression, } from "@microsoft/fast-element/declarative-utilities.js";
25
25
  import { installDomShim } from "./dom-shim.js";
26
26
  import { convertTemplate, definitionAsyncResolver, shadowOptionsToAttributes, } from "./generate-templates.js";
27
27
  const stylesMarker = `${openExpression}styles${closeExpression}`;
@@ -1,2 +1,2 @@
1
- import { TemplateElement } from "@microsoft/fast-html";
2
- TemplateElement.define({ name: "f-template" });
1
+ import { enableHydration } from "@microsoft/fast-element/hydration.js";
2
+ enableHydration();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@microsoft/fast-test-harness",
3
- "version": "0.3.0",
3
+ "version": "0.4.0-fast-element-v3-rc-20260615",
4
4
  "author": {
5
5
  "name": "Microsoft",
6
6
  "url": "https://discord.gg/FcSNfg4"
@@ -71,25 +71,23 @@
71
71
  "*.d.ts"
72
72
  ],
73
73
  "devDependencies": {
74
- "@microsoft/fast-element": "^2.10.4",
75
- "@microsoft/fast-build": "^0.7.0",
76
- "@microsoft/fast-html": "^1.0.0-alpha.53"
74
+ "@microsoft/fast-build": "0.8.0-fast-element-v3-rc-20260615",
75
+ "@microsoft/fast-element": "3.0.0-rc.2"
77
76
  },
78
77
  "dependencies": {
79
78
  "cheerio": "1.2.0"
80
79
  },
81
80
  "peerDependencies": {
82
- "@microsoft/fast-element": "^2.10.4 || ^3.0.0",
83
- "@microsoft/fast-build": "^0.7.0",
84
- "@microsoft/fast-html": ">=1.0.0-alpha.53 <1.0.0",
81
+ "@microsoft/fast-build": "0.8.0-fast-element-v3-rc-20260615",
82
+ "@microsoft/fast-element": "3.0.0-rc.2",
85
83
  "@playwright/test": ">=1.40.0",
86
84
  "vite": ">=7.0.0"
87
85
  },
88
86
  "peerDependenciesMeta": {
89
- "@microsoft/fast-element": {
87
+ "@microsoft/fast-build": {
90
88
  "optional": true
91
89
  },
92
- "@microsoft/fast-html": {
90
+ "@microsoft/fast-element": {
93
91
  "optional": true
94
92
  }
95
93
  },
package/vite.config.mjs CHANGED
@@ -27,7 +27,7 @@ export default defineConfig({
27
27
  sourcemap: true,
28
28
  },
29
29
  optimizeDeps: {
30
- exclude: ["@microsoft/fast-element", "@microsoft/fast-html"],
30
+ exclude: ["@microsoft/fast-element"],
31
31
  },
32
32
  preview: {
33
33
  port: PORT,