WEBUI-2038 : Migrate unit tests from Karma to Web Test Runner#3185
WEBUI-2038 : Migrate unit tests from Karma to Web Test Runner#3185madhurkulshrestha-hyland wants to merge 12 commits into
Conversation
Replace @open-wc/karma-esm with @web/test-runner, reorganize test scripts, restore full-tree coverage reporting for Sonar, and fix related test failures. Co-authored-by: Cursor <cursoragent@cursor.com>
The load-all-tests.js graph is slow to transform on CI runners; 30s browserStartTimeout caused false failures before Mocha could start. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Pull request overview
Migrates the project’s unit-test infrastructure from Karma to @web/test-runner while preserving the existing “single generated entry file” approach and maintaining Sonar-compatible LCOV coverage reporting.
Changes:
- Replace Karma runner/config with
web-test-runner.config.mjsand supporting WTR plugins/scripts (including coverage parity post-processing). - Reorganize test helper scripts under
scripts/test/unit/andscripts/test/ftest/, updatingpackage.jsonscripts accordingly. - Update CI and documentation to reflect the new unit test runner; apply small test fixes (i18n stubs, updated warning string).
Reviewed changes
Copilot reviewed 27 out of 29 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| web-test-runner.config.mjs | New Web Test Runner configuration (single entry + coverage + log filtering). |
| test/setup.js | Updated bootstrap for WTR coverage + async-error suppression tweaks. |
| test/nuxeo-edit-documents-button.test.js | Adjust expected i18n warning text to match updated UI string. |
| test/nuxeo-dropzone.test.js | Stub i18n to stabilize tests under the new runner. |
| test/nuxeo-document-create.test.js | Stub i18n to stabilize tests under the new runner. |
| sonar-project.properties | Update coverage comments to reflect WTR-based pipeline. |
| scripts/test/unit/web-test-runner-fallback-plugin.mjs | Add dev-server fallback responses to reduce noisy 404/invalid JSON during tests. |
| scripts/test/unit/web-test-runner-coverage-flag-plugin.mjs | Inject a browser flag so test/setup.js can detect coverage runs under V8 coverage. |
| scripts/test/unit/print-test-runner-notice.js | Print a short notice clarifying WTR “1 test file” reporting due to single entry. |
| scripts/test/unit/inject-zero-coverage.js | Post-process LCOV to inject zero-coverage records for manifest paths missing from output. |
| scripts/test/unit/generate-test-load-all.js | Move/update barrel generator for the single WTR entry (test/load-all-tests.js). |
| scripts/test/unit/generate-coverage-imports.js | Move/update coverage manifest generator (test/coverage-imports-data.js). |
| scripts/test/ftest/runner.js | Update functional test runner pathing after script re-org. |
| scripts/karma-esm-sequential-test-imports.js | Remove unused Karma-specific workaround script. |
| README.md | Note WTR is now used for unit tests. |
| package.json | Swap Karma deps for WTR deps; update scripts to run WTR + coverage post-processing. |
| package-lock.json | Lockfile regenerated to reflect dependency changes (Karma chain removed, WTR added). |
| karma.conf.js | Remove Karma configuration. |
| eslint.config.mjs | Treat web-test-runner.config.mjs as a config file for linting rulesets. |
| CONTRIBUTING.md | Update unit test instructions for WTR and barrel regeneration. |
| ARCHITECTURE.md | Update tooling table + workflow notes to reflect WTR. |
| AGENTS.md | Update “source of truth” contributor guidance to WTR-based testing. |
| .gitignore | Update comments for generated test/coverage barrel files (new script locations). |
| .github/workflows/test.yaml | CI test job now references WTR-based npm test. |
| .github/skills/write-unit-test/SKILL.md | Update skill guidance to reflect WTR and barrel regeneration step. |
| .github/skills/update-ai-context/SKILL.md | Update references from Karma to WTR in context-maintenance guidance. |
| .github/instructions/unit-tests.instructions.md | Update unit test instructions for WTR + barrel entry model. |
| .github/instructions/build-config.instructions.md | Replace Karma section with WTR section and updated rules. |
| .github/copilot-instructions.md | Update Copilot repo instructions to reflect WTR and barrel entry workflow. |
System google-chrome-stable on GitHub runners mismatches puppeteer-core. Pass puppeteer to chromeLauncher and install bundled Chromium in CI. Co-authored-by: Cursor <cursoragent@cursor.com>
npm ci --ignore-scripts skips Puppeteer's browser download, so Sonar and other workflows that run npm test failed to launch Chrome for Web Test Runner. Co-authored-by: Cursor <cursoragent@cursor.com>
Fix benign 404 suppression to accept error objects or message strings, rephrase setup.js comment, rename fallbackBody parameter to avoid shadowing path import, and update coverage-imports docs for Web Test Runner. Co-authored-by: Cursor <cursoragent@cursor.com>
WTR filterBrowserLogs only forwards error-level browser logs in CI, so console.warn import failures were invisible unless WTR_VERBOSE=1. Co-authored-by: Cursor <cursoragent@cursor.com>
Strip WTR query strings before matching setup.js for coverage flag injection, log non-benign stray async failures as console.error, stop filtering those logs in WTR config, and fix ftest runner cucumber report cleanup/spawn args. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 28 out of 30 changed files in this pull request and generated 5 comments.
Comments suppressed due to low confidence (4)
scripts/test/unit/inject-zero-coverage.js:109
- This long template string likely violates ESLint
max-len: 120and will fail lint. Consider breaking the log message across lines or building it from smaller string parts.
// eslint-disable-next-line no-console
console.log(
`inject-zero-coverage: added ${records.length} zero-coverage records (${covered.size} → ${covered.size + records.length} files, ${before.pct.toFixed(2)}% → ${after.pct.toFixed(2)}% lines)`,
);
scripts/test/unit/generate-test-load-all.js:7
- The JSDoc comment line here is very long and will likely violate ESLint
max-len: 120(comments are not ignored), causing lint failures. Please wrap the comment text to <=120 chars per line.
This issue also appears on line 60 of the same file.
scripts/test/unit/generate-test-load-all.js:64
- This
console.logmessage is long enough to violate ESLintmax-len: 120and fail lint. Please wrap/split the string literal.
scripts/test/unit/generate-coverage-imports.js:15 - Some of the comment lines in this header block are long enough to violate ESLint
max-len: 120(comments are not ignored), which will causenpm run lintto fail. Please wrap these comment lines to <=120 chars.
Only suppress stray async errors outside active tests, fail coverage materialization on import errors (Karma parity), and wrap long lines / encode TINY_JPEG as base64 for max-len compliance. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 28 out of 30 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (1)
scripts/test/ftest/runner.js:22
- This runner always appends
--cucumberReportwith the defaultCUCUMBER_REPORT_DIR, which will override a user-supplied--cucumberReportargument (supported bynuxeo-web-ui-ftest). Please respectargs.cucumberReportwhen provided (and only default when absent), and clean up the corresponding directory.
Add pretest:watch so watch mode installs Puppeteer Chromium, split the TINY_JPEG base64 across short lines, and wrap the coverage manifest expect.fail message for max-len readability. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 28 out of 30 changed files in this pull request and generated 4 comments.
Comments suppressed due to low confidence (1)
scripts/test/unit/generate-test-load-all.js:8
- The JSDoc line describing the import graph is longer than 120 characters, and
max-lenchecks comments in this repo. Please wrap this comment (and any similar long comment lines) to keepnpm run lintpassing.
Add a Notes column to the README commands table and omit blank lines from zero-coverage lcov DA/LF counts in inject-zero-coverage.js. Co-authored-by: Cursor <cursoragent@cursor.com>
Use dev-server transform hook for coverage flag injection and add empty Notes cells to all README command table rows. Co-authored-by: Cursor <cursoragent@cursor.com>
Document --grep and setup-first entry files; warn that --files on a suite alone skips test/setup.js and breaks globals. Co-authored-by: Cursor <cursoragent@cursor.com>
|
| }, | ||
| }), | ||
| ], | ||
| browserLogs: verbose, |



Summary
@open-wc/karma-esm/ Karma with@web/test-runner+ Mocha TDD for unit testsscripts/test/unit/andscripts/test/ftest/package-lock.jsonfor lts-2025 (remove Karma chain, add Web Test Runner)Test plan
npm test— 1888 tests pass, coverage generatednpm run lintJIRA: https://hyland.atlassian.net/browse/WEBUI-2038
Made with Cursor