Skip to content
Open
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
22 changes: 22 additions & 0 deletions e2e/browser-mode/fixtures/module-name-mapper/rstest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { defineConfig } from '@rstest/core';
import { BROWSER_PORTS } from '../ports';

export default defineConfig({
browser: {
enabled: true,
provider: 'playwright',
headless: true,
port: BROWSER_PORTS['module-name-mapper'],
},
include: ['tests/**/*.test.ts'],
testTimeout: 30000,
root: __dirname,
resolve: {
moduleNameMapper: {
// Map module-a to module-b using exact match
'^module-a$': '<rootDir>/src/moduleB.ts',
// Map @utils/* to ./src/utils/* using capture groups
'^@utils/(.*)$': '<rootDir>/src/utils/$1',
},
},
});
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const value = 'module-a';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const value = 'module-b';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const helper = 'helper-function';
15 changes: 15 additions & 0 deletions e2e/browser-mode/fixtures/module-name-mapper/tests/mapper.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { expect, it } from '@rstest/core';
// This should resolve to ./src/utils/helper.ts
// @ts-expect-error - moduleNameMapper redirect
import { helper } from '@utils/helper';
// This should resolve to module-b due to moduleNameMapper
// @ts-expect-error - moduleNameMapper redirect
import { value } from 'module-a';

it('moduleNameMapper should redirect module-a to module-b', () => {
expect(value).toBe('module-b');
});

it('moduleNameMapper should support capture groups', () => {
expect(helper).toBe('helper-function');
});
1 change: 1 addition & 0 deletions e2e/browser-mode/fixtures/ports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@ export const BROWSER_PORTS = {
'viewport-preset': 5216,
reporter: 5220,
'reporter-watch': 5222,
'module-name-mapper': 5224,
} as const;
12 changes: 12 additions & 0 deletions e2e/browser-mode/moduleNameMapper.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { describe, expect, it } from '@rstest/core';
import { runBrowserCli } from './utils';

describe('browser mode - moduleNameMapper', () => {
it('should resolve modules using moduleNameMapper config', async () => {
const { expectExecSuccess, cli } =
await runBrowserCli('module-name-mapper');

await expectExecSuccess();
expect(cli.stdout).toMatch(/Tests.*2 passed/);
});
});
15 changes: 15 additions & 0 deletions e2e/build/fixtures/moduleNameMapper/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { expect, it } from '@rstest/core';
// This should resolve to ./src/utils/helper.ts
// @ts-expect-error
import { helper } from '@utils/helper';
// This should resolve to module-b due to moduleNameMapper
// @ts-expect-error
import { value } from 'module-a';

it('moduleNameMapper should redirect module-a to module-b', () => {
expect(value).toBe('module-b');
});

it('moduleNameMapper should support capture groups', () => {
expect(helper).toBe('helper-function');
});
14 changes: 14 additions & 0 deletions e2e/build/fixtures/moduleNameMapper/rstest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { defineConfig } from '@rstest/core';

