Skip to content
Open
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ node_modules
/.sass-cache
/connect.lock
/coverage
**/.coverage/**
/examples/react-todos-app/coverage
/libpeerconnection.log
npm-debug.log
Expand Down
31 changes: 13 additions & 18 deletions e2e/ci-e2e/vitest.e2e.config.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
/// <reference types="vitest" />
import { defineConfig } from 'vite';
import { tsconfigPathAliases } from '../../tools/vitest-tsconfig-path-aliases.js';
import { createE2eConfig } from '../../testing/test-setup-config/src/lib/vitest-setup-presets.js';

export default defineConfig({
cacheDir: '../../node_modules/.vite/ci-e2e',
test: {
reporters: ['basic'],
testTimeout: 60_000,
globals: true,
alias: tsconfigPathAliases(),
pool: 'threads',
poolOptions: { threads: { singleThread: true } },
cache: {
dir: '../../node_modules/.vitest',
export default createE2eConfig(
'ci-e2e',
{
projectRoot: new URL('../../', import.meta.url),
cacheKey: 'ci-e2e',
},
{
test: {
testTimeout: 60_000,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this could be a default for the e2e target

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked other files and there are many different values, like 20k, 40k, 80k, 60k, 120k.
Just making sure that we want to have 60k as default?

Copy link
Collaborator

@BioPhoton BioPhoton Oct 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm.... I would put 20 as default. Or if there are more projects with 40 lets go with 40. And for the projects with higher or lower times go with a override.

Did not realise this is already an overwrite..

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked that and:

Timeout Occurences
20s 6
40s 1
60s 1
80s 2
120s 1

I suggest then use 20s as default (20_000ms)

globalSetup: ['./global-setup.ts'],
coverage: { enabled: false },
},
environment: 'node',
include: ['tests/**/*.e2e.test.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
globalSetup: './global-setup.ts',
setupFiles: ['../../testing/test-setup/src/lib/reset.mocks.ts'],
},
});
);
34 changes: 12 additions & 22 deletions e2e/plugin-typescript-e2e/vitest.e2e.config.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,16 @@
/// <reference types="vitest" />
import { defineConfig } from 'vite';
import { tsconfigPathAliases } from '../../tools/vitest-tsconfig-path-aliases.js';
import { createE2eConfig } from '../../testing/test-setup-config/src/lib/vitest-setup-presets.js';

