chore(webkit): remove most session usages from Page (#181)
These are moved to FrameManager, so that we can reuse Page between browsers.
This commit is contained in:
parent
f5cd742b79
commit
b3817aab2a
|
|
@ -30,6 +30,7 @@ import { NetworkManager, NetworkManagerEvents } from './NetworkManager';
|
||||||
import { Page } from './Page';
|
import { Page } from './Page';
|
||||||
import { Protocol } from './protocol';
|
import { Protocol } from './protocol';
|
||||||
import { DOMWorldDelegate } from './JSHandle';
|
import { DOMWorldDelegate } from './JSHandle';
|
||||||
|
import * as dialog from '../dialog';
|
||||||
|
|
||||||
export const FrameManagerEvents = {
|
export const FrameManagerEvents = {
|
||||||
FrameNavigatedWithinDocument: Symbol('FrameNavigatedWithinDocument'),
|
FrameNavigatedWithinDocument: Symbol('FrameNavigatedWithinDocument'),
|
||||||
|
|
@ -77,8 +78,17 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate {
|
||||||
this._handleFrameTree(frameTree);
|
this._handleFrameTree(frameTree);
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
this._session.send('Runtime.enable'),
|
this._session.send('Runtime.enable'),
|
||||||
|
this._session.send('Console.enable'),
|
||||||
|
this._session.send('Dialog.enable'),
|
||||||
|
this._session.send('Page.setInterceptFileChooserDialog', { enabled: true }),
|
||||||
this._networkManager.initialize(),
|
this._networkManager.initialize(),
|
||||||
]);
|
]);
|
||||||
|
if (this._page._userAgent !== null)
|
||||||
|
await this._session.send('Page.overrideUserAgent', { value: this._page._userAgent });
|
||||||
|
if (this._page._emulatedMediaType !== undefined)
|
||||||
|
await this._session.send('Page.setEmulatedMedia', { media: this._page._emulatedMediaType || '' });
|
||||||
|
if (!this._page._javascriptEnabled)
|
||||||
|
await this._session.send('Emulation.setJavaScriptEnabled', { enabled: this._page._javascriptEnabled });
|
||||||
}
|
}
|
||||||
|
|
||||||
_addSessionListeners() {
|
_addSessionListeners() {
|
||||||
|
|
@ -88,17 +98,22 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate {
|
||||||
helper.addEventListener(this._session, 'Page.frameDetached', event => this._onFrameDetached(event.frameId)),
|
helper.addEventListener(this._session, 'Page.frameDetached', event => this._onFrameDetached(event.frameId)),
|
||||||
helper.addEventListener(this._session, 'Page.frameStoppedLoading', event => this._onFrameStoppedLoading(event.frameId)),
|
helper.addEventListener(this._session, 'Page.frameStoppedLoading', event => this._onFrameStoppedLoading(event.frameId)),
|
||||||
helper.addEventListener(this._session, 'Runtime.executionContextCreated', event => this._onExecutionContextCreated(event.context)),
|
helper.addEventListener(this._session, 'Runtime.executionContextCreated', event => this._onExecutionContextCreated(event.context)),
|
||||||
|
helper.addEventListener(this._session, 'Page.loadEventFired', event => this._page.emit(Events.Page.Load)),
|
||||||
|
helper.addEventListener(this._session, 'Console.messageAdded', event => this._onConsoleMessage(event)),
|
||||||
|
helper.addEventListener(this._session, 'Page.domContentEventFired', event => this._page.emit(Events.Page.DOMContentLoaded)),
|
||||||
|
helper.addEventListener(this._session, 'Dialog.javascriptDialogOpening', event => this._onDialog(event)),
|
||||||
|
helper.addEventListener(this._session, 'Page.fileChooserOpened', event => this._onFileChooserOpened(event))
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
_swapSessionOnNavigation(newSession) {
|
async _swapSessionOnNavigation(newSession: TargetSession) {
|
||||||
helper.removeEventListeners(this._sessionListeners);
|
helper.removeEventListeners(this._sessionListeners);
|
||||||
this.disconnectFromTarget();
|
this.disconnectFromTarget();
|
||||||
this._session = newSession;
|
this._session = newSession;
|
||||||
this._addSessionListeners();
|
this._addSessionListeners();
|
||||||
this._networkManager.setSession(newSession);
|
this._networkManager.setSession(newSession);
|
||||||
this.emit(FrameManagerEvents.TargetSwappedOnNavigation);
|
this.emit(FrameManagerEvents.TargetSwappedOnNavigation);
|
||||||
// this.initialize() will be called by page.
|
await this.initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
disconnectFromTarget() {
|
disconnectFromTarget() {
|
||||||
|
|
@ -284,6 +299,55 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate {
|
||||||
}, html);
|
}, html);
|
||||||
await watchDog.waitForNavigation();
|
await watchDog.waitForNavigation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async _onConsoleMessage(event: Protocol.Console.messageAddedPayload) {
|
||||||
|
const { type, level, text, parameters, url, line: lineNumber, column: columnNumber } = event.message;
|
||||||
|
let derivedType: string = type;
|
||||||
|
if (type === 'log')
|
||||||
|
derivedType = level;
|
||||||
|
else if (type === 'timing')
|
||||||
|
derivedType = 'timeEnd';
|
||||||
|
const mainFrameContext = await this.mainFrame().executionContext();
|
||||||
|
const handles = (parameters || []).map(p => {
|
||||||
|
let context: js.ExecutionContext | null = null;
|
||||||
|
if (p.objectId) {
|
||||||
|
const objectId = JSON.parse(p.objectId);
|
||||||
|
context = this._contextIdToContext.get(objectId.injectedScriptId);
|
||||||
|
} else {
|
||||||
|
context = mainFrameContext;
|
||||||
|
}
|
||||||
|
return context._createHandle(p);
|
||||||
|
});
|
||||||
|
this._page._addConsoleMessage(derivedType, handles, { url, lineNumber, columnNumber }, handles.length ? undefined : text);
|
||||||
|
}
|
||||||
|
|
||||||
|
_onDialog(event: Protocol.Dialog.javascriptDialogOpeningPayload) {
|
||||||
|
this._page.emit(Events.Page.Dialog, new dialog.Dialog(
|
||||||
|
event.type as dialog.DialogType,
|
||||||
|
event.message,
|
||||||
|
async (accept: boolean, promptText?: string) => {
|
||||||
|
await this._session.send('Dialog.handleJavaScriptDialog', { accept, promptText });
|
||||||
|
},
|
||||||
|
event.defaultPrompt));
|
||||||
|
}
|
||||||
|
|
||||||
|
async _onFileChooserOpened(event: {frameId: Protocol.Network.FrameId, element: Protocol.Runtime.RemoteObject}) {
|
||||||
|
const context = await this.frame(event.frameId)._utilityContext();
|
||||||
|
const handle = context._createHandle(event.element).asElement()!;
|
||||||
|
this._page._onFileChooserOpened(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
async setUserAgent(userAgent: string) {
|
||||||
|
await this._session.send('Page.overrideUserAgent', { value: userAgent });
|
||||||
|
}
|
||||||
|
|
||||||
|
async setEmulatedMedia(type?: string | null) {
|
||||||
|
await this._session.send('Page.setEmulatedMedia', { media: type || '' });
|
||||||
|
}
|
||||||
|
|
||||||
|
async setJavaScriptEnabled(enabled: boolean) {
|
||||||
|
await this._session.send('Emulation.setJavaScriptEnabled', { enabled });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -17,10 +17,9 @@
|
||||||
|
|
||||||
import { EventEmitter } from 'events';
|
import { EventEmitter } from 'events';
|
||||||
import * as console from '../console';
|
import * as console from '../console';
|
||||||
import * as dialog from '../dialog';
|
|
||||||
import * as dom from '../dom';
|
import * as dom from '../dom';
|
||||||
import * as frames from '../frames';
|
import * as frames from '../frames';
|
||||||
import { assert, helper, RegisteredListener } from '../helper';
|
import { assert, helper } from '../helper';
|
||||||
import * as input from '../input';
|
import * as input from '../input';
|
||||||
import { ClickOptions, mediaColorSchemes, mediaTypes, MultiClickOptions } from '../input';
|
import { ClickOptions, mediaColorSchemes, mediaTypes, MultiClickOptions } from '../input';
|
||||||
import * as js from '../javascript';
|
import * as js from '../javascript';
|
||||||
|
|
@ -29,7 +28,7 @@ import { Screenshotter } from '../screenshotter';
|
||||||
import { TimeoutSettings } from '../TimeoutSettings';
|
import { TimeoutSettings } from '../TimeoutSettings';
|
||||||
import * as types from '../types';
|
import * as types from '../types';
|
||||||
import { Browser, BrowserContext } from './Browser';
|
import { Browser, BrowserContext } from './Browser';
|
||||||
import { TargetSession, TargetSessionEvents } from './Connection';
|
import { TargetSession } from './Connection';
|
||||||
import { Events } from './events';
|
import { Events } from './events';
|
||||||
import { FrameManager, FrameManagerEvents } from './FrameManager';
|
import { FrameManager, FrameManagerEvents } from './FrameManager';
|
||||||
import { RawKeyboardImpl, RawMouseImpl } from './Input';
|
import { RawKeyboardImpl, RawMouseImpl } from './Input';
|
||||||
|
|
@ -41,6 +40,9 @@ export class Page extends EventEmitter {
|
||||||
private _closed = false;
|
private _closed = false;
|
||||||
private _closedCallback: () => void;
|
private _closedCallback: () => void;
|
||||||
private _closedPromise: Promise<void>;
|
private _closedPromise: Promise<void>;
|
||||||
|
private _disconnected = false;
|
||||||
|
private _disconnectedCallback: (e: Error) => void;
|
||||||
|
private _disconnectedPromise: Promise<Error>;
|
||||||
_session: TargetSession;
|
_session: TargetSession;
|
||||||
private _browserContext: BrowserContext;
|
private _browserContext: BrowserContext;
|
||||||
private _keyboard: input.Keyboard;
|
private _keyboard: input.Keyboard;
|
||||||
|
|
@ -49,18 +51,16 @@ export class Page extends EventEmitter {
|
||||||
private _frameManager: FrameManager;
|
private _frameManager: FrameManager;
|
||||||
private _bootstrapScripts: string[] = [];
|
private _bootstrapScripts: string[] = [];
|
||||||
_javascriptEnabled = true;
|
_javascriptEnabled = true;
|
||||||
private _userAgent: string | null = null;
|
_userAgent: string | null = null;
|
||||||
|
_emulatedMediaType: string | undefined;
|
||||||
private _viewport: types.Viewport | null = null;
|
private _viewport: types.Viewport | null = null;
|
||||||
_screenshotter: Screenshotter;
|
_screenshotter: Screenshotter;
|
||||||
private _workers = new Map<string, Worker>();
|
|
||||||
private _disconnectPromise: Promise<Error> | undefined;
|
|
||||||
private _sessionListeners: RegisteredListener[] = [];
|
|
||||||
private _emulatedMediaType: string | undefined;
|
|
||||||
private _fileChooserInterceptors = new Set<(chooser: FileChooser) => void>();
|
private _fileChooserInterceptors = new Set<(chooser: FileChooser) => void>();
|
||||||
|
|
||||||
constructor(session: TargetSession, browserContext: BrowserContext) {
|
constructor(session: TargetSession, browserContext: BrowserContext) {
|
||||||
super();
|
super();
|
||||||
this._closedPromise = new Promise(f => this._closedCallback = f);
|
this._closedPromise = new Promise(f => this._closedCallback = f);
|
||||||
|
this._disconnectedPromise = new Promise(f => this._disconnectedCallback = f);
|
||||||
this._keyboard = new input.Keyboard(new RawKeyboardImpl(session));
|
this._keyboard = new input.Keyboard(new RawKeyboardImpl(session));
|
||||||
this._mouse = new input.Mouse(new RawMouseImpl(session), this._keyboard);
|
this._mouse = new input.Mouse(new RawMouseImpl(session), this._keyboard);
|
||||||
this._timeoutSettings = new TimeoutSettings();
|
this._timeoutSettings = new TimeoutSettings();
|
||||||
|
|
@ -68,7 +68,7 @@ export class Page extends EventEmitter {
|
||||||
|
|
||||||
this._screenshotter = new Screenshotter(this, new WKScreenshotDelegate(session), browserContext.browser());
|
this._screenshotter = new Screenshotter(this, new WKScreenshotDelegate(session), browserContext.browser());
|
||||||
|
|
||||||
this._setSession(session);
|
this._session = session;
|
||||||
this._browserContext = browserContext;
|
this._browserContext = browserContext;
|
||||||
|
|
||||||
this._frameManager.on(FrameManagerEvents.FrameAttached, event => this.emit(Events.Page.FrameAttached, event));
|
this._frameManager.on(FrameManagerEvents.FrameAttached, event => this.emit(Events.Page.FrameAttached, event));
|
||||||
|
|
@ -89,46 +89,20 @@ export class Page extends EventEmitter {
|
||||||
this._closedCallback();
|
this._closedCallback();
|
||||||
}
|
}
|
||||||
|
|
||||||
async _initialize() {
|
_didDisconnect() {
|
||||||
await Promise.all([
|
assert(!this._disconnected, 'Page disconnected twice');
|
||||||
this._frameManager.initialize(),
|
this._disconnected = true;
|
||||||
this._session.send('Console.enable'),
|
this._frameManager.disconnectFromTarget();
|
||||||
this._session.send('Dialog.enable'),
|
this._disconnectedCallback(new Error('Target closed'));
|
||||||
this._session.send('Page.setInterceptFileChooserDialog', { enabled: true }),
|
|
||||||
]);
|
|
||||||
if (this._userAgent !== null)
|
|
||||||
await this._session.send('Page.overrideUserAgent', { value: this._userAgent });
|
|
||||||
if (this._emulatedMediaType !== undefined)
|
|
||||||
await this._session.send('Page.setEmulatedMedia', { media: this._emulatedMediaType || '' });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_setSession(newSession: TargetSession) {
|
_initialize() {
|
||||||
helper.removeEventListeners(this._sessionListeners);
|
return this._frameManager.initialize();
|
||||||
this._session = newSession;
|
|
||||||
this._sessionListeners = [
|
|
||||||
helper.addEventListener(this._session, TargetSessionEvents.Disconnected, () => this._frameManager.disconnectFromTarget()),
|
|
||||||
helper.addEventListener(this._session, 'Page.loadEventFired', event => this.emit(Events.Page.Load)),
|
|
||||||
helper.addEventListener(this._session, 'Console.messageAdded', event => this._onConsoleMessage(event)),
|
|
||||||
helper.addEventListener(this._session, 'Page.domContentEventFired', event => this.emit(Events.Page.DOMContentLoaded)),
|
|
||||||
helper.addEventListener(this._session, 'Dialog.javascriptDialogOpening', event => this._onDialog(event)),
|
|
||||||
helper.addEventListener(this._session, 'Page.fileChooserOpened', event => this._onFileChooserOpened(event))
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
_onDialog(event: Protocol.Dialog.javascriptDialogOpeningPayload) {
|
|
||||||
this.emit(Events.Page.Dialog, new dialog.Dialog(
|
|
||||||
event.type as dialog.DialogType,
|
|
||||||
event.message,
|
|
||||||
async (accept: boolean, promptText?: string) => {
|
|
||||||
await this._session.send('Dialog.handleJavaScriptDialog', { accept, promptText });
|
|
||||||
},
|
|
||||||
event.defaultPrompt));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async _swapSessionOnNavigation(newSession: TargetSession) {
|
async _swapSessionOnNavigation(newSession: TargetSession) {
|
||||||
this._setSession(newSession);
|
this._session = newSession;
|
||||||
this._frameManager._swapSessionOnNavigation(newSession);
|
await this._frameManager._swapSessionOnNavigation(newSession);
|
||||||
await this._initialize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
browser(): Browser {
|
browser(): Browser {
|
||||||
|
|
@ -143,25 +117,12 @@ export class Page extends EventEmitter {
|
||||||
this.emit('error', new Error('Page crashed!'));
|
this.emit('error', new Error('Page crashed!'));
|
||||||
}
|
}
|
||||||
|
|
||||||
async _onConsoleMessage(event: Protocol.Console.messageAddedPayload) {
|
_addConsoleMessage(type: string, args: js.JSHandle[], location: console.ConsoleMessageLocation, text?: string) {
|
||||||
const { type, level, text, parameters, url, line: lineNumber, column: columnNumber } = event.message;
|
if (!this.listenerCount(Events.Page.Console)) {
|
||||||
let derivedType: string = type;
|
args.forEach(arg => arg.dispose());
|
||||||
if (type === 'log')
|
return;
|
||||||
derivedType = level;
|
}
|
||||||
else if (type === 'timing')
|
this.emit(Events.Page.Console, new console.ConsoleMessage(type, text, args, location));
|
||||||
derivedType = 'timeEnd';
|
|
||||||
const mainFrameContext = await this.mainFrame().executionContext();
|
|
||||||
const handles = (parameters || []).map(p => {
|
|
||||||
let context: js.ExecutionContext | null = null;
|
|
||||||
if (p.objectId) {
|
|
||||||
const objectId = JSON.parse(p.objectId);
|
|
||||||
context = this._frameManager._contextIdToContext.get(objectId.injectedScriptId);
|
|
||||||
} else {
|
|
||||||
context = mainFrameContext;
|
|
||||||
}
|
|
||||||
return context._createHandle(p);
|
|
||||||
});
|
|
||||||
this.emit(Events.Page.Console, new console.ConsoleMessage(derivedType, handles.length ? undefined : text, handles, { url, lineNumber, columnNumber }));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mainFrame(): frames.Frame {
|
mainFrame(): frames.Frame {
|
||||||
|
|
@ -176,11 +137,6 @@ export class Page extends EventEmitter {
|
||||||
return this._frameManager.frames();
|
return this._frameManager.frames();
|
||||||
}
|
}
|
||||||
|
|
||||||
workers(): Worker[] {
|
|
||||||
return Array.from(this._workers.values());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
setDefaultNavigationTimeout(timeout: number) {
|
setDefaultNavigationTimeout(timeout: number) {
|
||||||
this._timeoutSettings.setDefaultNavigationTimeout(timeout);
|
this._timeoutSettings.setDefaultNavigationTimeout(timeout);
|
||||||
}
|
}
|
||||||
|
|
@ -228,7 +184,7 @@ export class Page extends EventEmitter {
|
||||||
|
|
||||||
async setUserAgent(userAgent: string) {
|
async setUserAgent(userAgent: string) {
|
||||||
this._userAgent = userAgent;
|
this._userAgent = userAgent;
|
||||||
await this._session.send('Page.overrideUserAgent', { value: userAgent });
|
this._frameManager.setUserAgent(userAgent);
|
||||||
}
|
}
|
||||||
|
|
||||||
url(): string {
|
url(): string {
|
||||||
|
|
@ -279,12 +235,6 @@ export class Page extends EventEmitter {
|
||||||
return await this._frameManager.mainFrame().waitForNavigation();
|
return await this._frameManager.mainFrame().waitForNavigation();
|
||||||
}
|
}
|
||||||
|
|
||||||
_sessionClosePromise() {
|
|
||||||
if (!this._disconnectPromise)
|
|
||||||
this._disconnectPromise = new Promise(fulfill => this._session.once(TargetSessionEvents.Disconnected, () => fulfill(new Error('Target closed'))));
|
|
||||||
return this._disconnectPromise;
|
|
||||||
}
|
|
||||||
|
|
||||||
async waitForRequest(urlOrPredicate: (string | Function), options: { timeout?: number; } = {}): Promise<Request> {
|
async waitForRequest(urlOrPredicate: (string | Function), options: { timeout?: number; } = {}): Promise<Request> {
|
||||||
const {
|
const {
|
||||||
timeout = this._timeoutSettings.timeout(),
|
timeout = this._timeoutSettings.timeout(),
|
||||||
|
|
@ -295,7 +245,7 @@ export class Page extends EventEmitter {
|
||||||
if (typeof urlOrPredicate === 'function')
|
if (typeof urlOrPredicate === 'function')
|
||||||
return !!(urlOrPredicate(request));
|
return !!(urlOrPredicate(request));
|
||||||
return false;
|
return false;
|
||||||
}, timeout, this._sessionClosePromise());
|
}, timeout, this._disconnectedPromise);
|
||||||
}
|
}
|
||||||
|
|
||||||
async waitForResponse(urlOrPredicate: (string | Function), options: { timeout?: number; } = {}): Promise<Response> {
|
async waitForResponse(urlOrPredicate: (string | Function), options: { timeout?: number; } = {}): Promise<Response> {
|
||||||
|
|
@ -308,7 +258,7 @@ export class Page extends EventEmitter {
|
||||||
if (typeof urlOrPredicate === 'function')
|
if (typeof urlOrPredicate === 'function')
|
||||||
return !!(urlOrPredicate(response));
|
return !!(urlOrPredicate(response));
|
||||||
return false;
|
return false;
|
||||||
}, timeout, this._sessionClosePromise());
|
}, timeout, this._disconnectedPromise);
|
||||||
}
|
}
|
||||||
|
|
||||||
async emulate(options: { viewport: types.Viewport; userAgent: string; }) {
|
async emulate(options: { viewport: types.Viewport; userAgent: string; }) {
|
||||||
|
|
@ -325,7 +275,7 @@ export class Page extends EventEmitter {
|
||||||
assert(!options.colorScheme || mediaColorSchemes.has(options.colorScheme), 'Unsupported color scheme: ' + options.colorScheme);
|
assert(!options.colorScheme || mediaColorSchemes.has(options.colorScheme), 'Unsupported color scheme: ' + options.colorScheme);
|
||||||
assert(!options.colorScheme, 'Media feature emulation is not supported');
|
assert(!options.colorScheme, 'Media feature emulation is not supported');
|
||||||
this._emulatedMediaType = typeof options.type === 'undefined' ? this._emulatedMediaType : options.type;
|
this._emulatedMediaType = typeof options.type === 'undefined' ? this._emulatedMediaType : options.type;
|
||||||
await this._session.send('Page.setEmulatedMedia', { media: this._emulatedMediaType || '' });
|
this._frameManager.setEmulatedMedia(this._emulatedMediaType);
|
||||||
}
|
}
|
||||||
|
|
||||||
async setViewport(viewport: types.Viewport) {
|
async setViewport(viewport: types.Viewport) {
|
||||||
|
|
@ -351,11 +301,11 @@ export class Page extends EventEmitter {
|
||||||
await this._session.send('Page.setBootstrapScript', { source });
|
await this._session.send('Page.setBootstrapScript', { source });
|
||||||
}
|
}
|
||||||
|
|
||||||
async setJavaScriptEnabled(enabled: boolean) {
|
setJavaScriptEnabled(enabled: boolean) {
|
||||||
if (this._javascriptEnabled === enabled)
|
if (this._javascriptEnabled === enabled)
|
||||||
return;
|
return;
|
||||||
this._javascriptEnabled = enabled;
|
this._javascriptEnabled = enabled;
|
||||||
await this._session.send('Emulation.setJavaScriptEnabled', { enabled });
|
return this._frameManager.setJavaScriptEnabled(enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
async setCacheEnabled(enabled: boolean = true) {
|
async setCacheEnabled(enabled: boolean = true) {
|
||||||
|
|
@ -371,6 +321,7 @@ export class Page extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
async close() {
|
async close() {
|
||||||
|
assert(!this._disconnected, 'Protocol error: Connection closed. Most likely the page has been closed.');
|
||||||
this.browser()._closePage(this);
|
this.browser()._closePage(this);
|
||||||
await this._closedPromise;
|
await this._closedPromise;
|
||||||
}
|
}
|
||||||
|
|
@ -392,11 +343,11 @@ export class Page extends EventEmitter {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async _onFileChooserOpened(event: {frameId: Protocol.Network.FrameId, element: Protocol.Runtime.RemoteObject}) {
|
async _onFileChooserOpened(handle: dom.ElementHandle) {
|
||||||
if (!this._fileChooserInterceptors.size)
|
if (!this._fileChooserInterceptors.size) {
|
||||||
|
await handle.dispose();
|
||||||
return;
|
return;
|
||||||
const context = await this._frameManager.frame(event.frameId)._utilityContext();
|
}
|
||||||
const handle = context._createHandle(event.element).asElement()!;
|
|
||||||
const interceptors = Array.from(this._fileChooserInterceptors);
|
const interceptors = Array.from(this._fileChooserInterceptors);
|
||||||
this._fileChooserInterceptors.clear();
|
this._fileChooserInterceptors.clear();
|
||||||
const multiple = await handle.evaluate((element: HTMLInputElement) => !!element.multiple);
|
const multiple = await handle.evaluate((element: HTMLInputElement) => !!element.multiple);
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ import { RegisteredListener } from '../helper';
|
||||||
import { Browser, BrowserContext } from './Browser';
|
import { Browser, BrowserContext } from './Browser';
|
||||||
import { Page } from './Page';
|
import { Page } from './Page';
|
||||||
import { Protocol } from './protocol';
|
import { Protocol } from './protocol';
|
||||||
import { isSwappedOutError, TargetSession } from './Connection';
|
import { isSwappedOutError, TargetSession, TargetSessionEvents } from './Connection';
|
||||||
|
|
||||||
const targetSymbol = Symbol('target');
|
const targetSymbol = Symbol('target');
|
||||||
|
|
||||||
|
|
@ -74,6 +74,11 @@ export class Target {
|
||||||
if (this.browser()._defaultViewport)
|
if (this.browser()._defaultViewport)
|
||||||
await page.setViewport(this.browser()._defaultViewport);
|
await page.setViewport(this.browser()._defaultViewport);
|
||||||
(page as any)[targetSymbol] = this;
|
(page as any)[targetSymbol] = this;
|
||||||
|
session.once(TargetSessionEvents.Disconnected, () => {
|
||||||
|
// Check that this target has not been swapped out.
|
||||||
|
if ((page as any)[targetSymbol] === this)
|
||||||
|
page._didDisconnect();
|
||||||
|
});
|
||||||
f(page);
|
f(page);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue