chore: use braces in function bodies (#8525)

This commit is contained in:
jrandolf 2022-06-15 12:42:21 +02:00 committed by GitHub
parent 570087ea94
commit ce0dd25349
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
37 changed files with 563 additions and 306 deletions

View File

@ -23,6 +23,8 @@ module.exports = {
rules: { rules: {
// Brackets keep code readable. // Brackets keep code readable.
curly: [2, 'all'], curly: [2, 'all'],
// Brackets keep code readable and `return` intentions clear.
'arrow-body-style': ['error', 'always'],
// Error if files are not formatted with Prettier correctly. // Error if files are not formatted with Prettier correctly.
'prettier/prettier': 2, 'prettier/prettier': 2,
// syntax preferences // syntax preferences
@ -134,6 +136,8 @@ module.exports = {
rules: { rules: {
// Brackets keep code readable. // Brackets keep code readable.
curly: [2, 'all'], curly: [2, 'all'],
// Brackets keep code readable and `return` intentions clear.
'arrow-body-style': ['error', 'always'],
// Error if comments do not adhere to `tsdoc`. // Error if comments do not adhere to `tsdoc`.
'tsdoc/syntax': 2, 'tsdoc/syntax': 2,
'no-unused-vars': 0, 'no-unused-vars': 0,

View File

@ -38,7 +38,12 @@ function sniffDetector() {
const page = await browser.newPage(); const page = await browser.newPage();
await page.evaluateOnNewDocument(sniffDetector); await page.evaluateOnNewDocument(sniffDetector);
await page.goto('https://www.google.com', { waitUntil: 'networkidle2' }); await page.goto('https://www.google.com', { waitUntil: 'networkidle2' });
console.log('Sniffed: ' + (await page.evaluate(() => !!navigator.sniffed))); console.log(
'Sniffed: ' +
(await page.evaluate(() => {
return !!navigator.sniffed;
}))
);
await browser.close(); await browser.close();
})(); })();

View File

@ -23,7 +23,9 @@ async function attachFrame(frameId, url) {
frame.src = url; frame.src = url;
frame.id = frameId; frame.id = frameId;
document.body.appendChild(frame); document.body.appendChild(frame);
await new Promise((x) => (frame.onload = x)); await new Promise((x) => {
return (frame.onload = x);
});
return frame; return frame;
} }

View File

@ -30,7 +30,13 @@ for (const [depKey, depValue] of Object.entries(allDeps)) {
if (invalidDeps.size > 0) { if (invalidDeps.size > 0) {
console.error('Found non-pinned dependencies in package.json:'); console.error('Found non-pinned dependencies in package.json:');
console.log([...invalidDeps.keys()].map((k) => ` ${k}`).join('\n')); console.log(
[...invalidDeps.keys()]
.map((k) => {
return ` ${k}`;
})
.join('\n')
);
process.exit(1); process.exit(1);
} }

View File

@ -171,9 +171,9 @@ function testProject(folder: string) {
const result = compileAndCatchErrors(projectLocation); const result = compileAndCatchErrors(projectLocation);
const expectedErrors = EXPECTED_ERRORS.get(folder) || []; const expectedErrors = EXPECTED_ERRORS.get(folder) || [];
if ( if (
result.tsErrorMesssage.find( result.tsErrorMesssage.find((line) => {
(line) => line.includes('good.ts') || line.includes('good.js') return line.includes('good.ts') || line.includes('good.js');
) })
) { ) {
console.error( console.error(
`Error for ${projectLocation} contained unexpected failures in good.ts/good.js:\n${result.tsErrorMesssage.join( `Error for ${projectLocation} contained unexpected failures in good.ts/good.js:\n${result.tsErrorMesssage.join(
@ -182,9 +182,9 @@ function testProject(folder: string) {
); );
process.exit(1); process.exit(1);
} }
const errorsInTsMessage = result.tsErrorMesssage.filter( const errorsInTsMessage = result.tsErrorMesssage.filter((line) => {
(line) => line.includes('bad.ts') || line.includes('bad.js') return line.includes('bad.ts') || line.includes('bad.js');
); });
const expectedErrorsThatHaveOccurred = new Set<string>(); const expectedErrorsThatHaveOccurred = new Set<string>();
const unexpectedErrors = errorsInTsMessage.filter((message) => { const unexpectedErrors = errorsInTsMessage.filter((message) => {
const isExpected = expectedErrors.some((expectedError) => { const isExpected = expectedErrors.some((expectedError) => {

View File

@ -193,9 +193,9 @@ export class Accessibility {
const defaultRoot = AXNode.createTree(nodes); const defaultRoot = AXNode.createTree(nodes);
let needle: AXNode | null = defaultRoot; let needle: AXNode | null = defaultRoot;
if (backendNodeId) { if (backendNodeId) {
needle = defaultRoot.find( needle = defaultRoot.find((node) => {
(node) => node.payload.backendDOMNodeId === backendNodeId return node.payload.backendDOMNodeId === backendNodeId;
); });
if (!needle) { if (!needle) {
return null; return null;
} }
@ -455,8 +455,9 @@ class AXNode {
'roledescription', 'roledescription',
'valuetext', 'valuetext',
]; ];
const getUserStringPropertyValue = (key: UserStringProperty): string => const getUserStringPropertyValue = (key: UserStringProperty): string => {
properties.get(key) as string; return properties.get(key) as string;
};
for (const userStringProperty of userStringProperties) { for (const userStringProperty of userStringProperties) {
if (!properties.has(userStringProperty)) { if (!properties.has(userStringProperty)) {
@ -487,8 +488,9 @@ class AXNode {
'required', 'required',
'selected', 'selected',
]; ];
const getBooleanPropertyValue = (key: BooleanProperty): boolean => const getBooleanPropertyValue = (key: BooleanProperty): boolean => {
properties.get(key) as boolean; return properties.get(key) as boolean;
};
for (const booleanProperty of booleanProperties) { for (const booleanProperty of booleanProperties) {
// RootWebArea's treat focus differently than other nodes. They report whether // RootWebArea's treat focus differently than other nodes. They report whether
@ -521,8 +523,9 @@ class AXNode {
'valuemax', 'valuemax',
'valuemin', 'valuemin',
]; ];
const getNumericalPropertyValue = (key: NumbericalProperty): number => const getNumericalPropertyValue = (key: NumbericalProperty): number => {
properties.get(key) as number; return properties.get(key) as number;
};
for (const numericalProperty of numericalProperties) { for (const numericalProperty of numericalProperties) {
if (!properties.has(numericalProperty)) { if (!properties.has(numericalProperty)) {
continue; continue;
@ -541,8 +544,9 @@ class AXNode {
'invalid', 'invalid',
'orientation', 'orientation',
]; ];
const getTokenPropertyValue = (key: TokenProperty): string => const getTokenPropertyValue = (key: TokenProperty): string => {
properties.get(key) as string; return properties.get(key) as string;
};
for (const tokenProperty of tokenProperties) { for (const tokenProperty of tokenProperties) {
const value = getTokenPropertyValue(tokenProperty); const value = getTokenPropertyValue(tokenProperty);
if (!value || value === 'false') { if (!value || value === 'false') {

View File

@ -33,14 +33,16 @@ async function queryAXTree(
role, role,
}); });
const filteredNodes: Protocol.Accessibility.AXNode[] = nodes.filter( const filteredNodes: Protocol.Accessibility.AXNode[] = nodes.filter(
(node: Protocol.Accessibility.AXNode) => (node: Protocol.Accessibility.AXNode) => {
!node.role || node.role.value !== 'StaticText' return !node.role || node.role.value !== 'StaticText';
}
); );
return filteredNodes; return filteredNodes;
} }
const normalizeValue = (value: string): string => const normalizeValue = (value: string): string => {
value.replace(/ +/g, ' ').trim(); return value.replace(/ +/g, ' ').trim();
};
const knownAttributes = new Set(['name', 'role']); const knownAttributes = new Set(['name', 'role']);
const attributeRegexp = const attributeRegexp =
/\[\s*(?<attribute>\w+)\s*=\s*(?<quote>"|')(?<value>\\.|.*?(?=\k<quote>))\k<quote>\s*\]/g; /\[\s*(?<attribute>\w+)\s*=\s*(?<quote>"|')(?<value>\\.|.*?(?=\k<quote>))\k<quote>\s*\]/g;
@ -109,12 +111,13 @@ const waitFor = async (
}, },
}; };
return domWorld._waitForSelectorInPage( return domWorld._waitForSelectorInPage(
(_: Element, selector: string) => (_: Element, selector: string) => {
( return (
globalThis as any as unknown as { globalThis as any as unknown as {
ariaQuerySelector(selector: string): void; ariaQuerySelector(selector: string): void;
} }
).ariaQuerySelector(selector), ).ariaQuerySelector(selector);
},
selector, selector,
options, options,
binding binding
@ -129,7 +132,9 @@ const queryAll = async (
const { name, role } = parseAriaSelector(selector); const { name, role } = parseAriaSelector(selector);
const res = await queryAXTree(exeCtx._client, element, name, role); const res = await queryAXTree(exeCtx._client, element, name, role);
return Promise.all( return Promise.all(
res.map((axNode) => exeCtx._adoptBackendNodeId(axNode.backendDOMNodeId)) res.map((axNode) => {
return exeCtx._adoptBackendNodeId(axNode.backendDOMNodeId);
})
); );
}; };
@ -139,10 +144,9 @@ const queryAllArray = async (
): Promise<JSHandle> => { ): Promise<JSHandle> => {
const elementHandles = await queryAll(element, selector); const elementHandles = await queryAll(element, selector);
const exeCtx = element.executionContext(); const exeCtx = element.executionContext();
const jsHandle = exeCtx.evaluateHandle( const jsHandle = exeCtx.evaluateHandle((...elements) => {
(...elements) => elements, return elements;
...elementHandles }, ...elementHandles);
);
return jsHandle; return jsHandle;
}; };

View File

@ -280,7 +280,11 @@ export class Browser extends EventEmitter {
this.#screenshotTaskQueue = new TaskQueue(); this.#screenshotTaskQueue = new TaskQueue();
this.#connection = connection; this.#connection = connection;
this.#closeCallback = closeCallback || function (): void {}; this.#closeCallback = closeCallback || function (): void {};
this.#targetFilterCallback = targetFilterCallback || ((): boolean => true); this.#targetFilterCallback =
targetFilterCallback ||
((): boolean => {
return true;
});
this.#setIsPageTargetCallback(isPageTargetCallback); this.#setIsPageTargetCallback(isPageTargetCallback);
this.#defaultContext = new BrowserContext(this.#connection, this); this.#defaultContext = new BrowserContext(this.#connection, this);
@ -293,9 +297,9 @@ export class Browser extends EventEmitter {
} }
this.#targets = new Map(); this.#targets = new Map();
this.#connection.on(ConnectionEmittedEvents.Disconnected, () => this.#connection.on(ConnectionEmittedEvents.Disconnected, () => {
this.emit(BrowserEmittedEvents.Disconnected) return this.emit(BrowserEmittedEvents.Disconnected);
); });
this.#connection.on('Target.targetCreated', this.#targetCreated.bind(this)); this.#connection.on('Target.targetCreated', this.#targetCreated.bind(this));
this.#connection.on( this.#connection.on(
'Target.targetDestroyed', 'Target.targetDestroyed',
@ -423,7 +427,9 @@ export class Browser extends EventEmitter {
const target = new Target( const target = new Target(
targetInfo, targetInfo,
context, context,
() => this.#connection.createSession(targetInfo), () => {
return this.#connection.createSession(targetInfo);
},
this.#ignoreHTTPSErrors, this.#ignoreHTTPSErrors,
this.#defaultViewport ?? null, this.#defaultViewport ?? null,
this.#screenshotTaskQueue, this.#screenshotTaskQueue,
@ -542,18 +548,18 @@ export class Browser extends EventEmitter {
* an array with all the targets in all browser contexts. * an array with all the targets in all browser contexts.
*/ */
targets(): Target[] { targets(): Target[] {
return Array.from(this.#targets.values()).filter( return Array.from(this.#targets.values()).filter((target) => {
(target) => target._isInitialized return target._isInitialized;
); });
} }
/** /**
* The target associated with the browser. * The target associated with the browser.
*/ */
target(): Target { target(): Target {
const browserTarget = this.targets().find( const browserTarget = this.targets().find((target) => {
(target) => target.type() === 'browser' return target.type() === 'browser';
); });
if (!browserTarget) { if (!browserTarget) {
throw new Error('Browser target is not found'); throw new Error('Browser target is not found');
} }
@ -581,7 +587,9 @@ export class Browser extends EventEmitter {
const { timeout = 30000 } = options; const { timeout = 30000 } = options;
let resolve: (value: Target | PromiseLike<Target>) => void; let resolve: (value: Target | PromiseLike<Target>) => void;
let isResolved = false; let isResolved = false;
const targetPromise = new Promise<Target>((x) => (resolve = x)); const targetPromise = new Promise<Target>((x) => {
return (resolve = x);
});
this.on(BrowserEmittedEvents.TargetCreated, check); this.on(BrowserEmittedEvents.TargetCreated, check);
this.on(BrowserEmittedEvents.TargetChanged, check); this.on(BrowserEmittedEvents.TargetChanged, check);
try { try {
@ -614,10 +622,14 @@ export class Browser extends EventEmitter {
*/ */
async pages(): Promise<Page[]> { async pages(): Promise<Page[]> {
const contextPages = await Promise.all( const contextPages = await Promise.all(
this.browserContexts().map((context) => context.pages()) this.browserContexts().map((context) => {
return context.pages();
})
); );
// Flatten array. // Flatten array.
return contextPages.reduce((acc, x) => acc.concat(x), []); return contextPages.reduce((acc, x) => {
return acc.concat(x);
}, []);
} }
/** /**
@ -750,9 +762,9 @@ export class BrowserContext extends EventEmitter {
* An array of all active targets inside the browser context. * An array of all active targets inside the browser context.
*/ */
targets(): Target[] { targets(): Target[] {
return this.#browser return this.#browser.targets().filter((target) => {
.targets() return target.browserContext() === this;
.filter((target) => target.browserContext() === this); });
} }
/** /**
@ -776,10 +788,9 @@ export class BrowserContext extends EventEmitter {
predicate: (x: Target) => boolean | Promise<boolean>, predicate: (x: Target) => boolean | Promise<boolean>,
options: { timeout?: number } = {} options: { timeout?: number } = {}
): Promise<Target> { ): Promise<Target> {
return this.#browser.waitForTarget( return this.#browser.waitForTarget((target) => {
(target) => target.browserContext() === this && predicate(target), return target.browserContext() === this && predicate(target);
options }, options);
);
} }
/** /**
@ -792,17 +803,22 @@ export class BrowserContext extends EventEmitter {
async pages(): Promise<Page[]> { async pages(): Promise<Page[]> {
const pages = await Promise.all( const pages = await Promise.all(
this.targets() this.targets()
.filter( .filter((target) => {
(target) => return (
target.type() === 'page' || target.type() === 'page' ||
(target.type() === 'other' && (target.type() === 'other' &&
this.#browser._getIsPageTargetCallback()?.( this.#browser._getIsPageTargetCallback()?.(
target._getTargetInfo() target._getTargetInfo()
)) ))
) );
.map((target) => target.page()) })
.map((target) => {
return target.page();
})
); );
return pages.filter((page): page is Page => !!page); return pages.filter((page): page is Page => {
return !!page;
});
} }
/** /**

View File

@ -119,7 +119,9 @@ export async function _connectToBrowser(
ignoreHTTPSErrors, ignoreHTTPSErrors,
defaultViewport, defaultViewport,
undefined, undefined,
() => connection.send('Browser.close').catch(debugError), () => {
return connection.send('Browser.close').catch(debugError);
},
targetFilter, targetFilter,
isPageTarget isPageTarget
); );

View File

@ -20,9 +20,9 @@ export class BrowserWebSocketTransport implements ConnectionTransport {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const ws = new WebSocket(url); const ws = new WebSocket(url);
ws.addEventListener('open', () => ws.addEventListener('open', () => {
resolve(new BrowserWebSocketTransport(ws)) return resolve(new BrowserWebSocketTransport(ws));
); });
ws.addEventListener('error', reject); ws.addEventListener('error', reject);
}); });
} }

View File

@ -130,7 +130,9 @@ export class Connection extends EventEmitter {
async #onMessage(message: string): Promise<void> { async #onMessage(message: string): Promise<void> {
if (this.#delay) { if (this.#delay) {
await new Promise((f) => setTimeout(f, this.#delay)); await new Promise((f) => {
return setTimeout(f, this.#delay);
});
} }
debugProtocolReceive(message); debugProtocolReceive(message);
const object = JSON.parse(message); const object = JSON.parse(message);

View File

@ -480,5 +480,7 @@ function convertToDisjointRanges(
} }
} }
// Filter out empty ranges. // Filter out empty ranges.
return results.filter((range) => range.end - range.start > 1); return results.filter((range) => {
return range.end - range.start > 1;
});
} }

View File

@ -108,8 +108,9 @@ export class DOMWorld {
return this.#boundFunctions; return this.#boundFunctions;
} }
static #bindingIdentifier = (name: string, contextId: number) => static #bindingIdentifier = (name: string, contextId: number) => {
`${name}_${contextId}`; return `${name}_${contextId}`;
};
constructor( constructor(
client: CDPSession, client: CDPSession,
@ -444,7 +445,9 @@ export class DOMWorld {
script.id = id; script.id = id;
} }
let error = null; let error = null;
script.onerror = (e) => (error = e); script.onerror = (e) => {
return (error = e);
};
document.head.appendChild(script); document.head.appendChild(script);
if (error) { if (error) {
throw error; throw error;
@ -843,7 +846,9 @@ export class DOMWorld {
} }
async title(): Promise<string> { async title(): Promise<string> {
return this.evaluate(() => document.title); return this.evaluate(() => {
return document.title;
});
} }
} }
@ -933,10 +938,9 @@ export class WaitTask {
const timeoutError = new TimeoutError( const timeoutError = new TimeoutError(
`waiting for ${options.title} failed: timeout ${options.timeout}ms exceeded` `waiting for ${options.title} failed: timeout ${options.timeout}ms exceeded`
); );
this.#timeoutTimer = setTimeout( this.#timeoutTimer = setTimeout(() => {
() => this.terminate(timeoutError), return this.terminate(timeoutError);
options.timeout }, options.timeout);
);
} }
this.rerun(); this.rerun();
} }
@ -987,7 +991,13 @@ export class WaitTask {
// throw an error - ignore this predicate run altogether. // throw an error - ignore this predicate run altogether.
if ( if (
!error && !error &&
(await this.#domWorld.evaluate((s) => !s, success).catch(() => true)) (await this.#domWorld
.evaluate((s) => {
return !s;
}, success)
.catch(() => {
return true;
}))
) { ) {
if (!success) { if (!success) {
throw new Error('Assertion: result handle is not available'); throw new Error('Assertion: result handle is not available');
@ -1053,7 +1063,9 @@ async function waitForPredicatePageFunction(
const predicate = new Function('...args', predicateBody); const predicate = new Function('...args', predicateBody);
let timedOut = false; let timedOut = false;
if (timeout) { if (timeout) {
setTimeout(() => (timedOut = true), timeout); setTimeout(() => {
return (timedOut = true);
}, timeout);
} }
switch (polling) { switch (polling) {
case 'raf': case 'raf':
@ -1073,7 +1085,9 @@ async function waitForPredicatePageFunction(
} }
let fulfill = (_?: unknown) => {}; let fulfill = (_?: unknown) => {};
const result = new Promise((x) => (fulfill = x)); const result = new Promise((x) => {
return (fulfill = x);
});
const observer = new MutationObserver(async () => { const observer = new MutationObserver(async () => {
if (timedOut) { if (timedOut) {
observer.disconnect(); observer.disconnect();
@ -1100,7 +1114,9 @@ async function waitForPredicatePageFunction(
async function pollRaf(): Promise<unknown> { async function pollRaf(): Promise<unknown> {
let fulfill = (_?: unknown): void => {}; let fulfill = (_?: unknown): void => {};
const result = new Promise((x) => (fulfill = x)); const result = new Promise((x) => {
return (fulfill = x);
});
await onRaf(); await onRaf();
return result; return result;
@ -1122,7 +1138,9 @@ async function waitForPredicatePageFunction(
async function pollInterval(pollInterval: number): Promise<unknown> { async function pollInterval(pollInterval: number): Promise<unknown> {
let fulfill = (_?: unknown): void => {}; let fulfill = (_?: unknown): void => {};
const result = new Promise((x) => (fulfill = x)); const result = new Promise((x) => {
return (fulfill = x);
});
await onTimeout(); await onTimeout();
return result; return result;

View File

@ -166,9 +166,9 @@ export class FrameManager extends EventEmitter {
this.#handleFrameTree(client, frameTree); this.#handleFrameTree(client, frameTree);
await Promise.all([ await Promise.all([
client.send('Page.setLifecycleEventsEnabled', { enabled: true }), client.send('Page.setLifecycleEventsEnabled', { enabled: true }),
client client.send('Runtime.enable').then(() => {
.send('Runtime.enable') return this._ensureIsolatedWorld(client, UTILITY_WORLD_NAME);
.then(() => this._ensureIsolatedWorld(client, UTILITY_WORLD_NAME)), }),
// TODO: Network manager is not aware of OOP iframes yet. // TODO: Network manager is not aware of OOP iframes yet.
client === this.#client client === this.#client
? this.#networkManager.initialize() ? this.#networkManager.initialize()
@ -443,16 +443,18 @@ export class FrameManager extends EventEmitter {
// Frames might be removed before we send this. // Frames might be removed before we send this.
await Promise.all( await Promise.all(
this.frames() this.frames()
.filter((frame) => frame._client() === session) .filter((frame) => {
.map((frame) => return frame._client() === session;
session })
.map((frame) => {
return session
.send('Page.createIsolatedWorld', { .send('Page.createIsolatedWorld', {
frameId: frame._id, frameId: frame._id,
worldName: name, worldName: name,
grantUniveralAccess: true, grantUniveralAccess: true,
}) })
.catch(debugError) .catch(debugError);
) })
); );
} }
@ -1281,9 +1283,9 @@ export class Frame {
return this.waitForSelector(string, options); return this.waitForSelector(string, options);
} }
if (isNumber(selectorOrFunctionOrTimeout)) { if (isNumber(selectorOrFunctionOrTimeout)) {
return new Promise((fulfill) => return new Promise((fulfill) => {
setTimeout(fulfill, selectorOrFunctionOrTimeout) return setTimeout(fulfill, selectorOrFunctionOrTimeout);
); });
} }
if (typeof selectorOrFunctionOrTimeout === 'function') { if (typeof selectorOrFunctionOrTimeout === 'function') {
return this.waitForFunction( return this.waitForFunction(

View File

@ -269,10 +269,9 @@ export class HTTPRequest {
* the request interception. * the request interception.
*/ */
async finalizeInterceptions(): Promise<void> { async finalizeInterceptions(): Promise<void> {
await this.#interceptHandlers.reduce( await this.#interceptHandlers.reduce((promiseChain, interceptAction) => {
(promiseChain, interceptAction) => promiseChain.then(interceptAction), return promiseChain.then(interceptAction);
Promise.resolve() }, Promise.resolve());
);
const { action } = this.interceptResolutionState(); const { action } = this.interceptResolutionState();
switch (action) { switch (action) {
case 'abort': case 'abort':
@ -576,7 +575,9 @@ export class HTTPRequest {
const value = response.headers[header]; const value = response.headers[header];
responseHeaders[header.toLowerCase()] = Array.isArray(value) responseHeaders[header.toLowerCase()] = Array.isArray(value)
? value.map((item) => String(item)) ? value.map((item) => {
return String(item);
})
: String(value); : String(value);
} }
} }
@ -738,7 +739,11 @@ function headersArray(
if (!Object.is(value, undefined)) { if (!Object.is(value, undefined)) {
const values = Array.isArray(value) ? value : [value]; const values = Array.isArray(value) ? value : [value];
result.push(...values.map((value) => ({ name, value: value + '' }))); result.push(
...values.map((value) => {
return { name, value: value + '' };
})
);
} }
} }
return result; return result;

View File

@ -277,7 +277,9 @@ export class Keyboard {
await this.press(char, { delay }); await this.press(char, { delay });
} else { } else {
if (delay) { if (delay) {
await new Promise((f) => setTimeout(f, delay)); await new Promise((f) => {
return setTimeout(f, delay);
});
} }
await this.sendCharacter(char); await this.sendCharacter(char);
} }
@ -311,7 +313,9 @@ export class Keyboard {
const { delay = null } = options; const { delay = null } = options;
await this.down(key, options); await this.down(key, options);
if (delay) { if (delay) {
await new Promise((f) => setTimeout(f, options.delay)); await new Promise((f) => {
return setTimeout(f, options.delay);
});
} }
await this.up(key); await this.up(key);
} }
@ -453,7 +457,9 @@ export class Mouse {
if (delay !== null) { if (delay !== null) {
await this.move(x, y); await this.move(x, y);
await this.down(options); await this.down(options);
await new Promise((f) => setTimeout(f, delay)); await new Promise((f) => {
return setTimeout(f, delay);
});
await this.up(options); await this.up(options);
} else { } else {
await this.move(x, y); await this.move(x, y);
@ -535,9 +541,9 @@ export class Mouse {
*/ */
async drag(start: Point, target: Point): Promise<Protocol.Input.DragData> { async drag(start: Point, target: Point): Promise<Protocol.Input.DragData> {
const promise = new Promise<Protocol.Input.DragData>((resolve) => { const promise = new Promise<Protocol.Input.DragData>((resolve) => {
this.#client.once('Input.dragIntercepted', (event) => this.#client.once('Input.dragIntercepted', (event) => {
resolve(event.data) return resolve(event.data);
); });
}); });
await this.move(start.x, start.y); await this.move(start.x, start.y);
await this.down(); await this.down();
@ -608,7 +614,9 @@ export class Mouse {
await this.dragEnter(target, data); await this.dragEnter(target, data);
await this.dragOver(target, data); await this.dragOver(target, data);
if (delay) { if (delay) {
await new Promise((resolve) => setTimeout(resolve, delay)); await new Promise((resolve) => {
return setTimeout(resolve, delay);
});
} }
await this.drop(target, data); await this.drop(target, data);
await this.up(); await this.up();

View File

@ -86,8 +86,15 @@ export function _createJSHandle(
return new JSHandle(context, context._client, remoteObject); return new JSHandle(context, context._client, remoteObject);
} }
const applyOffsetsToQuad = (quad: Point[], offsetX: number, offsetY: number) => const applyOffsetsToQuad = (
quad.map((part) => ({ x: part.x + offsetX, y: part.y + offsetY })); quad: Point[],
offsetX: number,
offsetY: number
) => {
return quad.map((part) => {
return { x: part.x + offsetX, y: part.y + offsetY };
});
};
/** /**
* Represents an in-page JavaScript object. JSHandles can be created with the * Represents an in-page JavaScript object. JSHandles can be created with the
@ -634,12 +641,18 @@ export class ElementHandle<
layoutMetrics.cssLayoutViewport || layoutMetrics.layoutViewport; layoutMetrics.cssLayoutViewport || layoutMetrics.layoutViewport;
const { offsetX, offsetY } = await this.#getOOPIFOffsets(this.#frame); const { offsetX, offsetY } = await this.#getOOPIFOffsets(this.#frame);
const quads = result.quads const quads = result.quads
.map((quad) => this.#fromProtocolQuad(quad)) .map((quad) => {
.map((quad) => applyOffsetsToQuad(quad, offsetX, offsetY)) return this.#fromProtocolQuad(quad);
.map((quad) => })
this.#intersectQuadWithViewport(quad, clientWidth, clientHeight) .map((quad) => {
) return applyOffsetsToQuad(quad, offsetX, offsetY);
.filter((quad) => computeQuadArea(quad) > 1); })
.map((quad) => {
return this.#intersectQuadWithViewport(quad, clientWidth, clientHeight);
})
.filter((quad) => {
return computeQuadArea(quad) > 1;
});
if (!quads.length) { if (!quads.length) {
throw new Error('Node is either not clickable or not an HTMLElement'); throw new Error('Node is either not clickable or not an HTMLElement');
} }
@ -683,9 +696,9 @@ export class ElementHandle<
const params: Protocol.DOM.GetBoxModelRequest = { const params: Protocol.DOM.GetBoxModelRequest = {
objectId: this._remoteObject.objectId, objectId: this._remoteObject.objectId,
}; };
return this._client return this._client.send('DOM.getBoxModel', params).catch((error) => {
.send('DOM.getBoxModel', params) return debugError(error);
.catch((error) => debugError(error)); });
} }
#fromProtocolQuad(quad: number[]): Point[] { #fromProtocolQuad(quad: number[]): Point[] {
@ -702,10 +715,12 @@ export class ElementHandle<
width: number, width: number,
height: number height: number
): Point[] { ): Point[] {
return quad.map((point) => ({ return quad.map((point) => {
x: Math.min(Math.max(point.x, 0), width), return {
y: Math.min(Math.max(point.y, 0), height), x: Math.min(Math.max(point.x, 0), width),
})); y: Math.min(Math.max(point.y, 0), height),
};
});
} }
/** /**
@ -930,9 +945,9 @@ export class ElementHandle<
* Calls {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus | focus} on the element. * Calls {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus | focus} on the element.
*/ */
async focus(): Promise<void> { async focus(): Promise<void> {
await (this as ElementHandle<HTMLElement>).evaluate((element) => await (this as ElementHandle<HTMLElement>).evaluate((element) => {
element.focus() return element.focus();
); });
} }
/** /**

View File

@ -214,9 +214,9 @@ export class LifecycleWatcher {
} }
const errorMessage = const errorMessage =
'Navigation timeout of ' + this.#timeout + ' ms exceeded'; 'Navigation timeout of ' + this.#timeout + ' ms exceeded';
await new Promise( await new Promise((fulfill) => {
(fulfill) => (this.#maximumTimer = setTimeout(fulfill, this.#timeout)) return (this.#maximumTimer = setTimeout(fulfill, this.#timeout));
); });
return new TimeoutError(errorMessage); return new TimeoutError(errorMessage);
} }

View File

@ -554,49 +554,67 @@ export class Page extends EventEmitter {
this.emit(PageEmittedEvents.WorkerDestroyed, worker); this.emit(PageEmittedEvents.WorkerDestroyed, worker);
}); });
this.#frameManager.on(FrameManagerEmittedEvents.FrameAttached, (event) => this.#frameManager.on(FrameManagerEmittedEvents.FrameAttached, (event) => {
this.emit(PageEmittedEvents.FrameAttached, event) return this.emit(PageEmittedEvents.FrameAttached, event);
); });
this.#frameManager.on(FrameManagerEmittedEvents.FrameDetached, (event) => this.#frameManager.on(FrameManagerEmittedEvents.FrameDetached, (event) => {
this.emit(PageEmittedEvents.FrameDetached, event) return this.emit(PageEmittedEvents.FrameDetached, event);
); });
this.#frameManager.on(FrameManagerEmittedEvents.FrameNavigated, (event) => this.#frameManager.on(FrameManagerEmittedEvents.FrameNavigated, (event) => {
this.emit(PageEmittedEvents.FrameNavigated, event) return this.emit(PageEmittedEvents.FrameNavigated, event);
); });
const networkManager = this.#frameManager.networkManager(); const networkManager = this.#frameManager.networkManager();
networkManager.on(NetworkManagerEmittedEvents.Request, (event) => networkManager.on(NetworkManagerEmittedEvents.Request, (event) => {
this.emit(PageEmittedEvents.Request, event) return this.emit(PageEmittedEvents.Request, event);
); });
networkManager.on( networkManager.on(
NetworkManagerEmittedEvents.RequestServedFromCache, NetworkManagerEmittedEvents.RequestServedFromCache,
(event) => this.emit(PageEmittedEvents.RequestServedFromCache, event) (event) => {
); return this.emit(PageEmittedEvents.RequestServedFromCache, event);
networkManager.on(NetworkManagerEmittedEvents.Response, (event) => }
this.emit(PageEmittedEvents.Response, event)
);
networkManager.on(NetworkManagerEmittedEvents.RequestFailed, (event) =>
this.emit(PageEmittedEvents.RequestFailed, event)
);
networkManager.on(NetworkManagerEmittedEvents.RequestFinished, (event) =>
this.emit(PageEmittedEvents.RequestFinished, event)
); );
networkManager.on(NetworkManagerEmittedEvents.Response, (event) => {
return this.emit(PageEmittedEvents.Response, event);
});
networkManager.on(NetworkManagerEmittedEvents.RequestFailed, (event) => {
return this.emit(PageEmittedEvents.RequestFailed, event);
});
networkManager.on(NetworkManagerEmittedEvents.RequestFinished, (event) => {
return this.emit(PageEmittedEvents.RequestFinished, event);
});
this.#fileChooserInterceptors = new Set(); this.#fileChooserInterceptors = new Set();
client.on('Page.domContentEventFired', () => client.on('Page.domContentEventFired', () => {
this.emit(PageEmittedEvents.DOMContentLoaded) return this.emit(PageEmittedEvents.DOMContentLoaded);
); });
client.on('Page.loadEventFired', () => this.emit(PageEmittedEvents.Load)); client.on('Page.loadEventFired', () => {
client.on('Runtime.consoleAPICalled', (event) => this.#onConsoleAPI(event)); return this.emit(PageEmittedEvents.Load);
client.on('Runtime.bindingCalled', (event) => this.#onBindingCalled(event)); });
client.on('Page.javascriptDialogOpening', (event) => this.#onDialog(event)); client.on('Runtime.consoleAPICalled', (event) => {
client.on('Runtime.exceptionThrown', (exception) => return this.#onConsoleAPI(event);
this.#handleException(exception.exceptionDetails) });
); client.on('Runtime.bindingCalled', (event) => {
client.on('Inspector.targetCrashed', () => this.#onTargetCrashed()); return this.#onBindingCalled(event);
client.on('Performance.metrics', (event) => this.#emitMetrics(event)); });
client.on('Log.entryAdded', (event) => this.#onLogEntryAdded(event)); client.on('Page.javascriptDialogOpening', (event) => {
client.on('Page.fileChooserOpened', (event) => this.#onFileChooser(event)); return this.#onDialog(event);
});
client.on('Runtime.exceptionThrown', (exception) => {
return this.#handleException(exception.exceptionDetails);
});
client.on('Inspector.targetCrashed', () => {
return this.#onTargetCrashed();
});
client.on('Performance.metrics', (event) => {
return this.#emitMetrics(event);
});
client.on('Log.entryAdded', (event) => {
return this.#onLogEntryAdded(event);
});
client.on('Page.fileChooserOpened', (event) => {
return this.#onFileChooser(event);
});
this.#target._isClosedPromise.then(() => { this.#target._isClosedPromise.then(() => {
this.emit(PageEmittedEvents.Close); this.emit(PageEmittedEvents.Close);
this.#closed = true; this.#closed = true;
@ -662,9 +680,9 @@ export class Page extends EventEmitter {
const wrap = const wrap =
this.#handlerMap.get(handler) || this.#handlerMap.get(handler) ||
((event: HTTPRequest) => { ((event: HTTPRequest) => {
event.enqueueInterceptAction(() => event.enqueueInterceptAction(() => {
handler(event as PageEventObject[K]) return handler(event as PageEventObject[K]);
); });
}); });
this.#handlerMap.set(handler, wrap); this.#handlerMap.set(handler, wrap);
@ -727,7 +745,9 @@ export class Page extends EventEmitter {
const { timeout = this.#timeoutSettings.timeout() } = options; const { timeout = this.#timeoutSettings.timeout() } = options;
let callback!: (value: FileChooser | PromiseLike<FileChooser>) => void; let callback!: (value: FileChooser | PromiseLike<FileChooser>) => void;
const promise = new Promise<FileChooser>((x) => (callback = x)); const promise = new Promise<FileChooser>((x) => {
return (callback = x);
});
this.#fileChooserInterceptors.add(callback); this.#fileChooserInterceptors.add(callback);
return waitWithTimeout<FileChooser>( return waitWithTimeout<FileChooser>(
promise, promise,
@ -808,7 +828,9 @@ export class Page extends EventEmitter {
#onLogEntryAdded(event: Protocol.Log.EntryAddedEvent): void { #onLogEntryAdded(event: Protocol.Log.EntryAddedEvent): void {
const { level, text, args, source, url, lineNumber } = event.entry; const { level, text, args, source, url, lineNumber } = event.entry;
if (args) { if (args) {
args.map((arg) => releaseObject(this.#client, arg)); args.map((arg) => {
return releaseObject(this.#client, arg);
});
} }
if (source !== 'worker') { if (source !== 'worker') {
this.emit( this.emit(
@ -1455,7 +1477,9 @@ export class Page extends EventEmitter {
source: expression, source: expression,
}); });
await Promise.all( await Promise.all(
this.frames().map((frame) => frame.evaluate(expression).catch(debugError)) this.frames().map((frame) => {
return frame.evaluate(expression).catch(debugError);
})
); );
} }
@ -1585,7 +1609,9 @@ export class Page extends EventEmitter {
event.executionContextId, event.executionContextId,
this.#client this.#client
); );
const values = event.args.map((arg) => _createJSHandle(context, arg)); const values = event.args.map((arg) => {
return _createJSHandle(context, arg);
});
this.#addConsoleMessage(event.type, values, event.stackTrace); this.#addConsoleMessage(event.type, values, event.stackTrace);
} }
@ -1636,7 +1662,9 @@ export class Page extends EventEmitter {
stackTrace?: Protocol.Runtime.StackTrace stackTrace?: Protocol.Runtime.StackTrace
): void { ): void {
if (!this.listenerCount(PageEmittedEvents.Console)) { if (!this.listenerCount(PageEmittedEvents.Console)) {
args.forEach((arg) => arg.dispose()); args.forEach((arg) => {
return arg.dispose();
});
return; return;
} }
const textTokens = []; const textTokens = [];
@ -1882,11 +1910,11 @@ export class Page extends EventEmitter {
#sessionClosePromise(): Promise<Error> { #sessionClosePromise(): Promise<Error> {
if (!this.#disconnectPromise) { if (!this.#disconnectPromise) {
this.#disconnectPromise = new Promise((fulfill) => this.#disconnectPromise = new Promise((fulfill) => {
this.#client.once(CDPSessionEmittedEvents.Disconnected, () => return this.#client.once(CDPSessionEmittedEvents.Disconnected, () => {
fulfill(new Error('Target closed')) return fulfill(new Error('Target closed'));
) });
); });
} }
return this.#disconnectPromise; return this.#disconnectPromise;
} }
@ -2010,7 +2038,9 @@ export class Page extends EventEmitter {
}); });
let idleTimer: NodeJS.Timeout; let idleTimer: NodeJS.Timeout;
const onIdle = () => idleResolveCallback(); const onIdle = () => {
return idleResolveCallback();
};
const cleanup = () => { const cleanup = () => {
idleTimer && clearTimeout(idleTimer); idleTimer && clearTimeout(idleTimer);
@ -2031,8 +2061,15 @@ export class Page extends EventEmitter {
return false; return false;
}; };
const listenToEvent = (event: symbol) => const listenToEvent = (event: symbol) => {
waitForEvent(networkManager, event, eventHandler, timeout, abortPromise); return waitForEvent(
networkManager,
event,
eventHandler,
timeout,
abortPromise
);
};
const eventPromises = [ const eventPromises = [
listenToEvent(NetworkManagerEmittedEvents.Request), listenToEvent(NetworkManagerEmittedEvents.Request),
@ -2080,8 +2117,9 @@ export class Page extends EventEmitter {
let predicate: (frame: Frame) => Promise<boolean>; let predicate: (frame: Frame) => Promise<boolean>;
if (isString(urlOrPredicate)) { if (isString(urlOrPredicate)) {
predicate = (frame: Frame) => predicate = (frame: Frame) => {
Promise.resolve(urlOrPredicate === frame.url()); return Promise.resolve(urlOrPredicate === frame.url());
};
} else { } else {
predicate = (frame: Frame) => { predicate = (frame: Frame) => {
const value = urlOrPredicate(frame); const value = urlOrPredicate(frame);
@ -2799,9 +2837,9 @@ export class Page extends EventEmitter {
'Expected options.clip.height not to be 0.' 'Expected options.clip.height not to be 0.'
); );
} }
return this.#screenshotTaskQueue.postTask(() => return this.#screenshotTaskQueue.postTask(() => {
this.#screenshotTask(screenshotType, options) return this.#screenshotTask(screenshotType, options);
); });
} }
async #screenshotTask( async #screenshotTask(

View File

@ -78,7 +78,9 @@ function makeQueryHandler(handler: CustomQueryHandler): InternalQueryHandler {
domWorld: DOMWorld, domWorld: DOMWorld,
selector: string, selector: string,
options: WaitForSelectorOptions options: WaitForSelectorOptions
) => domWorld._waitForSelectorInPage(queryOne, selector, options); ) => {
return domWorld._waitForSelectorInPage(queryOne, selector, options);
};
} }
if (handler.queryAll) { if (handler.queryAll) {
@ -99,7 +101,9 @@ function makeQueryHandler(handler: CustomQueryHandler): InternalQueryHandler {
internalHandler.queryAllArray = async (element, selector) => { internalHandler.queryAllArray = async (element, selector) => {
const resultHandle = await element.evaluateHandle(queryAll, selector); const resultHandle = await element.evaluateHandle(queryAll, selector);
const arrayHandle = await resultHandle.evaluateHandle( const arrayHandle = await resultHandle.evaluateHandle(
(res: Element[] | NodeListOf<Element>) => Array.from(res) (res: Element[] | NodeListOf<Element>) => {
return Array.from(res);
}
); );
return arrayHandle; return arrayHandle;
}; };
@ -109,10 +113,12 @@ function makeQueryHandler(handler: CustomQueryHandler): InternalQueryHandler {
} }
const _defaultHandler = makeQueryHandler({ const _defaultHandler = makeQueryHandler({
queryOne: (element: Element | Document, selector: string) => queryOne: (element: Element | Document, selector: string) => {
element.querySelector(selector), return element.querySelector(selector);
queryAll: (element: Element | Document, selector: string) => },
element.querySelectorAll(selector), queryAll: (element: Element | Document, selector: string) => {
return element.querySelectorAll(selector);
},
}); });
const pierceHandler = makeQueryHandler({ const pierceHandler = makeQueryHandler({
@ -205,7 +211,9 @@ export function _unregisterCustomQueryHandler(name: string): void {
* @internal * @internal
*/ */
export function _customQueryHandlerNames(): string[] { export function _customQueryHandlerNames(): string[] {
return [...queryHandlers.keys()].filter((name) => !builtInHandlers.has(name)); return [...queryHandlers.keys()].filter((name) => {
return !builtInHandlers.has(name);
});
} }
/** /**

View File

@ -84,9 +84,9 @@ export class Target {
this.#defaultViewport = defaultViewport ?? undefined; this.#defaultViewport = defaultViewport ?? undefined;
this.#screenshotTaskQueue = screenshotTaskQueue; this.#screenshotTaskQueue = screenshotTaskQueue;
this._isPageTargetCallback = isPageTargetCallback; this._isPageTargetCallback = isPageTargetCallback;
this._initializedPromise = new Promise<boolean>( this._initializedPromise = new Promise<boolean>((fulfill) => {
(fulfill) => (this._initializedCallback = fulfill) return (this._initializedCallback = fulfill);
).then(async (success) => { }).then(async (success) => {
if (!success) { if (!success) {
return false; return false;
} }
@ -102,9 +102,9 @@ export class Target {
openerPage.emit(PageEmittedEvents.Popup, popupPage); openerPage.emit(PageEmittedEvents.Popup, popupPage);
return true; return true;
}); });
this._isClosedPromise = new Promise<void>( this._isClosedPromise = new Promise<void>((fulfill) => {
(fulfill) => (this._closedCallback = fulfill) return (this._closedCallback = fulfill);
); });
this._isInitialized = this._isInitialized =
!this._isPageTargetCallback(this.#targetInfo) || !this._isPageTargetCallback(this.#targetInfo) ||
this.#targetInfo.url !== ''; this.#targetInfo.url !== '';
@ -132,15 +132,15 @@ export class Target {
*/ */
async page(): Promise<Page | null> { async page(): Promise<Page | null> {
if (this._isPageTargetCallback(this.#targetInfo) && !this.#pagePromise) { if (this._isPageTargetCallback(this.#targetInfo) && !this.#pagePromise) {
this.#pagePromise = this.#sessionFactory().then((client) => this.#pagePromise = this.#sessionFactory().then((client) => {
Page._create( return Page._create(
client, client,
this, this,
this.#ignoreHTTPSErrors, this.#ignoreHTTPSErrors,
this.#defaultViewport ?? null, this.#defaultViewport ?? null,
this.#screenshotTaskQueue this.#screenshotTaskQueue
) );
); });
} }
return (await this.#pagePromise) ?? null; return (await this.#pagePromise) ?? null;
} }
@ -157,15 +157,14 @@ export class Target {
} }
if (!this.#workerPromise) { if (!this.#workerPromise) {
// TODO(einbinder): Make workers send their console logs. // TODO(einbinder): Make workers send their console logs.
this.#workerPromise = this.#sessionFactory().then( this.#workerPromise = this.#sessionFactory().then((client) => {
(client) => return new WebWorker(
new WebWorker( client,
client, this.#targetInfo.url,
this.#targetInfo.url, () => {} /* consoleAPICalled */,
() => {} /* consoleAPICalled */, () => {} /* exceptionThrown */
() => {} /* exceptionThrown */ );
) });
);
} }
return this.#workerPromise; return this.#workerPromise;
} }

View File

@ -24,8 +24,12 @@ export class TaskQueue {
postTask<T>(task: () => Promise<T>): Promise<T> { postTask<T>(task: () => Promise<T>): Promise<T> {
const result = this.#chain.then(task); const result = this.#chain.then(task);
this.#chain = result.then( this.#chain = result.then(
() => undefined, () => {
() => undefined return undefined;
},
() => {
return undefined;
}
); );
return result; return result;
} }

View File

@ -94,9 +94,15 @@ export class Tracing {
} }
const excludedCategories = categories const excludedCategories = categories
.filter((cat) => cat.startsWith('-')) .filter((cat) => {
.map((cat) => cat.slice(1)); return cat.startsWith('-');
const includedCategories = categories.filter((cat) => !cat.startsWith('-')); })
.map((cat) => {
return cat.slice(1);
});
const includedCategories = categories.filter((cat) => {
return !cat.startsWith('-');
});
this.#path = path; this.#path = path;
this.#recording = true; this.#recording = true;

View File

@ -79,31 +79,32 @@ export class WebWorker extends EventEmitter {
super(); super();
this.#client = client; this.#client = client;
this.#url = url; this.#url = url;
this.#executionContextPromise = new Promise<ExecutionContext>( this.#executionContextPromise = new Promise<ExecutionContext>((x) => {
(x) => (this.#executionContextCallback = x) return (this.#executionContextCallback = x);
); });
let jsHandleFactory: JSHandleFactory; let jsHandleFactory: JSHandleFactory;
this.#client.once('Runtime.executionContextCreated', async (event) => { this.#client.once('Runtime.executionContextCreated', async (event) => {
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
jsHandleFactory = (remoteObject) => jsHandleFactory = (remoteObject) => {
new JSHandle(executionContext, client, remoteObject); return new JSHandle(executionContext, client, remoteObject);
};
const executionContext = new ExecutionContext(client, event.context); const executionContext = new ExecutionContext(client, event.context);
this.#executionContextCallback(executionContext); this.#executionContextCallback(executionContext);
}); });
// This might fail if the target is closed before we receive all execution contexts. // This might fail if the target is closed before we receive all execution contexts.
this.#client.send('Runtime.enable').catch(debugError); this.#client.send('Runtime.enable').catch(debugError);
this.#client.on('Runtime.consoleAPICalled', (event) => this.#client.on('Runtime.consoleAPICalled', (event) => {
consoleAPICalled( return consoleAPICalled(
event.type, event.type,
event.args.map(jsHandleFactory), event.args.map(jsHandleFactory),
event.stackTrace event.stackTrace
) );
); });
this.#client.on('Runtime.exceptionThrown', (exception) => this.#client.on('Runtime.exceptionThrown', (exception) => {
exceptionThrown(exception.exceptionDetails) return exceptionThrown(exception.exceptionDetails);
); });
} }
/** /**

View File

@ -212,9 +212,9 @@ export function pageBindingInitString(type: string, name: string): string {
} }
const seq = (me.lastSeq || 0) + 1; const seq = (me.lastSeq || 0) + 1;
me.lastSeq = seq; me.lastSeq = seq;
const promise = new Promise((resolve, reject) => const promise = new Promise((resolve, reject) => {
callbacks.set(seq, { resolve, reject }) return callbacks.set(seq, { resolve, reject });
); });
binding(JSON.stringify({ type, name: bindingName, seq, args })); binding(JSON.stringify({ type, name: bindingName, seq, args }));
return promise; return promise;
}; };
@ -318,10 +318,14 @@ export async function waitWithTimeout<T>(
const timeoutError = new TimeoutError( const timeoutError = new TimeoutError(
`waiting for ${taskName} failed: timeout ${timeout}ms exceeded` `waiting for ${taskName} failed: timeout ${timeout}ms exceeded`
); );
const timeoutPromise = new Promise<T>((_res, rej) => (reject = rej)); const timeoutPromise = new Promise<T>((_res, rej) => {
return (reject = rej);
});
let timeoutTimer = null; let timeoutTimer = null;
if (timeout) { if (timeout) {
timeoutTimer = setTimeout(() => reject(timeoutError), timeout); timeoutTimer = setTimeout(() => {
return reject(timeoutError);
}, timeout);
} }
try { try {
return await Promise.race([promise, timeoutPromise]); return await Promise.race([promise, timeoutPromise]);

View File

@ -143,7 +143,9 @@ const chmodAsync = promisify(fs.chmod.bind(fs));
function existsAsync(filePath: string): Promise<boolean> { function existsAsync(filePath: string): Promise<boolean> {
return new Promise((resolve) => { return new Promise((resolve) => {
fs.access(filePath, (err) => resolve(!err)); fs.access(filePath, (err) => {
return resolve(!err);
});
}); });
} }
@ -365,14 +367,19 @@ export class BrowserFetcher {
} }
const fileNames = await readdirAsync(this.#downloadsFolder); const fileNames = await readdirAsync(this.#downloadsFolder);
return fileNames return fileNames
.map((fileName) => parseFolderPath(this.#product, fileName)) .map((fileName) => {
return parseFolderPath(this.#product, fileName);
})
.filter( .filter(
( (
entry entry
): entry is { product: string; platform: string; revision: string } => ): entry is { product: string; platform: string; revision: string } => {
(entry && entry.platform === this.#platform) ?? false return (entry && entry.platform === this.#platform) ?? false;
}
) )
.map((entry) => entry.revision); .map((entry) => {
return entry.revision;
});
} }
/** /**
@ -388,7 +395,9 @@ export class BrowserFetcher {
await existsAsync(folderPath), await existsAsync(folderPath),
`Failed to remove: revision ${revision} is not downloaded` `Failed to remove: revision ${revision} is not downloaded`
); );
await new Promise((fulfill) => removeRecursive(folderPath, fulfill)); await new Promise((fulfill) => {
return removeRecursive(folderPath, fulfill);
});
} }
/** /**
@ -518,15 +527,21 @@ function _downloadFile(
return; return;
} }
const file = fs.createWriteStream(destinationPath); const file = fs.createWriteStream(destinationPath);
file.on('finish', () => fulfill()); file.on('finish', () => {
file.on('error', (error) => reject(error)); return fulfill();
});
file.on('error', (error) => {
return reject(error);
});
response.pipe(file); response.pipe(file);
totalBytes = parseInt(response.headers['content-length']!, 10); totalBytes = parseInt(response.headers['content-length']!, 10);
if (progressCallback) { if (progressCallback) {
response.on('data', onData); response.on('data', onData);
} }
}); });
request.on('error', (error) => reject(error)); request.on('error', (error) => {
return reject(error);
});
return promise; return promise;
function onData(chunk: string): void { function onData(chunk: string): void {
@ -542,9 +557,9 @@ function install(archivePath: string, folderPath: string): Promise<unknown> {
} else if (archivePath.endsWith('.tar.bz2')) { } else if (archivePath.endsWith('.tar.bz2')) {
return _extractTar(archivePath, folderPath); return _extractTar(archivePath, folderPath);
} else if (archivePath.endsWith('.dmg')) { } else if (archivePath.endsWith('.dmg')) {
return mkdirAsync(folderPath).then(() => return mkdirAsync(folderPath).then(() => {
_installDMG(archivePath, folderPath) return _installDMG(archivePath, folderPath);
); });
} else { } else {
throw new Error(`Unsupported archive format: ${archivePath}`); throw new Error(`Unsupported archive format: ${archivePath}`);
} }
@ -582,9 +597,9 @@ function _installDMG(dmgPath: string, folderPath: string): Promise<void> {
mountPath = volumes[0]!; mountPath = volumes[0]!;
readdirAsync(mountPath) readdirAsync(mountPath)
.then((fileNames) => { .then((fileNames) => {
const appName = fileNames.find( const appName = fileNames.find((item) => {
(item) => typeof item === 'string' && item.endsWith('.app') return typeof item === 'string' && item.endsWith('.app');
); });
if (!appName) { if (!appName) {
return reject(new Error(`Cannot find app in ${mountPath}`)); return reject(new Error(`Cannot find app in ${mountPath}`));
} }

View File

@ -286,9 +286,15 @@ function waitForWSEndpoint(
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const listeners = [ const listeners = [
addEventListener(rl, 'line', onLine), addEventListener(rl, 'line', onLine),
addEventListener(rl, 'close', () => onClose()), addEventListener(rl, 'close', () => {
addEventListener(browserProcess, 'exit', () => onClose()), return onClose();
addEventListener(browserProcess, 'error', (error) => onClose(error)), }),
addEventListener(browserProcess, 'exit', () => {
return onClose();
}),
addEventListener(browserProcess, 'error', (error) => {
return onClose(error);
}),
]; ];
const timeoutId = timeout ? setTimeout(onTimeout, timeout) : 0; const timeoutId = timeout ? setTimeout(onTimeout, timeout) : 0;

View File

@ -35,7 +35,9 @@ import {
import { Product } from '../common/Product.js'; import { Product } from '../common/Product.js';
const tmpDir = () => process.env['PUPPETEER_TMP_DIR'] || os.tmpdir(); const tmpDir = () => {
return process.env['PUPPETEER_TMP_DIR'] || os.tmpdir();
};
/** /**
* Describes a launcher - a class that is able to create and launch a browser instance. * Describes a launcher - a class that is able to create and launch a browser instance.
@ -100,18 +102,18 @@ class ChromeLauncher implements ProductLauncher {
chromeArguments.push(...this.defaultArgs(options)); chromeArguments.push(...this.defaultArgs(options));
} else if (Array.isArray(ignoreDefaultArgs)) { } else if (Array.isArray(ignoreDefaultArgs)) {
chromeArguments.push( chromeArguments.push(
...this.defaultArgs(options).filter( ...this.defaultArgs(options).filter((arg) => {
(arg) => !ignoreDefaultArgs.includes(arg) return !ignoreDefaultArgs.includes(arg);
) })
); );
} else { } else {
chromeArguments.push(...args); chromeArguments.push(...args);
} }
if ( if (
!chromeArguments.some((argument) => !chromeArguments.some((argument) => {
argument.startsWith('--remote-debugging-') return argument.startsWith('--remote-debugging-');
) })
) { ) {
if (pipe) { if (pipe) {
assert( assert(
@ -202,7 +204,12 @@ class ChromeLauncher implements ProductLauncher {
if (waitForInitialPage) { if (waitForInitialPage) {
try { try {
await browser.waitForTarget((t) => t.type() === 'page', { timeout }); await browser.waitForTarget(
(t) => {
return t.type() === 'page';
},
{ timeout }
);
} catch (error) { } catch (error) {
await browser.close(); await browser.close();
throw error; throw error;
@ -264,7 +271,11 @@ class ChromeLauncher implements ProductLauncher {
'--mute-audio' '--mute-audio'
); );
} }
if (args.every((arg) => arg.startsWith('-'))) { if (
args.every((arg) => {
return arg.startsWith('-');
})
) {
chromeArguments.push('about:blank'); chromeArguments.push('about:blank');
} }
chromeArguments.push(...args); chromeArguments.push(...args);
@ -337,18 +348,18 @@ class FirefoxLauncher implements ProductLauncher {
firefoxArguments.push(...this.defaultArgs(options)); firefoxArguments.push(...this.defaultArgs(options));
} else if (Array.isArray(ignoreDefaultArgs)) { } else if (Array.isArray(ignoreDefaultArgs)) {
firefoxArguments.push( firefoxArguments.push(
...this.defaultArgs(options).filter( ...this.defaultArgs(options).filter((arg) => {
(arg) => !ignoreDefaultArgs.includes(arg) return !ignoreDefaultArgs.includes(arg);
) })
); );
} else { } else {
firefoxArguments.push(...args); firefoxArguments.push(...args);
} }
if ( if (
!firefoxArguments.some((argument) => !firefoxArguments.some((argument) => {
argument.startsWith('--remote-debugging-') return argument.startsWith('--remote-debugging-');
) })
) { ) {
if (pipe) { if (pipe) {
assert( assert(
@ -438,7 +449,12 @@ class FirefoxLauncher implements ProductLauncher {
if (waitForInitialPage) { if (waitForInitialPage) {
try { try {
await browser.waitForTarget((t) => t.type() === 'page', { timeout }); await browser.waitForTarget(
(t) => {
return t.type() === 'page';
},
{ timeout }
);
} catch (error) { } catch (error) {
await browser.close(); await browser.close();
throw error; throw error;
@ -499,7 +515,11 @@ class FirefoxLauncher implements ProductLauncher {
if (devtools) { if (devtools) {
firefoxArguments.push('--devtools'); firefoxArguments.push('--devtools');
} }
if (args.every((arg) => arg.startsWith('-'))) { if (
args.every((arg) => {
return arg.startsWith('-');
})
) {
firefoxArguments.push('about:blank'); firefoxArguments.push('about:blank');
} }
firefoxArguments.push(...args); firefoxArguments.push(...args);

View File

@ -43,9 +43,9 @@ export class NodeWebSocketTransport implements ConnectionTransport {
}, },
}); });
ws.addEventListener('open', () => ws.addEventListener('open', () => {
resolve(new NodeWebSocketTransport(ws)) return resolve(new NodeWebSocketTransport(ws));
); });
ws.addEventListener('error', reject); ws.addEventListener('error', reject);
}); });
} }

View File

@ -38,7 +38,9 @@ export class PipeTransport implements ConnectionTransport {
) { ) {
this.#pipeWrite = pipeWrite; this.#pipeWrite = pipeWrite;
this.#eventListeners = [ this.#eventListeners = [
addEventListener(pipeRead, 'data', (buffer) => this.#dispatch(buffer)), addEventListener(pipeRead, 'data', (buffer) => {
return this.#dispatch(buffer);
}),
addEventListener(pipeRead, 'close', () => { addEventListener(pipeRead, 'close', () => {
if (this.onclose) { if (this.onclose) {
this.onclose.call(null); this.onclose.call(null);

View File

@ -111,12 +111,12 @@ export async function downloadBrowser(): Promise<void> {
logPolitely( logPolitely(
`${supportedProducts[product]} (${revisionInfo.revision}) downloaded to ${revisionInfo.folderPath}` `${supportedProducts[product]} (${revisionInfo.revision}) downloaded to ${revisionInfo.folderPath}`
); );
localRevisions = localRevisions.filter( localRevisions = localRevisions.filter((revision) => {
(revision) => revision !== revisionInfo.revision return revision !== revisionInfo.revision;
); });
const cleanupOldVersions = localRevisions.map((revision) => const cleanupOldVersions = localRevisions.map((revision) => {
browserFetcher.remove(revision) return browserFetcher.remove(revision);
); });
Promise.all([...cleanupOldVersions]); Promise.all([...cleanupOldVersions]);
} }
@ -151,7 +151,9 @@ export async function downloadBrowser(): Promise<void> {
return browserFetcher return browserFetcher
.download(revisionInfo.revision, onProgress) .download(revisionInfo.revision, onProgress)
.then(() => browserFetcher.localRevisions()) .then(() => {
return browserFetcher.localRevisions();
})
.then(onSuccess) .then(onSuccess)
.catch(onError); .catch(onError);
} }

View File

@ -1,6 +1,5 @@
module.exports = { module.exports = {
rules: { rules: {
'arrow-body-style': ['error', 'always'],
'no-restricted-imports': [ 'no-restricted-imports': [
'error', 'error',
{ {

View File

@ -22,10 +22,15 @@ const { promisify } = require('util');
const exec = promisify(child_process.exec); const exec = promisify(child_process.exec);
const fsAccess = promisify(fs.access); const fsAccess = promisify(fs.access);
const fileExists = async (filePath) => const fileExists = async (filePath) => {
fsAccess(filePath) return fsAccess(filePath)
.then(() => true) .then(() => {
.catch(() => false); return true;
})
.catch(() => {
return false;
});
};
/* /*
* Now Puppeteer is built with TypeScript, we need to ensure that * Now Puppeteer is built with TypeScript, we need to ensure that

View File

@ -168,8 +168,12 @@ function runScript(scriptPath, revisionInfo) {
}, },
}); });
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
child.on('error', (err) => reject(err)); child.on('error', (err) => {
child.on('exit', (code) => resolve(code)); return reject(err);
});
child.on('exit', (code) => {
return resolve(code);
});
}); });
} }
@ -185,8 +189,12 @@ function runUnitTest(pattern, revisionInfo) {
}, },
}); });
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
child.on('error', (err) => reject(err)); child.on('error', (err) => {
child.on('exit', (code) => resolve(code)); return reject(err);
});
child.on('exit', (code) => {
return resolve(code);
});
}); });
} }
@ -274,10 +282,16 @@ function fetchJSON(url) {
const req = agent.request(options, function (res) { const req = agent.request(options, function (res) {
let result = ''; let result = '';
res.setEncoding('utf8'); res.setEncoding('utf8');
res.on('data', (chunk) => (result += chunk)); res.on('data', (chunk) => {
res.on('end', () => resolve(JSON.parse(result))); return (result += chunk);
});
res.on('end', () => {
return resolve(JSON.parse(result));
});
});
req.on('error', (err) => {
return reject(err);
}); });
req.on('error', (err) => reject(err));
req.end(); req.end();
}); });
} }

View File

@ -155,7 +155,9 @@ async function checkOmahaProxyAvailability() {
'https://storage.googleapis.com/chromium-browser-snapshots/Win_x64/LAST_CHANGE' 'https://storage.googleapis.com/chromium-browser-snapshots/Win_x64/LAST_CHANGE'
), ),
]) ])
).map((s) => parseInt(s, 10)); ).map((s) => {
return parseInt(s, 10);
});
const from = Math.max(...latestRevisions); const from = Math.max(...latestRevisions);
await checkRangeAvailability({ await checkRangeAvailability({
fromRevision: from, fromRevision: from,
@ -183,7 +185,9 @@ async function printLatestRevisionForPlatform(platform) {
'https://storage.googleapis.com/chromium-browser-snapshots/Win_x64/LAST_CHANGE' 'https://storage.googleapis.com/chromium-browser-snapshots/Win_x64/LAST_CHANGE'
), ),
]) ])
).map((s) => parseInt(s, 10)); ).map((s) => {
return parseInt(s, 10);
});
const from = Math.max(...latestRevisions); const from = Math.max(...latestRevisions);
await checkRangeAvailability({ await checkRangeAvailability({
fromRevision: from, fromRevision: from,
@ -233,13 +237,18 @@ async function checkRangeAvailability({
platforms = platforms || SUPPORTED_PLATFORMS; platforms = platforms || SUPPORTED_PLATFORMS;
let table; let table;
if (printAsTable) { if (printAsTable) {
table = new Table([10, ...platforms.map(() => 7)]); table = new Table([
10,
...platforms.map(() => {
return 7;
}),
]);
table.drawRow([''].concat(platforms)); table.drawRow([''].concat(platforms));
} }
const fetchers = platforms.map( const fetchers = platforms.map((platform) => {
(platform) => new BrowserFetcher('', { platform }) return new BrowserFetcher('', { platform });
); });
const inc = fromRevision < toRevision ? 1 : -1; const inc = fromRevision < toRevision ? 1 : -1;
const revisionToStop = toRevision + inc; // +inc so the range is fully inclusive const revisionToStop = toRevision + inc; // +inc so the range is fully inclusive
@ -248,9 +257,13 @@ async function checkRangeAvailability({
revision !== revisionToStop; revision !== revisionToStop;
revision += inc revision += inc
) { ) {
const promises = fetchers.map((fetcher) => fetcher.canDownload(revision)); const promises = fetchers.map((fetcher) => {
return fetcher.canDownload(revision);
});
const availability = await Promise.all(promises); const availability = await Promise.all(promises);
const allAvailable = availability.every((e) => !!e); const allAvailable = availability.every((e) => {
return !!e;
});
if (table) { if (table) {
const values = [ const values = [
' ' + ' ' +
@ -279,7 +292,9 @@ async function checkRangeAvailability({
*/ */
function fetch(url) { function fetch(url) {
let resolve; let resolve;
const promise = new Promise((x) => (resolve = x)); const promise = new Promise((x) => {
return (resolve = x);
});
https https
.get(url, (response) => { .get(url, (response) => {
if (response.statusCode !== 200) { if (response.statusCode !== 200) {

View File

@ -86,8 +86,12 @@ async function main(url) {
return; return;
} }
const devicePayloads = json.extensions const devicePayloads = json.extensions
.filter((extension) => extension.type === 'emulated-device') .filter((extension) => {
.map((extension) => extension.device); return extension.type === 'emulated-device';
})
.map((extension) => {
return extension.device;
});
let devices = []; let devices = [];
for (const payload of devicePayloads) { for (const payload of devicePayloads) {
let names = []; let names = [];
@ -112,8 +116,12 @@ async function main(url) {
} }
} }
} }
devices = devices.filter((device) => device.viewport.isMobile); devices = devices.filter((device) => {
devices.sort((a, b) => a.name.localeCompare(b.name)); return device.viewport.isMobile;
});
devices.sort((a, b) => {
return a.name.localeCompare(b.name);
});
// Use single-quotes instead of double-quotes to conform with codestyle. // Use single-quotes instead of double-quotes to conform with codestyle.
const serialized = JSON.stringify(devices, null, 2) const serialized = JSON.stringify(devices, null, 2)
.replace(/'/g, `\\'`) .replace(/'/g, `\\'`)
@ -282,8 +290,12 @@ function httpGET(url) {
const request = driver.get(url, (response) => { const request = driver.get(url, (response) => {
let data = ''; let data = '';
response.setEncoding('utf8'); response.setEncoding('utf8');
response.on('data', (chunk) => (data += chunk)); response.on('data', (chunk) => {
response.on('end', () => fulfill(data)); return (data += chunk);
});
response.on('end', () => {
return fulfill(data);
});
response.on('error', reject); response.on('error', reject);
}); });
request.on('error', reject); request.on('error', reject);

View File

@ -67,7 +67,9 @@ export class TestServer {
static async create(dirPath: string, port: number): Promise<TestServer> { static async create(dirPath: string, port: number): Promise<TestServer> {
const server = new TestServer(dirPath, port); const server = new TestServer(dirPath, port);
await new Promise((x) => server.#server.once('listening', x)); await new Promise((x) => {
return server.#server.once('listening', x);
});
return server; return server;
} }
@ -77,7 +79,9 @@ export class TestServer {
cert: readFileSync(join(__dirname, '..', 'cert.pem')), cert: readFileSync(join(__dirname, '..', 'cert.pem')),
passphrase: 'aaaa', passphrase: 'aaaa',
}); });
await new Promise((x) => server.#server.once('listening', x)); await new Promise((x) => {
return server.#server.once('listening', x);
});
return server; return server;
} }
@ -104,7 +108,9 @@ export class TestServer {
throw error; throw error;
} }
}); });
connection.once('close', () => this.#connections.delete(connection)); connection.once('close', () => {
return this.#connections.delete(connection);
});
}; };
enableHTTPCache(pathPrefix: string): void { enableHTTPCache(pathPrefix: string): void {
@ -129,7 +135,9 @@ export class TestServer {
socket.destroy(); socket.destroy();
} }
this.#connections.clear(); this.#connections.clear();
await new Promise((x) => this.#server.close(x)); await new Promise((x) => {
return this.#server.close(x);
});
} }
setRoute( setRoute(
@ -186,8 +194,12 @@ export class TestServer {
}); });
request.postBody = new Promise((resolve) => { request.postBody = new Promise((resolve) => {
let body = ''; let body = '';
request.on('data', (chunk: string) => (body += chunk)); request.on('data', (chunk: string) => {
request.on('end', () => resolve(body)); return (body += chunk);
});
request.on('end', () => {
return resolve(body);
});
}); });
assert(request.url); assert(request.url);
const url = new URL(request.url, `https://${request.headers.host}`); const url = new URL(request.url, `https://${request.headers.host}`);