Skip to content

Commit e352aca

Browse files
committed
Fix race in executeLine and waitForPrompt
1 parent 640d660 commit e352aca

File tree

1 file changed

+26
-35
lines changed

1 file changed

+26
-35
lines changed

packages/e2e-tests/test/test-shell.ts

+26-35
Original file line numberDiff line numberDiff line change
@@ -183,39 +183,19 @@ export class TestShell {
183183
return this._process;
184184
}
185185

186-
async waitForPrompt(start = 0): Promise<void> {
187-
await eventually(() => {
188-
const output = this._output.slice(start);
186+
/**
187+
* Wait for the last line of the output to become a prompt and resolve with it
188+
*/
189+
async waitForPrompt(start = 0): Promise<string> {
190+
return this.eventually(() => {
191+
const output = this._output.slice(start).trim();
189192
const lines = output.split('\n');
190-
const found = !!lines
191-
.filter((l) => PROMPT_PATTERN.exec(l)) // a line that is the prompt must at least match the pattern
192-
.find((l) => {
193-
// in some situations the prompt occurs multiple times in the line (but only in tests!)
194-
const prompts = l
195-
.trim()
196-
.replace(/>$/g, '')
197-
.split('>')
198-
.map((m) => m.trim());
199-
// if there are multiple prompt parts they must all equal
200-
if (prompts.length > 1) {
201-
for (const p of prompts) {
202-
if (p !== prompts[0]) {
203-
return false;
204-
}
205-
}
206-
}
207-
return true;
208-
});
209-
if (!found) {
210-
throw new assert.AssertionError({
211-
message: 'expected prompt',
212-
expected: PROMPT_PATTERN.toString(),
213-
actual:
214-
this._output.slice(0, start) +
215-
'[prompt search starts here]' +
216-
output,
217-
});
218-
}
193+
const lastLine = lines[lines.length - 1];
194+
assert(
195+
PROMPT_PATTERN.test(lastLine),
196+
`Expected a prompt (last line was "${lastLine}")`
197+
);
198+
return lastLine;
219199
});
220200
}
221201

@@ -311,10 +291,21 @@ export class TestShell {
311291
}
312292

313293
async executeLine(line: string): Promise<string> {
314-
const previousOutputLength = this._output.length;
294+
// Waiting for a prompt to appear since the last execution
295+
await this.waitForPrompt(this._previousOutputLength);
296+
// Keeping an the length of the output to return only output as result of the input
297+
const outputLengthBefore = this._output.length;
315298
this.writeInputLine(line);
316-
await this.waitForPrompt(previousOutputLength);
317-
return this._output.slice(previousOutputLength);
299+
// Wait for the execution and a new prompt to appear
300+
const prompt = await this.waitForPrompt(outputLengthBefore);
301+
// Store the output (excluding the following prompt)
302+
const output = this._output.slice(
303+
outputLengthBefore,
304+
this._output.length - prompt.length - 1
305+
);
306+
// Storing the output for future executions
307+
this._previousOutputLength = outputLengthBefore + output.length;
308+
return output;
318309
}
319310

320311
async executeLineWithJSONResult(line: string): Promise<any> {

0 commit comments

Comments
 (0)