From 7f5a537b26601a9511f77945ca8e327ca1752648 Mon Sep 17 00:00:00 2001 From: Joel Einbinder Date: Thu, 5 Dec 2019 23:04:36 +0000 Subject: [PATCH] fix(fill): throw when the element isn't fillable --- src/dom.ts | 2 -- src/input.ts | 24 ++++++++++++++++++++++-- test/page.spec.js | 35 +++++++++++++++++++++++++++++++++-- 3 files changed, 55 insertions(+), 6 deletions(-) diff --git a/src/dom.ts b/src/dom.ts index d26248e649..85e5b51ef1 100644 --- a/src/dom.ts +++ b/src/dom.ts @@ -330,8 +330,6 @@ export class ElementHandle extends js.JSHandle { const error = await this.evaluate(input.fillFunction); if (error) throw new Error(error); - await this.focus(); - // TODO: we should check that focus() succeeded. await this._world.delegate.keyboard.sendCharacters(value); } diff --git a/src/input.ts b/src/input.ts index 5e4e2885e3..9e876265db 100644 --- a/src/input.ts +++ b/src/input.ts @@ -318,26 +318,46 @@ export const selectFunction = (element: HTMLSelectElement, ...optionsToSelect: ( export const fillFunction = (element: HTMLElement) => { if (element.nodeType !== Node.ELEMENT_NODE) return 'Node is not of type HTMLElement'; + if (!element.isConnected) + return 'Element is not attached to the DOM'; + if (!element.ownerDocument || !element.ownerDocument.defaultView) + return 'Element does not belong to a window'; + + const style = element.ownerDocument.defaultView.getComputedStyle(element); + if (!style || style.visibility === 'hidden') + return 'Element is hidden'; + if (!element.offsetParent && element.tagName !== 'BODY') + return 'Element is not visible'; + if (element.nodeName.toLowerCase() === 'input') { const input = element as HTMLInputElement; const type = input.getAttribute('type') || ''; const kTextInputTypes = new Set(['', 'password', 'search', 'tel', 'text', 'url']); if (!kTextInputTypes.has(type.toLowerCase())) return 'Cannot fill input of type "' + type + '".'; + if (input.disabled) + return 'Cannot fill a disabled input.'; + if (input.readOnly) + return 'Cannot fill a readonly input.'; input.selectionStart = 0; input.selectionEnd = input.value.length; + input.focus(); } else if (element.nodeName.toLowerCase() === 'textarea') { const textarea = element as HTMLTextAreaElement; + if (textarea.disabled) + return 'Cannot fill a disabled textarea.'; + if (textarea.readOnly) + return 'Cannot fill a readonly textarea.'; textarea.selectionStart = 0; textarea.selectionEnd = textarea.value.length; + textarea.focus(); } else if (element.isContentEditable) { - if (!element.ownerDocument || !element.ownerDocument.defaultView) - return 'Element does not belong to a window'; const range = element.ownerDocument.createRange(); range.selectNodeContents(element); const selection = element.ownerDocument.defaultView.getSelection(); selection.removeAllRanges(); selection.addRange(range); + element.focus(); } else { return 'Element is not an ,