@frontmcp/skills 1.6.1 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -95,17 +95,17 @@ This is a router skill. Follow this order to pick a testing approach, then move
|
|
|
95
95
|
|
|
96
96
|
## Cross-Cutting Testing Patterns
|
|
97
97
|
|
|
98
|
-
| Pattern | Rule
|
|
99
|
-
| ------------------ |
|
|
100
|
-
| File naming | Always `.spec.ts` (not `.test.ts`); E2E uses `.e2e.spec.ts`
|
|
101
|
-
| File organization | Split E2E tests by app/feature: `e2e/calc.e2e.spec.ts`, `e2e/ecommerce.e2e.spec.ts`. Never put all tests in a single `server.e2e.spec.ts`
|
|
102
|
-
| Test runner | Standalone projects: use `frontmcp test` (auto-generates Jest/SWC config; discovers `src/**/*.spec.ts(x)`, `__tests__/**/*.spec.ts(x)`, and `e2e/**/*.e2e.spec.ts(x)`; transforms both `.ts` and `.tsx` with the automatic JSX runtime; delegates to a user-provided `jest.config.{ts,js,mjs,cjs,json}` if present). Nx monorepos: use `nx test <lib>` (resolves the project's `jest.config.ts`). Never invoke `jest --config ...` directly |
|
|
103
|
-
| Coverage threshold | 95%+ across statements, branches, functions, lines
|
|
104
|
-
| Test descriptions | Plain English, no prefixes like "PT-001"; describe behavior not implementation
|
|
105
|
-
| Mocking | Mock providers via DI token replacement, never mock the framework
|
|
106
|
-
| httpMock scope | `httpMock` intercepts HTTP in the **test process** only, NOT in the MCP server subprocess. Do not use httpMock to intercept server-to-API calls — those happen in the child process. Use httpMock for verifying client-to-server request shapes or mocking external APIs called from the test itself
|
|
107
|
-
| Error testing | Assert `instanceof` specific error class AND MCP error code
|
|
108
|
-
| Async | Always `await` async operations; use `expect(...).rejects.toThrow()` for async errors
|
|
98
|
+
| Pattern | Rule |
|
|
99
|
+
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
100
|
+
| File naming | Always `.spec.ts` (not `.test.ts`); E2E uses `.e2e.spec.ts` |
|
|
101
|
+
| File organization | Split E2E tests by app/feature: `e2e/calc.e2e.spec.ts`, `e2e/ecommerce.e2e.spec.ts`. Never put all tests in a single `server.e2e.spec.ts` |
|
|
102
|
+
| Test runner | Standalone projects: use `frontmcp test` (auto-generates Jest/SWC config; discovers `src/**/*.spec.ts(x)`, `__tests__/**/*.spec.ts(x)`, and `e2e/**/*.e2e.spec.ts(x)`; transforms both `.ts` and `.tsx` with the automatic JSX runtime; transpiles ESM-only deps such as `jose` under npm, yarn AND pnpm's `node_modules/.pnpm/` store — add your own via `test.esmPackages` in `frontmcp.config.ts`; delegates to a user-provided `jest.config.{ts,js,mjs,cjs,json}` if present, which drops the injected ESM transforms). Nx monorepos: use `nx test <lib>` (resolves the project's `jest.config.ts`). Never invoke `jest --config ...` directly |
|
|
103
|
+
| Coverage threshold | 95%+ across statements, branches, functions, lines |
|
|
104
|
+
| Test descriptions | Plain English, no prefixes like "PT-001"; describe behavior not implementation |
|
|
105
|
+
| Mocking | Mock providers via DI token replacement, never mock the framework |
|
|
106
|
+
| httpMock scope | `httpMock` intercepts HTTP in the **test process** only, NOT in the MCP server subprocess. Do not use httpMock to intercept server-to-API calls — those happen in the child process. Use httpMock for verifying client-to-server request shapes or mocking external APIs called from the test itself |
|
|
107
|
+
| Error testing | Assert `instanceof` specific error class AND MCP error code |
|
|
108
|
+
| Async | Always `await` async operations; use `expect(...).rejects.toThrow()` for async errors |
|
|
109
109
|
|
|
110
110
|
## Common Patterns
|
|
111
111
|
|
|
@@ -145,13 +145,14 @@ This is a router skill. Follow this order to pick a testing approach, then move
|
|
|
145
145
|
|
|
146
146
|
## Troubleshooting
|
|
147
147
|
|
|
148
|
-
| Problem
|
|
149
|
-
|
|
|
150
|
-
| Jest not finding test files
|
|
151
|
-
|
|
|
152
|
-
|
|
|
153
|
-
|
|
|
154
|
-
|
|
|
148
|
+
| Problem | Cause | Solution |
|
|
149
|
+
| ---------------------------------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
150
|
+
| Jest not finding test files | Wrong file extension (`.test.ts` instead of `.spec.ts`) | Rename to `.spec.ts`; check `testMatch` in jest.config |
|
|
151
|
+
| `SyntaxError: Unexpected token 'export'` | An ESM-only dependency is being ignored instead of transpiled | Add it to `test.esmPackages` in `frontmcp.config.ts`. With a hand-written `jest.config.ts`, use the pnpm-safe `transformIgnorePatterns` in [`setup-testing`](./references/setup-testing.md#jest-configuration) AND make sure `transform` matches `.js` (`^.+\.[tj]sx?$` + `allowJs`) — un-ignoring a file does nothing if no transform matches it |
|
|
152
|
+
| Coverage below 95% | Untested error paths or conditional branches | Run `frontmcp test --coverage` and inspect uncovered lines in the report |
|
|
153
|
+
| E2E test timeout | Server startup too slow or port conflict | Increase Jest timeout; use random port allocation |
|
|
154
|
+
| DI resolution fails in tests | Provider not registered in test scope | Register mock providers before creating the test context |
|
|
155
|
+
| Istanbul shows 0% on async methods | TypeScript source-map mismatch with Istanbul | Known issue with some TS compilation settings; verify coverage with actual test output |
|
|
155
156
|
|
|
156
157
|
## Examples
|
|
157
158
|
|
|
@@ -22,8 +22,14 @@ export default {
|
|
|
22
22
|
displayName: 'my-lib',
|
|
23
23
|
preset: '../../jest.preset.js',
|
|
24
24
|
transform: {
|
|
25
|
-
|
|
25
|
+
// Must cover `.js` too: `transformIgnorePatterns` only un-ignores a file,
|
|
26
|
+
// the transform still has to match it. An ESM dep's `.js` would otherwise
|
|
27
|
+
// reach Jest untransformed.
|
|
28
|
+
'^.+\\.[tj]sx?$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],
|
|
26
29
|
},
|
|
30
|
+
// ESM-only deps (jose, reached via @frontmcp/sdk) must be transpiled, not
|
|
31
|
+
// ignored. The `.pnpm` skip keeps this correct under pnpm's symlinked store.
|
|
32
|
+
transformIgnorePatterns: ['node_modules[/\\\\](?!\\.pnpm[/\\\\])(?!(jose)[/\\\\])'],
|
|
27
33
|
coverageThreshold: {
|
|
28
34
|
global: {
|
|
29
35
|
statements: 95,
|
|
@@ -42,6 +48,7 @@ export default {
|
|
|
42
48
|
"compilerOptions": {
|
|
43
49
|
"outDir": "../../dist/out-tsc",
|
|
44
50
|
"module": "commonjs",
|
|
51
|
+
"allowJs": true,
|
|
45
52
|
"types": ["jest", "node"]
|
|
46
53
|
},
|
|
47
54
|
"include": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.spec.tsx"]
|
|
@@ -432,8 +432,16 @@ export default {
|
|
|
432
432
|
displayName: 'my-lib',
|
|
433
433
|
preset: '../../jest.preset.js',
|
|
434
434
|
transform: {
|
|
435
|
-
|
|
435
|
+
// Must cover `.js` too: `transformIgnorePatterns` only un-ignores a file,
|
|
436
|
+
// the transform still has to match it. An ESM dep's `.js` would otherwise
|
|
437
|
+
// reach Jest untransformed.
|
|
438
|
+
'^.+\\.[tj]sx?$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],
|
|
436
439
|
},
|
|
440
|
+
// ESM-only deps (jose, reached via @frontmcp/sdk) must be transpiled, not
|
|
441
|
+
// ignored. Skipping the `.pnpm` segment re-anchors the regex on the inner
|
|
442
|
+
// `node_modules/`, so this holds under npm, yarn AND pnpm's symlinked store;
|
|
443
|
+
// the trailing character classes cover Windows separators.
|
|
444
|
+
transformIgnorePatterns: ['node_modules[/\\\\](?!\\.pnpm[/\\\\])(?!(jose)[/\\\\])'],
|
|
437
445
|
coverageThreshold: {
|
|
438
446
|
global: {
|
|
439
447
|
statements: 95,
|
|
@@ -445,6 +453,26 @@ export default {
|
|
|
445
453
|
};
|
|
446
454
|
```
|
|
447
455
|
|
|
456
|
+
Add further ESM-only packages to the alternation (`(jose|nanoid)`). A plain
|
|
457
|
+
`node_modules/(?!(jose)/)` silently breaks under pnpm: the real path is
|
|
458
|
+
`node_modules/.pnpm/jose@6.2.3/node_modules/jose/...`, the unanchored regex
|
|
459
|
+
matches at the first `node_modules/`, and the run fails with
|
|
460
|
+
`SyntaxError: Unexpected token 'export'`.
|
|
461
|
+
|
|
462
|
+
In standalone projects driven by `frontmcp test`, prefer `test.esmPackages` in
|
|
463
|
+
`frontmcp.config.ts` — the injected config already carries the pattern above:
|
|
464
|
+
|
|
465
|
+
```typescript
|
|
466
|
+
// frontmcp.config.ts
|
|
467
|
+
import { defineConfig } from 'frontmcp';
|
|
468
|
+
|
|
469
|
+
export default defineConfig({
|
|
470
|
+
name: 'my-server',
|
|
471
|
+
deployments: [{ target: 'node' }],
|
|
472
|
+
test: { esmPackages: ['nanoid'] },
|
|
473
|
+
});
|
|
474
|
+
```
|
|
475
|
+
|
|
448
476
|
## Manual Testing with frontmcp dev
|
|
449
477
|
|
|
450
478
|
For interactive development and manual testing, use the CLI:
|