ChromeDriver无头模式下MUI Fade组件opacity异常为0导致Selenium等待超时的问题求助
ChromeDriver无头模式下MUI Fade组件opacity异常为0导致Selenium等待超时的问题求助
我最近在用Selenium搭配ChromeDriver无头模式测试MUI的Fade淡入组件时,碰到了一个特别诡异的问题:组件的淡入过渡动画完全不触发,导致脚本一直超时等待元素变为可见。
具体的现象如下:
- 关闭无头模式运行脚本时,组件能正常显示,脚本顺利执行完成;
- 开启无头模式后,就算元素已经出现在DOM中(组件本身设置了2秒的淡入时长),它的
opacity值一直是0,is_displayed()也返回false,Selenium的visibility_of_element_located断言直接超时; - 但离谱的是,如果在等待元素可见之前调用
driver.save_screenshot或者driver.get_screenshot_as_png截图,组件就会正常触发淡入动画,能被检测到可见; - 用Edge浏览器(基于Chromium内核)测试时,这个问题完全不存在,组件正常显示。
我有两个疑问想请教大家:
- 有没有其他同学遇到过同样的行为?
- 有没有人能分析下这背后的原因?特别是为什么一张截图就能触发淡入动画?
以下是我用来复现问题的Python脚本:
from time import sleep from selenium import webdriver from selenium.webdriver.chrome.service import Service as ChromeService from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.wait import WebDriverWait opts = ( "--disable-extensions", "--disable-single-click-autofill", "--disable-autofill-keyboard-accessory-view[8]", "--disable-full-form-autofill-ios", "--disable-infobars", # chromedriver crashes without these two in linux "--no-sandbox", "--disable-dev-shm-usage", ) exp_prefs = {"autofill.profile_enabled": False} options = webdriver.ChromeOptions() for opt in opts: options.add_argument(opt) options.add_experimental_option("prefs", exp_prefs) #comment this out to run without headless to witness the script finish properly. options.add_argument("--headless") driver = webdriver.Chrome(service=ChromeService(), options=options) driver.set_window_position(0, 0) driver.set_window_size(1600, 1080) URL = "https://react-w7zntifk-wnhs8qae.stackblitz.io/" TEST_ID = (By.ID, "test-id") RUN_BUTTON = (By.XPATH, "//button[contains(string(), 'Run this project')]") driver.get(URL) wait = WebDriverWait(driver, 5) # get past the stackblitz initialization button = wait.until(EC.element_to_be_clickable(RUN_BUTTON)) button.click() # once we find the element in the DOM (which has a 2 second fade in timer) wait a moment # before printing the opacity value, which SHOULD be a float value not zero # but isn't in this bug. elem = wait.until(EC.presence_of_element_located(TEST_ID), "") sleep(0.5) print(f"{TEST_ID} is present") print(f'opacity: {elem.value_of_css_property("opacity")}') print(f"is_displayed: {elem.is_displayed()}") elem2 = wait.until( EC.visibility_of_element_located(TEST_ID), f"{TEST_ID} was not visible)" )
后续补充
- 提交这个问题后不久,Edge浏览器更新后也出现了同样的问题,说明这确实是Chromium和MUI结合导致的兼容性问题;
- 我还发现,无头模式下这类MUI组件渲染完成后很久,
is_displayed()仍然返回false; - 目前找到了一个临时解决方案:给ChromeOptions添加
--disable-renderer-backgrounding参数后,MUI组件在无头模式下就能正常工作了; - 我已经给Chromium团队提交了bug反馈,希望能定位到根本原因。
备注:内容来源于stack exchange,提问作者Marcel Wilson
相关产品推荐
相关产品推荐

