You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Selenium C#调用GetShadowRoot()时出现circular reference错误

Selenium C# 4.10调用GetShadowRoot()触发循环引用JavaScriptException问题

问题详情

使用C#版Selenium 4.10执行UI测试时,调用GetShadowRoot()方法触发JavaScriptException,错误信息:

{"javascript error: circular reference (Session info: chrome=114.0.5735.199)"}

错误堆栈:

at OpenQA.Selenium.WebDriver.UnpackAndThrowOnError(Response errorResponse, String commandToExecute) 
at OpenQA.Selenium.WebDriver.Execute(String driverCommandToExecute, Dictionary2 parameters)    
at OpenQA.Selenium.WebDriver.InternalExecute(String driverCommandToExecute, Dictionary2 parameters) 
at OpenQA.Selenium.WebElement.Execute(String commandToExecute, Dictionary`2 parameters) 
at OpenQA.Selenium.WebElement.GetShadowRoot() at TestProject1.UnitTest1.Test1() in C:\Git\TestProject1\UnitTest1.cs:line 27 
at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor) 
at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)

测试代码:

driver.Navigate().GoToUrl("https://mypage.address");
driver.FindElementCustom(By.XPath("//control-element"));
driver.SwitchTo().Frame("content");
var host = driver.FindElementCustom(By.CssSelector("shadow.root element"));
var root = host.GetShadowRoot();//error here
var menu = root.FindElement(By.CssSelector("div.menu-container button"));

已知情况:

  • 已使用最新Chrome浏览器及匹配版本的ChromeDriver
  • 尝试GetShadowRoot()方法和JSExecutor均触发相同错误
  • 所有CSS选择器在Chrome DevTools中可正常工作
  • Shadow DOM处于Open模式,DevTools中通过querySelector().shadowRoot.querySelector()可找到目标元素
  • 编写最小测试用例也无法解决问题

解决思路

  1. 直接通过JSExecutor链式查询元素
    既然DevTools中链式查询生效,直接将逻辑封装为JS脚本执行,绕过Selenium处理ShadowRoot对象的环节:

    IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
    var menu = js.ExecuteScript(@"
        return document.querySelector('shadow.root element').shadowRoot.querySelector('div.menu-container button');
    ") as IWebElement;
    

    注意需先切换到目标iframe后再执行脚本。

  2. 替换自定义查找方法为原生方法
    测试代码中使用了自定义的FindElementCustom方法,可能该方法对元素对象做了额外处理导致循环引用,尝试替换为Selenium原生FindElement测试:

    var host = driver.FindElement(By.CssSelector("shadow.root element"));
    
  3. 升级Selenium版本
    Selenium 4.10可能存在Shadow DOM相关的已知bug,升级到最新稳定版(如4.15+),验证是否修复循环引用问题。

  4. 直接提取目标元素而非ShadowRoot对象
    若组件Shadow Root包含循环引用属性,可通过JS直接提取目标元素,避免序列化ShadowRoot对象:

    var menu = js.ExecuteScript(@"
        const host = document.querySelector('shadow.root element');
        return host.shadowRoot.querySelector('div.menu-container button');
    ") as IWebElement;
    

内容的提问来源于stack exchange,提问作者kretes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 17:12:48