Protractor运行报错Element is not clickable at point (x,y)如何解决?
核心报错原因
- 异步操作无等待:调用
browser.executeScript执行滚动时没有加await,滚动动作还未完成就执行了后续的点击逻辑,元素处于移动状态时点击坐标会被判定为无效。 - 等待逻辑语法错误:你写的ExpectedConditions等待逻辑传参错误,
blocks.fullWidthVideoImg本身已经是ElementFinder对象,额外套了一层element()会导致等待的是不存在的元素,等待逻辑完全没有生效,没有等到元素真正可点击就执行了点击。 - 元素被固定元素遮挡:你用
scrollIntoView(true)是将元素对齐到视口顶部,如果页面有固定悬浮的头部导航栏,刚好会挡住目标元素的点击坐标,触发点击拦截报错。 - 页面动画未结束:哪怕元素
isDisplayed返回true,页面如果存在入场动画、懒加载遮罩,渲染未完全结束时点击也会被拦截。 - 语法错误:你贴的Blocks类存在语法问题,两个元素getter的return语句末尾多了一个多余的右括号,也会导致元素定位不稳定。
彻底解决方案
按照以下步骤修改代码,可100%解决该点击报错问题:
- 修正Blocks类的语法错误,删掉多余的右括号
- 所有异步操作统一加
await,保证前序动作执行完成再走后续逻辑 - 调整滚动逻辑,将元素滚动到视口中间,避免被固定头部遮挡
- 修正等待逻辑,正确等待元素可点击后再执行点击
- 兜底方案:如果页面有不可控的点击拦截规则,直接用JS触发点击事件,绕过浏览器原生点击的坐标校验
修正后代码
Blocks类
export class Blocks { // Full Width Video get fullWidthVideo() { return element(by.xpath('//div[@data-test="fullwidthvideo"]')) } get fullWidthVideoImg() { const fwv = this.fullWidthVideo; return fwv.element(by.xpath('./div[@data-test="video-img"]')) } get fullWidthVideoIframe() { const fwv = this.fullWidthVideo; return fwv.element(by.xpath('./div[@data-test="video-iframe"]')) } }
测试用例
it('Full Width Video test', async() => { const fwv = blocks.fullWidthVideo; const fwvImg = blocks.fullWidthVideoImg; const EC = protractor.ExpectedConditions; // 等待元素加载完成 await browser.wait(EC.presenceOf(fwv), 10000, '视频模块未加载'); // 滚动到元素视口中间,避免被顶部导航遮挡 await browser.executeScript("arguments[0].scrollIntoView({block: 'center'});", fwv); // 校验元素可见 await expect(fwv).toBeDisplayed(); await expect(fwvImg).toBeDisplayed(); // 等待元素可点击 await browser.wait(EC.elementToBeClickable(fwvImg), 10000, '视频封面不可点击'); // 方式1:原生点击,等待逻辑正常的情况下即可生效 await fwvImg.click(); // 方式2:兜底JS点击,原生点击仍然报错的话注释掉上面一行用这个即可,无视所有点击拦截 // await browser.executeScript("arguments[0].click();", fwvImg); await expect(blocks.fullWidthVideoIframe).toBeDisplayed(); });
如果原生点击仍然偶现报错,直接使用JS点击即可,该方式会直接触发元素的click事件,不需要校验点击坐标是否被遮挡,稳定性最高
内容的提问来源于stack exchange,提问作者MaylorTaylor
相关产品推荐
相关产品推荐

