close

extends

  • Type: ExtendConfig | ExtendConfigFn
  • Default: undefined

The extends option allows you to extend your Rstest configuration from external sources, such as adapters that convert other build tools' configurations to Rstest-compatible format.

This enables:

  • Adapter Integration: Extend from adapters like @rstest/adapter-rslib
  • Async Configuration: Load configuration from external sources asynchronously
  • Config Merging: Automatically merge extended configuration with your local Rstest config

Basic usage (object)

type ExtendConfig = Omit<RstestConfig, 'projects'>;

ExtendConfig is a plain subset of RstestConfig without projects.

You can use it to extend your Rstest configuration from external sources. Rstest will merge the extended config with your local config following the configuration merging rules.

import { defineConfig } from '@rstest/core';
import { sharedConfig } from './shared.config';

export default defineConfig({
  extends: sharedConfig,
  // Local configuration
  testTimeout: 10000,
  retry: 2,
});

Function usage

type ExtendConfigFn = (
  userConfig: Readonly<RstestConfig>,
) => ExtendConfig | Promise<ExtendConfig>;

ExtendConfigFn is a function that takes the user's Rstest config as input and returns an extended config.

You can use this to load external configuration files, fetch remote configs, or conditionally modify the config based on user settings.

import { defineConfig } from '@rstest/core';

export default defineConfig({
  extends: async (user) => {
    const useJsdom = user.testEnvironment === 'jsdom';
    return {
      setupFiles: useJsdom ? ['<rootDir>/setupDomTests.ts'] : undefined,
      source: {
        define: {
          BUILD_TARGET: '"test"',
        },
      },
    };
  },
  testTimeout: 10_000,
});

Configuration merging

Rstest deep-merges object fields and overrides primitives. Local config always takes precedence over the extended config.

Example:

import { defineConfig } from '@rstest/core';

export default defineConfig({
  extends: {
    testEnvironment: 'jsdom',
    globals: true,
    testTimeout: 5000,
    source: {
      define: {
        BASE_URL: '"https://example.com"',
    },
  },
  // Local configuration
  testTimeout: 10000,
  retry: 2,
  source: {
    define: {
      API_URL: '"https://api.example.com"',
    },
  },
});

// Result:
// {
//   testEnvironment: 'jsdom', // from extends
//   globals: true,            // from extends
//   testTimeout: 10000,       // local overrides extends
//   retry: 2                  // local added
//   source: {                 // deep merged
//     define: {
//       BASE_URL: '"https://example.com"',
//       API_URL: '"https://api.example.com"',
//     },
//   },
// }

Using adapters

Example: extend from Rslib config

Use the @rstest/adapter-rslib adapter to extend Rstest configuration from an existing Rslib config file. The adapter automatically maps compatible options like source.define, source.include, source.exclude, and more.

import { defineConfig } from '@rstest/core';
import { withRslibConfig } from '@rstest/adapter-rslib';

export default defineConfig({
  extends: withRslibConfig({}),
  // Additional rstest-specific configuration
  coverage: {
    enabled: true,
    reporters: ['text', 'html'],
  },
});

Limitations

The extends configuration cannot include the projects field. To define multiple projects, extend each project individually:

export default defineConfig({
  projects: [
    {
      extends: withRslibConfig({ libId: 'node' }),
      include: ['tests/node/**/*.{test,spec}.?(c|m)[jt]s'],
    },
    {
      extends: withRslibConfig({ libId: 'react' }),
      include: ['tests/react/**/*.{test,spec}.?(c|m)[jt]s?(x)'],
    },
  ],
});