From 9b60e985022d8b6fa6c643cbf6106c63bb0df0f2 Mon Sep 17 00:00:00 2001 From: codeGlaze Date: Mon, 5 Oct 2026 04:21:32 +0000 Subject: [PATCH 1/4] cljs-harness: pass a green full-suite run again A second exit rule (from 57d0c7ca, reached integration with #48) required a 'Ran N tests' line, which the full-suite page never prints (it reports 'Totals'), so every full run exited 1, green or not. The exit now uses the summary verdict computed just above, plus no FAIL/ERROR. Checked both ways: 606 passing tests exit 0; one planted failure exits 1. --- test/e2e/cljs-harness.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/e2e/cljs-harness.js b/test/e2e/cljs-harness.js index b8a81a738..8a6415303 100644 --- a/test/e2e/cljs-harness.js +++ b/test/e2e/cljs-harness.js @@ -28,6 +28,5 @@ const srv=http.createServer((q,r)=>{const u=decodeURIComponent(q.url.split('?')[ fs.writeFileSync('target/test/cljs-run.log',all); // Green only on a complete summary reading zero failures and zero errors; a // timeout or crash leaves no summary and must not pass. - const last=tot.slice(-1)[0]||''; const clean=ran.length>0&&/^0 failures, 0 errors\./.test(last); - process.exitCode=clean&&fails.length===0?0:1; + process.exitCode=passed&&fails.length===0?0:1; await br.close();srv.close();})(); From 6b6c140a35ae53ec847cd9354727b4797ddbb561 Mon Sep 17 00:00:00 2001 From: codeGlaze Date: Wed, 7 Oct 2026 02:44:28 +0000 Subject: [PATCH 2/4] CI: run the ClojureScript suite in headless Chromium The JVM suite runs on integration through locale.yml, but the builder's wiring (events, interceptors, subscriptions) is tested only in the browser suite, which ran by hand. browser-suite.yml compiles the test build (lein fig:test) and runs test/e2e/cljs-harness.js on pushes and pull requests to integration, develop and main; the harness exits 0 only when every test passes. cljs-harness.js serves the runner page itself when target/test has none (fig:test writes only the scripts), so neither CI nor a person has to write it by hand. Checked locally from a clean worktree: 606 tests, exit 0. --- .github/workflows/browser-suite.yml | 57 +++++++++++++++++++++++++++++ test/e2e/cljs-harness.js | 3 ++ 2 files changed, 60 insertions(+) create mode 100644 .github/workflows/browser-suite.yml diff --git a/.github/workflows/browser-suite.yml b/.github/workflows/browser-suite.yml new file mode 100644 index 000000000..1b515cf1e --- /dev/null +++ b/.github/workflows/browser-suite.yml @@ -0,0 +1,57 @@ +# Runs the ClojureScript test suite in headless Chromium (lein fig:test, then +# test/e2e/cljs-harness.js; docs/kb/cljs-headless-harness.md). +# +# The JVM suite runs on integration through locale.yml, but the builder's wiring +# (re-frame events, interceptors, subscriptions) is tested only in the browser, +# so until this ran a change that broke it passed CI. + +name: Browser suite + +on: + push: + branches: [integration, develop, main] + pull_request: + branches: [integration, develop, main] + workflow_dispatch: + +permissions: + contents: read + +jobs: + cljs-suite: + name: ClojureScript suite in Chromium + runs-on: ubuntu-latest + timeout-minutes: 25 + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: '21' + + # Pinned to the version locale.yml and continuous-integration.yml use. + - name: Install Leiningen + run: | + curl -fsSL -o "$HOME/lein" \ + https://raw.githubusercontent.com/technomancy/leiningen/2.11.2/bin/lein + chmod +x "$HOME/lein" + echo "$HOME" >> "$GITHUB_PATH" + "$HOME/lein" version + + - uses: actions/setup-node@v4 + with: + node-version: '22' + + # package.json declares Playwright; its own Chromium, which find-chrome falls back to. + - name: Install Playwright and Chromium + run: | + npm install --no-audit --no-fund + npx playwright install --with-deps chromium + + - name: Compile the test build + run: lein fig:test + + # Exits 0 only when every test passes and no FAIL or ERROR is reported. + - name: Run the suite headless + run: node test/e2e/cljs-harness.js diff --git a/test/e2e/cljs-harness.js b/test/e2e/cljs-harness.js index 8a6415303..d0e168102 100644 --- a/test/e2e/cljs-harness.js +++ b/test/e2e/cljs-harness.js @@ -2,7 +2,10 @@ const http=require('http'),fs=require('fs'),path=require('path');const {chromium}=require('playwright'); const {findChrome}=require('../browser/lib/find-chrome'); const ROOT=path.resolve('target/test'); +// fig:test writes only the scripts; the page that runs them is served from here unless one exists. +const RUNNER='
'; const srv=http.createServer((q,r)=>{const u=decodeURIComponent(q.url.split('?')[0]);const f=path.join(ROOT,u==='/'?'runner-all.html':u); + if(f===path.join(ROOT,'runner-all.html')&&!fs.existsSync(f)){r.writeHead(200,{'Content-Type':'text/html; charset=utf-8'});return r.end(RUNNER);} if(!f.startsWith(ROOT)||!fs.existsSync(f)||fs.statSync(f).isDirectory()){r.writeHead(404);return r.end();} r.writeHead(200,{'Content-Type':f.endsWith('.js')?'application/javascript; charset=utf-8':f.endsWith('.html')?'text/html; charset=utf-8':'application/octet-stream'});fs.createReadStream(f).pipe(r);}); (async()=>{await new Promise(r=>srv.listen(0,r));const port=srv.address().port; From bdc29e6f3efd005c0bf5e5327be0fb420ddb44a9 Mon Sep 17 00:00:00 2001 From: codeGlaze Date: Wed, 7 Oct 2026 22:29:16 +0000 Subject: [PATCH 3/4] CI: run lint, tests and the app build on integration too continuous-integration.yml ran only for develop and main, so no PR into integration (#47 to #56) was linted or had the app build checked; only locale.yml's JVM suite ran there. Integration is added to its push and pull_request branches. The dependency-graph job keeps to develop and main, as before. Checked on integration's code: lint 0 errors 0 warnings, fig:build clean. --- .github/workflows/continuous-integration.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 83aa9268d..7e8ea72da 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -6,9 +6,9 @@ name: CI on: push: - branches: [develop, main] + branches: [integration, develop, main] pull_request: - branches: [develop, main] + branches: [integration, develop, main] workflow_dispatch: permissions: @@ -134,7 +134,8 @@ jobs: name: Submit Clojure dependencies runs-on: ubuntu-latest needs: detect-stack - if: github.event_name != 'pull_request' + # Not integration: alerts read the default branch, and this job ran only for develop and main. + if: github.event_name != 'pull_request' && github.ref_name != 'integration' permissions: contents: write steps: From 515dfb2d36d3e3429f92c0a19a99ad2b5975d031 Mon Sep 17 00:00:00 2001 From: codeGlaze Date: Thu, 8 Oct 2026 08:58:07 +0000 Subject: [PATCH 4/4] cljs-harness: a pass needs a positive test count Figwheel's page says "All Tests Passed" when it finds or loads no tests at all, so a test runner that lost its namespaces would have passed CI. The verdict now also needs a positive count in the Totals block ("606 Tests"). The "Ran N tests" path and the FAIL/ERROR check are unchanged. Checked: a full run (606 tests) exits 0; "0 Tests", empty totals and a failing verdict all read as not passed. CodeRabbit, PR #59. --- test/e2e/cljs-harness.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/e2e/cljs-harness.js b/test/e2e/cljs-harness.js index d0e168102..d0e9f677a 100644 --- a/test/e2e/cljs-harness.js +++ b/test/e2e/cljs-harness.js @@ -21,7 +21,8 @@ const srv=http.createServer((q,r)=>{const u=decodeURIComponent(q.url.split('?')[ const totals=ti>=0?lines.slice(ti+1,lines.indexOf('Hide/Show Passing',ti)).join(', '):''; const verdict=ti>0?lines[ti-1]:''; console.log('SUMMARY:',ran.slice(-1)[0]||(totals?`${verdict}: ${totals}`:'(none)'),tot.slice(-1)[0]||''); - const passed=ran.length?/ 0 failures, 0 errors/.test(' '+(tot.slice(-1)[0]||'')):verdict==='All Tests Passed'; + // Figwheel says "All Tests Passed" for zero tests too (none found or loaded), so a pass needs a count. + const passed=ran.length?/ 0 failures, 0 errors/.test(' '+(tot.slice(-1)[0]||'')):verdict==='All Tests Passed'&&/\b[1-9]\d*\s+Tests\b/.test(totals); process.exitCode=passed?0:1; // The auto-testing page marks each failed assertion with a .test-fail node inside its test's node. const shown=await pg.evaluate(()=>[...document.querySelectorAll('.test-fail')].map(n=>