mirror of
https://github.com/microsoft/playwright.git
synced 2024-09-11 12:36:22 +03:00
feat(electron): expose ElectronApplication console events (#29322)
Fixes https://github.com/microsoft/playwright/issues/5905
This commit is contained in:
parent
2690e4c827
commit
47f8ba2a04
@ -106,7 +106,7 @@ The reason to be reported to the operations interrupted by the context closure.
|
||||
- alias-java: consoleMessage
|
||||
- argument: <[ConsoleMessage]>
|
||||
|
||||
Emitted when JavaScript within the page calls one of console API methods, e.g. `console.log` or `console.dir`. Also emitted if the page throws an error or a warning.
|
||||
Emitted when JavaScript within the page calls one of console API methods, e.g. `console.log` or `console.dir`.
|
||||
|
||||
The arguments passed into `console.log` and the page are available on the [ConsoleMessage] event handler argument.
|
||||
|
||||
|
@ -41,6 +41,26 @@ const { _electron: electron } = require('playwright');
|
||||
|
||||
This event is issued when the application closes.
|
||||
|
||||
## event: ElectronApplication.console
|
||||
* since: v1.42
|
||||
- argument: <[ConsoleMessage]>
|
||||
|
||||
Emitted when JavaScript within the Electron main process calls one of console API methods, e.g. `console.log` or `console.dir`.
|
||||
|
||||
The arguments passed into `console.log` are available on the [ConsoleMessage] event handler argument.
|
||||
|
||||
**Usage**
|
||||
|
||||
```js
|
||||
electronApp.on('console', async msg => {
|
||||
const values = [];
|
||||
for (const arg of msg.args())
|
||||
values.push(await arg.jsonValue());
|
||||
console.log(...values);
|
||||
});
|
||||
await electronApp.evaluate(() => console.log('hello', 5, { foo: 'bar' }));
|
||||
```
|
||||
|
||||
## event: ElectronApplication.window
|
||||
* since: v1.9
|
||||
- argument: <[Page]>
|
||||
|
@ -163,7 +163,7 @@ Emitted when the page closes.
|
||||
- alias-java: consoleMessage
|
||||
- argument: <[ConsoleMessage]>
|
||||
|
||||
Emitted when JavaScript within the page calls one of console API methods, e.g. `console.log` or `console.dir`. Also emitted if the page throws an error or a warning.
|
||||
Emitted when JavaScript within the page calls one of console API methods, e.g. `console.log` or `console.dir`.
|
||||
|
||||
The arguments passed into `console.log` are available on the [ConsoleMessage] event handler argument.
|
||||
|
||||
|
@ -25,10 +25,10 @@ type ConsoleMessageLocation = channels.BrowserContextConsoleEvent['location'];
|
||||
export class ConsoleMessage implements api.ConsoleMessage {
|
||||
|
||||
private _page: Page | null;
|
||||
private _event: channels.BrowserContextConsoleEvent;
|
||||
private _event: channels.BrowserContextConsoleEvent | channels.ElectronApplicationConsoleEvent;
|
||||
|
||||
constructor(event: channels.BrowserContextConsoleEvent) {
|
||||
this._page = event.page ? Page.from(event.page) : null;
|
||||
constructor(event: channels.BrowserContextConsoleEvent | channels.ElectronApplicationConsoleEvent) {
|
||||
this._page = ('page' in event && event.page) ? Page.from(event.page) : null;
|
||||
this._event = event;
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,7 @@ import { envObjectToArray } from './clientHelper';
|
||||
import { Events } from './events';
|
||||
import { JSHandle, parseResult, serializeArgument } from './jsHandle';
|
||||
import type { Page } from './page';
|
||||
import { ConsoleMessage } from './consoleMessage';
|
||||
import type { Env, WaitForEventOptions, Headers, BrowserContextOptions } from './types';
|
||||
import { Waiter } from './waiter';
|
||||
import { TargetClosedError } from './errors';
|
||||
@ -81,6 +82,10 @@ export class ElectronApplication extends ChannelOwner<channels.ElectronApplicati
|
||||
this._isClosed = true;
|
||||
this.emit(Events.ElectronApplication.Close);
|
||||
});
|
||||
this._channel.on('console', event => this.emit(Events.ElectronApplication.Console, new ConsoleMessage(event)));
|
||||
this._setEventToSubscriptionMapping(new Map<string, channels.ElectronApplicationUpdateSubscriptionParams['event']>([
|
||||
[Events.ElectronApplication.Console, 'console'],
|
||||
]));
|
||||
}
|
||||
|
||||
process(): childProcess.ChildProcess {
|
||||
|
@ -91,6 +91,7 @@ export const Events = {
|
||||
|
||||
ElectronApplication: {
|
||||
Close: 'close',
|
||||
Console: 'console',
|
||||
Window: 'window',
|
||||
},
|
||||
};
|
||||
|
@ -765,7 +765,6 @@ scheme.BrowserContextBindingCallEvent = tObject({
|
||||
binding: tChannel(['BindingCall']),
|
||||
});
|
||||
scheme.BrowserContextConsoleEvent = tObject({
|
||||
page: tChannel(['Page']),
|
||||
type: tString,
|
||||
text: tString,
|
||||
args: tArray(tChannel(['ElementHandle', 'JSHandle'])),
|
||||
@ -774,6 +773,7 @@ scheme.BrowserContextConsoleEvent = tObject({
|
||||
lineNumber: tNumber,
|
||||
columnNumber: tNumber,
|
||||
}),
|
||||
page: tChannel(['Page']),
|
||||
});
|
||||
scheme.BrowserContextCloseEvent = tOptional(tObject({}));
|
||||
scheme.BrowserContextDialogEvent = tObject({
|
||||
@ -2258,6 +2258,16 @@ scheme.ElectronApplicationInitializer = tObject({
|
||||
context: tChannel(['BrowserContext']),
|
||||
});
|
||||
scheme.ElectronApplicationCloseEvent = tOptional(tObject({}));
|
||||
scheme.ElectronApplicationConsoleEvent = tObject({
|
||||
type: tString,
|
||||
text: tString,
|
||||
args: tArray(tChannel(['ElementHandle', 'JSHandle'])),
|
||||
location: tObject({
|
||||
url: tString,
|
||||
lineNumber: tNumber,
|
||||
columnNumber: tNumber,
|
||||
}),
|
||||
});
|
||||
scheme.ElectronApplicationBrowserWindowParams = tObject({
|
||||
page: tChannel(['Page']),
|
||||
});
|
||||
@ -2280,6 +2290,11 @@ scheme.ElectronApplicationEvaluateExpressionHandleParams = tObject({
|
||||
scheme.ElectronApplicationEvaluateExpressionHandleResult = tObject({
|
||||
handle: tChannel(['ElementHandle', 'JSHandle']),
|
||||
});
|
||||
scheme.ElectronApplicationUpdateSubscriptionParams = tObject({
|
||||
event: tEnum(['console']),
|
||||
enabled: tBoolean,
|
||||
});
|
||||
scheme.ElectronApplicationUpdateSubscriptionResult = tOptional(tObject({}));
|
||||
scheme.ElectronApplicationCloseParams = tOptional(tObject({}));
|
||||
scheme.ElectronApplicationCloseResult = tOptional(tObject({}));
|
||||
scheme.AndroidInitializer = tOptional(tObject({}));
|
||||
|
@ -14,20 +14,18 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { SdkObject } from './instrumentation';
|
||||
import type * as js from './javascript';
|
||||
import type { ConsoleMessageLocation } from './types';
|
||||
import type { Page } from './page';
|
||||
|
||||
export class ConsoleMessage extends SdkObject {
|
||||
export class ConsoleMessage {
|
||||
private _type: string;
|
||||
private _text?: string;
|
||||
private _args: js.JSHandle[];
|
||||
private _location: ConsoleMessageLocation;
|
||||
private _page: Page;
|
||||
private _page: Page | null;
|
||||
|
||||
constructor(page: Page, type: string, text: string | undefined, args: js.JSHandle[], location?: ConsoleMessageLocation) {
|
||||
super(page, 'console-message');
|
||||
constructor(page: Page | null, type: string, text: string | undefined, args: js.JSHandle[], location?: ConsoleMessageLocation) {
|
||||
this._page = page;
|
||||
this._type = type;
|
||||
this._text = text;
|
||||
|
@ -90,8 +90,9 @@ export class BrowserContextDispatcher extends Dispatcher<BrowserContext, channel
|
||||
this._dispatchEvent('pageError', { error: serializeError(error), page: PageDispatcher.from(this, page) });
|
||||
});
|
||||
this.addObjectListener(BrowserContext.Events.Console, (message: ConsoleMessage) => {
|
||||
if (this._shouldDispatchEvent(message.page(), 'console')) {
|
||||
const pageDispatcher = PageDispatcher.from(this, message.page());
|
||||
const page = message.page()!;
|
||||
if (this._shouldDispatchEvent(page, 'console')) {
|
||||
const pageDispatcher = PageDispatcher.from(this, page);
|
||||
this._dispatchEvent('console', {
|
||||
page: pageDispatcher,
|
||||
type: message.type(),
|
||||
|
@ -21,6 +21,7 @@ import { ElectronApplication } from '../electron/electron';
|
||||
import type * as channels from '@protocol/channels';
|
||||
import { BrowserContextDispatcher } from './browserContextDispatcher';
|
||||
import type { PageDispatcher } from './pageDispatcher';
|
||||
import type { ConsoleMessage } from '../console';
|
||||
import { parseArgument, serializeResult } from './jsHandleDispatcher';
|
||||
import { ElementHandleDispatcher } from './elementHandlerDispatcher';
|
||||
|
||||
@ -40,6 +41,7 @@ export class ElectronDispatcher extends Dispatcher<Electron, channels.ElectronCh
|
||||
export class ElectronApplicationDispatcher extends Dispatcher<ElectronApplication, channels.ElectronApplicationChannel, ElectronDispatcher> implements channels.ElectronApplicationChannel {
|
||||
_type_EventTarget = true;
|
||||
_type_ElectronApplication = true;
|
||||
private readonly _subscriptions = new Set<channels.ElectronApplicationUpdateSubscriptionParams['event']>();
|
||||
|
||||
constructor(scope: ElectronDispatcher, electronApplication: ElectronApplication) {
|
||||
super(scope, electronApplication, 'ElectronApplication', {
|
||||
@ -49,6 +51,16 @@ export class ElectronApplicationDispatcher extends Dispatcher<ElectronApplicatio
|
||||
this._dispatchEvent('close');
|
||||
this._dispose();
|
||||
});
|
||||
this.addObjectListener(ElectronApplication.Events.Console, (message: ConsoleMessage) => {
|
||||
if (!this._subscriptions.has('console'))
|
||||
return;
|
||||
this._dispatchEvent('console', {
|
||||
type: message.type(),
|
||||
text: message.text(),
|
||||
args: message.args().map(a => ElementHandleDispatcher.fromJSHandle(this, a)),
|
||||
location: message.location()
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async browserWindow(params: channels.ElectronApplicationBrowserWindowParams): Promise<channels.ElectronApplicationBrowserWindowResult> {
|
||||
@ -67,6 +79,13 @@ export class ElectronApplicationDispatcher extends Dispatcher<ElectronApplicatio
|
||||
return { handle: ElementHandleDispatcher.fromJSHandle(this, result) };
|
||||
}
|
||||
|
||||
async updateSubscription(params: channels.ElectronApplicationUpdateSubscriptionParams): Promise<void> {
|
||||
if (params.enabled)
|
||||
this._subscriptions.add(params.event);
|
||||
else
|
||||
this._subscriptions.delete(params.event);
|
||||
}
|
||||
|
||||
async close(): Promise<void> {
|
||||
await this._object.close();
|
||||
}
|
||||
|
@ -43,12 +43,15 @@ import * as readline from 'readline';
|
||||
import { RecentLogsCollector } from '../../utils/debugLogger';
|
||||
import { serverSideCallMetadata, SdkObject } from '../instrumentation';
|
||||
import type * as channels from '@protocol/channels';
|
||||
import { toConsoleMessageLocation } from '../chromium/crProtocolHelper';
|
||||
import { ConsoleMessage } from '../console';
|
||||
|
||||
const ARTIFACTS_FOLDER = path.join(os.tmpdir(), 'playwright-artifacts-');
|
||||
|
||||
export class ElectronApplication extends SdkObject {
|
||||
static Events = {
|
||||
Close: 'close',
|
||||
Console: 'console',
|
||||
};
|
||||
|
||||
private _browserContext: CRBrowserContext;
|
||||
@ -82,6 +85,7 @@ export class ElectronApplication extends SdkObject {
|
||||
});
|
||||
this._nodeElectronHandlePromise.resolve(new js.JSHandle(this._nodeExecutionContext!, 'object', 'ElectronModule', remoteObject.objectId!));
|
||||
});
|
||||
this._nodeSession.on('Runtime.consoleAPICalled', event => this._onConsoleAPI(event));
|
||||
this._browserContext.setCustomCloseHandler(async () => {
|
||||
await this._browserContext.stopVideoRecording();
|
||||
const electronHandle = await this._nodeElectronHandlePromise;
|
||||
@ -89,6 +93,30 @@ export class ElectronApplication extends SdkObject {
|
||||
});
|
||||
}
|
||||
|
||||
async _onConsoleAPI(event: Protocol.Runtime.consoleAPICalledPayload) {
|
||||
if (event.executionContextId === 0) {
|
||||
// DevTools protocol stores the last 1000 console messages. These
|
||||
// messages are always reported even for removed execution contexts. In
|
||||
// this case, they are marked with executionContextId = 0 and are
|
||||
// reported upon enabling Runtime agent.
|
||||
//
|
||||
// Ignore these messages since:
|
||||
// - there's no execution context we can use to operate with message
|
||||
// arguments
|
||||
// - these messages are reported before Playwright clients can subscribe
|
||||
// to the 'console'
|
||||
// page event.
|
||||
//
|
||||
// @see https://github.com/GoogleChrome/puppeteer/issues/3865
|
||||
return;
|
||||
}
|
||||
if (!this._nodeExecutionContext)
|
||||
return;
|
||||
const args = event.args.map(arg => this._nodeExecutionContext!.createHandle(arg));
|
||||
const message = new ConsoleMessage(null, event.type, undefined, args, toConsoleMessageLocation(event.stackTrace));
|
||||
this.emit(ElectronApplication.Events.Console, message);
|
||||
}
|
||||
|
||||
async initialize() {
|
||||
await this._nodeSession.send('Runtime.enable', {});
|
||||
// Delay loading the app until browser is started and the browser targets are configured to auto-attach.
|
||||
|
@ -450,7 +450,7 @@ export class Tracing extends SdkObject implements InstrumentationListener, Snaps
|
||||
args: message.args().map(a => ({ preview: a.toString(), value: a.rawValue() })),
|
||||
location: message.location(),
|
||||
time: monotonicTime(),
|
||||
pageId: message.page().guid,
|
||||
pageId: message.page()?.guid,
|
||||
};
|
||||
this._appendTraceEvent(event);
|
||||
}
|
||||
|
123
packages/playwright-core/types/types.d.ts
vendored
123
packages/playwright-core/types/types.d.ts
vendored
@ -901,8 +901,7 @@ export interface Page {
|
||||
on(event: 'close', listener: (page: Page) => void): this;
|
||||
|
||||
/**
|
||||
* Emitted when JavaScript within the page calls one of console API methods, e.g. `console.log` or `console.dir`. Also
|
||||
* emitted if the page throws an error or a warning.
|
||||
* Emitted when JavaScript within the page calls one of console API methods, e.g. `console.log` or `console.dir`.
|
||||
*
|
||||
* The arguments passed into `console.log` are available on the {@link ConsoleMessage} event handler argument.
|
||||
*
|
||||
@ -1197,8 +1196,7 @@ export interface Page {
|
||||
addListener(event: 'close', listener: (page: Page) => void): this;
|
||||
|
||||
/**
|
||||
* Emitted when JavaScript within the page calls one of console API methods, e.g. `console.log` or `console.dir`. Also
|
||||
* emitted if the page throws an error or a warning.
|
||||
* Emitted when JavaScript within the page calls one of console API methods, e.g. `console.log` or `console.dir`.
|
||||
*
|
||||
* The arguments passed into `console.log` are available on the {@link ConsoleMessage} event handler argument.
|
||||
*
|
||||
@ -1588,8 +1586,7 @@ export interface Page {
|
||||
prependListener(event: 'close', listener: (page: Page) => void): this;
|
||||
|
||||
/**
|
||||
* Emitted when JavaScript within the page calls one of console API methods, e.g. `console.log` or `console.dir`. Also
|
||||
* emitted if the page throws an error or a warning.
|
||||
* Emitted when JavaScript within the page calls one of console API methods, e.g. `console.log` or `console.dir`.
|
||||
*
|
||||
* The arguments passed into `console.log` are available on the {@link ConsoleMessage} event handler argument.
|
||||
*
|
||||
@ -4340,8 +4337,7 @@ export interface Page {
|
||||
waitForEvent(event: 'close', optionsOrPredicate?: { predicate?: (page: Page) => boolean | Promise<boolean>, timeout?: number } | ((page: Page) => boolean | Promise<boolean>)): Promise<Page>;
|
||||
|
||||
/**
|
||||
* Emitted when JavaScript within the page calls one of console API methods, e.g. `console.log` or `console.dir`. Also
|
||||
* emitted if the page throws an error or a warning.
|
||||
* Emitted when JavaScript within the page calls one of console API methods, e.g. `console.log` or `console.dir`.
|
||||
*
|
||||
* The arguments passed into `console.log` are available on the {@link ConsoleMessage} event handler argument.
|
||||
*
|
||||
@ -7663,8 +7659,7 @@ export interface BrowserContext {
|
||||
on(event: 'close', listener: (browserContext: BrowserContext) => void): this;
|
||||
|
||||
/**
|
||||
* Emitted when JavaScript within the page calls one of console API methods, e.g. `console.log` or `console.dir`. Also
|
||||
* emitted if the page throws an error or a warning.
|
||||
* Emitted when JavaScript within the page calls one of console API methods, e.g. `console.log` or `console.dir`.
|
||||
*
|
||||
* The arguments passed into `console.log` and the page are available on the {@link ConsoleMessage} event handler
|
||||
* argument.
|
||||
@ -7855,8 +7850,7 @@ export interface BrowserContext {
|
||||
addListener(event: 'close', listener: (browserContext: BrowserContext) => void): this;
|
||||
|
||||
/**
|
||||
* Emitted when JavaScript within the page calls one of console API methods, e.g. `console.log` or `console.dir`. Also
|
||||
* emitted if the page throws an error or a warning.
|
||||
* Emitted when JavaScript within the page calls one of console API methods, e.g. `console.log` or `console.dir`.
|
||||
*
|
||||
* The arguments passed into `console.log` and the page are available on the {@link ConsoleMessage} event handler
|
||||
* argument.
|
||||
@ -8102,8 +8096,7 @@ export interface BrowserContext {
|
||||
prependListener(event: 'close', listener: (browserContext: BrowserContext) => void): this;
|
||||
|
||||
/**
|
||||
* Emitted when JavaScript within the page calls one of console API methods, e.g. `console.log` or `console.dir`. Also
|
||||
* emitted if the page throws an error or a warning.
|
||||
* Emitted when JavaScript within the page calls one of console API methods, e.g. `console.log` or `console.dir`.
|
||||
*
|
||||
* The arguments passed into `console.log` and the page are available on the {@link ConsoleMessage} event handler
|
||||
* argument.
|
||||
@ -8720,8 +8713,7 @@ export interface BrowserContext {
|
||||
waitForEvent(event: 'close', optionsOrPredicate?: { predicate?: (browserContext: BrowserContext) => boolean | Promise<boolean>, timeout?: number } | ((browserContext: BrowserContext) => boolean | Promise<boolean>)): Promise<BrowserContext>;
|
||||
|
||||
/**
|
||||
* Emitted when JavaScript within the page calls one of console API methods, e.g. `console.log` or `console.dir`. Also
|
||||
* emitted if the page throws an error or a warning.
|
||||
* Emitted when JavaScript within the page calls one of console API methods, e.g. `console.log` or `console.dir`.
|
||||
*
|
||||
* The arguments passed into `console.log` and the page are available on the {@link ConsoleMessage} event handler
|
||||
* argument.
|
||||
@ -13931,6 +13923,27 @@ export interface ElectronApplication {
|
||||
*/
|
||||
on(event: 'close', listener: () => void): this;
|
||||
|
||||
/**
|
||||
* Emitted when JavaScript within the Electron main process calls one of console API methods, e.g. `console.log` or
|
||||
* `console.dir`.
|
||||
*
|
||||
* The arguments passed into `console.log` are available on the {@link ConsoleMessage} event handler argument.
|
||||
*
|
||||
* **Usage**
|
||||
*
|
||||
* ```js
|
||||
* electronApp.on('console', async msg => {
|
||||
* const values = [];
|
||||
* for (const arg of msg.args())
|
||||
* values.push(await arg.jsonValue());
|
||||
* console.log(...values);
|
||||
* });
|
||||
* await electronApp.evaluate(() => console.log('hello', 5, { foo: 'bar' }));
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
on(event: 'console', listener: (consoleMessage: ConsoleMessage) => void): this;
|
||||
|
||||
/**
|
||||
* This event is issued for every window that is created **and loaded** in Electron. It contains a {@link Page} that
|
||||
* can be used for Playwright automation.
|
||||
@ -13942,6 +13955,11 @@ export interface ElectronApplication {
|
||||
*/
|
||||
once(event: 'close', listener: () => void): this;
|
||||
|
||||
/**
|
||||
* Adds an event listener that will be automatically removed after it is triggered once. See `addListener` for more information about this event.
|
||||
*/
|
||||
once(event: 'console', listener: (consoleMessage: ConsoleMessage) => void): this;
|
||||
|
||||
/**
|
||||
* Adds an event listener that will be automatically removed after it is triggered once. See `addListener` for more information about this event.
|
||||
*/
|
||||
@ -13952,6 +13970,27 @@ export interface ElectronApplication {
|
||||
*/
|
||||
addListener(event: 'close', listener: () => void): this;
|
||||
|
||||
/**
|
||||
* Emitted when JavaScript within the Electron main process calls one of console API methods, e.g. `console.log` or
|
||||
* `console.dir`.
|
||||
*
|
||||
* The arguments passed into `console.log` are available on the {@link ConsoleMessage} event handler argument.
|
||||
*
|
||||
* **Usage**
|
||||
*
|
||||
* ```js
|
||||
* electronApp.on('console', async msg => {
|
||||
* const values = [];
|
||||
* for (const arg of msg.args())
|
||||
* values.push(await arg.jsonValue());
|
||||
* console.log(...values);
|
||||
* });
|
||||
* await electronApp.evaluate(() => console.log('hello', 5, { foo: 'bar' }));
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
addListener(event: 'console', listener: (consoleMessage: ConsoleMessage) => void): this;
|
||||
|
||||
/**
|
||||
* This event is issued for every window that is created **and loaded** in Electron. It contains a {@link Page} that
|
||||
* can be used for Playwright automation.
|
||||
@ -13963,6 +14002,11 @@ export interface ElectronApplication {
|
||||
*/
|
||||
removeListener(event: 'close', listener: () => void): this;
|
||||
|
||||
/**
|
||||
* Removes an event listener added by `on` or `addListener`.
|
||||
*/
|
||||
removeListener(event: 'console', listener: (consoleMessage: ConsoleMessage) => void): this;
|
||||
|
||||
/**
|
||||
* Removes an event listener added by `on` or `addListener`.
|
||||
*/
|
||||
@ -13973,6 +14017,11 @@ export interface ElectronApplication {
|
||||
*/
|
||||
off(event: 'close', listener: () => void): this;
|
||||
|
||||
/**
|
||||
* Removes an event listener added by `on` or `addListener`.
|
||||
*/
|
||||
off(event: 'console', listener: (consoleMessage: ConsoleMessage) => void): this;
|
||||
|
||||
/**
|
||||
* Removes an event listener added by `on` or `addListener`.
|
||||
*/
|
||||
@ -13983,6 +14032,27 @@ export interface ElectronApplication {
|
||||
*/
|
||||
prependListener(event: 'close', listener: () => void): this;
|
||||
|
||||
/**
|
||||
* Emitted when JavaScript within the Electron main process calls one of console API methods, e.g. `console.log` or
|
||||
* `console.dir`.
|
||||
*
|
||||
* The arguments passed into `console.log` are available on the {@link ConsoleMessage} event handler argument.
|
||||
*
|
||||
* **Usage**
|
||||
*
|
||||
* ```js
|
||||
* electronApp.on('console', async msg => {
|
||||
* const values = [];
|
||||
* for (const arg of msg.args())
|
||||
* values.push(await arg.jsonValue());
|
||||
* console.log(...values);
|
||||
* });
|
||||
* await electronApp.evaluate(() => console.log('hello', 5, { foo: 'bar' }));
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
prependListener(event: 'console', listener: (consoleMessage: ConsoleMessage) => void): this;
|
||||
|
||||
/**
|
||||
* This event is issued for every window that is created **and loaded** in Electron. It contains a {@link Page} that
|
||||
* can be used for Playwright automation.
|
||||
@ -14039,6 +14109,27 @@ export interface ElectronApplication {
|
||||
*/
|
||||
waitForEvent(event: 'close', optionsOrPredicate?: { predicate?: () => boolean | Promise<boolean>, timeout?: number } | (() => boolean | Promise<boolean>)): Promise<void>;
|
||||
|
||||
/**
|
||||
* Emitted when JavaScript within the Electron main process calls one of console API methods, e.g. `console.log` or
|
||||
* `console.dir`.
|
||||
*
|
||||
* The arguments passed into `console.log` are available on the {@link ConsoleMessage} event handler argument.
|
||||
*
|
||||
* **Usage**
|
||||
*
|
||||
* ```js
|
||||
* electronApp.on('console', async msg => {
|
||||
* const values = [];
|
||||
* for (const arg of msg.args())
|
||||
* values.push(await arg.jsonValue());
|
||||
* console.log(...values);
|
||||
* });
|
||||
* await electronApp.evaluate(() => console.log('hello', 5, { foo: 'bar' }));
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
waitForEvent(event: 'console', optionsOrPredicate?: { predicate?: (consoleMessage: ConsoleMessage) => boolean | Promise<boolean>, timeout?: number } | ((consoleMessage: ConsoleMessage) => boolean | Promise<boolean>)): Promise<ConsoleMessage>;
|
||||
|
||||
/**
|
||||
* This event is issued for every window that is created **and loaded** in Electron. It contains a {@link Page} that
|
||||
* can be used for Playwright automation.
|
||||
|
@ -1453,7 +1453,6 @@ export type BrowserContextBindingCallEvent = {
|
||||
binding: BindingCallChannel,
|
||||
};
|
||||
export type BrowserContextConsoleEvent = {
|
||||
page: PageChannel,
|
||||
type: string,
|
||||
text: string,
|
||||
args: JSHandleChannel[],
|
||||
@ -1462,6 +1461,7 @@ export type BrowserContextConsoleEvent = {
|
||||
lineNumber: number,
|
||||
columnNumber: number,
|
||||
},
|
||||
page: PageChannel,
|
||||
};
|
||||
export type BrowserContextCloseEvent = {};
|
||||
export type BrowserContextDialogEvent = {
|
||||
@ -4082,15 +4082,27 @@ export type ElectronApplicationInitializer = {
|
||||
};
|
||||
export interface ElectronApplicationEventTarget {
|
||||
on(event: 'close', callback: (params: ElectronApplicationCloseEvent) => void): this;
|
||||
on(event: 'console', callback: (params: ElectronApplicationConsoleEvent) => void): this;
|
||||
}
|
||||
export interface ElectronApplicationChannel extends ElectronApplicationEventTarget, EventTargetChannel {
|
||||
_type_ElectronApplication: boolean;
|
||||
browserWindow(params: ElectronApplicationBrowserWindowParams, metadata?: CallMetadata): Promise<ElectronApplicationBrowserWindowResult>;
|
||||
evaluateExpression(params: ElectronApplicationEvaluateExpressionParams, metadata?: CallMetadata): Promise<ElectronApplicationEvaluateExpressionResult>;
|
||||
evaluateExpressionHandle(params: ElectronApplicationEvaluateExpressionHandleParams, metadata?: CallMetadata): Promise<ElectronApplicationEvaluateExpressionHandleResult>;
|
||||
updateSubscription(params: ElectronApplicationUpdateSubscriptionParams, metadata?: CallMetadata): Promise<ElectronApplicationUpdateSubscriptionResult>;
|
||||
close(params?: ElectronApplicationCloseParams, metadata?: CallMetadata): Promise<ElectronApplicationCloseResult>;
|
||||
}
|
||||
export type ElectronApplicationCloseEvent = {};
|
||||
export type ElectronApplicationConsoleEvent = {
|
||||
type: string,
|
||||
text: string,
|
||||
args: JSHandleChannel[],
|
||||
location: {
|
||||
url: string,
|
||||
lineNumber: number,
|
||||
columnNumber: number,
|
||||
},
|
||||
};
|
||||
export type ElectronApplicationBrowserWindowParams = {
|
||||
page: PageChannel,
|
||||
};
|
||||
@ -4122,12 +4134,21 @@ export type ElectronApplicationEvaluateExpressionHandleOptions = {
|
||||
export type ElectronApplicationEvaluateExpressionHandleResult = {
|
||||
handle: JSHandleChannel,
|
||||
};
|
||||
export type ElectronApplicationUpdateSubscriptionParams = {
|
||||
event: 'console',
|
||||
enabled: boolean,
|
||||
};
|
||||
export type ElectronApplicationUpdateSubscriptionOptions = {
|
||||
|
||||
};
|
||||
export type ElectronApplicationUpdateSubscriptionResult = void;
|
||||
export type ElectronApplicationCloseParams = {};
|
||||
export type ElectronApplicationCloseOptions = {};
|
||||
export type ElectronApplicationCloseResult = void;
|
||||
|
||||
export interface ElectronApplicationEvents {
|
||||
'close': ElectronApplicationCloseEvent;
|
||||
'console': ElectronApplicationConsoleEvent;
|
||||
}
|
||||
|
||||
// ----------- Android -----------
|
||||
|
@ -970,6 +970,21 @@ Browser:
|
||||
|
||||
close:
|
||||
|
||||
ConsoleMessage:
|
||||
type: mixin
|
||||
properties:
|
||||
type: string
|
||||
text: string
|
||||
args:
|
||||
type: array
|
||||
items: JSHandle
|
||||
location:
|
||||
type: object
|
||||
properties:
|
||||
url: string
|
||||
lineNumber: number
|
||||
columnNumber: number
|
||||
|
||||
|
||||
EventTarget:
|
||||
type: interface
|
||||
@ -1175,18 +1190,8 @@ BrowserContext:
|
||||
|
||||
console:
|
||||
parameters:
|
||||
$mixin: ConsoleMessage
|
||||
page: Page
|
||||
type: string
|
||||
text: string
|
||||
args:
|
||||
type: array
|
||||
items: JSHandle
|
||||
location:
|
||||
type: object
|
||||
properties:
|
||||
url: string
|
||||
lineNumber: number
|
||||
columnNumber: number
|
||||
|
||||
close:
|
||||
|
||||
@ -3208,11 +3213,21 @@ ElectronApplication:
|
||||
returns:
|
||||
handle: JSHandle
|
||||
|
||||
updateSubscription:
|
||||
parameters:
|
||||
event:
|
||||
type: enum
|
||||
literals:
|
||||
- console
|
||||
enabled: boolean
|
||||
|
||||
close:
|
||||
|
||||
events:
|
||||
close:
|
||||
|
||||
console:
|
||||
parameters:
|
||||
$mixin: ConsoleMessage
|
||||
|
||||
Android:
|
||||
type: interface
|
||||
|
@ -18,6 +18,7 @@ import type { BrowserWindow } from 'electron';
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
import { electronTest as test, expect } from './electronTest';
|
||||
import type { ConsoleMessage } from 'playwright';
|
||||
|
||||
test('should fire close event', async ({ launchElectronApp }) => {
|
||||
const electronApp = await launchElectronApp('electron-app.js');
|
||||
@ -31,6 +32,48 @@ test('should fire close event', async ({ launchElectronApp }) => {
|
||||
expect(events.join('|')).toBe('context|application');
|
||||
});
|
||||
|
||||
test('should fire console events', async ({ launchElectronApp }) => {
|
||||
const electronApp = await launchElectronApp('electron-app.js');
|
||||
const messages = [];
|
||||
electronApp.on('console', message => messages.push({ type: message.type(), text: message.text() }));
|
||||
await electronApp.evaluate(() => {
|
||||
console.log('its type log');
|
||||
console.debug('its type debug');
|
||||
console.info('its type info');
|
||||
console.error('its type error');
|
||||
console.warn('its type warn');
|
||||
});
|
||||
await electronApp.close();
|
||||
expect(messages).toEqual([
|
||||
{ type: 'log', text: 'its type log' },
|
||||
{ type: 'debug', text: 'its type debug' },
|
||||
{ type: 'info', text: 'its type info' },
|
||||
{ type: 'error', text: 'its type error' },
|
||||
{ type: 'warning', text: 'its type warn' },
|
||||
]);
|
||||
});
|
||||
|
||||
test('should fire console events with handles and complex objects', async ({ launchElectronApp }) => {
|
||||
const electronApp = await launchElectronApp('electron-app.js');
|
||||
const messages: ConsoleMessage[] = [];
|
||||
electronApp.on('console', message => messages.push(message));
|
||||
await electronApp.evaluate(() => {
|
||||
globalThis.complexObject = [{ a: 1, b: 2, c: 3 }, { a: 4, b: 5, c: 6 }, { a: 7, b: 8, c: 9 }];
|
||||
console.log(globalThis.complexObject[0], globalThis.complexObject[1], globalThis.complexObject[2]);
|
||||
});
|
||||
expect(messages.length).toBe(1);
|
||||
const message = messages[0];
|
||||
expect(message.text()).toBe('{a: 1, b: 2, c: 3} {a: 4, b: 5, c: 6} {a: 7, b: 8, c: 9}');
|
||||
expect(message.args().length).toBe(3);
|
||||
expect(await message.args()[0].jsonValue()).toEqual({ a: 1, b: 2, c: 3 });
|
||||
expect(await message.args()[0].evaluate(part => part === globalThis.complexObject[0])).toBeTruthy();
|
||||
expect(await message.args()[1].jsonValue()).toEqual({ a: 4, b: 5, c: 6 });
|
||||
expect(await message.args()[1].evaluate(part => part === globalThis.complexObject[1])).toBeTruthy();
|
||||
expect(await message.args()[2].jsonValue()).toEqual({ a: 7, b: 8, c: 9 });
|
||||
expect(await message.args()[2].evaluate(part => part === globalThis.complexObject[2])).toBeTruthy();
|
||||
await electronApp.close();
|
||||
});
|
||||
|
||||
test('should dispatch ready event', async ({ launchElectronApp }) => {
|
||||
const electronApp = await launchElectronApp('electron-app-ready-event.js');
|
||||
const events = await electronApp.evaluate(() => globalThis.__playwrightLog);
|
||||
|
Loading…
Reference in New Issue
Block a user