Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ All work should be driven by items on the project board.
- Run unit tests with `npm run test` (or `npm run test:watch` during development) from `clients/web/`
- Run `npm run test:coverage` to verify the per-file gate: lines ≥ 90, statements ≥ 85, functions ≥ 80, branches ≥ 50 (CI enforces this gate). Branches is intentionally relaxed because Mantine portal/media-query branches are not exercisable under happy-dom; new business-logic branches should still be covered.
- Run `npm run test:integration` (also from `clients/web/`) for the v1.5-ported InspectorClient + transport + auth integration suite. It runs under a separate `integration` vitest project in node env (no happy-dom) with 30s timeouts. The script builds `test-servers/` first via `tsc -p ../../test-servers --noCheck` so the stdio MCP test server can be spawned as a real subprocess. CI runs it as its own step after unit tests.
- Test files live alongside the source as `<Name>.test.tsx` (or `.test.ts` for non-React modules). v1.5-ported integration tests live under `clients/web/src/test/core/` and are wired into the `integration` project via the `integrationTests` list in `vite.config.ts`.
- Test files live alongside the source as `<Name>.test.tsx` (or `.test.ts` for non-React modules). v1.5-ported integration tests live under `clients/web/src/test/integration/`, mirroring the `core/` source layout (`mcp/`, `mcp/node/`, `mcp/remote/`, `auth/`, `auth/node/`, `storage/`). Any test file under that folder is automatically picked up by the `integration` vitest project (node env, 30s timeouts) via the folder glob in `vite.config.ts` — placement is the manifest, there is no enumeration to keep in sync. Tests outside the folder run in the `unit` project (happy-dom). When adding a new test for, e.g., `core/mcp/remote/foo.ts`, put it at `src/test/integration/mcp/remote/foo.test.ts`.
- Use `renderWithMantine` from `src/test/renderWithMantine.tsx` to render components — it wraps in `MantineProvider` with the project theme

### Responding to Code Reviews
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import {
completeOAuthAuthorization,
createClientMetadataServer,
type ClientMetadataDocument,
} from "./helpers/oauth-client-fixtures.js";
} from "../helpers/oauth-client-fixtures.js";
import {
clearAllOAuthClientState,
NodeOAuthStorage,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { InspectorClient } from "@inspector/core/mcp/inspectorClient.js";
import { createTransportNode } from "@inspector/core/mcp/node/transport.js";
import type { MCPServerConfig } from "@inspector/core/mcp/types.js";
import { NodeOAuthStorage } from "@inspector/core/auth/node/storage-node.js";
import { createOAuthClientConfig } from "./helpers/oauth-client-fixtures.js";
import { createOAuthClientConfig } from "../helpers/oauth-client-fixtures.js";
import type { InspectorClientOptions } from "@inspector/core/mcp/inspectorClient.js";

const oauthTestStatePath = path.join(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import {
import {
createOAuthClientConfig,
completeOAuthAuthorization,
} from "./helpers/oauth-client-fixtures.js";
} from "../helpers/oauth-client-fixtures.js";
import { ConsoleNavigation } from "@inspector/core/auth/providers.js";
import type { InspectorClientOptions } from "@inspector/core/mcp/inspectorClient.js";
import type { MCPServerConfig } from "@inspector/core/mcp/types.js";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import {
import {
createOAuthClientConfig,
completeOAuthAuthorization,
} from "./helpers/oauth-client-fixtures.js";
} from "../helpers/oauth-client-fixtures.js";
import type { InspectorClientOptions } from "@inspector/core/mcp/inspectorClient.js";

const oauthTestStatePath = path.join(
Expand Down
35 changes: 13 additions & 22 deletions clients/web/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,26 +70,17 @@ const projectResolve = {
dedupe: sharedDedupe,
};

// v1.5-ported integration tests that need a node-env vitest project — they
// spawn real HTTP/stdio servers via test-servers/, run end-to-end OAuth flows,
// talk to fs/network, or mock `@modelcontextprotocol/sdk/client/auth.js` (the
// SDK auth mock identity is lost under happy-dom + Vitest 4, but works under
// node env). Tracked in #1307.
const integrationTests = [
'clients/web/src/test/core/inspectorClient.test.ts',
'clients/web/src/test/core/inspectorClient-oauth.test.ts',
'clients/web/src/test/core/inspectorClient-oauth-e2e.test.ts',
'clients/web/src/test/core/inspectorClient-oauth-fetchFn.test.ts',
'clients/web/src/test/core/inspectorClient-oauth-remote-storage-e2e.test.ts',
'clients/web/src/test/core/transport.test.ts',
'clients/web/src/test/core/remote-transport.test.ts',
'clients/web/src/test/core/remote-server-config.test.ts',
'clients/web/src/test/core/storage-adapters.test.ts',
'clients/web/src/test/core/auth/storage-node.test.ts',
'clients/web/src/test/core/auth/oauth-callback-server.test.ts',
'clients/web/src/test/core/auth/discovery.test.ts',
'clients/web/src/test/core/auth/state-machine.test.ts',
];
// Integration tests live under clients/web/src/test/integration/ and run in
// the node-env vitest project below. The folder is the manifest: anything
// inside it is integration (node env, 30s timeout, real servers); anything
// outside is a unit test (happy-dom). This prevents the silent
// misclassification trap where a file's environment depended on whether
// someone remembered to add it to an enumeration (#1314).
//
// Match `{ts,tsx}` to mirror the unit project's include below — otherwise a
// stray `.test.tsx` placed inside this folder would slip past the integration
// include AND fail to be excluded from unit, silently landing under happy-dom.
const integrationGlob = 'clients/web/src/test/integration/**/*.test.{ts,tsx}';

// More info at: https://storybook.js.org/docs/next/writing-tests/integrations/vitest-addon
export default defineConfig({
Expand Down Expand Up @@ -182,7 +173,7 @@ export default defineConfig({
// global lifecycle hooks; cleanup is invoked manually in setup.ts.
include: ['clients/web/src/**/*.test.{ts,tsx}'],
// Integration tests run in the integration project below (node env).
exclude: integrationTests,
exclude: [integrationGlob],
setupFiles: [path.join(dirname, 'src/test/setup.ts')],
},
},
Expand All @@ -199,7 +190,7 @@ export default defineConfig({
// Same reason as the unit project: rooted at repoRoot so vitest
// can transform core/ modules and run tests against the source.
root: repoRoot,
include: integrationTests,
include: [integrationGlob],
// Integration tests spawn real HTTP/stdio servers via test-servers/,
// bind sockets, run e2e OAuth flows, and exercise filesystem-backed
// storage. 30s matches the v1.5 core/vitest.config.ts.
Expand Down
Loading