Skip to content
File

Blob: tests/e2e/global-setup.ts

typescript82 lines
1import { mkdtemp, rm, writeFile } from "node:fs/promises";
2import { tmpdir } from "node:os";
3import { join } from "node:path";
4 
5import {
6 applyMigrations,
7 startDevServer,
8 stopDevServer,
9 closeContextLogs,
10 printFailureContext,
11 printLogTails,
12 type IntegrationContext,
13} from "../integration/queue-runner/harness";
14import { startMockOidcProvider, type MockOidcServer } from "../helpers/oidc-mock";
15 
16export const E2E_CONTEXT_PATH_ENV = "ANVIL_E2E_CONTEXT_PATH";
17 
18export interface E2eContext {
19 baseUrl: string;
20 oidcIssuer: string;
21 tempDir: string;
22}
23 
24export default async function globalSetup(): Promise<() => Promise<void>> {
25 const tempDir = await mkdtemp(join(tmpdir(), "anvil-e2e-"));
26 console.log(`[e2e] temp state: ${tempDir}`);
27 
28 let mockOidc: MockOidcServer | null = null;
29 let ctx: IntegrationContext | null = null;
30 
31 try {
32 mockOidc = await startMockOidcProvider();
33 await applyMigrations(tempDir);
34 ctx = await startDevServer(tempDir, mockOidc.issuer);
35 } catch (error) {
36 if (ctx) {
37 await stopDevServer(ctx.serverProcess);
38 await closeContextLogs(ctx);
39 }
40 if (mockOidc) {
41 await mockOidc.close();
42 }
43 await rm(tempDir, { recursive: true, force: true });
44 throw error;
45 }
46 if (!ctx || !mockOidc) {
47 throw new Error("E2E setup did not initialize the dev server and OIDC provider.");
48 }
49 
50 const e2eContext: E2eContext = {
51 baseUrl: ctx.baseUrl,
52 oidcIssuer: mockOidc.issuer,
53 tempDir,
54 };
55 
56 const contextPath = join(tempDir, ".e2e-context.json");
57 await writeFile(contextPath, JSON.stringify(e2eContext));
58 
59 process.env.ANVIL_E2E_BASE_URL = ctx.baseUrl;
60 process.env[E2E_CONTEXT_PATH_ENV] = contextPath;
61 
62 return async () => {
63 await teardown(ctx, tempDir, mockOidc);
64 };
65}
66 
67async function teardown(ctx: IntegrationContext, tempDir: string, mockOidc: MockOidcServer): Promise<void> {
68 await stopDevServer(ctx.serverProcess);
69 await closeContextLogs(ctx);
70 await mockOidc.close();
71 
72 if (process.env.ANVIL_E2E_PRESERVE === "1") {
73 printFailureContext(ctx);
74 await printLogTails(ctx);
75 console.log(`[e2e] temp state preserved: ${tempDir}`);
76 } else {
77 await rm(ctx.devVarsPath, { force: true });
78 await rm(tempDir, { recursive: true, force: true });
79 console.log(`[e2e] temp state cleaned up`);
80 }
81}