export default defineConfig({
cacheDir: '../../node_modules/.vite/plugin-typescript-e2e',
test: {
reporters: ['basic'],
testTimeout: 20_000,
globals: true,
alias: tsconfigPathAliases(),
pool: 'threads',
poolOptions: { threads: { singleThread: true } },
coverage: {
reporter: ['text', 'lcov'],
reportsDirectory: '../../coverage/plugin-typescript-e2e/e2e-tests',
exclude: ['mocks/**', '**/types.ts'],
},
cache: {
dir: '../../node_modules/.vitest',
export default createE2eConfig(
'plugin-typescript-e2e',
{
projectRoot: new URL('../../', import.meta.url),
cacheKey: 'plugin-typescript-e2e',
},
{
test: {
testTimeout: 20_000,
coverage: { enabled: true },
},
environment: 'node',
include: ['tests/**/*.e2e.test.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
setupFiles: ['../../testing/test-setup/src/lib/reset.mocks.ts'],
},
});
);
39 changes: 13 additions & 26 deletions packages/core/vitest.int.config.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,17 @@
/// <reference types="vitest" />
import { defineConfig } from 'vite';
import { tsconfigPathAliases } from '../../tools/vitest-tsconfig-path-aliases.js';
import {
createIntConfig,
setupPresets,
} from '../../testing/test-setup-config/src/lib/vitest-setup-presets.js';

export default defineConfig({
cacheDir: '../../node_modules/.vite/core',
test: {
reporters: ['basic'],
globals: true,
cache: {
dir: '../../node_modules/.vitest',
},
alias: tsconfigPathAliases(),
pool: 'threads',
poolOptions: { threads: { singleThread: true } },
coverage: {
reporter: ['text', 'lcov'],
reportsDirectory: '../../coverage/core/int-tests',
exclude: ['mocks/**', '**/types.ts'],
export default createIntConfig(
'core',
{
projectRoot: new URL('../../', import.meta.url),
},
{
test: {
setupFiles: [...setupPresets.int.base, ...setupPresets.int.portalClient],
},
environment: 'node',
include: ['src/**/*.int.test.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
globalSetup: ['../../global-setup.ts'],
setupFiles: [
'../../testing/test-setup/src/lib/console.mock.ts',
'../../testing/test-setup/src/lib/reset.mocks.ts',
'../../testing/test-setup/src/lib/portal-client.mock.ts',
],
},
});
);
50 changes: 18 additions & 32 deletions packages/core/vitest.unit.config.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,22 @@
/// <reference types="vitest" />
import { defineConfig } from 'vite';
import { tsconfigPathAliases } from '../../tools/vitest-tsconfig-path-aliases.js';
import {
createUnitConfig,
setupPresets,
} from '../../testing/test-setup-config/src/lib/vitest-setup-presets.js';

export default defineConfig({
cacheDir: '../../node_modules/.vite/core',
test: {
reporters: ['basic'],
globals: true,
cache: {
dir: '../../node_modules/.vitest',
},
alias: tsconfigPathAliases(),
pool: 'threads',
poolOptions: { threads: { singleThread: true } },
coverage: {
reporter: ['text', 'lcov'],
reportsDirectory: '../../coverage/core/unit-tests',
exclude: ['mocks/**', '**/types.ts'],
export default createUnitConfig(
'core',
{
projectRoot: new URL('../../', import.meta.url),
},
{
test: {
setupFiles: [
...setupPresets.unit.base,
...setupPresets.unit.git,
...setupPresets.unit.portalClient,
...setupPresets.unit.matchersCore,
],
},
environment: 'node',
include: ['src/**/*.unit.test.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
globalSetup: ['../../global-setup.ts'],
setupFiles: [
'../../testing/test-setup/src/lib/cliui.mock.ts',
'../../testing/test-setup/src/lib/fs.mock.ts',
'../../testing/test-setup/src/lib/git.mock.ts',
'../../testing/test-setup/src/lib/console.mock.ts',
'../../testing/test-setup/src/lib/reset.mocks.ts',
'../../testing/test-setup/src/lib/portal-client.mock.ts',
'../../testing/test-setup/src/lib/extend/ui-logger.matcher.ts',
'../../testing/test-setup/src/lib/extend/markdown-table.matcher.ts',
'../../testing/test-setup/src/lib/extend/jest-extended.matcher.ts',
],
},
});
);
40 changes: 14 additions & 26 deletions packages/utils/vitest.int.config.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,18 @@
/// <reference types="vitest" />
import { defineConfig } from 'vite';
import { tsconfigPathAliases } from '../../tools/vitest-tsconfig-path-aliases.js';
import {
createIntConfig,
setupPresets,
} from '../../testing/test-setup-config/src/lib/vitest-setup-presets.js';

export default defineConfig({
cacheDir: '../../node_modules/.vite/utils',
test: {
reporters: ['basic'],
globals: true,
cache: {
dir: '../../node_modules/.vitest',
},
alias: tsconfigPathAliases(),
pool: 'threads',
poolOptions: { threads: { singleThread: true } },
coverage: {
reporter: ['text', 'lcov'],
reportsDirectory: '../../coverage/utils/int-tests',
exclude: ['mocks/**', 'perf/**', '**/types.ts'],
export default createIntConfig(
'utils',
{
projectRoot: new URL('../../', import.meta.url),
},
{
test: {
coverage: { exclude: ['perf/**'] },
setupFiles: [...setupPresets.int.base, ...setupPresets.int.cliui],
},
environment: 'node',
include: ['src/**/*.int.test.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
globalSetup: ['../../global-setup.ts'],
setupFiles: [
'../../testing/test-setup/src/lib/cliui.mock.ts',
'../../testing/test-setup/src/lib/console.mock.ts',
'../../testing/test-setup/src/lib/reset.mocks.ts',
],
},
});
);
54 changes: 20 additions & 34 deletions packages/utils/vitest.unit.config.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,24 @@
/// <reference types="vitest" />
import { defineConfig } from 'vite';
import { tsconfigPathAliases } from '../../tools/vitest-tsconfig-path-aliases.js';
import {
createUnitConfig,
setupPresets,
} from '../../testing/test-setup-config/src/lib/vitest-setup-presets.js';

export default defineConfig({
cacheDir: '../../node_modules/.vite/utils',
test: {
reporters: ['basic'],
globals: true,
cache: {
dir: '../../node_modules/.vitest',
},
alias: tsconfigPathAliases(),
pool: 'threads',
poolOptions: { threads: { singleThread: true } },
coverage: {
reporter: ['text', 'lcov'],
reportsDirectory: '../../coverage/utils/unit-tests',
exclude: ['mocks/**', 'perf/**', '**/types.ts'],
},
environment: 'node',
include: ['src/**/*.{unit,type}.test.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
typecheck: {
include: ['**/*.type.test.ts'],
export default createUnitConfig(
'utils',
{
projectRoot: new URL('../../', import.meta.url),
},
{
test: {
include: ['src/**/*.{unit,type}.test.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
typecheck: { include: ['**/*.type.test.ts'] },
coverage: { exclude: ['perf/**'] },
setupFiles: [
...setupPresets.unit.base,
...setupPresets.unit.matchersCore,
...setupPresets.unit.matcherPath,
],
},
globalSetup: ['../../global-setup.ts'],
setupFiles: [
'../../testing/test-setup/src/lib/cliui.mock.ts',
'../../testing/test-setup/src/lib/fs.mock.ts',
'../../testing/test-setup/src/lib/console.mock.ts',
'../../testing/test-setup/src/lib/reset.mocks.ts',
'../../testing/test-setup/src/lib/extend/ui-logger.matcher.ts',
'../../testing/test-setup/src/lib/extend/markdown-table.matcher.ts',
'../../testing/test-setup/src/lib/extend/path.matcher.ts',
'../../testing/test-setup/src/lib/extend/jest-extended.matcher.ts',
],
},
});
);
24 changes: 24 additions & 0 deletions testing/test-setup-config/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
## Vitest config factory and setup presets

Utilities to centralize and standardize Vitest configuration across the monorepo.

- `vitest-config-factory.ts`: builds typed Vitest configs with sensible defaults
- `vitest-setup-presets.ts`: provides create functions and exportable setup file groups

The create functions (`createUnitConfig`, `createIntConfig`, `createE2eConfig`) automatically include appropriate setup files for each test type. See the unit tests for detailed documentation of defaults, coverage settings, and setup file presets.

### Examples

**Using defaults:**

```ts
export default createUnitConfig('my-package', import.meta.url);
```

**Extending default setup files:**

```ts
export default createIntConfig('my-package', import.meta.url, {
setupFiles: [...setupPresets.int.base, ...setupPresets.int.git, './custom-setup.ts'],
});
```
12 changes: 12 additions & 0 deletions testing/test-setup-config/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import tseslint from 'typescript-eslint';
import baseConfig from '../../eslint.config.js';

export default tseslint.config(...baseConfig, {
files: ['**/*.ts'],
languageOptions: {
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
});
12 changes: 12 additions & 0 deletions testing/test-setup-config/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "test-setup-config",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "testing/test-setup/src",
"projectType": "library",
"targets": {
"build": {},
"lint": {},
"unit-test": {}
},
"tags": ["scope:shared", "type:testing"]
}
14 changes: 14 additions & 0 deletions testing/test-setup-config/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export {
createVitestConfig,
type TestKind,
type VitestConfigFactoryOptions,
type VitestOverrides,
type ConfigRestParams,
} from './lib/vitest-config-factory.js';

export {
setupPresets,
createUnitConfig,
createIntConfig,
createE2eConfig,
} from './lib/vitest-setup-presets.js';
Loading