Skip to content
Merged
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
33 changes: 31 additions & 2 deletions scripts/e2e-terminal-stop.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
clearTerminal,
onRunStart,
onRunResult,
prepareCompilerRestart,
printInfo,
resetTerminalSession,
showInitialPrompt,
Expand Down Expand Up @@ -69,7 +70,7 @@ function ctrlCEvent() {

test('e2e: compiler ready status prints before the first terminal prompt', () => {
const ctx = setupTerminalHarness();
const status = 'Clang WASM compiler loaded. Ready to compile C++20.';
const status = 'Clang WASM compiler loaded, ready to compile C++ in browser';

printInfo(status);
showInitialPrompt();
Expand Down Expand Up @@ -116,7 +117,7 @@ test('e2e: clearing during startup does not reveal the initial prompt early', ()
const ctx = setupTerminalHarness();

clearTerminal();
printInfo('Clang WASM compiler loaded. Ready to compile C++20.');
printInfo('Clang WASM compiler loaded, ready to compile C++ in browser');
showInitialPrompt();

const output = ctx.writes.join('');
Expand Down Expand Up @@ -186,6 +187,34 @@ test('e2e: STOP discards stdout queued after a stopped run', async () => {
assert.ok(!ctx.writes.join('').includes('Process interrupted.'));
});

test('e2e: compiler restart waits to restore the prompt until the worker is ready', async () => {
const ctx = setupTerminalHarness();
const status = 'Clang WASM compiler loaded, ready to compile C++ in browser';

showInitialPrompt();
assert.equal(await startRun(), true);
onRunStart({ stdinMode: 'interactive' });
assert.equal(stopRun(), true);

const clearCallsBeforeRestart = ctx.clearCalls.length;
const writesBeforeRestart = ctx.writes.length;
prepareCompilerRestart();
assert.equal(ctx.clearCalls.length, clearCallsBeforeRestart + 1);
assert.equal(__getTerminalStateForTesting().busy, true);
const writesBeforeInput = ctx.writes.length;
__handleTerminalKeyForTesting('x', { key: 'x', ctrlKey: false, altKey: false });
assert.equal(ctx.writes.length, writesBeforeInput);

printInfo(status);
showInitialPrompt();

const output = ctx.writes.slice(writesBeforeRestart).join('');
assert.equal(__getTerminalStateForTesting().busy, false);
assert.ok(output.indexOf(status) < output.indexOf('browser.cpp'));
assert.equal(output.match(/browser\.cpp/g)?.length, 1);
assert.ok(!output.includes(`browser.cpp:~$ ${status}`));
});

test('e2e: STOP ignores a late nonzero run result', async () => {
const ctx = setupTerminalHarness();

Expand Down
1 change: 1 addition & 0 deletions src/ui/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ window.addEventListener('DOMContentLoaded', async () => {
onStdinData: (message) => worker.postMessage(message),
onStdinEOF: (message) => worker.postMessage(message),
onStopRun: () => {
terminalAPI.prepareCompilerRestart();
worker.terminate();
worker = createCompilerWorker();
toolbarController?.setWorker(worker);
Expand Down
12 changes: 12 additions & 0 deletions src/ui/terminal.js
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,18 @@ export function stopRun() {
return true;
}

/**
* Clear the stopped-run prompt while a replacement compiler worker loads.
* The next compiler-ready or compiler-error event restores the prompt.
*/
export function prepareCompilerRestart() {
clearScreen();
initialPromptShown = false;
inputBuffer = '';
historyIdx = -1;
busy = true;
}

// ── Output helpers called by toolbar.js / app.js ─────────────────────────────

/** Write stdout text from the running program. */
Expand Down
2 changes: 1 addition & 1 deletion src/ui/toolbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ async function handleWorkerMessage(data) {
}
updateStatusBar('compiler', 'ready', 'Compiler ready');
updateCompileButtons();
_terminalAPI.printInfo('Clang WASM compiler loaded. Ready to compile C++20.');
_terminalAPI.printInfo('Clang WASM compiler loaded, ready to compile C++ in browser');
_terminalAPI.showInitialPrompt?.();
break;

Expand Down
Loading