refactor readKeyPress to be self-contained
This commit is contained in:
parent
382f41d89e
commit
f0de6ccd81
|
|
@ -28,7 +28,6 @@ import { EventEmitter } from 'stream';
|
||||||
import { type TestServerTransport, TestServerConnection } from '../isomorphic/testServerConnection';
|
import { type TestServerTransport, TestServerConnection } from '../isomorphic/testServerConnection';
|
||||||
import { TeleSuiteUpdater } from '../isomorphic/teleSuiteUpdater';
|
import { TeleSuiteUpdater } from '../isomorphic/teleSuiteUpdater';
|
||||||
import { restartWithExperimentalTsEsm } from '../common/configLoader';
|
import { restartWithExperimentalTsEsm } from '../common/configLoader';
|
||||||
import type { Disposable } from '../isomorphic/events';
|
|
||||||
|
|
||||||
class InMemoryTransport extends EventEmitter implements TestServerTransport {
|
class InMemoryTransport extends EventEmitter implements TestServerTransport {
|
||||||
public readonly _send: (data: string) => void;
|
public readonly _send: (data: string) => void;
|
||||||
|
|
@ -96,7 +95,7 @@ export async function runWatchModeLoop(configLocation: ConfigLocation, initialOp
|
||||||
const teleSuiteUpdater = new TeleSuiteUpdater({ pathSeparator: path.sep, onUpdate() { } });
|
const teleSuiteUpdater = new TeleSuiteUpdater({ pathSeparator: path.sep, onUpdate() { } });
|
||||||
|
|
||||||
const dirtyTestIds = new Set<string>();
|
const dirtyTestIds = new Set<string>();
|
||||||
let onDirtyTests = new ManualPromise();
|
let onDirtyTests = new ManualPromise<'changed'>();
|
||||||
|
|
||||||
let queue = Promise.resolve();
|
let queue = Promise.resolve();
|
||||||
const changedFiles = new Set<string>();
|
const changedFiles = new Set<string>();
|
||||||
|
|
@ -118,7 +117,7 @@ export async function runWatchModeLoop(configLocation: ConfigLocation, initialOp
|
||||||
changedFiles.clear();
|
changedFiles.clear();
|
||||||
|
|
||||||
if (dirtyTestIds.size > 0)
|
if (dirtyTestIds.size > 0)
|
||||||
onDirtyTests.resolve?.();
|
onDirtyTests.resolve('changed');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
testServerConnection.onReport(report => teleSuiteUpdater.processTestReportEvent(report));
|
testServerConnection.onReport(report => teleSuiteUpdater.processTestReportEvent(report));
|
||||||
|
|
@ -139,15 +138,10 @@ export async function runWatchModeLoop(configLocation: ConfigLocation, initialOp
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
printPrompt();
|
printPrompt();
|
||||||
const readCommandPromise = readCommand();
|
const command = await Promise.race([
|
||||||
await Promise.race([
|
|
||||||
onDirtyTests,
|
onDirtyTests,
|
||||||
readCommandPromise,
|
readCommand(),
|
||||||
]);
|
]);
|
||||||
if (!readCommandPromise.isDone())
|
|
||||||
readCommandPromise.resolve('changed');
|
|
||||||
|
|
||||||
const command = await readCommandPromise;
|
|
||||||
|
|
||||||
if (command === 'changed') {
|
if (command === 'changed') {
|
||||||
onDirtyTests = new ManualPromise();
|
onDirtyTests = new ManualPromise();
|
||||||
|
|
@ -252,22 +246,27 @@ export async function runWatchModeLoop(configLocation: ConfigLocation, initialOp
|
||||||
return result === 'passed' ? teardown.status : result;
|
return result === 'passed' ? teardown.status : result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function readKeyPress(handler: (text: string, key: any) => void): Disposable {
|
function readKeyPress<T extends string>(handler: (text: string, key: any) => T | undefined): Promise<T> {
|
||||||
|
return new Promise(resolve => {
|
||||||
const rl = readline.createInterface({ input: process.stdin, escapeCodeTimeout: 50 });
|
const rl = readline.createInterface({ input: process.stdin, escapeCodeTimeout: 50 });
|
||||||
readline.emitKeypressEvents(process.stdin, rl);
|
readline.emitKeypressEvents(process.stdin, rl);
|
||||||
if (process.stdin.isTTY)
|
if (process.stdin.isTTY)
|
||||||
process.stdin.setRawMode(true);
|
process.stdin.setRawMode(true);
|
||||||
|
|
||||||
process.stdin.on('keypress', handler);
|
function onKeypress(text: string, key: any) {
|
||||||
|
const result = handler(text, key);
|
||||||
return {
|
if (result) {
|
||||||
dispose: () => {
|
process.stdin.off('keypress', onKeypress);
|
||||||
process.stdin.off('keypress', handler);
|
|
||||||
rl.close();
|
rl.close();
|
||||||
if (process.stdin.isTTY)
|
if (process.stdin.isTTY)
|
||||||
process.stdin.setRawMode(false);
|
process.stdin.setRawMode(false);
|
||||||
|
|
||||||
|
resolve(result);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
process.stdin.on('keypress', onKeypress);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const isInterrupt = (text: string, key: any) => text === '\x03' || text === '\x1B' || (key && key.name === 'escape') || (key && key.ctrl && key.name === 'c');
|
const isInterrupt = (text: string, key: any) => text === '\x03' || text === '\x1B' || (key && key.name === 'escape') || (key && key.ctrl && key.name === 'c');
|
||||||
|
|
@ -278,9 +277,11 @@ async function runTests(watchOptions: WatchModeOptions, testServerConnection: Te
|
||||||
}) {
|
}) {
|
||||||
printConfiguration(watchOptions, options?.title);
|
printConfiguration(watchOptions, options?.title);
|
||||||
|
|
||||||
const reader = readKeyPress((text: string, key: any) => {
|
void readKeyPress((text: string, key: any) => {
|
||||||
if (isInterrupt(text, key))
|
if (isInterrupt(text, key)) {
|
||||||
testServerConnection.stopTestsNoReply({});
|
testServerConnection.stopTestsNoReply({});
|
||||||
|
return 'done';
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
await testServerConnection.runTests({
|
await testServerConnection.runTests({
|
||||||
|
|
@ -292,26 +293,21 @@ async function runTests(watchOptions: WatchModeOptions, testServerConnection: Te
|
||||||
reuseContext: connectWsEndpoint ? true : undefined,
|
reuseContext: connectWsEndpoint ? true : undefined,
|
||||||
workers: connectWsEndpoint ? 1 : undefined,
|
workers: connectWsEndpoint ? 1 : undefined,
|
||||||
headed: connectWsEndpoint ? true : undefined,
|
headed: connectWsEndpoint ? true : undefined,
|
||||||
}).finally(reader.dispose);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function readCommand(): ManualPromise<Command> {
|
function readCommand(): Promise<Command> {
|
||||||
const result = new ManualPromise<Command>();
|
return readKeyPress<Command>((text: string, key: any) => {
|
||||||
|
if (isInterrupt(text, key))
|
||||||
const reader = readKeyPress((text: string, key: any) => {
|
return 'interrupted';
|
||||||
if (isInterrupt(text, key)) {
|
|
||||||
result.resolve('interrupted');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (process.platform !== 'win32' && key && key.ctrl && key.name === 'z') {
|
if (process.platform !== 'win32' && key && key.ctrl && key.name === 'z') {
|
||||||
process.kill(process.ppid, 'SIGTSTP');
|
process.kill(process.ppid, 'SIGTSTP');
|
||||||
process.kill(process.pid, 'SIGTSTP');
|
process.kill(process.pid, 'SIGTSTP');
|
||||||
}
|
}
|
||||||
const name = key?.name;
|
const name = key?.name;
|
||||||
if (name === 'q') {
|
if (name === 'q')
|
||||||
result.resolve('exit');
|
return 'exit';
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (name === 'h') {
|
if (name === 'h') {
|
||||||
process.stdout.write(`${separator()}
|
process.stdout.write(`${separator()}
|
||||||
Run tests
|
Run tests
|
||||||
|
|
@ -330,18 +326,15 @@ Change settings
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (name) {
|
switch (name) {
|
||||||
case 'return': result.resolve('run'); break;
|
case 'return': return 'run';
|
||||||
case 'r': result.resolve('repeat'); break;
|
case 'r': return 'repeat';
|
||||||
case 'c': result.resolve('project'); break;
|
case 'c': return 'project';
|
||||||
case 'p': result.resolve('file'); break;
|
case 'p': return 'file';
|
||||||
case 't': result.resolve('grep'); break;
|
case 't': return 'grep';
|
||||||
case 'f': result.resolve('failed'); break;
|
case 'f': return 'failed';
|
||||||
case 's': result.resolve('toggle-show-browser'); break;
|
case 's': return 'toggle-show-browser';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
void result.finally(reader.dispose);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let showBrowserServer: PlaywrightServer | undefined;
|
let showBrowserServer: PlaywrightServer | undefined;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue