diff --git a/packages/page-controller/src/actions.ts b/packages/page-controller/src/actions.ts index 3198bc3..8a86fa7 100644 --- a/packages/page-controller/src/actions.ts +++ b/packages/page-controller/src/actions.ts @@ -70,15 +70,15 @@ export async function clickElement(element: HTMLElement) { const frame = element.ownerDocument.defaultView?.frameElement if (frame) await scrollIntoViewIfNeeded(frame) - await movePointerToElement(element) - await clickPointer() - - await waitFor(0.1) - const rect = element.getBoundingClientRect() const x = rect.left + rect.width / 2 const y = rect.top + rect.height / 2 + await movePointerToElement(element, x, y) + await clickPointer() + + await waitFor(0.1) + // Hit-test to find the deepest element at click coordinates, matching // real browser behavior where events target the innermost element. // @note This may hit a element in the blacklist diff --git a/packages/page-controller/src/utils/index.ts b/packages/page-controller/src/utils/index.ts index 97b8b89..885357d 100644 --- a/packages/page-controller/src/utils/index.ts +++ b/packages/page-controller/src/utils/index.ts @@ -50,13 +50,19 @@ export async function waitFor(seconds: number): Promise { // ======= mask events ======= -export async function movePointerToElement(element: HTMLElement) { - const rect = element.getBoundingClientRect() +/** + * Move the visual pointer to a position within an element. + * @param x - x coordinate in the element's document viewport + * @param y - y coordinate in the element's document viewport + */ +export async function movePointerToElement(element: HTMLElement, x: number, y: number) { const offset = getIframeOffset(element) - const x = rect.left + rect.width / 2 + offset.x - const y = rect.top + rect.height / 2 + offset.y - window.dispatchEvent(new CustomEvent('PageAgent::MovePointerTo', { detail: { x, y } })) + window.dispatchEvent( + new CustomEvent('PageAgent::MovePointerTo', { + detail: { x: x + offset.x, y: y + offset.y }, + }) + ) await waitFor(0.3) }