756582322f8a53fef19e8c24ba902e353ba3623f
chmalee
  Thu Aug 27 14:38:34 2026 -0700
uiTest: shared browser UI test harness, plus an hgTracks example, refs #38188

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

diff --git src/hg/utils/uiTest/tests/assert.js src/hg/utils/uiTest/tests/assert.js
new file mode 100644
index 00000000000..c54cf260d15
--- /dev/null
+++ src/hg/utils/uiTest/tests/assert.js
@@ -0,0 +1,39 @@
+// A twenty-line harness for the harness. These tests parse strings and stat
+// files -- no browser, no network -- so they are the one tests/ directory here
+// whose `make test` really runs.
+
+'use strict';
+
+let pass = 0;
+const bad = [];
+
+function ok(cond, what) {
+    if (cond) {
+        pass++;
+    } else {
+        bad.push(what);
+        console.log(`FAIL  ${what}`);
+    }
+}
+
+function is(got, want, what) {
+    ok(got === want, `${what} (got ${JSON.stringify(got)}, wanted ${JSON.stringify(want)})`);
+}
+
+function throws(fn, re, what) {
+    try {
+        fn();
+    } catch (e) {
+        ok(re.test(e.message), `${what} (message was "${e.message}")`);
+        return e;
+    }
+    ok(false, `${what} (nothing was thrown)`);
+    return null;
+}
+
+function done(name) {
+    console.log(`${name}: ${pass} passed, ${bad.length} failed`);
+    process.exit(bad.length ? 1 : 0);
+}
+
+module.exports = { ok, is, throws, done };