Skip to content

Run v1.5-ported integration tests under a node-env vitest project (#1302 follow-up) #1307

@cliffhall

Description

@cliffhall

Background

#1302 (PR #1306) landed the v1.5 InspectorClient runtime + transports + auth subsystem into v2. The port included all 19 v1.5 test files (~11,170 LOC) verbatim under clients/web/src/test/core/, but 13 of them are currently excluded from the unit vitest project because they can't run under happy-dom. This issue tracks closing those three deferred gaps so the PR's "no regression vs. v1.5" intent is actually backed by passing tests.

Gap 1 — Integration tests excluded from the unit project

These tests are listed in clients/web/vite.config.ts (projects[0].test.exclude, marked TODO(#1302 follow-up)). They fail in the unit project because they:

  • Spawn real HTTP / stdio servers via test-servers/ (createTestServerHttp, getTestMcpServerCommand, etc.)
  • Run end-to-end OAuth flows that require real network round-trips
  • Use node:fs / node:os / node:net for file storage or socket binding
  • Or (in the auth/discovery.test.ts and auth/state-machine.test.ts cases) mock @modelcontextprotocol/sdk/client/auth.js but the mock identity is lost in happy-dom + Vitest 4, so a real fetch fires and CORS blocks it

Affected files:

File LOC Why excluded
inspectorClient.test.ts 4,005 Spawns stdio/HTTP test servers, drives full client lifecycle
inspectorClient-oauth.test.ts 553 OAuth flow against TestServerOAuth
inspectorClient-oauth-e2e.test.ts 1,880 E2E OAuth across SSE + streamable-HTTP × static/CIMD/DCR modes
inspectorClient-oauth-fetchFn.test.ts 200 Verifies fetchFn is threaded through OAuth
inspectorClient-oauth-remote-storage-e2e.test.ts 507 OAuth + RemoteOAuthStorage against a live Hono server
transport.test.ts 192 Real stdio / streamable-HTTP transports
remote-transport.test.ts 1,003 Spawns Hono remote server + MCP test servers
remote-server-config.test.ts 58 Hono server config parsing under real env vars
storage-adapters.test.ts 327 File + remote storage adapters (node:fs, HTTP)
auth/storage-node.test.ts 521 NodeOAuthStorage against the filesystem
auth/oauth-callback-server.test.ts 196 Binds a real http.Server
auth/discovery.test.ts 317 SDK auth-module mock identity lost under happy-dom + Vitest 4
auth/state-machine.test.ts 374 Same as above

Gap 2 — Coverage gate doesn't measure source files exercised only by those tests

clients/web/vite.config.ts (coverage.exclude) currently excludes the corresponding source paths so the per-file gate from #1301 still passes:

  • core/mcp/inspectorClient.ts
  • core/mcp/oauthManager.ts
  • core/mcp/fetchTracking.ts
  • core/mcp/messageTrackingTransport.ts
  • core/mcp/config.ts
  • core/mcp/node/**
  • core/mcp/remote/**
  • core/auth/**
  • core/storage/**
  • core/logging/**
  • test-servers/**

Once each test family comes back online, the corresponding entry in coverage.exclude should be dropped so the gate enforces ≥90/85/80/50 on those files.

Gap 3 — Manual smoke tests per the original AC on #1302 still unverified

The acceptance criteria on #1302 included:

  • new InspectorClient({ transport: 'stdio', command: 'node', args: ['…'] }) connects against a real stdio MCP server
  • new InspectorClient({ transport: 'http', url: '…' }) connects against a streamable-HTTP server
  • OAuth flow completes against at least one provider

These can probably be verified by hand once gap 1 is closed (the integration tests cover all three cases), but they should be explicitly signed off before declaring "no regression vs. v1.5."

Proposed approach

  1. Add a node-env vitest project to clients/web/vite.config.ts, alongside unit and storybook:
    • name: 'integration'
    • environment: 'node'
    • testTimeout: 30000, hookTimeout: 30000 (matches v1.5's core/vitest.config.ts)
    • include: the 13 file paths currently in unit.exclude
    • No setupFiles (or a minimal node-side one — no happy-dom cleanup)
  2. Wire it into CI (probably a new test:integration script alongside test:storybook) and update AGENTS.md.
  3. Sort out the SDK-mock identity issue for auth/discovery.test.ts and auth/state-machine.test.ts — these don't need a real network, just a working vi.mock("@modelcontextprotocol/sdk/client/auth.js", …). Likely a Vitest module-resolution tweak or a small mock helper.
  4. Drop entries from coverage.exclude as each test family comes online, verifying the gate stays green.
  5. Run the three manual smoke flows from the Port v1.5 InspectorClient runtime + transports + auth subsystem #1302 AC and check them off.

Acceptance criteria

  • All 13 currently-excluded test files run and pass in a node-env vitest project
  • npm run validate continues to pass; CI runs the new integration project
  • Every entry under coverage.exclude that points at v1.5-ported source has been removed, and the per-file gate (≥90/85/80/50) passes for those files
  • The three manual smoke flows from Port v1.5 InspectorClient runtime + transports + auth subsystem #1302 are verified and documented
  • clients/web/vite.config.ts no longer carries any TODO(#1302 follow-up) markers

Out of scope

Metadata

Metadata

Assignees

Labels

v2Issues and PRs for v2

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions