fix(misc): assorted fixes (#3031)

This commit is contained in:
Pavel Feldman 2020-07-21 23:48:21 -07:00 committed by GitHub
parent ced0bc2d1b
commit 2b0b0a9119
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 16 additions and 20 deletions

View File

@ -685,7 +685,7 @@ export class Frame {
let result; let result;
if (path !== null) { if (path !== null) {
let contents = await util.promisify(fs.readFile)(path, 'utf8'); let contents = await util.promisify(fs.readFile)(path, 'utf8');
contents += '//# sourceURL=' + path.replace(/\n/g, ''); contents += '\n//# sourceURL=' + path.replace(/\n/g, '');
result = (await context.evaluateHandleInternal(addScriptContent, { content: contents, type })).asElement()!; result = (await context.evaluateHandleInternal(addScriptContent, { content: contents, type })).asElement()!;
} else { } else {
result = (await context.evaluateHandleInternal(addScriptContent, { content: content!, type })).asElement()!; result = (await context.evaluateHandleInternal(addScriptContent, { content: content!, type })).asElement()!;
@ -740,7 +740,7 @@ export class Frame {
if (path !== null) { if (path !== null) {
let contents = await util.promisify(fs.readFile)(path, 'utf8'); let contents = await util.promisify(fs.readFile)(path, 'utf8');
contents += '/*# sourceURL=' + path.replace(/\n/g, '') + '*/'; contents += '\n/*# sourceURL=' + path.replace(/\n/g, '') + '*/';
return (await context.evaluateHandleInternal(addStyleContent, contents)).asElement()!; return (await context.evaluateHandleInternal(addStyleContent, contents)).asElement()!;
} }

View File

@ -26,7 +26,6 @@ import { Browser } from './browser';
import { Events } from '../../events'; import { Events } from '../../events';
import { TimeoutSettings } from '../../timeoutSettings'; import { TimeoutSettings } from '../../timeoutSettings';
import { Waiter } from './waiter'; import { Waiter } from './waiter';
import { TimeoutError } from '../../errors';
import { headersObjectToArray } from '../serializers'; import { headersObjectToArray } from '../serializers';
export class BrowserContext extends ChannelOwner<BrowserContextChannel, BrowserContextInitializer> { export class BrowserContext extends ChannelOwner<BrowserContextChannel, BrowserContextInitializer> {
@ -207,7 +206,7 @@ export class BrowserContext extends ChannelOwner<BrowserContextChannel, BrowserC
const timeout = this._timeoutSettings.timeout(typeof optionsOrPredicate === 'function' ? {} : optionsOrPredicate); const timeout = this._timeoutSettings.timeout(typeof optionsOrPredicate === 'function' ? {} : optionsOrPredicate);
const predicate = typeof optionsOrPredicate === 'function' ? optionsOrPredicate : optionsOrPredicate.predicate; const predicate = typeof optionsOrPredicate === 'function' ? optionsOrPredicate : optionsOrPredicate.predicate;
const waiter = new Waiter(); const waiter = new Waiter();
waiter.rejectOnTimeout(timeout, new TimeoutError(`Timeout while waiting for event "${event}"`)); waiter.rejectOnTimeout(timeout, `Timeout while waiting for event "${event}"`);
if (event !== Events.BrowserContext.Close) if (event !== Events.BrowserContext.Close)
waiter.rejectOnEvent(this, Events.BrowserContext.Close, new Error('Context closed')); waiter.rejectOnEvent(this, Events.BrowserContext.Close, new Error('Context closed'));
const result = await waiter.waitForEvent(this, event, predicate as any); const result = await waiter.waitForEvent(this, event, predicate as any);

View File

@ -23,7 +23,6 @@ import { serializeArgument, FuncOn, parseResult, SmartHandle, JSHandle } from '.
import { ElectronEvents, ElectronLaunchOptionsBase } from '../../server/electron'; import { ElectronEvents, ElectronLaunchOptionsBase } from '../../server/electron';
import { TimeoutSettings } from '../../timeoutSettings'; import { TimeoutSettings } from '../../timeoutSettings';
import { Waiter } from './waiter'; import { Waiter } from './waiter';
import { TimeoutError } from '../../errors';
import { Events } from '../../events'; import { Events } from '../../events';
import { LoggerSink } from '../../loggerSink'; import { LoggerSink } from '../../loggerSink';
import { envObjectToArray } from '../serializers'; import { envObjectToArray } from '../serializers';
@ -102,7 +101,7 @@ export class ElectronApplication extends ChannelOwner<ElectronApplicationChannel
const timeout = this._timeoutSettings.timeout(typeof optionsOrPredicate === 'function' ? {} : optionsOrPredicate); const timeout = this._timeoutSettings.timeout(typeof optionsOrPredicate === 'function' ? {} : optionsOrPredicate);
const predicate = typeof optionsOrPredicate === 'function' ? optionsOrPredicate : optionsOrPredicate.predicate; const predicate = typeof optionsOrPredicate === 'function' ? optionsOrPredicate : optionsOrPredicate.predicate;
const waiter = new Waiter(); const waiter = new Waiter();
waiter.rejectOnTimeout(timeout, new TimeoutError(`Timeout while waiting for event "${event}"`)); waiter.rejectOnTimeout(timeout, `Timeout while waiting for event "${event}"`);
if (event !== ElectronEvents.ElectronApplication.Close) if (event !== ElectronEvents.ElectronApplication.Close)
waiter.rejectOnEvent(this, ElectronEvents.ElectronApplication.Close, new Error('Electron application closed')); waiter.rejectOnEvent(this, ElectronEvents.ElectronApplication.Close, new Error('Electron application closed'));
const result = await waiter.waitForEvent(this, event, predicate as any); const result = await waiter.waitForEvent(this, event, predicate as any);

View File

@ -29,7 +29,6 @@ import { Page } from './page';
import { EventEmitter } from 'events'; import { EventEmitter } from 'events';
import { Waiter } from './waiter'; import { Waiter } from './waiter';
import { Events } from '../../events'; import { Events } from '../../events';
import { TimeoutError } from '../../errors';
const fsReadFileAsync = util.promisify(fs.readFile.bind(fs)); const fsReadFileAsync = util.promisify(fs.readFile.bind(fs));
@ -94,20 +93,21 @@ export class Frame extends ChannelOwner<FrameChannel, FrameInitializer> {
}); });
} }
private _setupNavigationWaiter(): Waiter { private _setupNavigationWaiter(options: types.TimeoutOptions): Waiter {
const waiter = new Waiter(); const waiter = new Waiter();
waiter.rejectOnEvent(this._page!, Events.Page.Close, new Error('Navigation failed because page was closed!')); waiter.rejectOnEvent(this._page!, Events.Page.Close, new Error('Navigation failed because page was closed!'));
waiter.rejectOnEvent(this._page!, Events.Page.Crash, new Error('Navigation failed because page crashed!')); waiter.rejectOnEvent(this._page!, Events.Page.Crash, new Error('Navigation failed because page crashed!'));
waiter.rejectOnEvent<Frame>(this._page!, Events.Page.FrameDetached, new Error('Navigating frame was detached!'), frame => frame === this); waiter.rejectOnEvent<Frame>(this._page!, Events.Page.FrameDetached, new Error('Navigating frame was detached!'), frame => frame === this);
const timeout = this._page!._timeoutSettings.navigationTimeout(options);
waiter.rejectOnTimeout(timeout, `Timeout ${timeout}ms exceeded.`);
return waiter; return waiter;
} }
async waitForNavigation(options: types.WaitForNavigationOptions = {}): Promise<network.Response | null> { async waitForNavigation(options: types.WaitForNavigationOptions = {}): Promise<network.Response | null> {
return this._wrapApiCall(this._apiName('waitForNavigation'), async () => { return this._wrapApiCall(this._apiName('waitForNavigation'), async () => {
const waitUntil = verifyLoadState('waitUntil', options.waitUntil === undefined ? 'load' : options.waitUntil); const waitUntil = verifyLoadState('waitUntil', options.waitUntil === undefined ? 'load' : options.waitUntil);
const timeout = this._page!._timeoutSettings.navigationTimeout(options); const waiter = this._setupNavigationWaiter(options);
const waiter = this._setupNavigationWaiter();
waiter.rejectOnTimeout(timeout, new TimeoutError(`Timeout ${timeout}ms exceeded.`));
const toUrl = typeof options.url === 'string' ? ` to "${options.url}"` : ''; const toUrl = typeof options.url === 'string' ? ` to "${options.url}"` : '';
waiter.log(`waiting for navigation${toUrl} until "${waitUntil}"`); waiter.log(`waiting for navigation${toUrl} until "${waitUntil}"`);
@ -144,9 +144,7 @@ export class Frame extends ChannelOwner<FrameChannel, FrameInitializer> {
if (this._loadStates.has(state)) if (this._loadStates.has(state))
return; return;
return this._wrapApiCall(this._apiName('waitForLoadState'), async () => { return this._wrapApiCall(this._apiName('waitForLoadState'), async () => {
const timeout = this._page!._timeoutSettings.navigationTimeout(options); const waiter = this._setupNavigationWaiter(options);
const waiter = this._setupNavigationWaiter();
waiter.rejectOnTimeout(timeout, new TimeoutError(`Timeout ${timeout}ms exceeded.`));
await waiter.waitForEvent<types.LifecycleEvent>(this._eventEmitter, 'loadstate', s => { await waiter.waitForEvent<types.LifecycleEvent>(this._eventEmitter, 'loadstate', s => {
waiter.log(` "${s}" event fired`); waiter.log(` "${s}" event fired`);
return s === state; return s === state;

View File

@ -15,7 +15,6 @@
* limitations under the License. * limitations under the License.
*/ */
import { TimeoutError } from '../../errors';
import { Events } from '../../events'; import { Events } from '../../events';
import { assert, assertMaxArguments, helper, Listener } from '../../helper'; import { assert, assertMaxArguments, helper, Listener } from '../../helper';
import { TimeoutSettings } from '../../timeoutSettings'; import { TimeoutSettings } from '../../timeoutSettings';
@ -335,7 +334,7 @@ export class Page extends ChannelOwner<PageChannel, PageInitializer> {
const timeout = this._timeoutSettings.timeout(typeof optionsOrPredicate === 'function' ? {} : optionsOrPredicate); const timeout = this._timeoutSettings.timeout(typeof optionsOrPredicate === 'function' ? {} : optionsOrPredicate);
const predicate = typeof optionsOrPredicate === 'function' ? optionsOrPredicate : optionsOrPredicate.predicate; const predicate = typeof optionsOrPredicate === 'function' ? optionsOrPredicate : optionsOrPredicate.predicate;
const waiter = new Waiter(); const waiter = new Waiter();
waiter.rejectOnTimeout(timeout, new TimeoutError(`Timeout while waiting for event "${event}"`)); waiter.rejectOnTimeout(timeout, `Timeout while waiting for event "${event}"`);
if (event !== Events.Page.Crash) if (event !== Events.Page.Crash)
waiter.rejectOnEvent(this, Events.Page.Crash, new Error('Page crashed')); waiter.rejectOnEvent(this, Events.Page.Crash, new Error('Page crashed'));
if (event !== Events.Page.Close) if (event !== Events.Page.Close)

View File

@ -16,6 +16,7 @@
import { EventEmitter } from 'events'; import { EventEmitter } from 'events';
import { rewriteErrorMessage } from '../../utils/stackTrace'; import { rewriteErrorMessage } from '../../utils/stackTrace';
import { TimeoutError } from '../../errors';
export class Waiter { export class Waiter {
private _dispose: (() => void)[] = []; private _dispose: (() => void)[] = [];
@ -33,11 +34,11 @@ export class Waiter {
this._rejectOn(promise.then(() => { throw error; }), dispose); this._rejectOn(promise.then(() => { throw error; }), dispose);
} }
rejectOnTimeout(timeout: number, error: Error) { rejectOnTimeout(timeout: number, message: string) {
if (!timeout) if (!timeout)
return; return;
const { promise, dispose } = waitForTimeout(timeout); const { promise, dispose } = waitForTimeout(timeout);
this._rejectOn(promise.then(() => { throw error; }), dispose); this._rejectOn(promise.then(() => { throw new TimeoutError(message); }), dispose);
} }
dispose() { dispose() {

View File

@ -979,13 +979,13 @@ describe('Page.selectOption', function() {
}); });
it('should return [] on no matched values', async({page, server}) => { it('should return [] on no matched values', async({page, server}) => {
await page.goto(server.PREFIX + '/input/select.html'); await page.goto(server.PREFIX + '/input/select.html');
const result = await page.selectOption('select','42','abc'); const result = await page.selectOption('select', ['42','abc']);
expect(result).toEqual([]); expect(result).toEqual([]);
}); });
it('should return an array of matched values', async({page, server}) => { it('should return an array of matched values', async({page, server}) => {
await page.goto(server.PREFIX + '/input/select.html'); await page.goto(server.PREFIX + '/input/select.html');
await page.evaluate(() => makeMultiple()); await page.evaluate(() => makeMultiple());
const result = await page.selectOption('select','blue','black','magenta'); const result = await page.selectOption('select', ['blue','black','magenta']);
expect(result.reduce((accumulator,current) => ['blue', 'black', 'magenta'].includes(current) && accumulator, true)).toEqual(true); expect(result.reduce((accumulator,current) => ['blue', 'black', 'magenta'].includes(current) && accumulator, true)).toEqual(true);
}); });
it('should return an array of one element when multiple is not set', async({page, server}) => { it('should return an array of one element when multiple is not set', async({page, server}) => {