Skip to content

Commit

Permalink
feat: use strict typescript
Browse files Browse the repository at this point in the history
  • Loading branch information
jrandolf committed May 30, 2022
1 parent 54efc2c commit 7a9daaf
Show file tree
Hide file tree
Showing 45 changed files with 703 additions and 557 deletions.
3 changes: 2 additions & 1 deletion package.json
Expand Up @@ -49,7 +49,7 @@
"generate-api-docs-for-testing": "commonmark docs/api.md > docs/api.html",
"clean-lib": "rimraf lib",
"build": "npm run tsc && npm run generate-d-ts && npm run generate-esm-package-json",
"tsc": "npm run clean-lib && tsc --version && (npm run tsc-cjs & npm run tsc-esm) && (npm run tsc-compat-cjs & npm run tsc-compat-esm)",
"tsc": "npm run clean-lib && tsc --version && (npm run tsc-cjs && npm run tsc-esm) && (npm run tsc-compat-cjs && npm run tsc-compat-esm)",
"tsc-cjs": "tsc -b src/tsconfig.cjs.json",
"tsc-esm": "tsc -b src/tsconfig.esm.json",
"tsc-compat-cjs": "tsc -b compat/cjs/tsconfig.json",
Expand Down Expand Up @@ -107,6 +107,7 @@
"@types/rimraf": "3.0.2",
"@types/sinon": "10.0.11",
"@types/tar-fs": "2.0.1",
"@types/unbzip2-stream": "1.4.0",
"@types/ws": "8.5.3",
"@typescript-eslint/eslint-plugin": "5.23.0",
"@typescript-eslint/parser": "5.22.0",
Expand Down
8 changes: 7 additions & 1 deletion scripts/ensure-correct-devtools-protocol-package.ts
Expand Up @@ -36,6 +36,7 @@
// eslint-disable-next-line import/extensions
import { PUPPETEER_REVISIONS } from '../src/revisions';
import { execSync } from 'child_process';
import { strict as assert } from 'assert/strict';

import packageJson from '../package.json';

Expand Down Expand Up @@ -66,7 +67,12 @@ const output = execSync(command, {
encoding: 'utf8',
});

