UI 自动化测试中元素被遮挡无法点击的解决方案(Selenium + Python 实战)
UI 自动化测试中元素被遮挡无法点击的解决方案
在进行 Web UI 自动化测试 时,经常会遇到一个令人头疼的问题:元素明明存在,却始终点不到。
报错信息通常类似:
selenium.common.exceptions.ElementClickInterceptedException:
Message: element click intercepted: Element <span>...</span> is not clickable at point (107, 883).
Other element would receive the click: <div class="uni-tabbar__item">...</div>
意思就是:你想点的元素被其它东西挡住了(比如悬浮导航栏、广告弹窗、底部 tabbar 等)。
本文结合一个实际案例,介绍几种常见的解决方案,并给出企业级封装。
1. 问题场景:商城首页「人气推荐」点击失败
在商城 H5 首页,我们需要测试点击「人气推荐」模块。
对应 Page Object 定位符如下:
class HomePage(BasePage):hot_recommend_section = (By.XPATH, "//view[contains(., '人气推荐')]")def click_hot_recommend(self):"""点击人气推荐"""self.scroll_to_element(*self.hot_recommend_section) # 滚动到模块self.click(self.hot_recommend_section) # 点击
运行测试用例时,报错:
ElementClickInterceptedException: Other element would receive the click: <div class="uni-tabbar__item">...</div>
原因就是:底部 tabbar 遮住了点击区域。
2. 常见解决方案
方案一:滚动到可见区域
Selenium 提供了 scrollIntoView() 方法,把元素滚动到屏幕中间:
self.driver.execute_script("arguments[0].scrollIntoView({block: 'center'});", element)
这样可以避免元素在屏幕外导致的点击失败。
方案二:等待元素可点击
即使元素在页面上,还需要确认它 真正可交互。
可以用 WebDriverWait + element_to_be_clickable:
WebDriverWait(self.driver, self.timeout).until(EC.element_to_be_clickable(locator)
)
方案三:JS 点击兜底
有时即使元素可见,但还是被其他元素挡住(比如悬浮弹窗)。
这时可以使用 JavaScript 直接触发点击事件:
self.driver.execute_script("arguments[0].click();", element)
3. 企业级封装:BasePage.click()
综合以上思路,可以在 BasePage 封装一个更强大的 click() 方法:
def click(self, locator):"""点击元素(带滚动 + JS 兜底)"""try:element = self.find_element(locator)# 1. 滚动到可见区域self.driver.execute_script("arguments[0].scrollIntoView({block: 'center'});", element)# 2. 等待可点击WebDriverWait(self.driver, self.timeout).until(EC.element_to_be_clickable(locator))# 3. 尝试正常点击element.click()logger.info(f"点击元素: {locator}")except ElementClickInterceptedException:# 4. 如果被遮挡,使用 JS 点击兜底element = self.find_element(locator)self.driver.execute_script("arguments[0].click();", element)logger.warning(f"元素 {locator} 被遮挡,已用 JS 点击代替")except Exception as e:self._handle_error("click", locator, e)
这样写的好处是:
- 统一封装,所有页面都能复用
- 出现遮挡问题时自动兜底,不会导致用例失败
- 日志里能清楚记录是「正常点击」还是「JS 点击」
4. Page Object 调用示例
在 HomePage 里只需写:
def click_hot_recommend(self):"""点击人气推荐"""self.click(self.hot_recommend_section)
完全不用关心它是滚动还是 JS 触发,一行代码搞定。
5. 测试用例示例
@allure.feature("首页模块")
class TestHomePage:@allure.story("点击人气推荐")@allure.title("验证点击人气推荐模块跳转")def test_click_hot_recommend(self):home = HomePage()home.open()home.click_hot_recommend()assert "人气推荐" in home.driver.page_source
6. 总结
UI 自动化中 元素被遮挡/点击失败 是非常常见的问题。
最佳实践是:
- 先滚动到可见区域
- 等待元素可点击
- 点击失败时用 JS 兜底
通过在 BasePage 封装增强版 click(),可以极大提高脚本稳定性,减少无效报错。