diff --git a/src/injected/injected.ts b/src/injected/injected.ts
index 7f781b6405..ff7a443793 100644
--- a/src/injected/injected.ts
+++ b/src/injected/injected.ts
@@ -286,12 +286,16 @@ class Injected {
// and only force layout during actual rafs as a small optimisation.
if (++counter === 1)
return false;
+ if (!node.isConnected)
+ return 'Element is not attached to the DOM';
const clientRect = element.getBoundingClientRect();
const rect = { x: clientRect.top, y: clientRect.left, width: clientRect.width, height: clientRect.height };
const isDisplayedAndStable = lastRect && rect.x === lastRect.x && rect.y === lastRect.y && rect.width === lastRect.width && rect.height === lastRect.height && rect.width > 0 && rect.height > 0;
lastRect = rect;
return isDisplayedAndStable;
});
+ if (typeof result === 'string')
+ throw new Error(result);
if (!result)
throw new Error(`waiting for element to be displayed and not moving failed: timeout exceeded`);
}
@@ -303,11 +307,15 @@ class Injected {
if (!element)
throw new Error('Element is not attached to the DOM');
const result = await this.poll('raf', timeout, () => {
+ if (!element!.isConnected)
+ return 'Element is not attached to the DOM';
let hitElement = this._deepElementFromPoint(document, point.x, point.y);
while (hitElement && hitElement !== element)
hitElement = this._parentElementOrShadowHost(hitElement);
return hitElement === element;
});
+ if (typeof result === 'string')
+ throw new Error(result);
if (!result)
throw new Error(`waiting for element to receive mouse events failed: timeout exceeded`);
}
diff --git a/test/click.spec.js b/test/click.spec.js
index f749004611..70ce13adac 100644
--- a/test/click.spec.js
+++ b/test/click.spec.js
@@ -554,6 +554,25 @@ describe('Page.click', function() {
if (error2)
expect(error2.message).toContain('timeout exceeded');
});
+ it('should fail when element detaches after animation', async({page, server}) => {
+ await page.setContent(``);
+ await page.$eval('button', button => {
+ button.style.transition = 'margin-left 100000ms linear';
+ });
+ await page.$eval('button', button => {
+ button.style.marginLeft = '100000px';
+ });
+ const handle = await page.$('button');
+ const promise = handle.click().catch(e => e);
+ await page.$eval('button', button => {
+ button.style.marginLeft = button.getBoundingClientRect().left + 'px';
+ button.style.transition = '';
+ button.remove();
+ });
+ const error = await promise;
+ expect(await page.evaluate(() => window.clicked)).toBe(undefined);
+ expect(error.message).toContain('Element is not attached to the DOM');
+ });
});
describe('Page.check', function() {