diff --git a/src/dom.ts b/src/dom.ts index 1bf8725b56..8ce223af24 100644 --- a/src/dom.ts +++ b/src/dom.ts @@ -226,6 +226,7 @@ export class ElementHandle extends js.JSHandle { const point = position ? await this._offsetPoint(position) : await this._clickablePoint(); point.x = (point.x * 100 | 0) / 100; point.y = (point.y * 100 | 0) / 100; + await this._page.mouse.move(point.x, point.y); // Force any hover effects before waiting for hit target. if (!force) await this._waitForHitTargetAt(point, deadline); diff --git a/test/click.spec.js b/test/click.spec.js index df00f49e0e..f41a2c4ab6 100644 --- a/test/click.spec.js +++ b/test/click.spec.js @@ -198,6 +198,7 @@ describe('Page.click', function() { 'mouseover', 'mouseenter', 'mousemove', + 'mousemove', 'mousedown', 'mouseup', 'click', @@ -596,6 +597,36 @@ describe('Page.click', function() { expect(clicked).toBe(true); expect(await page.evaluate(() => window.clicked)).toBe(true); }); + it('should fail when element is blocked on hover', async({page, server}) => { + await page.setContent(` + + +
+
`); + const error = await page.click('button', { timeout: 3000 }).catch(e => e); + expect(error.message).toBe('waiting for element to receive pointer events failed: timeout exceeded'); + expect(await page.evaluate(() => window.clicked)).toBe(undefined); + }); + it('should wait while element is blocked on hover', async({page, server}) => { + await page.setContent(` + + +
+
`); + await page.click('button'); + expect(await page.evaluate(() => window.clicked)).toBe(true); + }); }); describe('Page.check', function() {