Skip to content

Commit 6b5b794

Browse files
Merge pull request #1410 from firebase/e2e-build-before-playwright
fix(e2e): build packages before Playwright starts dev servers
2 parents 4c5d95e + 27ed5a1 commit 6b5b794

6 files changed

Lines changed: 11 additions & 29 deletions

File tree

LOCAL_DEVELOPMENT.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ This guide walks you through running FirebaseUI Web locally so you can test feat
66

77
Make sure you have these installed:
88

9-
- [Node.js](https://nodejs.org/) v18+ locally; **CI uses v24**use Node 24 for pre-push verification to match CI ([change-authoring-verification.md](developer-docs/playbooks/change-authoring-verification.md))
9+
- [Node.js](https://nodejs.org/) v24.15+ locally; **CI uses v24.18**match CI for pre-push verification ([change-authoring-verification.md](developer-docs/playbooks/change-authoring-verification.md))
1010
- [pnpm](https://pnpm.io/) — if you have Node.js 18+, [corepack](https://nodejs.org/api/corepack.html) can install pnpm on demand when you run it
1111
- [Firebase CLI](https://firebase.google.com/docs/cli):
1212
```bash

developer-docs/decisions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ Example apps are verified with **Playwright smoke tests**, not full user-flow e2
3030

3131
## AD-4: Playwright-managed dev servers, serial, shared emulator
3232

33-
Each example has a **unique e2e port** — see [examples-inventory.md](architecture/examples-inventory.md). Playwright's **top-level** `webServer` (one at a time, selected via `E2E_PROJECT`) starts each UI example's dev server, waits for its URL, and stops it — replacing hand-rolled preflight/postflight/PID scripts. Execution is **serial** (`workers: 1`) for resource predictability and clean logs; because ports are unique, parallelization is possible later but deferred ([Deferred](work-queues/playwright-e2e-smoke.md#deferred)). **`globalSetup`** builds packages (`build:packages`, asserting `dist/` exists — examples consume built `@firebase-oss/ui-*`), ensures a single Auth emulator on `:9099` for the whole run (reuse-aware), and starts it when not already running; **`globalTeardown`** stops what globalSetup started unless the serial runner is mid-suite (`E2E_KEEP_EMULATOR=1`). Angular reuses its package `start` semantics (`pnpm clean && ng serve`) rather than duplicating the `.angular/cache` clean.
33+
Each example has a **unique e2e port** — see [examples-inventory.md](architecture/examples-inventory.md). Playwright's **top-level** `webServer` (one at a time, selected via `E2E_PROJECT`) starts each UI example's dev server, waits for its URL, and stops it — replacing hand-rolled preflight/postflight/PID scripts. Execution is **serial** (`workers: 1`) for resource predictability and clean logs; because ports are unique, parallelization is possible later but deferred ([Deferred](work-queues/playwright-e2e-smoke.md#deferred)). Supported root entrypoints build packages **before Playwright starts the dev server** (`test:e2e` once for the suite; `test:e2e:<example>` once for that project), preventing Vite/Angular from observing partially rebuilt `dist/` files. **`globalSetup`** asserts the required package artifacts exist, ensures a single Auth emulator on `:9099` for the whole run (reuse-aware), and starts it when not already running; **`globalTeardown`** stops what globalSetup started unless the serial runner is mid-suite (`E2E_KEEP_EMULATOR=1`). Angular reuses its package `start` semantics (`pnpm clean && ng serve`) rather than duplicating the `.angular/cache` clean.
3434

3535
---
3636

developer-docs/work-queues/playwright-e2e-smoke.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ scripts/e2e-run.mjs (pnpm test:e2e)
5959

6060
- **Serial:** `workers: 1`; `E2E_PROJECT` selects both the single Playwright project and the top-level `webServer`, so one dev server is up at a time.
6161
- **Emulator:** `globalSetup` ensures `:9099` is reachable (starts via `npx firebase-tools` when not already running); serial runner sets `E2E_KEEP_EMULATOR=1` so teardown does not stop it between examples; `pnpm emulators` remains the first-class manual target ([LOCAL_DEVELOPMENT.md](../../LOCAL_DEVELOPMENT.md)).
62-
- **Per-example debug:** `pnpm test:e2e:react` runs one project; `globalSetup` starts the emulator with reuse if not already running.
62+
- **Per-example debug:** `pnpm test:e2e:react` builds packages before Playwright starts Vite, then runs one project; `globalSetup` asserts `dist/` and starts the emulator with reuse if not already running.
6363

6464
# Example ports, commands, and root scripts
6565

e2e/global-setup.ts

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -97,24 +97,11 @@ function assertPackagesBuilt(): void {
9797

9898
if (missing.length > 0) {
9999
throw new Error(
100-
`Expected built package artifacts are missing after build:packages:\n${missing.map((entry) => ` - ${entry}`).join("\n")}`
100+
`Expected built package artifacts are missing. Run pnpm build:packages before Playwright:\n${missing.map((entry) => ` - ${entry}`).join("\n")}`
101101
);
102102
}
103103
}
104104

105-
function runBuildPackages(): void {
106-
try {
107-
execSync("pnpm build:packages", {
108-
cwd: REPO_ROOT,
109-
stdio: "inherit",
110-
});
111-
} catch {
112-
throw new Error("pnpm build:packages failed — examples require built @firebase-oss/ui-* packages");
113-
}
114-
115-
assertPackagesBuilt();
116-
}
117-
118105
function writeEmulatorState(state: EmulatorState): void {
119106
mkdirSync(STATE_DIR, { recursive: true });
120107
writeFileSync(STATE_FILE, JSON.stringify(state, null, 2));
@@ -161,11 +148,7 @@ function startAuthEmulator(version: string): ChildProcess {
161148
}
162149

163150
export default async function globalSetup(): Promise<void> {
164-
if (process.env.E2E_SKIP_BUILD_PACKAGES === "1") {
165-
assertPackagesBuilt();
166-
} else {
167-
runBuildPackages();
168-
}
151+
assertPackagesBuilt();
169152

170153
if (await isAuthEmulatorReachable()) {
171154
const existing = readEmulatorState();

package.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@
1414
"format:write": "prettier --write **/{src,tests}/**/*.{ts,tsx}",
1515
"test": "pnpm --filter=@firebase-oss/ui-core run test && pnpm --filter=@firebase-oss/ui-translations run test && pnpm --filter=@firebase-oss/ui-styles run test && pnpm --filter=@firebase-oss/ui-react run test && pnpm --filter=@firebase-oss/ui-shadcn run test && pnpm --filter=@firebase-oss/ui-angular run test",
1616
"test:e2e": "node scripts/e2e-run.mjs",
17-
"test:e2e:react": "E2E_PROJECT=react pnpm --filter=e2e exec playwright test --project=react",
18-
"test:e2e:shadcn": "E2E_PROJECT=shadcn pnpm --filter=e2e exec playwright test --project=shadcn",
19-
"test:e2e:nextjs": "E2E_PROJECT=nextjs pnpm --filter=e2e exec playwright test --project=nextjs",
20-
"test:e2e:nextjs-ssr": "E2E_PROJECT=nextjs-ssr pnpm --filter=e2e exec playwright test --project=nextjs-ssr",
21-
"test:e2e:angular": "E2E_PROJECT=angular-example pnpm --filter=e2e exec playwright test --project=angular-example",
22-
"test:e2e:custom-auth-server": "E2E_PROJECT=custom-auth-server pnpm --filter=e2e exec playwright test --project=custom-auth-server",
17+
"test:e2e:react": "pnpm --filter=@firebase-oss/ui-react... build && E2E_PROJECT=react pnpm --filter=e2e exec playwright test --project=react",
18+
"test:e2e:shadcn": "pnpm --filter=@firebase-oss/ui-shadcn... build && E2E_PROJECT=shadcn pnpm --filter=e2e exec playwright test --project=shadcn",
19+
"test:e2e:nextjs": "pnpm --filter=@firebase-oss/ui-react... build && E2E_PROJECT=nextjs pnpm --filter=e2e exec playwright test --project=nextjs",
20+
"test:e2e:nextjs-ssr": "pnpm --filter=@firebase-oss/ui-react... build && E2E_PROJECT=nextjs-ssr pnpm --filter=e2e exec playwright test --project=nextjs-ssr",
21+
"test:e2e:angular": "pnpm --filter=@firebase-oss/ui-angular... build && E2E_PROJECT=angular-example pnpm --filter=e2e exec playwright test --project=angular-example",
22+
"test:e2e:custom-auth-server": "pnpm build:packages && E2E_PROJECT=custom-auth-server pnpm --filter=e2e exec playwright test --project=custom-auth-server",
2323
"test:watch": "pnpm --filter=@firebase-oss/ui-core run test:unit:watch & pnpm --filter=@firebase-oss/ui-react run test:unit:watch & pnpm --filter=@firebase-oss/ui-angular run test:watch",
2424
"version:bump:all": "pnpm --filter=@firebase-oss/ui-core run version:bump && pnpm --filter=@firebase-oss/ui-translations run version:bump && pnpm --filter=@firebase-oss/ui-react run version:bump && pnpm --filter=@firebase-oss/ui-styles run version:bump && pnpm --filter=@firebase-oss/ui-angular run version:bump",
2525
"publish:tags:all": "pnpm i && pnpm --filter=@firebase-oss/ui-core run publish:tags && pnpm --filter=@firebase-oss/ui-translations run publish:tags && pnpm --filter=@firebase-oss/ui-react run publish:tags && pnpm --filter=@firebase-oss/ui-styles run publish:tags && pnpm --filter=@firebase-oss/ui-angular run publish:tags",

scripts/e2e-run.mjs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ function runExample(example) {
4848
env: {
4949
...process.env,
5050
E2E_PROJECT: example,
51-
E2E_SKIP_BUILD_PACKAGES: "1",
5251
E2E_KEEP_EMULATOR: "1",
5352
},
5453
});

0 commit comments

Comments
 (0)