create full task runner

This commit is contained in:
Simon Knott 2024-07-24 13:43:59 +02:00
parent a2139795c8
commit 473b08a3f9
No known key found for this signature in database
GPG key ID: 8CEDC00028084AEC
4 changed files with 26 additions and 22 deletions

View file

@ -48,7 +48,7 @@ export function createPlugin(): TestRunnerPlugin {
configDir = configDirectory; configDir = configDirectory;
}, },
populateDependencies: async (config: FullConfig, configDir: string) => { populateDependencies: async () => {
await buildBundle(config, configDir); await buildBundle(config, configDir);
}, },

View file

@ -20,7 +20,7 @@ import type { ReporterV2 } from '../reporters/reporterV2';
export interface TestRunnerPlugin { export interface TestRunnerPlugin {
name: string; name: string;
setup?(config: FullConfig, configDir: string, reporter: ReporterV2): Promise<void>; setup?(config: FullConfig, configDir: string, reporter: ReporterV2): Promise<void>;
populateDependencies?(config: FullConfig, configDir: string): Promise<void>; populateDependencies?(): Promise<void>;
begin?(suite: Suite): Promise<void>; begin?(suite: Suite): Promise<void>;
end?(): Promise<void>; end?(): Promise<void>;
teardown?(): Promise<void>; teardown?(): Promise<void>;

View file

@ -22,7 +22,7 @@ import type { FullResult, TestError } from '../../types/testReporter';
import { webServerPluginsForConfig } from '../plugins/webServerPlugin'; import { webServerPluginsForConfig } from '../plugins/webServerPlugin';
import { collectFilesForProject, filterProjects } from './projectUtils'; import { collectFilesForProject, filterProjects } from './projectUtils';
import { createReporters } from './reporters'; import { createReporters } from './reporters';
import { TestRun, createTaskRunner, createTaskRunnerForList } from './tasks'; import { TestRun, createTaskRunner, createTaskRunnerForFindRelatedTests, createTaskRunnerForList } from './tasks';
import type { FullConfigInternal } from '../common/config'; import type { FullConfigInternal } from '../common/config';
import { runWatchModeLoop } from './watchMode'; import { runWatchModeLoop } from './watchMode';
import type { Suite } from '../common/test'; import type { Suite } from '../common/test';
@ -138,18 +138,10 @@ export class Runner {
} }
async findRelatedTestFiles(mode: 'in-process' | 'out-of-process', files: string[]): Promise<FindRelatedTestFilesReport> { async findRelatedTestFiles(mode: 'in-process' | 'out-of-process', files: string[]): Promise<FindRelatedTestFilesReport> {
const result = await this.loadAllTests(mode); const taskRunner = createTaskRunnerForFindRelatedTests(this._config, mode);
if (result.status !== 'passed' || !result.suite) await taskRunner.run(new TestRun(this._config), 0);
return { errors: result.errors, testFiles: [] };
const resolvedFiles = (files as string[]).map(file => path.resolve(process.cwd(), file)); const resolvedFiles = (files as string[]).map(file => path.resolve(process.cwd(), file));
for (const plugin of this._config.plugins) {
if (!plugin.instance)
plugin.instance = typeof plugin.factory === 'function' ? await plugin.factory() : plugin.factory;
await plugin.instance.populateDependencies?.(this._config.config, this._config.configDir);
}
return { testFiles: affectedTestFiles(resolvedFiles) }; return { testFiles: affectedTestFiles(resolvedFiles) };
} }
} }

View file

