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_oss Playwright e2e tests CAN ERASE THE DATABASE. The dedicated e2e profile runs the server with NODE_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 registers globalTeardown (vuer_oss/playwright.config.ts:187) and forbidOnly is enabled in CI (:20).


1. Test types per repo

RepoUnit (Jest)E2e (Playwright)Lint (ESLint)Security audit
vuer_ossyes — test:unityes — test:e2eyes — lintin CI (yarn audit + improved-yarn-audit)
vuer_cssyes — test:unitnoyes — lintyes — dedicated audit.yaml workflow
esign_ossyes — test:unit / test:e2e (Jest)no Playwrightyes — lintin CI — audit job runs improved-yarn-audit --min-severity critical
esign_cssno unit scriptnoyes — lint (test = lint-only)in CI — audit job runs improved-yarn-audit --min-severity critical
portal_cssJest configured, no unit scriptnoyes — 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.js matches <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 is ts-jest for .ts; coverage via v8 into test/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", where jest = "jest --config ./test/jest.config.js --runInBand --forceExit" (vuer_css/package.json:11-12).
  • Config: test/jest.config.jsrootDir is repo root, ignores /web/ + /node_modules/ + /yarn-offline-cache/, v8 coverage (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/test pinned to 1.56.1 (vuer_oss/package.json:175).
  • Config: vuer_oss/playwright.config.ts. fullyParallel: true but workers: 1 (serial) and retries: 0 (:19-22); reporters list + html (:23); media faked via Chromium flags --use-fake-ui-for-media-stream / --use-fake-device-for-media-stream, --disable-web-security, camera+microphone permissions granted (:28-37).
  • Ordered dependency chain (each project dependencies on the prior) drives a stateful scenario: SetupOpenHoursSetupAuditlogVideochatVideochatReplay → {VideochatInspect, FourEye} → SelfServiceVideochatCoreCustomizationSelfServiceV2 → {SelfServiceOssPages, Archive} → EmergencyShutdownWaitingList (vuer_oss/playwright.config.ts:40-186).
  • Auth handled by setup project writing storage state to ./test/tests/playwright/.auth/user.json (and guest.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 the vuer_oss Node processes, all with environment=NODE_ENV="dev":
    • vuer_oss web: npx nyc node server.js (:29-32) — wrapped in nyc to 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) — each npx nyc node … (:50-174).

e2e is NOT run in PR CI

No PR workflow invokes test:e2e/Playwright. The vuer_oss PR 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); its test script 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 test is 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_css and portal_css, npm/yarn test only runs ESLint. Real unit tests use test: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_oss e2e 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) via env.NODE_VERSION: "24" (:10-11).
  • Jobs (vuer_oss/.github/workflows/pull-request.yaml):
    1. lintyarn --frozen-lockfile then yarn lint (:18-46).
    2. 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). Uploads lcov.info (:81-86).
    3. audityarn audit --groups dependencies (non-fatal) then yarn run improved-yarn-audit --min-severity critical (:88-117).
    4. sonar (SonarQube Scan)needs: test; downloads lcov, runs SonarSource/sonarqube-scan-action@v6 with PR decoration (:125-160).
    5. buildneeds: [lint, test, audit, sonar]; yarn build (:169-191).

vuer_oss unit CI is incremental

CI runs --findRelatedTests against the PR’s changed files, not the whole suite — full local run is yarn test:unit without that flag.

vuer_css — two workflows

  • .github/workflows/pull-request.yaml — a single job lint-and-build with a real Node matrix [22, 24] (vuer_css/.github/workflows/pull-request.yaml:7-11). Steps: yarn install --frozen-lockfileyarn lintyarn build only (:23-30). No unit-test job, no audit job, no Sonar job — test:unit is not run in PR CI here.
  • .github/workflows/audit.yaml — separate “Github CI - Branch” workflow that triggers on push to devel and customization/* (not PRs) (vuer_css/.github/workflows/audit.yaml:3-7). Node 22 (:19). It runs yarn audit --groups dependencies then yarn 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_css whose 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-triggered audit.yaml (:19). The other repos’ PR workflows pin Node 24 only via env.NODE_VERSION: "24": vuer_oss (:11), esign_css (:11), esign_oss (:11). So repo docs’ “CI Node 22 & 24” note for vuer_css is correct.

esign_css.github/workflows/pull-request.yaml

  • “Pull Request” on pull_request, Node 24 (single version) via env.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 dependencies then yarn run improved-yarn-audit --min-severity critical, :66-76), sonar (SonarQube scan, :85-112), and build with needs: [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 as vuer_oss: lint, test (incremental via tj-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 buildyarn install --production=false --force --frozen-lockfileyarn 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 *@* touching projects/*/release/*/release.json or base/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 the vuer-release-cli release_tool from GitHub releases, then release-tool gen/build/publish for project or base@ 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 0 means any ESLint warning fails the build.

  • vuer_oss
    • Unit: yarn test:unit (matches test/tests/unit/**). Whole-suite locally; CI only runs --findRelatedTests on changed files.
    • Lint: yarn lint (or yarn lint:fix).
    • E2e (rare, destructive): bring up the backend via the supervisor_vuer_oss_e2e_test.conf profile against a throwaway DB, then yarn test:e2e. Never against shared/prod. Not part of PR CI.
  • vuer_css
    • Unit: yarn test:unit (test/tests/unit/**, run-in-band). Lint: yarn lint.
    • Security: optional yarn run improved-yarn-audit --min-severity critical locally (this is what push CI does).
  • esign_oss
    • Unit: yarn test:unit; “e2e” Jest glob: yarn test:e2e. Lint: yarn lint.
  • esign_css
    • No unit script — yarn test and yarn lint both run ESLint only. Build with yarn build.
  • portal_css
    • npm test / npm run lint = ESLint only. Build with npm run build. (CI additionally runs yarn 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:

  1. Check out the client’s update branch (per-customer fork/branch).
  2. Install with a frozen lockfile (mirror CI): yarn --frozen-lockfile.
  3. Run the gating checks CI would run for that repo:
    • yarn lint (StandardJS, --max-warnings 0).
    • yarn test:unit where 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).
  4. Only merge once lint + unit (and any audit) pass green, matching the PR pipeline in §3.

Client data safety during updates

Because vuer_oss e2e 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 coverageThreshold is set in any Jest config read; SonarQube gate behavior lives server-side (not in repo) — not verifiable here.
  • esign_oss / esign_css audit IS in PR CI: both PR workflows have a dedicated audit job running yarn 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_css has lint+audit+sonar+build (no unit job, since it has no unit script); esign_oss adds a unit-test job on top.
  • Where esign_oss e2e (Jest e2e/*) 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_css Jest: test/jest.config.js + @jest/test-sequencer present, but no jest/test:unit script actually runs Jest in CI (Travis runs lint+audit only). Whether Jest suites exist/run is unverified.
  • vuer_css Playwright: none found (git ls-files shows no playwright.config.ts); e2e is vuer_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 — single lint-and-build job, 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).