feat: add Playwright test harness with SSR and CSR support#7428
Open
feat: add Playwright test harness with SSR and CSR support#7428
Conversation
| () => `${preloadLinks ?? ""}${styleTags}`, | ||
| ); | ||
|
|
||
| await fs.writeFile(filePath, html, "utf-8"); |
Comment on lines
+117
to
+136
| app.use("*all", async (req, res, next) => { | ||
| // Only serve the HTML shell for navigation requests, not for | ||
| // module/asset requests that Vite's middleware didn't handle. | ||
| const accept = req.headers.accept || ""; | ||
| if (!accept.includes("text/html")) { | ||
| return next(); | ||
| } | ||
|
|
||
| try { | ||
| const url = req.originalUrl.replace(base, ""); | ||
|
|
||
| const indexHtml = await fs.readFile(indexPath, "utf-8"); | ||
| const index = await vite.transformIndexHtml(url, indexHtml); | ||
| res.status(200).set({ "Content-Type": "text/html" }).send(index); | ||
| } catch (e) { | ||
| vite?.ssrFixStacktrace?.(e); | ||
| console.log(e.stack); | ||
| res.status(500).end(e.stack); | ||
| } | ||
| }); |
Comment on lines
+21
to
+36
| let processed = dsd.replace( | ||
| /(\s?)(\??)([a-zA-Z0-9-]+)="{{([a-zA-Z0-9]+)}}"/g, | ||
| (match, space, isBoolean, attrName, varName) => { | ||
| const value = templateValues[varName]; | ||
|
|
||
| if (value === undefined) { | ||
| return ""; | ||
| } | ||
|
|
||
| if (isBoolean === "?") { | ||
| return value ? `${space}${attrName}` : ""; | ||
| } | ||
|
|
||
| return `${space}${attrName}="${value}"`; | ||
| }, | ||
| ); |
| } | ||
|
|
||
| // Directory-based scan: walk and collect. | ||
| const dir = resolve(cwd, pattern.replace(/\/\*.*$/, "")); |
| } catch (e) { | ||
| vite?.ssrFixStacktrace?.(e); | ||
| console.log(e.stack); | ||
| res.status(500).end(e.stack); |
| } catch (e) { | ||
| vite?.ssrFixStacktrace?.(e); | ||
| console.log(e.stack); | ||
| res.status(500).end(e.stack); |
| } catch (e) { | ||
| vite?.ssrFixStacktrace?.(e); | ||
| console.log(e.stack); | ||
| res.status(500).end(e.stack); |
| } catch (e) { | ||
| vite?.ssrFixStacktrace?.(e); | ||
| console.log(e.stack); | ||
| res.status(500).end(e.stack); |
janechu
reviewed
Apr 11, 2026
| test.describe("Button", () => { | ||
| test.use({ tagName: "my-button", innerHTML: "Click me" }); | ||
|
|
||
| test("should render", async ({ fastPage }) => { |
Collaborator
There was a problem hiding this comment.
Since this is specifically from the @microsoft/fast-test-harness package, could this just be page instead of fastPage?
| try { | ||
| // The WASM bindings are a CJS module generated by wasm-pack. | ||
| const wasmPath = require.resolve( | ||
| "@microsoft/fast-build/wasm/microsoft_fast_build.js", |
Collaborator
There was a problem hiding this comment.
does this already throw some error message? should we give explicit instructions?
janechu
reviewed
Apr 11, 2026
|
|
||
| ```bash | ||
| npm install --save-dev @microsoft/fast-test-harness | ||
| ``` |
Collaborator
There was a problem hiding this comment.
For this top section, can we match how it is written in the @microsoft/fast-element README.md?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pull Request
📖 Description
Adds
@microsoft/fast-test-harness, a new Playwright testing harness package for FAST web components. The harness provides shared fixtures for both client-side rendering (CSR) and server-side rendering (SSR) test workflows, a custom Express + Vite dev server, SSR rendering utilities, and support for custom assertions.This package is intended to be consumed by component packages in the monorepo (and downstream projects like MAI) to standardize how Playwright tests are authored and run against FAST-based web components.
👩💻 Reviewer Notes
privateand is not published to npm.@microsoft/fast-htmland@microsoft/fast-build.server.mjsentrypoint uses Express 5 and Vite'screateServerAPI to handle both CSR page serving and SSR fixture generation in a single process.📑 Test Plan
This package provides test infrastructure rather than component behavior. Validation will come from downstream adoption in component packages that use the harness fixtures. No Playwright tests are included in this package itself.
✅ Checklist
General
$ npm run change⏭ Next Steps
wasm-renderer.tsmodule wraps the Rust-basedfast-buildWASM renderer for SSR template compilation. This may be extracted or refined asfast-buildstabilizes.