feat(webkit): dialogs (#75)

This commit is contained in:
Joel Einbinder 2019-11-27 12:24:52 -08:00 committed by GitHub
parent d70133b232
commit 49f8963bf1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 105 additions and 2 deletions

View file

@ -373,7 +373,7 @@ export class Page extends EventEmitter {
this.emit(Events.Page.Console, message); this.emit(Events.Page.Console, message);
} }
_onDialog(event) { _onDialog(event : Protocol.Page.javascriptDialogOpeningPayload) {
let dialogType = null; let dialogType = null;
if (event.type === 'alert') if (event.type === 'alert')
dialogType = DialogType.Alert; dialogType = DialogType.Alert;

70
src/webkit/Dialog.ts Normal file
View file

@ -0,0 +1,70 @@
/**
* Copyright 2017 Google Inc. All rights reserved.
* Modifications copyright (c) Microsoft Corporation.
*
* 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.
*/
import { TargetSession } from './Connection';
import { assert } from '../helper';
export class Dialog {
private _client: TargetSession;
private _type: string;
private _message: string;
private _handled = false;
private _defaultValue: string;
constructor(client: TargetSession, type: string, message: string, defaultValue: (string | undefined) = '') {
this._client = client;
this._type = type;
this._message = message;
this._defaultValue = defaultValue;
}
type(): string {
return this._type;
}
message(): string {
return this._message;
}
defaultValue(): string {
return this._defaultValue;
}
async accept(promptText: string | undefined) {
assert(!this._handled, 'Cannot accept dialog which is already handled!');
this._handled = true;
await this._client.send('Dialog.handleJavaScriptDialog', {
accept: true,
promptText: promptText
});
}
async dismiss() {
assert(!this._handled, 'Cannot dismiss dialog which is already handled!');
this._handled = true;
await this._client.send('Dialog.handleJavaScriptDialog', {
accept: false
});
}
}
export const DialogType = {
Alert: 'alert',
BeforeUnload: 'beforeunload',
Confirm: 'confirm',
Prompt: 'prompt'
};

View file

@ -34,6 +34,7 @@ import { Target } from './Target';
import { TaskQueue } from './TaskQueue'; import { TaskQueue } from './TaskQueue';
import * as input from '../input'; import * as input from '../input';
import * as types from '../types'; import * as types from '../types';
import { Dialog, DialogType } from './Dialog';
const writeFileAsync = helper.promisify(fs.writeFile); const writeFileAsync = helper.promisify(fs.writeFile);
@ -94,6 +95,7 @@ export class Page extends EventEmitter {
return Promise.all([ return Promise.all([
this._frameManager.initialize(), this._frameManager.initialize(),
this._session.send('Console.enable'), this._session.send('Console.enable'),
this._session.send('Dialog.enable'),
]); ]);
} }
@ -105,9 +107,25 @@ export class Page extends EventEmitter {
helper.addEventListener(this._session, 'Page.loadEventFired', event => this.emit(Events.Page.Load)), 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, 'Console.messageAdded', event => this._onConsoleMessage(event)),
helper.addEventListener(this._session, 'Page.domContentEventFired', event => this.emit(Events.Page.DOMContentLoaded)), helper.addEventListener(this._session, 'Page.domContentEventFired', event => this.emit(Events.Page.DOMContentLoaded)),
helper.addEventListener(this._session, 'Dialog.javascriptDialogOpening', event => this._onDialog(event))
]; ];
} }
_onDialog(event: Protocol.Dialog.javascriptDialogOpeningPayload) {
let dialogType = null;
if (event.type === 'alert')
dialogType = DialogType.Alert;
else if (event.type === 'confirm')
dialogType = DialogType.Confirm;
else if (event.type === 'prompt')
dialogType = DialogType.Prompt;
else if (event.type === 'beforeunload')
dialogType = DialogType.BeforeUnload;
assert(dialogType, 'Unknown javascript dialog type: ' + event.type);
const dialog = new Dialog(this._session, dialogType, event.message, event.defaultPrompt);
this.emit(Events.Page.Dialog, dialog);
}
_setTarget(newTarget: Target) { _setTarget(newTarget: Target) {
this._target = newTarget; this._target = newTarget;
this._target._isClosedPromise.then(() => { this._target._isClosedPromise.then(() => {

View file

@ -19,6 +19,7 @@ export const Events = {
Page: { Page: {
Close: 'close', Close: 'close',
Console: 'console', Console: 'console',
Dialog: 'dialog',
DOMContentLoaded: 'domcontentloaded', DOMContentLoaded: 'domcontentloaded',
Request: 'request', Request: 'request',
Response: 'response', Response: 'response',

View file

@ -19,7 +19,7 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
const {it, fit, xit} = testRunner; const {it, fit, xit} = testRunner;
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner; const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
describe.skip(WEBKIT)('Page.Events.Dialog', function() { describe('Page.Events.Dialog', function() {
it('should fire', async({page, server}) => { it('should fire', async({page, server}) => {
page.on('dialog', dialog => { page.on('dialog', dialog => {
expect(dialog.type()).toBe('alert'); expect(dialog.type()).toBe('alert');
@ -46,5 +46,19 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
const result = await page.evaluate(() => prompt('question?')); const result = await page.evaluate(() => prompt('question?'));
expect(result).toBe(null); expect(result).toBe(null);
}); });
it('should accept the confirm prompt', async({page, server}) => {
page.on('dialog', dialog => {
dialog.accept();
});
const result = await page.evaluate(() => confirm('boolean?'));
expect(result).toBe(true);
});
it('should dismiss the confirm prompt', async({page, server}) => {
page.on('dialog', dialog => {
dialog.dismiss();
});
const result = await page.evaluate(() => confirm('boolean?'));
expect(result).toBe(false);
});
}); });
}; };