test: migrate remaining packages from Jest to vitest (#657988)#44
Merged
Conversation
Replace Jest dual-project (dom + node) config with vitest test.projects. One vi.fn() conversion in lf-localization.service.spec.ts. Drop ts-jest, jest-environment-jsdom, jest-junit, jest-config, @types/jest, jest; add vitest, jsdom. 362 tests pass (matches baseline from run 22864885222).
Single node config, no Jest API usage in test bodies. Drop ts-jest, babel-jest, jest-junit, @types/jest, jest; add vitest. Also drops the --experimental-vm-modules opt-in flag. 3 tests pass (matches baseline).
Two vitest configs (node + jsdom) mirroring V2's pattern. Conditional JUnit output filename preserved via process.env.AUTHORIZATION_TYPE check (matches the existing jest-junit dynamic naming for cloud vs self-hosted runs). Drops --experimental-vm-modules --experimental-fetch flags (vitest covers both natively). Drops ts-jest, jest-junit, babel-jest, @types/jest, jest; adds vitest, jsdom. 66 tests collected on each config (matches baseline).
Replaces jest-runner-groups with a filename-suffix convention that vitest filters via positional substring args: *.unit.test.ts UnitTests group *.integration-cloud.test.ts IntegrationTests/Cloud group *.integration-selfhosted.test.ts IntegrationTests/SelfHosted group 9 test files renamed per group; PKCEUtils.test.ts keeps its plain extension to remain auto-excluded (it is broken under jsdom; preserves the modulePathIgnorePatterns behavior). Strips the now-dead /** @group */ JSDoc blocks at the top of each test file. Two vitest configs (node + jsdom) mirror the V1 client pattern, including the conditional JUnit output filename via process.env.AUTHORIZATION_TYPE so cloud and self-hosted CI runs do not overwrite each other. Drops jest-runner-groups, ts-jest, jest-junit, jest-environment-jsdom, babel-jest, @types/jest, jest; adds vitest, jsdom. Locally verified: test:Cloud collects 7 files, test:SelfHosted collects 7 files (matches CI baseline "7 of 9"). Full test count parity (41 / 43) will be confirmed in CI where AUTHORIZATION_TYPE and creds are set.
…(#657988) Switches all five Test Report steps from reporter: jest-junit to reporter: java-junit (vitest emits standard JUnit XML, not jest-junit attribute set). Updates path globs for packages whose vitest config sets root: 'test' so JUnit is written to test/junit*.xml: - lf-repository-api-client-v1 - lf-api-js Adds --reporter=junit --outputFile.junit=junit.xml to lf-api-js's test script so the dorny step finds something to read (its previous Jest invocation also did not emit JUnit, so this is a net new gain). V2 client (pre-existing vitest, out of scope for this migration) keeps its current report path — its reporter step has been finding nothing since the V2 vitest migration on page_manipulation_APIs and is unrelated to this PR.
Vitest splits hook timeouts from test timeouts. The default hookTimeout is 10s, so afterEach cleanup loops with 5s setTimeouts per entry (CreateCopyEntryCopyShortcut, CreateCopyEntryCopyEntry, SearchTests, CloseSearchTests, Task) would fail under vitest where they passed under Jest (Jest applies testTimeout to hooks as well). Mirror testTimeout: 200_000 with hookTimeout: 200_000 in both vitest configs. Caught by Codex review on the migration branch diff.
Vitest+jsdom regression vs jest+jsdom: the test sends a Blob-bearing FormData body to importDocument, expecting a 400 from the server. Under vitest+jsdom the underlying fetch throws TypeError: fetch failed before reaching the server (passes under vitest+node and was passing under jest+jsdom in the baseline). Skip under jsdom via test.skipIf(isBrowser()) so the test_libraries CI chain can flow through to V1 self-hosted, V2, and lf-api-js. Investigate isomorphic-fetch / jsdom Blob handling under vitest as a follow-up.
c768154 to
c5f4209
Compare
alexgomezlf
approved these changes
May 5, 2026
3 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Migrates the four remaining packages in this workspace from Jest to vitest, matching the V2 client migration that already shipped on
page_manipulation_APIs(PR #42).Closes TFS #657988.
Why
The mixed Jest/vitest workspace caused real CI flakiness — most visibly the 200s hang in
OAuthClientCredentialsHandler.test.ts("Correct config beforeFetchRequestAsync returns regional domain") on the V2 cloud-node CI step on 2026-05-01, which Jest reported as "A worker process has failed to exit gracefully…" (a known footprint of jsdom's fetch polyfill not cleaning up sockets). Switching to vitest gets us:--experimental-fetchopt-in).--experimental-vm-modulesopt-in).vi.*API (no test-body rewrites required beyond a singlejest.fn→vi.fn).Coverage baseline
Captured from the most recent fully-green
test_librariesrun onmain: run 22864885222 (2026-03-09, headb6094b06). Post-migration CI must match these counts.lf-js-utilstest:cilf-api-client-coretest:Cloud(node + jsdom)lf-api-client-coretest:SelfHosted(node + jsdom)lf-repository-api-clientcloudtest:all(node + jsdom)lf-repository-api-clientself-hostedtest:all(node + jsdom)lf-api-jstestV2 client (
lf-repository-api-client-v2) is out of scope; its baseline at the time was 23/61.Group convention (replaces
jest-runner-groups)lf-api-client-corepreviously used/** @group … */JSDoc annotations +jest-runner-groupsto split UnitTests / IntegrationTests/Cloud / IntegrationTests/SelfHosted. Vitest has no equivalent; this PR replaces the annotation with a filename-suffix convention:*.unit.test.ts*.integration-cloud.test.ts*.integration-selfhosted.test.tsPKCEUtils.test.tskeeps its plain extension to remain auto-excluded — it's broken under jsdom and was previously listed inmodulePathIgnorePatterns.test:Cloud/test:SelfHostedscripts use vitest positional args as substring filters against the file paths.Sequencing
This PR is based off
main, notpage_manipulation_APIs. It expects PR #42 to merge first; once it does, the rebase here should be trivial (no overlapping V2 file edits — this PR doesn't touch the V2 package). If for any reason this PR has to land first, V2 stays Jest until #42 lands and then re-acquires its existing vitest migration through the merge.The dorny/test-reporter step for
lf-repository-api-client-v2has been finding zero JUnit files since V2's own vitest migration (V2's vitest config doesn't emit JUnit). Pre-existing on PR #42's branch; not touched here.Out of scope / follow-ups
PR #43 (
ci/split-test-libraries) was originally motivated by exactly the kind of cross-package gating that vitest's better isolation should now eliminate. Re-evaluate after this lands; it may be reducible to "nice-to-have" or droppable.