import { FirestoreServer } from "@firestore-emulator/server"; import type { EnvironmentContext, JestEnvironmentConfig, } from "@jest/environment"; import { findFreePorts } from "find-free-ports"; import { TestEnvironment } from "jest-environment-node"; import type { FirestoreEmulatorEnvironmentConfig } from "../types"; export default class FirestoreEmulatorEnvironment extends TestEnvironment { private server: FirestoreServer; constructor( config: FirestoreEmulatorEnvironmentConfig & JestEnvironmentConfig, context: EnvironmentContext, ) { super(config, context); this.server = new FirestoreServer(); } override async setup() { await super.setup(); let tryCount = 0; while (tryCount < 50) { const [port] = await findFreePorts(1); if (!port) throw new Error("Could not find a free port"); try { await this.server.start(port); this.global.emulator = { host: `0.0.0.0:${port}`, port, state: this.server.state, }; return; } catch (err) { if (!(err instanceof Error)) throw err; if (!err.message.startsWith("No address added out of total")) throw err; } tryCount++; } throw new Error("Could not find a free port"); } override async teardown() { this.server.stop(); await super.teardown(); } }