all repos — sz-chrome-remote-cdp @ master

pi-browser-harness, patched to drive a Chrome on another host over CDP, with castle_cdp_search web search

test/profile/launch-test.ts (view raw)

 1
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
import { test, before, after, describe } from "node:test";
import assert from "node:assert/strict";
import { existsSync, mkdtempSync, readdirSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { fileURLToPath } from "node:url";
import { openProfileWindow } from "../../src/profile/launch";

describe("openProfileWindow's failure reporting", () => {
  let root: string;

  before(() => {
    root = mkdtempSync(join(tmpdir(), "pi-launch-"));
  });

  after(() => {
    rmSync(root, { recursive: true, force: true });
  });

  describe("L1", () => {
    const missing = (): string => join(root, "chrome (deleted)");

    test("L1: a missing executable fails the launch", async () => {
      const r = await openProfileWindow({ exePath: missing(), profileDir: "Default" });
      assert.ok(!r.success);
    });

    test("L1: the error names the path that could not be launched", async () => {
      const r = await openProfileWindow({ exePath: missing(), profileDir: "Default" });
      assert.ok(!r.success);
      assert.ok(r.error.includes(missing()));
    });

    test("L1: the error carries spawn's own cause", async () => {
      const r = await openProfileWindow({ exePath: missing(), profileDir: "Default" });
      assert.ok(!r.success);
      assert.ok(r.error.includes("ENOENT"));
    });
  });

  test(
    "L2: a non-executable file fails the launch",
    { skip: process.platform === "win32" || process.getuid?.() === 0 },
    async () => {
      const notExec = join(root, "not-executable");
      writeFileSync(notExec, "#!/bin/sh\n", { mode: 0o644 });
      const r = await openProfileWindow({ exePath: notExec, profileDir: "Default" });
      assert.ok(!r.success);
    },
  );

  describe("L3", () => {
    let before_: string | undefined;

    before(() => {
      before_ = process.env["TMPDIR"];
      process.env["TMPDIR"] = root;
    });

    after(() => {
      if (before_ === undefined) delete process.env["TMPDIR"];
      else process.env["TMPDIR"] = before_;
    });

    test("L3: launch failed as set up", async () => {
      const r = await openProfileWindow({ exePath: join(root, "absent"), profileDir: "Default" });
      assert.ok(!r.success);
    });

    test("L3: no handshake page is left on disk after a failed launch", async () => {
      await openProfileWindow({ exePath: join(root, "absent"), profileDir: "Default" });
      const leftovers = readdirSync(root).filter((n) => n.startsWith("pi-harness-"));
      assert.equal(leftovers.length, 0);
    });
  });

  describe("L4", () => {
    let r: Awaited<ReturnType<typeof openProfileWindow>>;

    before(async () => {
      const stub = join(root, "stub-browser");
      writeFileSync(stub, "#!/bin/sh\nexit 0\n", { mode: 0o755 });
      r = await openProfileWindow({ exePath: stub, profileDir: "Default" });
    });

    test("L4: a startable binary yields a handle", () => {
      assert.ok(r.success);
    });

    test("L4: the sentinel page exists before the browser is polled", () => {
      assert.ok(r.success);
      if (r.success) {
        const sentinel = fileURLToPath(r.data.sentinelUrl);
        assert.ok(existsSync(sentinel));
      }
    });

    test("L4: cleanup removes the sentinel page", async () => {
      assert.ok(r.success);
      if (r.success) {
        const sentinel = fileURLToPath(r.data.sentinelUrl);
        await r.data.cleanup();
        assert.ok(!existsSync(sentinel));
      }
    });

    test("L4: kill is safe to call twice", () => {
      assert.ok(r.success);
      if (r.success) {
        r.data.kill();
        r.data.kill();
      }
    });
  });
});