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()可找到目标元素 - 编写最小测试用例也无法解决问题
解决思路
直接通过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后再执行脚本。
替换自定义查找方法为原生方法
测试代码中使用了自定义的FindElementCustom方法,可能该方法对元素对象做了额外处理导致循环引用,尝试替换为Selenium原生FindElement测试:var host = driver.FindElement(By.CssSelector("shadow.root element"));升级Selenium版本
Selenium 4.10可能存在Shadow DOM相关的已知bug,升级到最新稳定版(如4.15+),验证是否修复循环引用问题。直接提取目标元素而非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
相关产品推荐
相关产品推荐