const bestRevisionFromNpm = output.split(' ')[1].replace(/'|\n/g, '');
let bestRevisionFromNpm: string;
{
let tmp;
assert((tmp = output.split(' ')[1]));
bestRevisionFromNpm = tmp.replace(/'|\n/g, '');
}

if (currentProtocolPackageInstalledVersion !== bestRevisionFromNpm) {
console.log(`ERROR: bad devtools-protocol revision detected:
Expand Down
2 changes: 1 addition & 1 deletion scripts/ensure-pinned-deps.ts
Expand Up @@ -21,7 +21,7 @@ const allDeps = { ...packageJson.dependencies, ...packageJson.devDependencies };
const invalidDeps = new Map<string, string>();

for (const [depKey, depValue] of Object.entries(allDeps)) {
if (/[0-9]/.test(depValue[0])) {
if (/[0-9]/.test(depValue[0]!)) {
continue;
}

Expand Down
12 changes: 6 additions & 6 deletions src/common/Accessibility.ts
Expand Up @@ -180,30 +180,30 @@ export class Accessibility {
*/
public async snapshot(
options: SnapshotOptions = {}
): Promise<SerializedAXNode> {
): Promise<SerializedAXNode | null> {
const { interestingOnly = true, root = null } = options;
const { nodes } = await this._client.send('Accessibility.getFullAXTree');
let backendNodeId = null;
let backendNodeId: number | undefined;
if (root) {
const { node } = await this._client.send('DOM.describeNode', {
objectId: root._remoteObject.objectId,
});
backendNodeId = node.backendNodeId;
}
const defaultRoot = AXNode.createTree(nodes);
let needle = defaultRoot;
let needle: AXNode | null = defaultRoot;
if (backendNodeId) {
needle = defaultRoot.find(
(node) => node.payload.backendDOMNodeId === backendNodeId
);
if (!needle) return null;
}
if (!interestingOnly) return this.serializeTree(needle)[0];
if (!interestingOnly) return this.serializeTree(needle)[0] ?? null;

const interestingNodes = new Set<AXNode>();
this.collectInterestingNodes(interestingNodes, defaultRoot, false);
if (!interestingNodes.has(needle)) return null;
return this.serializeTree(needle, interestingNodes)[0];
return this.serializeTree(needle, interestingNodes)[0] ?? null;
}

private serializeTree(
Expand Down Expand Up @@ -496,7 +496,7 @@ class AXNode {
nodeById.set(payload.nodeId, new AXNode(payload));
for (const node of nodeById.values()) {
for (const childId of node.payload.childIds || [])
node.children.push(nodeById.get(childId));
node.children.push(nodeById.get(childId)!);
}
return nodeById.values().next().value;
}
Expand Down
33 changes: 23 additions & 10 deletions src/common/AriaQueryHandler.ts
Expand Up @@ -19,6 +19,7 @@ import { ElementHandle, JSHandle } from './JSHandle.js';
import { Protocol } from 'devtools-protocol';
import { CDPSession } from './Connection.js';
import { DOMWorld, PageBinding, WaitForSelectorOptions } from './DOMWorld.js';
import { assert } from './assert.js';

async function queryAXTree(
client: CDPSession,
Expand All @@ -32,7 +33,8 @@ async function queryAXTree(
role,
});
const filteredNodes: Protocol.Accessibility.AXNode[] = nodes.filter(
(node: Protocol.Accessibility.AXNode) => node.role.value !== 'StaticText'
(node: Protocol.Accessibility.AXNode) =>
!node.role || node.role.value !== 'StaticText'
);
return filteredNodes;
}
Expand All @@ -43,6 +45,13 @@ const knownAttributes = new Set(['name', 'role']);
const attributeRegexp =
/\[\s*(?<attribute>\w+)\s*=\s*(?<quote>"|')(?<value>\\.|.*?(?=\k<quote>))\k<quote>\s*\]/g;

type ARIAQueryOption = { name?: string; role?: string };
function isKnownAttribute(
attribute: string
): attribute is keyof ARIAQueryOption {
return knownAttributes.has(attribute);
}

/*
* The selectors consist of an accessible name to query for and optionally
* further aria attributes on the form `[<attribute>=<value>]`.
Expand All @@ -53,15 +62,16 @@ const attributeRegexp =
* - 'label' queries for elements with name 'label' and any role.
* - '[name=""][role="button"]' queries for elements with no name and role 'button'.
*/
type ariaQueryOption = { name?: string; role?: string };
function parseAriaSelector(selector: string): ariaQueryOption {
const queryOptions: ariaQueryOption = {};
function parseAriaSelector(selector: string): ARIAQueryOption {
const queryOptions: ARIAQueryOption = {};
const defaultName = selector.replace(
attributeRegexp,
(_, attribute: string, quote: string, value: string) => {
(_, attribute: string, _quote: string, value: string) => {
attribute = attribute.trim();
if (!knownAttributes.has(attribute))
throw new Error(`Unknown aria attribute "${attribute}" in selector`);
assert(
isKnownAttribute(attribute),
`Unknown aria attribute "${attribute}" in selector`
);
queryOptions[attribute] = normalizeValue(value);
return '';
}
Expand All @@ -78,7 +88,7 @@ const queryOne = async (
const exeCtx = element.executionContext();
const { name, role } = parseAriaSelector(selector);
const res = await queryAXTree(exeCtx._client, element, name, role);
if (res.length < 1) {
if (!res[0] || !res[0].backendDOMNodeId) {
return null;
}
return exeCtx._adoptBackendNodeId(res[0].backendDOMNodeId);
Expand All @@ -88,7 +98,7 @@ const waitFor = async (
domWorld: DOMWorld,
selector: string,
options: WaitForSelectorOptions
): Promise<ElementHandle<Element>> => {
): Promise<ElementHandle<Element> | null> => {
const binding: PageBinding = {
name: 'ariaQuerySelector',
pptrFunction: async (selector: string) => {
Expand All @@ -98,7 +108,10 @@ const waitFor = async (
},
};
return domWorld.waitForSelectorInPage(
(_: Element, selector: string) => globalThis.ariaQuerySelector(selector),
(_: Element, selector: string) =>
(
globalThis as unknown as { ariaQuerySelector(selector: string): void }
).ariaQuerySelector(selector),
selector,
options,
binding
Expand Down
29 changes: 10 additions & 19 deletions src/common/Browser.ts
Expand Up @@ -246,7 +246,7 @@ export class Browser extends EventEmitter {
private _connection: Connection;
private _closeCallback: BrowserCloseCallback;
private _targetFilterCallback: TargetFilterCallback;
private _isPageTargetCallback: IsPageTargetCallback;
private _isPageTargetCallback!: IsPageTargetCallback;
private _defaultContext: BrowserContext;
private _contexts: Map<string, BrowserContext>;
private _screenshotTaskQueue: TaskQueue;
Expand Down Expand Up @@ -572,33 +572,24 @@ export class Browser extends EventEmitter {
): Promise<Target> {
const { timeout = 30000 } = options;
let resolve: (value: Target | PromiseLike<Target>) => void;
let isResolved = false;
const targetPromise = new Promise<Target>((x) => (resolve = x));
this.on(BrowserEmittedEvents.TargetCreated, check);
this.on(BrowserEmittedEvents.TargetChanged, check);
try {
if (!timeout) return await targetPromise;
return await helper.waitWithTimeout<Target>(
Promise.race([
targetPromise,
(async () => {
for (const target of this.targets()) {
if (await predicate(target)) {
return target;
}
}
await targetPromise;
})(),
]),
'target',
timeout
);
this.targets().forEach(check);
return await helper.waitWithTimeout(targetPromise, 'target', timeout);
} finally {
this.removeListener(BrowserEmittedEvents.TargetCreated, check);
this.removeListener(BrowserEmittedEvents.TargetChanged, check);
this.off(BrowserEmittedEvents.TargetCreated, check);
this.off(BrowserEmittedEvents.TargetChanged, check);
}

async function check(target: Target): Promise<void> {
if (await predicate(target)) resolve(target);
if ((await predicate(target)) && !isResolved) {
isResolved = true;
resolve(target);
}
}
}

Expand Down
12 changes: 7 additions & 5 deletions src/common/BrowserConnector.ts
Expand Up @@ -93,7 +93,7 @@ export const connectToBrowser = async (
'Exactly one of browserWSEndpoint, browserURL or transport must be passed to puppeteer.connect'
);

let connection = null;
let connection!: Connection;
if (transport) {
connection = new Connection('', transport, slowMo);
} else if (browserWSEndpoint) {
Expand All @@ -117,7 +117,7 @@ export const connectToBrowser = async (
browserContextIds,
ignoreHTTPSErrors,
defaultViewport,
null,
undefined,
() => connection.send('Browser.close').catch(debugError),
targetFilter,
isPageTarget
Expand All @@ -138,9 +138,11 @@ async function getWSEndpoint(browserURL: string): Promise<string> {
const data = await result.json();
return data.webSocketDebuggerUrl;
} catch (error) {
error.message =
`Failed to fetch browser webSocket URL from ${endpointURL}: ` +
error.message;
if (error instanceof Error) {
error.message =
`Failed to fetch browser webSocket URL from ${endpointURL}: ` +
error.message;
}
throw error;
}
}
2 changes: 0 additions & 2 deletions src/common/BrowserWebSocketTransport.ts
Expand Up @@ -41,8 +41,6 @@ export class BrowserWebSocketTransport implements ConnectionTransport {
});
// Silently ignore all errors - we don't know what to do with them.
this._ws.addEventListener('error', () => {});
this.onmessage = null;
this.onclose = null;
}

send(message: string): void {
Expand Down
2 changes: 1 addition & 1 deletion src/common/ConsoleMessage.ts
Expand Up @@ -111,7 +111,7 @@ export class ConsoleMessage {
* @returns The location of the console message.
*/
location(): ConsoleMessageLocation {
return this._stackTraceLocations.length ? this._stackTraceLocations[0] : {};
return this._stackTraceLocations[0] ?? {};
}

/**
Expand Down
13 changes: 9 additions & 4 deletions src/common/Coverage.ts
Expand Up @@ -395,10 +395,12 @@ export class CSSCoverage {
});
}

const coverage = [];
const coverage: CoverageEntry[] = [];
for (const styleSheetId of this._stylesheetURLs.keys()) {
const url = this._stylesheetURLs.get(styleSheetId);
assert(url);
const text = this._stylesheetSources.get(styleSheetId);
assert(text);
const ranges = convertToDisjointRanges(
styleSheetIdToCoverage.get(styleSheetId) || []
);
Expand Down Expand Up @@ -432,16 +434,19 @@ function convertToDisjointRanges(
});

const hitCountStack = [];
const results = [];
const results: Array<{
start: number;
end: number;
}> = [];
let lastOffset = 0;
// Run scanning line to intersect all ranges.
for (const point of points) {
if (
hitCountStack.length &&
lastOffset < point.offset &&
hitCountStack[hitCountStack.length - 1] > 0
hitCountStack[hitCountStack.length - 1]! > 0
) {
const lastResult = results.length ? results[results.length - 1] : null;
const lastResult = results[results.length - 1];
if (lastResult && lastResult.end === lastOffset)
lastResult.end = point.offset;
else results.push({ start: lastOffset, end: point.offset });
Expand Down

0 comments on commit 7a9daaf

Please sign in to comment.