mirror of
https://github.com/electron/electron.git
synced 2026-10-28 11:44:46 +08:00
test: listen for both singleton exits before either can happen (#54593)
* test: listen for both singleton exits before either can happen 'prevents the second launch of app' only started listening for the first instance's 'exit' after the second instance's exit had been handled. The two copies quit within milliseconds of each other, so when the spec process's event loop is busy and sees both exits in the same pass, the first copy's 'exit' is emitted with no listener, and the test then waits for it until the 120s test timeout. Register both exit listeners as each process is spawned, as the other requestSingleInstanceLock tests already do, kill both copies on the way out, and fail within 30s naming which copy stalled instead of waiting out the test timeout. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XT1kpjmqsAdPLBVZMV1pVX * test: use waitUntil for the singleton launch waits Record each copy's exit code from an 'exit' listener attached at spawn and wait on it with the existing waitUntil helper instead of a local within() helper. Only kill a copy that is still running. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XT1kpjmqsAdPLBVZMV1pVX --------- Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
1 parent
bc8e748ec8
commit
338a350f7e
1 file changed
+27
-5
+27
-5
@@ -351,14 +351,36 @@ describe('app module', () => {
|
||||
it('prevents the second launch of app', async function () {
|
||||
this.timeout(120000);
|
||||
const appPath = path.join(fixturesPath, 'api', 'singleton-data');
|
||||
// The two copies quit within milliseconds of each other, so record each
|
||||
// exit as soon as the copy is spawned: an 'exit' emitted before a
|
||||
// listener is attached is lost, and the test would wait for it until it
|
||||
// timed out.
|
||||
const first = cp.spawn(process.execPath, [appPath]);
|
||||
await once(first.stdout, 'data');
|
||||
let firstCode: number | null = null;
|
||||
first.on('exit', (code) => {
|
||||
firstCode = code;
|
||||
});
|
||||
defer(() => {
|
||||
if (first.exitCode === null && first.signalCode === null) first.kill();
|
||||
});
|
||||
let firstOutput = '';
|
||||
first.stdout.on('data', (data) => {
|
||||
firstOutput += data;
|
||||
});
|
||||
await waitUntil(() => firstOutput.length > 0, { timeout: 30000 });
|
||||
// Start second app when received output.
|
||||
const second = cp.spawn(process.execPath, [appPath]);
|
||||
const [code2] = await once(second, 'exit');
|
||||
expect(code2).to.equal(1);
|
||||
const [code1] = await once(first, 'exit');
|
||||
expect(code1).to.equal(0);
|
||||
let secondCode: number | null = null;
|
||||
second.on('exit', (code) => {
|
||||
secondCode = code;
|
||||
});
|
||||
defer(() => {
|
||||
if (second.exitCode === null && second.signalCode === null) second.kill();
|
||||
});
|
||||
await waitUntil(() => secondCode !== null, { timeout: 30000 });
|
||||
expect(secondCode).to.equal(1);
|
||||
await waitUntil(() => firstCode !== null, { timeout: 30000 });
|
||||
expect(firstCode).to.equal(0);
|
||||
});
|
||||
|
||||
it('returns true when setting non-existent user data folder', async function () {
|
||||
|
||||
Reference in new issue
Block a user