export default defineConfig({
name: 'node',
root: __dirname,
resolve: {
moduleNameMapper: {
// Map module-a to module-b using exact match
'^module-a$': '<rootDir>/src/moduleB.ts',
// Map @utils/* to ./src/utils/* using capture groups
'^@utils/(.*)$': '<rootDir>/src/utils/$1',
},
},
});
1 change: 1 addition & 0 deletions e2e/build/fixtures/moduleNameMapper/src/moduleA.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const value = 'module-a';
1 change: 1 addition & 0 deletions e2e/build/fixtures/moduleNameMapper/src/moduleB.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const value = 'module-b';
1 change: 1 addition & 0 deletions e2e/build/fixtures/moduleNameMapper/src/utils/helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const helper = 'helper-function';
19 changes: 14 additions & 5 deletions e2e/build/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,25 @@ describe('test build config', () => {
{ name: 'plugin' },
{ name: 'tools/rspack' },
{ name: 'decorators' },
])('$name config should work correctly', async ({ name }, {
onTestFinished,
}) => {
{ name: 'moduleNameMapper' },
{
name: 'moduleNameMapperHappyDom',
fixtureDir: 'moduleNameMapper',
testEnvironment: 'happy-dom',
},
])('$name config should work correctly', async ({
name,
fixtureDir = name,
testEnvironment,
}, { onTestFinished }) => {
const { expectExecSuccess } = await runRstestCli({
command: 'rstest',
args: [
'run',
`fixtures/${name}`,
`fixtures/${fixtureDir}`,
'-c',
`fixtures/${name}/rstest.config.ts`,
`fixtures/${fixtureDir}/rstest.config.ts`,
...(testEnvironment ? ['--testEnvironment', testEnvironment] : []),
],
onTestFinished,
options: {
Expand Down
17 changes: 14 additions & 3 deletions packages/browser/src/hostController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import fs from 'node:fs/promises';
import type { IncomingMessage, ServerResponse } from 'node:http';
import type { AddressInfo } from 'node:net';
import { fileURLToPath } from 'node:url';
import type { RsbuildPlugin } from '@rstest/core';
import {
type BrowserTestRunOptions,
type BrowserTestRunResult,
Expand Down Expand Up @@ -869,6 +870,7 @@ const createBrowserRuntime = async ({
containerDistPath,
containerDevServer,
forceHeadless,
builtinRsbuildPlugins,
}: {
context: Rstest;
manifestPath: string;
Expand All @@ -880,6 +882,9 @@ const createBrowserRuntime = async ({
containerDevServer?: string;
/** Force headless mode regardless of user config (used for list command) */
forceHeadless?: boolean;
builtinRsbuildPlugins: {
pluginModuleNameMapper: RsbuildPlugin;
};
}): Promise<BrowserRuntime> => {
const virtualManifestPlugin = new rspack.experiments.VirtualModulesPlugin({
[manifestPath]: manifestSource,
Expand Down Expand Up @@ -951,6 +956,7 @@ const createBrowserRuntime = async ({

// Add plugin to merge user Rsbuild config with rstest required config
rsbuildInstance.addPlugins([
builtinRsbuildPlugins.pluginModuleNameMapper,
{
name: 'rstest:browser-user-config',
setup(api) {
Expand Down Expand Up @@ -1337,9 +1343,9 @@ async function resolveProjectEntries(

export const runBrowserController = async (
context: Rstest,
options?: BrowserTestRunOptions,
options: BrowserTestRunOptions,
): Promise<BrowserTestRunResult | void> => {
const { skipOnTestRunEnd = false } = options ?? {};
const { skipOnTestRunEnd = false, builtinRsbuildPlugins } = options;
const buildStart = Date.now();
const browserProjects = getBrowserProjects(context);
const useHeadlessDirect = browserProjects.every(
Expand Down Expand Up @@ -1540,6 +1546,7 @@ export const runBrowserController = async (
: undefined,
containerDistPath,
containerDevServer,
builtinRsbuildPlugins,
});
} catch (error) {
return failWithError(error, async () => {
Expand Down Expand Up @@ -2525,8 +2532,11 @@ export type ListBrowserTestsResult = {
*/
export const listBrowserTests = async (
context: Rstest,
options?: {
options: {
shardedEntries?: Map<string, { entries: Record<string, string> }>;
builtinRsbuildPlugins: {
pluginModuleNameMapper: RsbuildPlugin;
};
},
): Promise<ListBrowserTestsResult> => {
const projectEntries = await resolveProjectEntries(
Expand Down Expand Up @@ -2570,6 +2580,7 @@ export const listBrowserTests = async (
containerDistPath: undefined,
containerDevServer: undefined,
forceHeadless: true, // Always use headless for list command
builtinRsbuildPlugins: options.builtinRsbuildPlugins,
});
} catch (error) {
logger.error(
Expand Down
5 changes: 3 additions & 2 deletions packages/browser/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,16 @@ export {

export async function runBrowserTests(
context: Rstest,
options?: BrowserTestRunOptions,
options: BrowserTestRunOptions,
): Promise<BrowserTestRunResult | void> {
return runBrowserController(context, options);
}

export async function listBrowserTests(
context: Rstest,
options: BrowserTestRunOptions,
): Promise<ListBrowserTestsResult> {
return listBrowserTestsImpl(context);
return listBrowserTestsImpl(context, options);
}

export type {
Expand Down
6 changes: 2 additions & 4 deletions packages/core/src/core/browserLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,11 @@ export interface BrowserModule {
validateBrowserConfig: (context: unknown) => void;
runBrowserTests: (
context: unknown,
options?: BrowserTestRunOptions,
options: BrowserTestRunOptions,
) => Promise<BrowserTestRunResult | void>;
listBrowserTests: (
context: unknown,
options?: {
shardedEntries?: Map<string, { entries: Record<string, string> }>;
},
options: BrowserTestRunOptions,
) => Promise<{
list: ListCommandResult[];
close: () => Promise<void>;
Expand Down
9 changes: 8 additions & 1 deletion packages/core/src/core/listTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,14 @@ const collectBrowserTests = async ({
projectRoots,
});
validateBrowserConfig(context);
return listBrowserTests(context, { shardedEntries });
const { pluginModuleNameMapper } = await import('./plugins/moduleNameMapper');

return listBrowserTests(context, {
shardedEntries,
builtinRsbuildPlugins: {
pluginModuleNameMapper: pluginModuleNameMapper(context),
},
});
};

const collectTestFiles = async ({
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/core/plugins/external.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ export const pluginExternal: (context: RstestContext) => RsbuildPlugin = (
normalizedConfig: { testEnvironment },
outputModule,
} = context.projects.find((p) => p.environmentName === name)!;

return mergeEnvironmentConfig(config, {
output: {
externals:
Expand Down
Loading
Loading