diff --git a/lib/helper/Playwright.js b/lib/helper/Playwright.js index 33399fdef..b8f3902ed 100644 --- a/lib/helper/Playwright.js +++ b/lib/helper/Playwright.js @@ -1525,6 +1525,7 @@ class Playwright extends Helper { assertElementExists(el, locator) } + await el.scrollIntoViewIfNeeded() // Use manual mouse.move instead of .hover() so the offset can be added to the coordinates const { x, y } = await clickablePoint(el) await this.page.mouse.move(x + offsetX, y + offsetY) diff --git a/lib/helper/Puppeteer.js b/lib/helper/Puppeteer.js index 3d1f7a02e..4ba0b7974 100644 --- a/lib/helper/Puppeteer.js +++ b/lib/helper/Puppeteer.js @@ -845,6 +845,9 @@ class Puppeteer extends Helper { } } + if (!(await el.isIntersectingViewport({ threshold: 1 }))) { + await el.evaluate(el => el.scrollIntoView({ block: 'center', inline: 'center' })) + } // Use manual mouse.move instead of .hover() so the offset can be added to the coordinates const { x, y } = await getClickablePoint(el) await this.page.mouse.move(x + offsetX, y + offsetY) diff --git a/test/data/app/view/form/hover.php b/test/data/app/view/form/hover.php index bbf3534f9..fbbf12f1a 100644 --- a/test/data/app/view/form/hover.php +++ b/test/data/app/view/form/hover.php @@ -7,5 +7,8 @@
+
+Hover me too! + diff --git a/test/helper/Playwright_test.js b/test/helper/Playwright_test.js index 21bd02deb..45c3cec99 100644 --- a/test/helper/Playwright_test.js +++ b/test/helper/Playwright_test.js @@ -395,6 +395,18 @@ describe('Playwright', function () { I.amOnPage('/form/hover') .then(() => I.moveCursorTo('#hover', 'body')) .then(() => I.see('Hovered', '#show'))) + + it('should scroll element into view before hovering', async () => { + await I.amOnPage('/form/hover') + await I.moveCursorTo('#offscreen_hover') + await I.see('Hovered offscreen', '#offscreen_show') + }) + + it('should scroll element into view before hovering within a context', async () => { + await I.amOnPage('/form/hover') + await I.moveCursorTo('#offscreen_hover', 'body') + await I.see('Hovered offscreen', '#offscreen_show') + }) }) describe('#switchToNextTab, #switchToPreviousTab, #openNewTab, #closeCurrentTab, #closeOtherTabs, #grabNumberOfOpenTabs, #waitForNumberOfTabs', () => { diff --git a/test/helper/Puppeteer_test.js b/test/helper/Puppeteer_test.js index 796178066..cbb83b925 100644 --- a/test/helper/Puppeteer_test.js +++ b/test/helper/Puppeteer_test.js @@ -245,6 +245,18 @@ describe('Puppeteer', function () { I.amOnPage('/form/hover') .then(() => I.moveCursorTo('#hover', 'body')) .then(() => I.see('Hovered', '#show'))) + + it('should scroll element into view before hovering', async () => { + await I.amOnPage('/form/hover') + await I.moveCursorTo('#offscreen_hover') + await I.see('Hovered offscreen', '#offscreen_show') + }) + + it('should scroll element into view before hovering within a context', async () => { + await I.amOnPage('/form/hover') + await I.moveCursorTo('#offscreen_hover', 'body') + await I.see('Hovered offscreen', '#offscreen_show') + }) }) describe('#switchToNextTab, #switchToPreviousTab, #openNewTab, #closeCurrentTab, #closeOtherTabs, #grabNumberOfOpenTabs, #waitForNumberOfTabs', () => {