Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions .github/workflows/browser-suite.yml
Original file line number Diff line number Diff line change
@@ -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
7 changes: 4 additions & 3 deletions .github/workflows/continuous-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down
9 changes: 6 additions & 3 deletions test/e2e/cljs-harness.js
Original file line number Diff line number Diff line change
Expand Up @@ -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='<body><div id="app-auto-testing"></div><script src="js/test-auto-testing.js"></script></body>';
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;
Expand All @@ -18,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=>
Expand All @@ -28,6 +32,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;
Comment thread
codeGlaze marked this conversation as resolved.
Resolved
await br.close();srv.close();})();
Loading