Files
phaseflow/e2e/pocketbase-harness.test.ts
Petru Paler 8c59b3bd67
Some checks failed
CI / quality (push) Failing after 29s
Deploy / deploy (push) Successful in 2m37s
Add self-contained e2e test harness with ephemeral PocketBase
Previously, 15 e2e tests were skipped because TEST_USER_EMAIL and
TEST_USER_PASSWORD env vars weren't set. Now the test harness:

- Starts a fresh PocketBase instance in /tmp on port 8091
- Creates admin user, collections, and API rules automatically
- Seeds test user with period data for authenticated tests
- Cleans up temp directory after tests complete

Also fixes:
- Override toggle tests now use checkbox role (not button)
- Adds proper wait for OVERRIDES section before testing toggles
- Suppresses document.cookie lint warning with explanation

Test results: 64 e2e tests pass, 1014 unit tests pass

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-13 09:38:24 +00:00

141 lines
3.9 KiB
TypeScript

// ABOUTME: Integration tests for the PocketBase e2e test harness.
// ABOUTME: Verifies the harness can start, setup, and stop PocketBase instances.
// @vitest-environment node
import PocketBase from "pocketbase";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import {
DEFAULT_CONFIG,
getState,
type HarnessState,
start,
stop,
} from "./pocketbase-harness";
describe("pocketbase-harness", () => {
describe("start/stop lifecycle", () => {
let state: HarnessState;
beforeAll(async () => {
state = await start();
}, 60000);
afterAll(async () => {
await stop();
});
it("returns a valid harness state", () => {
expect(state).toBeDefined();
expect(state.url).toBe(`http://127.0.0.1:${DEFAULT_CONFIG.port}`);
expect(state.dataDir).toContain("pocketbase-e2e-");
expect(state.process).toBeDefined();
});
it("getState returns the current state while running", () => {
const currentState = getState();
expect(currentState).toBe(state);
});
it("PocketBase is accessible at the expected URL", async () => {
const response = await fetch(`${state.url}/api/health`);
expect(response.ok).toBe(true);
});
it("admin can authenticate", async () => {
const pb = new PocketBase(state.url);
pb.autoCancellation(false);
const auth = await pb
.collection("_superusers")
.authWithPassword(
DEFAULT_CONFIG.adminEmail,
DEFAULT_CONFIG.adminPassword,
);
expect(auth.token).toBeDefined();
});
it("test user can authenticate", async () => {
const pb = new PocketBase(state.url);
pb.autoCancellation(false);
const auth = await pb
.collection("users")
.authWithPassword(
DEFAULT_CONFIG.testUserEmail,
DEFAULT_CONFIG.testUserPassword,
);
expect(auth.token).toBeDefined();
expect(auth.record.email).toBe(DEFAULT_CONFIG.testUserEmail);
});
it("test user has period data configured", async () => {
const pb = new PocketBase(state.url);
pb.autoCancellation(false);
await pb
.collection("users")
.authWithPassword(
DEFAULT_CONFIG.testUserEmail,
DEFAULT_CONFIG.testUserPassword,
);
const user = pb.authStore.record;
expect(user).toBeDefined();
expect(user?.lastPeriodDate).toBeDefined();
expect(user?.cycleLength).toBe(28);
expect(user?.timezone).toBe("UTC");
});
it("period_logs collection exists with test data", async () => {
const pb = new PocketBase(state.url);
pb.autoCancellation(false);
await pb
.collection("users")
.authWithPassword(
DEFAULT_CONFIG.testUserEmail,
DEFAULT_CONFIG.testUserPassword,
);
const userId = pb.authStore.record?.id;
const logs = await pb
.collection("period_logs")
.getList(1, 10, { filter: `user="${userId}"` });
expect(logs.totalItems).toBeGreaterThan(0);
expect(logs.items[0].startDate).toBeDefined();
});
it("dailyLogs collection exists", async () => {
const pb = new PocketBase(state.url);
pb.autoCancellation(false);
await pb
.collection("_superusers")
.authWithPassword(
DEFAULT_CONFIG.adminEmail,
DEFAULT_CONFIG.adminPassword,
);
const collections = await pb.collections.getFullList();
const collectionNames = collections.map((c) => c.name);
expect(collectionNames).toContain("period_logs");
expect(collectionNames).toContain("dailyLogs");
});
});
describe("after stop", () => {
it("getState returns null after stop", async () => {
// Start and immediately stop
await start({ ...DEFAULT_CONFIG, port: 8092 });
await stop();
const state = getState();
expect(state).toBeNull();
}, 60000);
});
});