Testing & CI
Source-verified map of how the FaceKom v2 web repos test themselves: unit tests (Jest), e2e (Playwright, vuer_oss only), linting (ESLint StandardJS), and security audit. Plus the CI pipelines that gate every PR.
See also: INDEX · running-the-stack · devel-update-workflow · conventions-and-glossary · vuer_oss · vuer_css
Read this first — the e2e database wipe
vuer_ossPlaywright e2e tests CAN ERASE THE DATABASE. The dedicated e2e profile runs the server withNODE_ENV="dev"(vuer_oss/supervisor_vuer_oss_e2e_test.conf:31) and the suites perform destructive setup/teardown. Never point e2e at a real, shared, or production database. Run it only against a throwaway/isolated DB. Cross-ref vuer_oss. The Playwright config registersglobalTeardown(vuer_oss/playwright.config.ts:187) andforbidOnlyis enabled in CI (:20).
1. Test types per repo
| Repo | Unit (Jest) | E2e (Playwright) | Lint (ESLint) | Security audit |
|---|---|---|---|---|
vuer_oss | yes — test:unit | yes — test:e2e | yes — lint | in CI (yarn audit + improved-yarn-audit) |
vuer_css | yes — test:unit | no | yes — lint | yes — dedicated audit.yaml workflow |
esign_oss | yes — test:unit / test:e2e (Jest) | no Playwright | yes — lint | in CI — audit job runs improved-yarn-audit --min-severity critical |
esign_css | no unit script | no | yes — lint (test = lint-only) | in CI — audit job runs improved-yarn-audit --min-severity critical |
portal_css | Jest configured, no unit script | no | yes — lint (test = lint-only) | yes — Travis yarn audit |
vuer_oss — Unit (Jest 30)
- Run:
yarn test:unit→"test:unit": "yarn node --experimental-vm-modules $(yarn bin jest) --config ./jest.config-unit.js"(vuer_oss/package.json:17). - Full Jest (all, incl. coverage):
yarn jest→--config ./jest.config.js(vuer_oss/package.json:16). - Where tests live / what’s matched:
jest.config-unit.jsmatches<rootDir>/test/tests/unit/**/*.test.[jt]s?(x)and ignores/web/,/e2e/,/node_modules/,/yarn-offline-cache/(vuer_oss/jest.config-unit.js:6-12). Transform ists-jestfor.ts; coverage viav8intotest/coverage/jest;testTimeout: 10000(:13-38). - Counts (cross-ref vuer_oss): Jest 30, 349 unit / 396 total test files.
vuer_css — Unit (Jest 30)
- Run:
yarn test:unit→"test:unit": "yarn jest unit/* --forceExit", wherejest="jest --config ./test/jest.config.js --runInBand --forceExit"(vuer_css/package.json:11-12). - Config:
test/jest.config.js—rootDiris repo root, ignores/web/+/node_modules/+/yarn-offline-cache/,v8coverage (lcovonly),testTimeout: 30000(vuer_css/test/jest.config.js:3-13). - Where tests live:
test/tests/unit/**(e.g.test/tests/unit/api/can-identify.test.js). Count: 115 unit tests (cross-ref vuer_css).
esign_oss — Unit + e2e are both Jest (no Playwright)
"test": "jest --config ./test/jest.config.js --runInBand --forceExit"(esign_oss/package.json:18)."test:unit": "yarn node --experimental-vm-modules $(yarn bin jest) --config ./test/jest.config.js"(:19)."test:e2e": "yarn jest e2e/* --forceExit"(:20) — note “e2e” here is a Jest path glob, not Playwright.
vuer_oss — E2e (Playwright 1.56)
- Run:
yarn test:e2e→"test:e2e": "yarn playwright test"(vuer_oss/package.json:18).@playwright/testpinned to1.56.1(vuer_oss/package.json:175). - Config:
vuer_oss/playwright.config.ts.fullyParallel: truebutworkers: 1(serial) andretries: 0(:19-22); reporterslist+html(:23); media faked via Chromium flags--use-fake-ui-for-media-stream/--use-fake-device-for-media-stream,--disable-web-security,camera+microphonepermissions granted (:28-37). - Ordered dependency chain (each project
dependencieson the prior) drives a stateful scenario:Setup→OpenHoursSetup→Auditlog→Videochat→VideochatReplay→ {VideochatInspect,FourEye} →SelfServiceVideochat→Core→Customization→SelfServiceV2→ {SelfServiceOssPages,Archive} →EmergencyShutdown→WaitingList(vuer_oss/playwright.config.ts:40-186). - Auth handled by setup project writing storage state to
./test/tests/playwright/.auth/user.json(andguest.json) (:12, :43, :60, :90). - Test sources:
test/tests/e2e/**+test/tests/playwright/**+customization/test/tests/e2e/**(e.g.test/tests/e2e/videochat.test.ts,archive.test.ts).
The dedicated e2e supervisor profile
vuer_oss/supervisor_vuer_oss_e2e_test.conf is the process profile that brings up the full backend so Playwright can drive a live instance. It runs, under supervisord:
nginx(:5),redis(:21), and thevuer_ossNode processes, all withenvironment=NODE_ENV="dev":vuer_ossweb:npx nyc node server.js(:29-32) — wrapped innycto collect coverage during e2e.- plus
vuer_integration_log(integrationLog.js),vuer_media(media.js),vuer_oss_convert(convert.js),vuer_cron(cron.js),vuer_background(background.js),vuer_oss_storage(storage.js) — eachnpx nyc node …(:50-174).
e2e is NOT run in PR CI
No PR workflow invokes
test:e2e/Playwright. Thevuer_ossPR pipeline runs lint + unit + audit + Sonar + build only (see §3). E2e is a manual/dedicated-profile activity (and is destructive — see top warning).
Lint — ESLint StandardJS (all repos)
Cross-ref conventions-and-glossary: StandardJS style, no semicolons, --max-warnings 0. The lint scripts:
vuer_oss:"lint": "eslint . --max-warnings 0 --ignore-pattern \"test/*\" && echo 'yarn eslint --max-warnings 0'"(vuer_oss/package.json:14).vuer_css: same shape,--max-warnings 0 --ignore-pattern "test/*"(vuer_css/package.json:13).esign_oss: same shape (esign_oss/package.json:15).esign_css: same shape (esign_css/package.json:12); itstestscript is lint-only:"test": "eslint . --quiet --ignore-pattern \"test/*\" && echo 'eslint --quiet'"(:11).portal_css:"lint": "eslint . ./bin/**/* ./bin/* && echo 'npm run lint: OK'"and"test": "npm run lint --silent && echo 'npm test: OK'"— i.e.npm testis lint-only (portal_css/package.json:12-13).- All repos:
lint:fix=eslint . --fix && eslint --max-warnings 0 .(e.g.vuer_oss/package.json:15).
"test" ≠ unit tests in some repos
In
esign_cssandportal_css,npm/yarn testonly runs ESLint. Real unit tests usetest:unit(vuer_oss,vuer_css,esign_oss).
Security audit — improved-yarn-audit
improved-yarn-audit is a devDependency in vuer_oss (package.json:100), vuer_css (:70), esign_css (:97), and esign_oss (:77). It is actually invoked in CI: in the PR workflow audit job for vuer_oss, esign_css, and esign_oss; for vuer_css only in the push-triggered audit.yaml (its PR workflow is lint+build only); and via Travis for portal_css (yarn audit) — see §3.
2. The verified gotcha (restated)
vuer_oss Playwright e2e can erase the database
Do not run
vuer_osse2e against any real/shared/production DB. It is destructive by design (stateful chained scenarios + global teardown). Use a disposable DB only. Cross-ref vuer_oss and the top-of-page callout.
3. CI pipeline (what runs on every PR)
vuer_oss — .github/workflows/pull-request.yaml
- Trigger:
pull_request; concurrency cancels in-progress per PR (:4-8). Node 24 (single version) viaenv.NODE_VERSION: "24"(:10-11). - Jobs (
vuer_oss/.github/workflows/pull-request.yaml):- lint —
yarn --frozen-lockfilethenyarn lint(:18-46). - test (Unit Tests) — installs deps, computes changed files via
tj-actions/changed-files@v47.0.5, then runs only related tests:yarn test:unit --maxWorkers=6 --findRelatedTests <changed files> --json --coverage --outputFile=jest-results.json(:48-72). Uploadslcov.info(:81-86). - audit —
yarn audit --groups dependencies(non-fatal) thenyarn run improved-yarn-audit --min-severity critical(:88-117). - sonar (SonarQube Scan) —
needs: test; downloads lcov, runsSonarSource/sonarqube-scan-action@v6with PR decoration (:125-160). - build —
needs: [lint, test, audit, sonar];yarn build(:169-191).
- lint —
vuer_oss unit CI is incremental
CI runs
--findRelatedTestsagainst the PR’s changed files, not the whole suite — full local run isyarn test:unitwithout that flag.
vuer_css — two workflows
.github/workflows/pull-request.yaml— a single joblint-and-buildwith a real Node matrix[22, 24](vuer_css/.github/workflows/pull-request.yaml:7-11). Steps:yarn install --frozen-lockfile→yarn lint→yarn buildonly (:23-30). No unit-test job, no audit job, no Sonar job —test:unitis not run in PR CI here..github/workflows/audit.yaml— separate “Github CI - Branch” workflow that triggers on push todevelandcustomization/*(not PRs) (vuer_css/.github/workflows/audit.yaml:3-7). Node 22 (:19). It runsyarn audit --groups dependenciesthenyarn run improved-yarn-audit --min-severity critical --exclude GHSA-wrh9-cjv3-2hpw,GHSA-vqfx-gj96-3w95,GHSA-f598-mfpv-gmfx(:28-33), and a guard that fails if executables are found outside allowed folders (:38-44).
Node matrix nuance
It is
vuer_csswhose PR workflow uses the real[22, 24]matrix (vuer_css/.github/workflows/pull-request.yaml:9-11); the Node 22 path also appears in its push-triggeredaudit.yaml(:19). The other repos’ PR workflows pin Node 24 only viaenv.NODE_VERSION: "24":vuer_oss(:11),esign_css(:11),esign_oss(:11). So repo docs’ “CI Node 22 & 24” note forvuer_cssis correct.
esign_css — .github/workflows/pull-request.yaml
- “Pull Request” on
pull_request, Node 24 (single version) viaenv.NODE_VERSION: "24"(esign_css/.github/workflows/pull-request.yaml:10-11) — no matrix. Four jobs: lint (yarn lint,:36-46), audit (yarn audit --groups dependenciesthenyarn run improved-yarn-audit --min-severity critical,:66-76), sonar (SonarQube scan,:85-112), and build withneeds: [lint, audit, sonar](yarn build,:114-143). No unit-test job (esign_css has no unit script), but the audit is wired into PR CI.
esign_oss — .github/workflows/pull-request.yaml
- “Pull Request” on
pull_request, Node 24 (esign_oss/.github/workflows/pull-request.yaml:10-11). Same 5-job shape asvuer_oss: lint, test (incremental viatj-actions/changed-files@v47.0.5+yarn test:unit --maxWorkers=6 --findRelatedTests <changed files> --json --coverage,:56-72), audit (improved-yarn-audit --min-severity critical,:111-113), sonar (needs: test), build (needs: [lint, test, audit, sonar],:172).
portal_css — Travis (.travis.yml + test/travis.sh)
- Travis CI,
dist: focal, Node 20 (portal_css/.travis.yml:6-7), Slack notifications. Runs only on branch names matching the FaceKom branch regex (devel,customization/*, or<type>/PROJ-NNN-…) (:28). Script =./test/travis.sh(:26). test/travis.sh(set -ev):npm run build→yarn install --production=false --force --frozen-lockfile→yarn audit(fails only on CRITICAL, exit code ≥ 16) →npm test(= lint-only) →git diff --exit-code→ executable-location guard (portal_css/test/travis.sh:6-28).
vuer-release — .github/workflows/autobuild.yml (release build, not test)
- “Backend - Build and Publish V2”. Trigger: push of tags matching
*@*touchingprojects/*/release/*/release.jsonorbase/release/*/release.json(vuer-release/.github/workflows/autobuild.yml:3-9). Runs on[self-hosted, docker]. - Parses the tag into
project_name@release_version, downloads thevuer-release-clirelease_toolfrom GitHub releases, thenrelease-tool gen/build/publishfor project orbase@builds, pushing images to the Harbor registry (HARBOR_USER/HARBOR_SECRET) (:16-126). This is the artifact/image build pipeline — it does not run unit/e2e/lint.
4. “How do I test my change” — per repo
Match CI before pushing
CI uses
yarn --frozen-lockfile; run the same lint/unit commands locally to catch failures early.--max-warnings 0means any ESLint warning fails the build.
vuer_oss- Unit:
yarn test:unit(matchestest/tests/unit/**). Whole-suite locally; CI only runs--findRelatedTestson changed files. - Lint:
yarn lint(oryarn lint:fix). - E2e (rare, destructive): bring up the backend via the
supervisor_vuer_oss_e2e_test.confprofile against a throwaway DB, thenyarn test:e2e. Never against shared/prod. Not part of PR CI.
- Unit:
vuer_css- Unit:
yarn test:unit(test/tests/unit/**, run-in-band). Lint:yarn lint. - Security: optional
yarn run improved-yarn-audit --min-severity criticallocally (this is what push CI does).
- Unit:
esign_oss- Unit:
yarn test:unit; “e2e” Jest glob:yarn test:e2e. Lint:yarn lint.
- Unit:
esign_css- No unit script —
yarn testandyarn lintboth run ESLint only. Build withyarn build.
- No unit script —
portal_cssnpm test/npm run lint= ESLint only. Build withnpm run build. (CI additionally runsyarn audit.)
5. Testing in the devel→update workflow
When applying an update to a client (see devel-update-workflow), you re-run that client’s tests on the update branch before merging:
- Check out the client’s update branch (per-customer fork/branch).
- Install with a frozen lockfile (mirror CI):
yarn --frozen-lockfile. - Run the gating checks CI would run for that repo:
yarn lint(StandardJS,--max-warnings 0).yarn test:unitwhere the repo has it (vuer_oss,vuer_css,esign_oss).- For
vuer_oss, optionally the destructive Playwright e2e against an isolated DB (never the client’s real data).
- Only merge once lint + unit (and any audit) pass green, matching the PR pipeline in §3.
Client data safety during updates
Because
vuer_osse2e can wipe the database, never run it against a client’s real/staging DB while validating an update branch. Use a disposable instance.
Unverified / gaps
- Coverage thresholds / Sonar quality gate pass-fail: no
coverageThresholdis set in any Jest config read; SonarQube gate behavior lives server-side (not in repo) — not verifiable here. esign_oss/esign_cssaudit IS in PR CI: both PR workflows have a dedicated audit job runningyarn run improved-yarn-audit --min-severity critical(esign_css/.github/workflows/pull-request.yaml:74-76;esign_oss/.github/workflows/pull-request.yaml:111-113).esign_csshas lint+audit+sonar+build (no unit job, since it has no unit script);esign_ossadds a unit-test job on top.- Where
esign_osse2e (Jeste2e/*) tests live and counts: script exists (package.json:20) but file locations/counts not enumerated here. - Test counts for
esign_oss,esign_css,portal_css: not cross-referenced (no per-repo counts provided in scope). portal_cssJest:test/jest.config.js+@jest/test-sequencerpresent, but nojest/test:unitscript actually runs Jest in CI (Travis runs lint+audit only). Whether Jest suites exist/run is unverified.vuer_cssPlaywright: none found (git ls-filesshows noplaywright.config.ts); e2e isvuer_oss-only.- Forward wikilinks:
[[running-the-stack]]and[[devel-update-workflow]]are referenced per task spec but not yet present in the KB at verification time.
Sources
vuer_oss/package.json:14,16,17,18,100,175— lint, jest, test:unit, test:e2e scripts; improved-yarn-audit; Playwright pin.vuer_oss/jest.config.js:1-41;vuer_oss/jest.config-unit.js:6-38— Jest roots, testMatch, ignore, ts-jest, v8 coverage, timeout.vuer_oss/playwright.config.ts:12,19-37,40-186,187— workers/retries, media flags, project dependency chain, globalTeardown.vuer_oss/supervisor_vuer_oss_e2e_test.conf:5,21,29-32,50-174— nginx/redis + vuer_oss Node processes under nyc, NODE_ENV=dev.vuer_oss/.github/workflows/pull-request.yaml:4-11,18-46,48-72,88-117,125-160,169-191— PR jobs, Node 24, findRelatedTests, audit, Sonar, build.vuer_css/package.json:6,11,12,13,70— engines, jest/test:unit/lint scripts, improved-yarn-audit.vuer_css/test/jest.config.js:3-13— config, lcovonly, timeout 30000.vuer_css/.github/workflows/pull-request.yaml:7-11,23-30— singlelint-and-buildjob, Node[22, 24]matrix, install → lint → build only (no unit/audit/sonar).vuer_css/.github/workflows/audit.yaml:3-7,19,28-33,38-44— push devel/customization, Node 22, improved-yarn-audit excludes, executable guard.esign_css/package.json:11,12— lint-only test, lint script.esign_css/.github/workflows/pull-request.yaml:10-11,36-46,66-76,85-112,114-143— Node 24 (no matrix); jobs lint, audit (improved-yarn-audit), sonar, build (needs: [lint, audit, sonar]).esign_oss/package.json:15,18,19,20,77— lint, test, test:unit, test:e2e, improved-yarn-audit.esign_oss/.github/workflows/pull-request.yaml:10-11,56-72,111-113,172— Node 24; lint, unit (changed-files + findRelatedTests), audit (improved-yarn-audit), sonar, build.portal_css/package.json:12,13— lint-only test, lint script.portal_css/.travis.yml:6-7,26,28— Node 20, travis.sh, branch regex.portal_css/test/travis.sh:6-28— build, audit (≥16=critical), npm test, guards.vuer-release/.github/workflows/autobuild.yml:3-9,16-126— tag-triggered release build, release-tool, Harbor publish.- Cross-ref: vuer_oss (Jest 30, Playwright 1.56.1, 349 unit/396 total, Node ≥22.18, e2e DB-wipe), vuer_css (115 unit tests), conventions-and-glossary (ESLint StandardJS, no semicolons,
--max-warnings 0).