Skip to content

Commit ac4f79a

Browse files
committed
fix: display error when project is not found
1 parent 1936cfa commit ac4f79a

File tree

3 files changed

+43
-12
lines changed

3 files changed

+43
-12
lines changed

packages/playwright/src/common/ipc.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ export type DonePayload = {
125125
fatalErrors: TestInfoErrorImpl[];
126126
skipTestsDueToSetupFailure: string[]; // test ids
127127
fatalUnknownTestIds?: string[];
128+
missingProjectById?: string;
128129
};
129130

130131
export type TestOutputPayload = {

packages/playwright/src/runner/dispatcher.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -412,11 +412,18 @@ class JobDispatcher {
412412
// - there are no remaining
413413
// - we are here not because something failed
414414
// - no unrecoverable worker error
415-
if (!this._remainingByTestId.size && !this._failedTests.size && !params.fatalErrors.length && !params.skipTestsDueToSetupFailure.length && !params.fatalUnknownTestIds && !params.unexpectedExitError) {
415+
if (!this._remainingByTestId.size && !this._failedTests.size && !params.fatalErrors.length && !params.skipTestsDueToSetupFailure.length && !params.fatalUnknownTestIds && !params.missingProjectById && !params.unexpectedExitError) {
416416
this._finished({ didFail: false });
417417
return;
418418
}
419419

420+
if (params.missingProjectById) {
421+
this._failureTracker.onWorkerError();
422+
this._reporter.onError?.({ message: `Project with name ${params.missingProjectById} not found. Make sure project name does not change.` });
423+
this._finished({ didFail: true, newJob: undefined });
424+
return;
425+
}
426+
420427
for (const testId of params.fatalUnknownTestIds || []) {
421428
const test = this._remainingByTestId.get(testId);
422429
if (test) {

packages/playwright/src/worker/workerMain.ts

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ export class WorkerMain extends ProcessRunner {
5050
private _didRunFullCleanup = false;
5151
// Whether the worker was requested to stop.
5252
private _isStopped = false;
53+
// Whether a fatal error was caused by a missing project.
54+
private _isMissingProject = false;
5355
// This promise resolves once the single "run test group" call finishes.
5456
private _runFinished = new ManualPromise<void>();
5557
private _currentTest: TestInfoImpl | null = null;
@@ -103,13 +105,18 @@ export class WorkerMain extends ProcessRunner {
103105
}
104106

105107
override async gracefullyClose() {
108+
if (this._isMissingProject) {
109+
// Never set anything up and we can crash on attempting cleanup
110+
return;
111+
}
112+
106113
try {
107114
await this._stop();
108115
// Ignore top-level errors, they are already inside TestInfo.errors.
109116
const fakeTestInfo = new TestInfoImpl(this._config, this._project, this._params, undefined, 0, () => {}, () => {}, () => {});
110117
const runnable = { type: 'teardown' } as const;
111118
// We have to load the project to get the right deadline below.
112-
await fakeTestInfo._runAsStage({ title: 'worker cleanup', runnable }, () => this._loadIfNeeded()).catch(() => {});
119+
await fakeTestInfo._runAsStage({ title: 'worker cleanup', runnable }, () => this._load()).catch(() => {});
113120
await this._fixtureRunner.teardownScope('test', fakeTestInfo, runnable).catch(() => {});
114121
await this._fixtureRunner.teardownScope('worker', fakeTestInfo, runnable).catch(() => {});
115122
// Close any other browsers launched in this process. This includes anything launched
@@ -186,28 +193,43 @@ export class WorkerMain extends ProcessRunner {
186193
void this._stop();
187194
}
188195

189-
private async _loadIfNeeded() {
196+
private async _load(): Promise<{
197+
config: FullConfigInternal,
198+
project: FullProjectInternal,
199+
poolBuilder: PoolBuilder,
200+
} | undefined> {
190201
if (this._config)
191-
return;
202+
return { config: this._config, project: this._project, poolBuilder: this._poolBuilder };
192203

193204
this._config = await deserializeConfig(this._params.config);
194-
this._project = this._config.projects.find(p => p.id === this._params.projectId)!;
205+
const project = this._config.projects.find(p => p.id === this._params.projectId);
206+
if (!project)
207+
return undefined;
208+
this._project = project;
195209
this._poolBuilder = PoolBuilder.createForWorker(this._project);
210+
211+
return { config: this._config, project: this._project, poolBuilder: this._poolBuilder };
196212
}
197213

198214
async runTestGroup(runPayload: RunPayload) {
199215
this._runFinished = new ManualPromise<void>();
200216
const entries = new Map(runPayload.entries.map(e => [e.testId, e]));
201-
let fatalUnknownTestIds;
217+
let fatalUnknownTestIds: string[] | undefined;
202218
try {
203-
await this._loadIfNeeded();
204-
const fileSuite = await loadTestFile(runPayload.file, this._config.config.rootDir);
205-
const suite = bindFileSuiteToProject(this._project, fileSuite);
219+
const workerState = await this._load();
220+
if (!workerState) {
221+
this._isMissingProject = true;
222+
void this._stop();
223+
return;
224+
}
225+
const { config, project, poolBuilder } = workerState;
226+
const fileSuite = await loadTestFile(runPayload.file, config.config.rootDir);
227+
const suite = bindFileSuiteToProject(project, fileSuite);
206228
if (this._params.repeatEachIndex)
207-
applyRepeatEachIndex(this._project, suite, this._params.repeatEachIndex);
229+
applyRepeatEachIndex(project, suite, this._params.repeatEachIndex);
208230
const hasEntries = filterTestsRemoveEmptySuites(suite, test => entries.has(test.id));
209231
if (hasEntries) {
210-
this._poolBuilder.buildPools(suite);
232+
poolBuilder.buildPools(suite);
211233
this._activeSuites = new Map();
212234
this._didRunFullCleanup = false;
213235
const tests = suite.allTests();
@@ -235,7 +257,8 @@ export class WorkerMain extends ProcessRunner {
235257
const donePayload: DonePayload = {
236258
fatalErrors: this._fatalErrors,
237259
skipTestsDueToSetupFailure: [],
238-
fatalUnknownTestIds
260+
fatalUnknownTestIds,
261+
missingProjectById: this._isMissingProject ? this._params.projectId : undefined
239262
};
240263
for (const test of this._skipRemainingTestsInSuite?.allTests() || []) {
241264
if (entries.has(test.id))

0 commit comments

Comments
 (0)