From 734705e9b3c0753a2f41b7664b9ab7c9a0798cb5 Mon Sep 17 00:00:00 2001 From: Dmitry Gozman Date: Fri, 9 Jun 2023 07:18:13 -0700 Subject: [PATCH] chore: elementHandle getters implemented through Frame (#23557) This is a step towards not using handles for locator operations. --- .../src/server/chromium/crPage.ts | 2 +- .../dispatchers/elementHandlerDispatcher.ts | 24 ++--- packages/playwright-core/src/server/dom.ts | 97 ++++++------------- .../src/server/firefox/ffPage.ts | 6 +- packages/playwright-core/src/server/frames.ts | 79 +++++++-------- packages/playwright-core/src/server/page.ts | 2 +- .../src/server/trace/recorder/tracing.ts | 6 +- .../src/server/webkit/wkPage.ts | 2 +- tests/library/trace-viewer.spec.ts | 47 +++++---- 9 files changed, 116 insertions(+), 149 deletions(-) diff --git a/packages/playwright-core/src/server/chromium/crPage.ts b/packages/playwright-core/src/server/chromium/crPage.ts index 4b93c1d410..c992d0632a 100644 --- a/packages/playwright-core/src/server/chromium/crPage.ts +++ b/packages/playwright-core/src/server/chromium/crPage.ts @@ -333,7 +333,7 @@ export class CRPage implements PageDelegate { injected.setInputFiles(node, files), files); } - async setInputFilePaths(handle: dom.ElementHandle, files: string[]): Promise { + async setInputFilePaths(progress: Progress, handle: dom.ElementHandle, files: string[]): Promise { const frame = await handle.ownerFrame(); if (!frame) throw new Error('Cannot set input files to detached input element'); diff --git a/packages/playwright-core/src/server/dispatchers/elementHandlerDispatcher.ts b/packages/playwright-core/src/server/dispatchers/elementHandlerDispatcher.ts index 7c7cc2e80b..e39e58ace3 100644 --- a/packages/playwright-core/src/server/dispatchers/elementHandlerDispatcher.ts +++ b/packages/playwright-core/src/server/dispatchers/elementHandlerDispatcher.ts @@ -66,54 +66,54 @@ export class ElementHandleDispatcher extends JSHandleDispatcher implements chann } async getAttribute(params: channels.ElementHandleGetAttributeParams, metadata: CallMetadata): Promise { - const value = await this._elementHandle.getAttribute(params.name); + const value = await this._elementHandle.getAttribute(metadata, params.name); return { value: value === null ? undefined : value }; } async inputValue(params: channels.ElementHandleInputValueParams, metadata: CallMetadata): Promise { - const value = await this._elementHandle.inputValue(); + const value = await this._elementHandle.inputValue(metadata); return { value }; } async textContent(params: channels.ElementHandleTextContentParams, metadata: CallMetadata): Promise { - const value = await this._elementHandle.textContent(); + const value = await this._elementHandle.textContent(metadata); return { value: value === null ? undefined : value }; } async innerText(params: channels.ElementHandleInnerTextParams, metadata: CallMetadata): Promise { - return { value: await this._elementHandle.innerText() }; + return { value: await this._elementHandle.innerText(metadata) }; } async innerHTML(params: channels.ElementHandleInnerHTMLParams, metadata: CallMetadata): Promise { - return { value: await this._elementHandle.innerHTML() }; + return { value: await this._elementHandle.innerHTML(metadata) }; } async isChecked(params: channels.ElementHandleIsCheckedParams, metadata: CallMetadata): Promise { - return { value: await this._elementHandle.isChecked() }; + return { value: await this._elementHandle.isChecked(metadata) }; } async isDisabled(params: channels.ElementHandleIsDisabledParams, metadata: CallMetadata): Promise { - return { value: await this._elementHandle.isDisabled() }; + return { value: await this._elementHandle.isDisabled(metadata) }; } async isEditable(params: channels.ElementHandleIsEditableParams, metadata: CallMetadata): Promise { - return { value: await this._elementHandle.isEditable() }; + return { value: await this._elementHandle.isEditable(metadata) }; } async isEnabled(params: channels.ElementHandleIsEnabledParams, metadata: CallMetadata): Promise { - return { value: await this._elementHandle.isEnabled() }; + return { value: await this._elementHandle.isEnabled(metadata) }; } async isHidden(params: channels.ElementHandleIsHiddenParams, metadata: CallMetadata): Promise { - return { value: await this._elementHandle.isHidden() }; + return { value: await this._elementHandle.isHidden(metadata) }; } async isVisible(params: channels.ElementHandleIsVisibleParams, metadata: CallMetadata): Promise { - return { value: await this._elementHandle.isVisible() }; + return { value: await this._elementHandle.isVisible(metadata) }; } async dispatchEvent(params: channels.ElementHandleDispatchEventParams, metadata: CallMetadata): Promise { - await this._elementHandle.dispatchEvent(params.type, parseArgument(params.eventInit)); + await this._elementHandle.dispatchEvent(metadata, params.type, parseArgument(params.eventInit)); } async scrollIntoViewIfNeeded(params: channels.ElementHandleScrollIntoViewIfNeededParams, metadata: CallMetadata): Promise { diff --git a/packages/playwright-core/src/server/dom.ts b/packages/playwright-core/src/server/dom.ts index 52aa5caecf..51b34dba8a 100644 --- a/packages/playwright-core/src/server/dom.ts +++ b/packages/playwright-core/src/server/dom.ts @@ -192,55 +192,28 @@ export class ElementHandle extends js.JSHandle { return this._page._delegate.getContentFrame(this); } - async getAttribute(name: string): Promise { - return throwRetargetableDOMError(await this.evaluateInUtility(([injected, node, name]) => { - if (node.nodeType !== Node.ELEMENT_NODE) - throw injected.createStacklessError('Node is not an element'); - const element = node as unknown as Element; - return { value: element.getAttribute(name) }; - }, name)).value; + async getAttribute(metadata: CallMetadata, name: string): Promise { + return this._frame.getAttribute(metadata, ':scope', name, {}, this); } - async inputValue(): Promise { - return throwRetargetableDOMError(await this.evaluateInUtility(([injected, node]) => { - const element = injected.retarget(node, 'follow-label'); - if (!element || (element.nodeName !== 'INPUT' && element.nodeName !== 'TEXTAREA' && element.nodeName !== 'SELECT')) - throw injected.createStacklessError('Node is not an ,