From dcf92e4d2f85c97ffe282a0753743d63cc785036 Mon Sep 17 00:00:00 2001 From: Joel Einbinder Date: Fri, 6 Dec 2019 00:14:16 +0000 Subject: [PATCH] runtime checks --- src/dom.ts | 22 +++++++++++++++++----- src/injected/injected.ts | 6 ++++-- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/dom.ts b/src/dom.ts index f1e28aeaa2..7f379575b5 100644 --- a/src/dom.ts +++ b/src/dom.ts @@ -78,7 +78,7 @@ export class DOMWorld { const resolved = await this.resolveSelector(selector); const handle = await this.context.evaluateHandle( (injected: Injected, selector: string, scope?: Node, visible?: boolean) => { - const element = injected.querySelector(selector, scope as SelectorRoot || document); + const element = injected.querySelector(selector, scope || document); if (visible === undefined || !element) return element; return injected.isVisible(element) === visible ? element : undefined; @@ -96,7 +96,7 @@ export class DOMWorld { const resolved = await this.resolveSelector(selector); const arrayHandle = await this.context.evaluateHandle( (injected: Injected, selector: string, scope?: Node, visible?: boolean) => { - const elements = injected.querySelectorAll(selector, scope as SelectorRoot || document); + const elements = injected.querySelectorAll(selector, scope || document); if (visible !== undefined) return elements.filter(element => injected.isVisible(element) === visible); return elements; @@ -131,7 +131,7 @@ export class DOMWorld { const resolved = await this.resolveSelector(selector); const arrayHandle = await this.context.evaluateHandle( (injected: Injected, selector: string, scope?: Node, visible?: boolean) => { - const elements = injected.querySelectorAll(selector, scope as SelectorRoot || document); + const elements = injected.querySelectorAll(selector, scope || document); if (visible !== undefined) return elements.filter(element => injected.isVisible(element) === visible); return elements; @@ -246,13 +246,25 @@ export class ElementHandle extends js.JSHandle { } async setInputFiles(...files: (string|input.FilePayload)[]) { - const multiple = await this.evaluate((element: Node) => !!(element as HTMLInputElement).multiple); + const multiple = await this.evaluate((node: Node) => { + if (node.nodeType !== Node.ELEMENT_NODE || (node as Element).tagName !== 'INPUT') + throw new Error('Node is not an HTMLInputElement'); + const input = node as HTMLInputElement; + return input.multiple; + }); assert(multiple || files.length <= 1, 'Non-multiple file input can only accept single file!'); await this._world.delegate.setInputFiles(this, await input.loadFiles(files)); } async focus() { - await this.evaluate((element: Node) => (element as HTMLElement).focus()); + const errorMessage = await this.evaluate((element: Node) => { + if (!element['focus']) + return 'Node is not an HTML or SVG element.'; + (element as HTMLElement|SVGElement).focus(); + return false; + }); + if (errorMessage) + throw new Error(errorMessage); } async type(text: string, options: { delay: (number | undefined); } | undefined) { diff --git a/src/injected/injected.ts b/src/injected/injected.ts index 545558be5f..046ffa3169 100644 --- a/src/injected/injected.ts +++ b/src/injected/injected.ts @@ -31,9 +31,11 @@ class Injected { return element as Element; } - querySelectorAll(selector: string, root: SelectorRoot): Element[] { + querySelectorAll(selector: string, root: Node): Element[] { const parsed = this._parseSelector(selector); - let set = new Set([ root ]); + if (!root["querySelectorAll"]) + throw new Error('Node is not queryable.'); + let set = new Set([ root as SelectorRoot ]); for (const { engine, selector } of parsed) { const newSet = new Set(); for (const prev of set) {