208 lines · 8.9 KB
#!/usr/bin/env bun
/**
 * Browser e2e for the workspace editor: signs in, presses `.`, edits a file inside the sandboxed frame,
 * commits, and verifies the commit through the editor API. Drives a headless Chrome over CDP.
 * Usage: BASE=http://localhost:3000 GITFOR_TOKEN=... E2E_LOGIN=... E2E_PASSWORD=... bun run scripts/e2e-editor-browser.ts
 */
import { spawn } from "node:child_process";
import { mkdtempSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";

const BASE = process.env.BASE ?? "http://localhost:3000";
const PAT = process.env.GITFOR_TOKEN ?? "";
const LOGIN = process.env.E2E_LOGIN ?? "";
const PASSWORD = process.env.E2E_PASSWORD ?? "";
const CHROME = process.env.CHROME ?? "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome";
const DEBUG_PORT = 9333;
const POLL_MS = 250;
const WAIT_MS = 30_000;
const HTTP_CREATED = 201;
const HYDRATE_MS = 3000;
if (!PAT || !LOGIN || !PASSWORD) throw new Error("Set GITFOR_TOKEN, E2E_LOGIN and E2E_PASSWORD");

function check(condition: unknown, message: string): asserts condition {
  if (!condition) throw new Error(`FAIL: ${message}`);
  console.log(`ok - ${message}`);
}

async function api(path: string, token: string, method = "GET", body?: unknown) {
  const response = await fetch(`${BASE}${path}`, {
    method,
    headers: { authorization: `Bearer ${token}`, "content-type": "application/json" },
    body: body === undefined ? undefined : JSON.stringify(body),
  });
  const text = await response.text();
  return { status: response.status, body: text ? JSON.parse(text) : null };
}

const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));