aboutsummaryrefslogtreecommitdiff
path: root/test-suite/_lib.js
blob: c6d121cb4b001488684e86ee05735a91945bd06c (plain)
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
// Tiny shared harness for challenge pages.
// Each page calls Challenge.init({id, instructions}) then Challenge.pass()/fail()
// based on its own listeners.
(function () {
  const events = [];
  const state = {
    id: null,
    verdict: "PENDING",
    reason: [],
    events,
  };

  function render() {
    const el = document.getElementById("__verdict");
    if (!el) return;
    el.textContent = state.verdict;
    el.dataset.verdict = state.verdict;
    el.style.background =
      state.verdict === "PASS" ? "#1f7a1f" :
      state.verdict === "FAIL" ? "#a11" : "#444";
    el.style.color = "#fff";
    const r = document.getElementById("__reason");
    if (r) r.textContent = state.reason.join("\n");
  }

  function log(name, detail) {
    events.push({ t: performance.now(), name, ...detail });
    if (events.length > 500) events.shift();
  }

  const Challenge = {
    init({ id, instructions }) {
      state.id = id;
      document.title = `[${state.verdict}] ${id}`;
      const root = document.body;
      const bar = document.createElement("div");
      bar.style.cssText =
        "position:sticky;top:0;background:#111;color:#eee;padding:8px 12px;font:13px monospace;border-bottom:1px solid #333;z-index:9999";
      bar.innerHTML = `
        <b>${id}</b>
        <span id="__verdict" style="margin-left:8px;padding:2px 8px;border-radius:4px;background:#444">PENDING</span>
        <span style="margin-left:12px;opacity:.7">${instructions}</span>
        <pre id="__reason" style="white-space:pre-wrap;margin:6px 0 0;color:#bbb;font:12px monospace"></pre>
      `;
      root.insertBefore(bar, root.firstChild);
      window.__challenge = id;
      window.__verdict = state.verdict;
      window.__reason = state.reason;
      window.__events = state.events;
      render();
    },
    pass(...reasons) {
      if (state.verdict === "FAIL") return; // sticky
      state.verdict = "PASS";
      state.reason.push(...reasons.map((r) => "✓ " + r));
      window.__verdict = state.verdict;
      document.title = `[PASS] ${state.id}`;
      persist(); render();
    },
    fail(...reasons) {
      state.verdict = "FAIL";
      state.reason.push(...reasons.map((r) => "✗ " + r));
      window.__verdict = state.verdict;
      document.title = `[FAIL] ${state.id}`;
      persist(); render();
    },
    log,
    state,
  };

  function persist() {
    try {
      localStorage.setItem(
        "pi-chrome-suite:" + state.id,
        JSON.stringify({ verdict: state.verdict, reason: state.reason, ts: Date.now() })
      );
    } catch {}
  }

  window.Challenge = Challenge;
})();