From 3b42f5bb834c5c20bf36cc652971e968575efd8f Mon Sep 17 00:00:00 2001 From: Pavel Feldman Date: Mon, 21 Nov 2022 14:38:43 -0800 Subject: [PATCH] fix(electron): consistently emit ready event after app is loaded --- .../src/server/electron/loader.ts | 21 ++++++++++++++++++- tests/electron/electron-app.spec.ts | 18 ++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/packages/playwright-core/src/server/electron/loader.ts b/packages/playwright-core/src/server/electron/loader.ts index b95687083ca2f4..862c344402328d 100644 --- a/packages/playwright-core/src/server/electron/loader.ts +++ b/packages/playwright-core/src/server/electron/loader.ts @@ -32,6 +32,25 @@ for (const arg of chromiumSwitches) { app.getAppPath = () => path.dirname(appPath); } -(globalThis as any).__playwright_run = () => { +let launchInfoEventPayload: any; +app.on('ready', launchInfo => launchInfoEventPayload = launchInfo); + +(globalThis as any).__playwright_run = async () => { + // Wait for app to be ready to avoid browser initialization races. + await app.whenReady(); + + // Override isReady pipeline. + let isReady = false; + let whenReadyCallback: () => void; + const whenReadyPromise = new Promise(f => whenReadyCallback = f); + app.isReady = () => isReady; + app.whenReady = () => whenReadyPromise; + require(appPath); + + // Trigger isReady. + isReady = true; + whenReadyCallback!(); + app.emit('will-finish-launching'); + app.emit('ready', launchInfoEventPayload); }; diff --git a/tests/electron/electron-app.spec.ts b/tests/electron/electron-app.spec.ts index 9fc88906a05ed8..e017c0c67e7a0f 100644 --- a/tests/electron/electron-app.spec.ts +++ b/tests/electron/electron-app.spec.ts @@ -33,6 +33,24 @@ test('should fire close event', async ({ playwright }) => { expect(events.join('|')).toBe('context|application'); }); +test('should dispatch ready event', async ({ playwright }) => { + const electronApp = await playwright._electron.launch({ + args: [path.join(__dirname, 'electron-app-ready-event.js')], + }); + try { + const events = await electronApp.evaluate(() => globalThis.__playwrightLog); + expect(events).toEqual([ + 'isReady == false', + 'will-finish-launching fired', + 'ready fired', + 'whenReady resolved', + 'isReady == true', + ]); + } finally { + await electronApp.close(); + } +}); + test('should script application', async ({ electronApp }) => { const appPath = await electronApp.evaluate(async ({ app }) => app.getAppPath()); expect(appPath).toBe(path.resolve(__dirname));