diff --git a/test/automation/src/code.ts b/test/automation/src/code.ts index de18b09cb4f..42dcf482dcc 100644 --- a/test/automation/src/code.ts +++ b/test/automation/src/code.ts @@ -157,24 +157,15 @@ export class Code { // after 5 / 10 seconds: try to exit gracefully again case 10: case 20: { - this.logger.log('Smoke test exit call did not terminate process after 5-10s, gracefully trying to exit the application again...'); + this.logger.log('Smoke test exit() call did not terminate process after 5-10s, gracefully trying to exit the application again...'); this.driver.exitApplication(); break; } // after 20 seconds: forcefully kill case 40: { - this.logger.log('Smoke test exit call did not terminate process after 20s, forcefully exiting the application...'); - - // no need to await since we're polling for the process to die anyways - treekill(pid, err => { - try { - process.kill(pid, 0); // throws an exception if the process doesn't exist anymore - this.logger.log('Failed to kill Electron process tree:', err?.message); - } catch (error) { - // Expected when process is gone - } - }); + this.logger.log('Smoke test exit() call did not terminate process after 20s, forcefully exiting the application...'); + this.kill(pid); // no need to await since we're polling for the process to die anyways break; } @@ -182,16 +173,27 @@ export class Code { // after 30 seconds: give up case 60: { done = true; - this.logger.log('Smoke test exit call did not terminate process after 30s, giving up'); + this.logger.log('Smoke test exit() call did not terminate process after 30s, giving up'); resolve(); } } try { process.kill(pid, 0); // throws an exception if the process doesn't exist anymore. + + const isAlive = await this.driver.isAlive(); + if (!isAlive) { + this.logger.log('Smoke test exit() call did not terminate process, but process is not alive anymore, forcefully exiting the application...'); + this.kill(pid); // no need to await since we're polling for the process to die anyways + } + await this.wait(500); + + process.kill(pid, 0); // throws an exception if the process doesn't exist anymore. } catch (error) { + this.logger.log('Smoke test exit() call terminated process successfully'); done = true; + resolve(); } } @@ -199,6 +201,21 @@ export class Code { }), 'Code#exit()', this.logger); } + private kill(pid: number): Promise { + return new Promise(resolve => { + treekill(pid, err => { + try { + process.kill(pid, 0); // throws an exception if the process doesn't exist anymore + this.logger.log('Failed to kill Electron process tree:', err?.message); + } catch (error) { + // Expected when process is gone + } + + resolve(); + }); + }); + } + async getElement(selector: string): Promise { return (await this.driver.getElements(selector))?.[0]; } diff --git a/test/automation/src/playwrightDriver.ts b/test/automation/src/playwrightDriver.ts index 018fe7c351a..99c11fd1a7e 100644 --- a/test/automation/src/playwrightDriver.ts +++ b/test/automation/src/playwrightDriver.ts @@ -329,6 +329,15 @@ export class PlaywrightDriver { private async getDriverHandle(): Promise> { return this.page.evaluateHandle('window.driver'); } + + async isAlive(): Promise { + try { + await this.getDriverHandle(); + return true; + } catch (error) { + return false; + } + } } export function wait(ms: number): Promise {