2022-09-21 06:10:50 +00:00
|
|
|
/**
|
|
|
|
* Copyright 2022 Google Inc. All rights reserved.
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
2023-02-20 12:00:29 +00:00
|
|
|
import * as Bidi from 'chromium-bidi/lib/cjs/protocol/protocol.js';
|
|
|
|
|
2023-03-15 16:51:34 +00:00
|
|
|
import {HTTPResponse} from '../../api/HTTPResponse.js';
|
2023-03-10 15:59:02 +00:00
|
|
|
import {
|
|
|
|
Page as PageBase,
|
|
|
|
PageEmittedEvents,
|
|
|
|
WaitForOptions,
|
|
|
|
} from '../../api/Page.js';
|
2023-02-20 12:00:29 +00:00
|
|
|
import {ConsoleMessage, ConsoleMessageLocation} from '../ConsoleMessage.js';
|
2023-02-28 10:10:14 +00:00
|
|
|
import {EvaluateFunc, HandleFor} from '../types.js';
|
2023-02-15 23:09:31 +00:00
|
|
|
|
2023-02-28 10:10:14 +00:00
|
|
|
import {Context, getBidiHandle} from './Context.js';
|
2023-02-15 23:09:31 +00:00
|
|
|
import {BidiSerializer} from './Serializer.js';
|
2023-02-15 10:29:18 +00:00
|
|
|
|
2022-09-21 06:10:50 +00:00
|
|
|
/**
|
|
|
|
* @internal
|
|
|
|
*/
|
|
|
|
export class Page extends PageBase {
|
2023-02-28 10:10:14 +00:00
|
|
|
#context: Context;
|
2023-02-20 12:00:29 +00:00
|
|
|
#subscribedEvents = [
|
|
|
|
'log.entryAdded',
|
2023-03-10 15:59:02 +00:00
|
|
|
'browsingContext.load',
|
2023-02-20 12:00:29 +00:00
|
|
|
] as Bidi.Session.SubscribeParameters['events'];
|
2023-03-10 15:59:02 +00:00
|
|
|
|
2023-02-28 10:10:14 +00:00
|
|
|
#boundOnLogEntryAdded = this.#onLogEntryAdded.bind(this);
|
2023-03-10 15:59:02 +00:00
|
|
|
#boundOnLoaded = this.#onLoad.bind(this);
|
2022-09-21 06:10:50 +00:00
|
|
|
|
2023-02-28 10:10:14 +00:00
|
|
|
constructor(context: Context) {
|
2022-09-21 06:10:50 +00:00
|
|
|
super();
|
2023-02-28 10:10:14 +00:00
|
|
|
this.#context = context;
|
2023-02-20 12:00:29 +00:00
|
|
|
|
2023-03-01 10:09:17 +00:00
|
|
|
this.#context.connection.send('session.subscribe', {
|
2023-02-20 12:00:29 +00:00
|
|
|
events: this.#subscribedEvents,
|
2023-03-01 10:09:17 +00:00
|
|
|
contexts: [this.#context.id],
|
2023-02-20 12:00:29 +00:00
|
|
|
});
|
|
|
|
|
2023-02-28 10:10:14 +00:00
|
|
|
this.#context.on('log.entryAdded', this.#boundOnLogEntryAdded);
|
2023-03-10 15:59:02 +00:00
|
|
|
this.#context.on('browsingContext.load', this.#boundOnLoaded);
|
2023-02-20 12:00:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#onLogEntryAdded(event: Bidi.Log.LogEntry): void {
|
|
|
|
if (isConsoleLogEntry(event)) {
|
|
|
|
const args = event.args.map(arg => {
|
2023-02-28 10:10:14 +00:00
|
|
|
return getBidiHandle(this.#context, arg);
|
2023-02-20 12:00:29 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
const text = args
|
|
|
|
.reduce((value, arg) => {
|
|
|
|
const parsedValue = arg.isPrimitiveValue
|
2023-02-28 10:10:14 +00:00
|
|
|
? BidiSerializer.deserialize(arg.remoteValue())
|
2023-02-20 12:00:29 +00:00
|
|
|
: arg.toString();
|
|
|
|
return `${value} ${parsedValue}`;
|
|
|
|
}, '')
|
|
|
|
.slice(1);
|
|
|
|
|
|
|
|
this.emit(
|
|
|
|
PageEmittedEvents.Console,
|
|
|
|
new ConsoleMessage(
|
|
|
|
event.method as any,
|
|
|
|
text,
|
|
|
|
args,
|
|
|
|
getStackTraceLocations(event.stackTrace)
|
|
|
|
)
|
|
|
|
);
|
|
|
|
} else if (isJavaScriptLogEntry(event)) {
|
|
|
|
this.emit(
|
|
|
|
PageEmittedEvents.Console,
|
|
|
|
new ConsoleMessage(
|
|
|
|
event.level as any,
|
|
|
|
event.text ?? '',
|
|
|
|
[],
|
|
|
|
getStackTraceLocations(event.stackTrace)
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
2022-09-21 06:10:50 +00:00
|
|
|
}
|
|
|
|
|
2023-03-10 15:59:02 +00:00
|
|
|
#onLoad(_event: Bidi.BrowsingContext.NavigationInfo): void {
|
|
|
|
this.emit(PageEmittedEvents.Load);
|
|
|
|
}
|
|
|
|
|
2022-09-21 06:10:50 +00:00
|
|
|
override async close(): Promise<void> {
|
2023-03-01 10:09:17 +00:00
|
|
|
await this.#context.connection.send('session.unsubscribe', {
|
2023-02-28 10:10:14 +00:00
|
|
|
events: this.#subscribedEvents,
|
2023-03-01 10:09:17 +00:00
|
|
|
contexts: [this.#context.id],
|
2022-09-21 06:10:50 +00:00
|
|
|
});
|
2023-02-20 12:00:29 +00:00
|
|
|
|
2023-03-01 10:09:17 +00:00
|
|
|
await this.#context.connection.send('browsingContext.close', {
|
|
|
|
context: this.#context.id,
|
2023-02-20 12:00:29 +00:00
|
|
|
});
|
|
|
|
|
2023-02-28 10:10:14 +00:00
|
|
|
this.#context.off('log.entryAdded', this.#boundOnLogEntryAdded);
|
2023-03-10 15:59:02 +00:00
|
|
|
this.#context.off('browsingContext.load', this.#boundOnLogEntryAdded);
|
2022-09-21 06:10:50 +00:00
|
|
|
}
|
|
|
|
|
2023-02-15 10:29:18 +00:00
|
|
|
override async evaluateHandle<
|
|
|
|
Params extends unknown[],
|
|
|
|
Func extends EvaluateFunc<Params> = EvaluateFunc<Params>
|
|
|
|
>(
|
|
|
|
pageFunction: Func | string,
|
|
|
|
...args: Params
|
|
|
|
): Promise<HandleFor<Awaited<ReturnType<Func>>>> {
|
2023-02-28 10:10:14 +00:00
|
|
|
return this.#context.evaluateHandle(pageFunction, ...args);
|
2023-02-15 10:29:18 +00:00
|
|
|
}
|
|
|
|
|
2022-09-21 06:10:50 +00:00
|
|
|
override async evaluate<
|
|
|
|
Params extends unknown[],
|
|
|
|
Func extends EvaluateFunc<Params> = EvaluateFunc<Params>
|
|
|
|
>(
|
|
|
|
pageFunction: Func | string,
|
2023-02-02 14:14:28 +00:00
|
|
|
...args: Params
|
2022-09-21 06:10:50 +00:00
|
|
|
): Promise<Awaited<ReturnType<Func>>> {
|
2023-02-28 10:10:14 +00:00
|
|
|
return this.#context.evaluate(pageFunction, ...args);
|
2022-09-21 06:10:50 +00:00
|
|
|
}
|
2023-03-10 15:59:02 +00:00
|
|
|
|
|
|
|
override async goto(
|
|
|
|
url: string,
|
|
|
|
options?: WaitForOptions & {
|
|
|
|
referer?: string | undefined;
|
|
|
|
referrerPolicy?: string | undefined;
|
|
|
|
}
|
|
|
|
): Promise<HTTPResponse | null> {
|
|
|
|
return this.#context.goto(url, options);
|
|
|
|
}
|
|
|
|
|
|
|
|
override url(): string {
|
|
|
|
return this.#context.url();
|
|
|
|
}
|
|
|
|
|
|
|
|
override setDefaultNavigationTimeout(timeout: number): void {
|
|
|
|
this.#context._timeoutSettings.setDefaultNavigationTimeout(timeout);
|
|
|
|
}
|
|
|
|
|
|
|
|
override setDefaultTimeout(timeout: number): void {
|
|
|
|
this.#context._timeoutSettings.setDefaultTimeout(timeout);
|
|
|
|
}
|
2022-09-21 06:10:50 +00:00
|
|
|
}
|
2023-02-20 12:00:29 +00:00
|
|
|
|
|
|
|
function isConsoleLogEntry(
|
|
|
|
event: Bidi.Log.LogEntry
|
|
|
|
): event is Bidi.Log.ConsoleLogEntry {
|
|
|
|
return event.type === 'console';
|
|
|
|
}
|
|
|
|
|
|
|
|
function isJavaScriptLogEntry(
|
|
|
|
event: Bidi.Log.LogEntry
|
|
|
|
): event is Bidi.Log.JavascriptLogEntry {
|
|
|
|
return event.type === 'javascript';
|
|
|
|
}
|
|
|
|
|
|
|
|
function getStackTraceLocations(stackTrace?: Bidi.Script.StackTrace) {
|
|
|
|
const stackTraceLocations: ConsoleMessageLocation[] = [];
|
|
|
|
if (stackTrace) {
|
|
|
|
for (const callFrame of stackTrace.callFrames) {
|
|
|
|
stackTraceLocations.push({
|
|
|
|
url: callFrame.url,
|
|
|
|
lineNumber: callFrame.lineNumber,
|
|
|
|
columnNumber: callFrame.columnNumber,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return stackTraceLocations;
|
|
|
|
}
|