From b0a6db55abbd092ce5440eebe0f20f8d21d074be Mon Sep 17 00:00:00 2001 From: Max Schmitt Date: Tue, 5 Dec 2023 11:00:35 -0800 Subject: [PATCH] fix(electron): after v28.0 --- .../src/server/chromium/crExecutionContext.ts | 2 +- .../src/server/electron/electron.ts | 25 +++++++++++++------ 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/packages/playwright-core/src/server/chromium/crExecutionContext.ts b/packages/playwright-core/src/server/chromium/crExecutionContext.ts index c6952f5c82b386..00bfab51b8eab8 100644 --- a/packages/playwright-core/src/server/chromium/crExecutionContext.ts +++ b/packages/playwright-core/src/server/chromium/crExecutionContext.ts @@ -112,7 +112,7 @@ export class CRExecutionContext implements js.ExecutionContextDelegate { } } -function rewriteError(error: Error): Protocol.Runtime.evaluateReturnValue { +export function rewriteError(error: Error): Protocol.Runtime.evaluateReturnValue { if (error.message.includes('Object reference chain is too long')) return { result: { type: 'undefined' } }; if (error.message.includes('Object couldn\'t be returned by value')) diff --git a/packages/playwright-core/src/server/electron/electron.ts b/packages/playwright-core/src/server/electron/electron.ts index eeb27552a87c09..f921250ccae992 100644 --- a/packages/playwright-core/src/server/electron/electron.ts +++ b/packages/playwright-core/src/server/electron/electron.ts @@ -22,7 +22,8 @@ import { CRBrowser } from '../chromium/crBrowser'; import type { CRSession } from '../chromium/crConnection'; import { CRConnection } from '../chromium/crConnection'; import type { CRPage } from '../chromium/crPage'; -import { CRExecutionContext } from '../chromium/crExecutionContext'; +import { CRExecutionContext, rewriteError } from '../chromium/crExecutionContext'; +import { getExceptionMessage } from '../chromium/crProtocolHelper'; import * as js from '../javascript'; import type { Page } from '../page'; import { TimeoutSettings } from '../../common/timeoutSettings'; @@ -54,7 +55,7 @@ export class ElectronApplication extends SdkObject { private _nodeConnection: CRConnection; private _nodeSession: CRSession; private _nodeExecutionContext: js.ExecutionContext | undefined; - _nodeElectronHandlePromise: Promise>; + _nodeElectronHandlePromise: Promise>; readonly _timeoutSettings = new TimeoutSettings(); private _process: childProcess.ChildProcess; @@ -69,11 +70,21 @@ export class ElectronApplication extends SdkObject { this._nodeConnection = nodeConnection; this._nodeSession = nodeConnection.rootSession; this._nodeElectronHandlePromise = new Promise(f => { - this._nodeSession.on('Runtime.executionContextCreated', async (event: any) => { + this._nodeSession.on('Runtime.executionContextCreated', async (event: import('../chromium/protocol').Protocol.Runtime.executionContextCreatedPayload) => { if (event.context.auxData && event.context.auxData.isDefault) { - this._nodeExecutionContext = new js.ExecutionContext(this, new CRExecutionContext(this._nodeSession, event.context), 'electron'); - const source = `process.mainModule.require('electron')`; - f(await this._nodeExecutionContext.rawEvaluateHandle(source).then(objectId => new js.JSHandle(this._nodeExecutionContext!, 'object', 'ElectronModule', objectId))); + const crExecutionContext = new CRExecutionContext(this._nodeSession, event.context); + this._nodeExecutionContext = new js.ExecutionContext(this, crExecutionContext, 'electron'); + f(await this._nodeExecutionContext._raceAgainstContextDestroyed((async () => { + const { exceptionDetails, result: remoteObject } = await crExecutionContext._client.send('Runtime.evaluate', { + expression: `require('electron')`, + contextId: event.context.id, + // Needed after Electron 28 to get access to require: https://github.com/microsoft/playwright/issues/28048 + includeCommandLineAPI: true, + }).catch(rewriteError); + if (exceptionDetails) + throw new js.JavaScriptErrorInEvaluate(getExceptionMessage(exceptionDetails)); + return remoteObject.objectId!; + })()).then(objectId => new js.JSHandle(this._nodeExecutionContext!, 'object', 'ElectronModule', objectId))); } }); }); @@ -112,7 +123,7 @@ export class ElectronApplication extends SdkObject { const electronHandle = await this._nodeElectronHandlePromise; return await electronHandle.evaluateHandle(({ BrowserWindow, webContents }, targetId) => { const wc = webContents.fromDevToolsTargetId(targetId); - return BrowserWindow.fromWebContents(wc); + return BrowserWindow.fromWebContents(wc!)!; }, targetId); } }