Summary
Karma is deprecated and @angular/build:karma goes with it. The groundwork is done — a Vitest runner, a codemod, and a CI ratchet that stops the Karma set growing — so what remains is moving the specs, batch by batch.
This is the best-stocked source of good first issues in the repo right now. Each sub-issue is a self-contained batch: run one command, run the suite, commit. No design decisions, no domain knowledge, and the result is verifiable by anyone.
How a batch works
# 1. Convert. The codemod does the dialect swap AND the .spec.ts -> .test.ts rename.
node scripts/codemod-jasmine-to-vitest.mjs src/app/features/<area>/**/*.spec.ts
# 2. Run the migrated suite.
npm run test:unit
# 3. Re-record the ratchet baseline.
node scripts/check-test-runner.mjs --write
# 4. The rest of the usual checks.
npm run lint:prune && npm run format && npm test -- --watch=false
npm run check:test-runner prints how many are left.
What the codemod handles, and what it doesn't
It converts dialect — vi.fn() for jasmine.createSpy(), .mockReturnValue() for .and.returnValue(), toBe(true) for toBeTrue(), SpyObj<T>/createSpyObj<T>() from src/app/testing/mocks.ts for the Jasmine equivalents.
It skips whole files that use fakeAsync, tick, flush, done() callbacks, jasmine.clock or the object form of createSpyObj, and tells you which. Those carry zone or callback semantics rather than a spelling, and they are collected in a separate issue that is explicitly not a first issue.
Remaining work by area
| Area |
Mechanical |
Needs a person |
features/products |
38 |
1 |
features/system |
32 |
0 |
features/accounting |
15 |
0 |
features/clients |
13 |
0 |
features/loans |
13 |
0 |
features/organization |
10 |
0 |
features/working-capital |
10 |
0 |
features/spm |
5 |
0 |
| 17 smaller areas |
23 |
3 |
core |
1 |
11 |
shared |
2 |
3 |
| Total |
173 |
19 |
Ground rules
- One area per PR. A 192-file diff is unreviewable; a 15-file one is not.
- The suite must stay arithmetically whole — Karma total + Vitest total should not drop. State both counts in the PR.
- Do not "improve" a spec while migrating it. A migration diff that also changes assertions cannot be reviewed as either.
Background, and the open question about Vitest browser mode: DOCS/adr/0004-vitest-migration.md.
Summary
Karma is deprecated and
@angular/build:karmagoes with it. The groundwork is done — a Vitest runner, a codemod, and a CI ratchet that stops the Karma set growing — so what remains is moving the specs, batch by batch.This is the best-stocked source of good first issues in the repo right now. Each sub-issue is a self-contained batch: run one command, run the suite, commit. No design decisions, no domain knowledge, and the result is verifiable by anyone.
How a batch works
npm run check:test-runnerprints how many are left.What the codemod handles, and what it doesn't
It converts dialect —
vi.fn()forjasmine.createSpy(),.mockReturnValue()for.and.returnValue(),toBe(true)fortoBeTrue(),SpyObj<T>/createSpyObj<T>()fromsrc/app/testing/mocks.tsfor the Jasmine equivalents.It skips whole files that use
fakeAsync,tick,flush,done()callbacks,jasmine.clockor the object form ofcreateSpyObj, and tells you which. Those carry zone or callback semantics rather than a spelling, and they are collected in a separate issue that is explicitly not a first issue.Remaining work by area
features/productsfeatures/systemfeatures/accountingfeatures/clientsfeatures/loansfeatures/organizationfeatures/working-capitalfeatures/spmcoresharedGround rules
Background, and the open question about Vitest browser mode:
DOCS/adr/0004-vitest-migration.md.