@ -63,7 +63,7 @@ export class TestRun {
export function createTaskRunner(config: FullConfigInternal, reporters: ReporterV2[]): TaskRunner<TestRun> { export function createTaskRunner(config: FullConfigInternal, reporters: ReporterV2[]): TaskRunner<TestRun> {
const taskRunner = TaskRunner.create<TestRun>(reporters, config.config.globalTimeout); const taskRunner = TaskRunner.create<TestRun>(reporters, config.config.globalTimeout);
addGlobalSetupTasks(taskRunner, config); addGlobalSetupTasks(taskRunner, config);
taskRunner.addTask('load tests', createLoadTask('in-process', { filterOnly: true, filterOnlyChanged: true, failOnLoadErrors: true })); taskRunner.addTask('load tests', createLoadTask('in-process', { filterOnly: true, failOnLoadErrors: true }));
addRunTasks(taskRunner, config); addRunTasks(taskRunner, config);
return taskRunner; return taskRunner;
} }
@ -76,14 +76,14 @@ export function createTaskRunnerForWatchSetup(config: FullConfigInternal, report
export function createTaskRunnerForWatch(config: FullConfigInternal, reporters: ReporterV2[], additionalFileMatcher?: Matcher): TaskRunner<TestRun> { export function createTaskRunnerForWatch(config: FullConfigInternal, reporters: ReporterV2[], additionalFileMatcher?: Matcher): TaskRunner<TestRun> {
const taskRunner = TaskRunner.create<TestRun>(reporters); const taskRunner = TaskRunner.create<TestRun>(reporters);
taskRunner.addTask('load tests', createLoadTask('out-of-process', { filterOnly: true, filterOnlyChanged: true, failOnLoadErrors: false, doNotRunDepsOutsideProjectFilter: true, additionalFileMatcher })); taskRunner.addTask('load tests', createLoadTask('out-of-process', { filterOnly: true, failOnLoadErrors: false, doNotRunDepsOutsideProjectFilter: true, additionalFileMatcher }));
addRunTasks(taskRunner, config); addRunTasks(taskRunner, config);
return taskRunner; return taskRunner;
} }
export function createTaskRunnerForTestServer(config: FullConfigInternal, reporters: ReporterV2[]): TaskRunner<TestRun> { export function createTaskRunnerForTestServer(config: FullConfigInternal, reporters: ReporterV2[]): TaskRunner<TestRun> {
const taskRunner = TaskRunner.create<TestRun>(reporters); const taskRunner = TaskRunner.create<TestRun>(reporters);
taskRunner.addTask('load tests', createLoadTask('out-of-process', { filterOnly: true, filterOnlyChanged: true, failOnLoadErrors: false, doNotRunDepsOutsideProjectFilter: true })); taskRunner.addTask('load tests', createLoadTask('out-of-process', { filterOnly: true, failOnLoadErrors: false, doNotRunDepsOutsideProjectFilter: true }));
addRunTasks(taskRunner, config); addRunTasks(taskRunner, config);
return taskRunner; return taskRunner;
} }
@ -106,9 +106,18 @@ function addRunTasks(taskRunner: TaskRunner<TestRun>, config: FullConfigInternal
return taskRunner; return taskRunner;
} }
export function createTaskRunnerForList(config: FullConfigInternal, reporters: ReporterV2[], mode: 'in-process' | 'out-of-process', options: { failOnLoadErrors: boolean }): TaskRunner<TestRun> { export function createTaskRunnerForList(config: FullConfigInternal, reporters: ReporterV2[], mode: 'in-process' | 'out-of-process', options: { failOnLoadErrors: boolean, populatePluginDependencies?: boolean }): TaskRunner<TestRun> {
const taskRunner = TaskRunner.create<TestRun>(reporters, config.config.globalTimeout); const taskRunner = TaskRunner.create<TestRun>(reporters, config.config.globalTimeout);
taskRunner.addTask('load tests', createLoadTask(mode, { ...options, filterOnly: false, filterOnlyChanged: false })); taskRunner.addTask('load tests', createLoadTask(mode, { ...options, filterOnly: false }));
taskRunner.addTask('report begin', createReportBeginTask());
return taskRunner;
}
export function createTaskRunnerForFindRelatedTests(config: FullConfigInternal, mode: 'in-process' | 'out-of-process'): TaskRunner<TestRun> {
const taskRunner = TaskRunner.create<TestRun>([], config.config.globalTimeout);
for (const plugin of config.plugins)
taskRunner.addTask('plugin setup', createPluginSetupTask(plugin));
taskRunner.addTask('load tests', createLoadTask(mode, { filterOnly: false, populatePluginDependencies: true, failOnLoadErrors: false }));
taskRunner.addTask('report begin', createReportBeginTask()); taskRunner.addTask('report begin', createReportBeginTask());
return taskRunner; return taskRunner;
} }
@ -222,16 +231,19 @@ function createListFilesTask(): Task<TestRun> {
}; };
} }
function createLoadTask(mode: 'out-of-process' | 'in-process', options: { filterOnly: boolean, filterOnlyChanged: boolean, failOnLoadErrors: boolean, doNotRunDepsOutsideProjectFilter?: boolean, additionalFileMatcher?: Matcher }): Task<TestRun> { function createLoadTask(mode: 'out-of-process' | 'in-process', options: { populatePluginDependencies?: boolean, filterOnly: boolean, failOnLoadErrors: boolean, doNotRunDepsOutsideProjectFilter?: boolean, additionalFileMatcher?: Matcher }): Task<TestRun> {
return { return {
setup: async (reporter, testRun, errors, softErrors) => { setup: async (reporter, testRun, errors, softErrors) => {
await collectProjectsAndTestFiles(testRun, !!options.doNotRunDepsOutsideProjectFilter, options.additionalFileMatcher); await collectProjectsAndTestFiles(testRun, !!options.doNotRunDepsOutsideProjectFilter, options.additionalFileMatcher);
await loadFileSuites(testRun, mode, options.failOnLoadErrors ? errors : softErrors); await loadFileSuites(testRun, mode, options.failOnLoadErrors ? errors : softErrors);
let cliOnlyChangedMatcher: Matcher | undefined = undefined; if (options.populatePluginDependencies || testRun.config.cliOnlyChanged) {
if (testRun.config.cliOnlyChanged && options.filterOnlyChanged) {
for (const plugin of testRun.config.plugins) for (const plugin of testRun.config.plugins)
await plugin.instance?.populateDependencies?.(testRun.config.config, testRun.config.configDir); await plugin.instance?.populateDependencies?.();
}
let cliOnlyChangedMatcher: Matcher | undefined = undefined;
if (testRun.config.cliOnlyChanged) {
const changedFiles = await detectChangedTests(testRun.config.cliOnlyChanged, testRun.config.configDir); const changedFiles = await detectChangedTests(testRun.config.cliOnlyChanged, testRun.config.configDir);
cliOnlyChangedMatcher = file => changedFiles.has(file); cliOnlyChangedMatcher = file => changedFiles.has(file);
} }