升级至Angular 14后,Selenium测试出现document unloaded随机错误求助
问题
将复杂站点从旧版本升级至Angular 14后,在Tekton中运行Selenium/Cucumber/Java测试套件时,随机出现无法在本地复现的错误,错误信息如下:
org.openqa.selenium.JavascriptException: javascript error: document unloaded while waiting for result
未在Selenium相关资料中找到该错误的相关内容,仅在通用页面功能和JavaScript相关案例中发现少量信息。
该错误并非等待(Wait)问题,因为Selenium未报告任何元素查找相关异常,完全未提及页面元素,仅提示‘document unloaded’。Cucumber也未生成截图,未标记最后一步为失败,仅在步骤后出现该错误。
完整错误栈信息:
org.openqa.selenium.JavascriptException: javascript error: document unloaded while waiting for result (Session info: chrome=105.0.5195.52) Build info: version: '3.141.59', revision: 'e82be7d358', time: '2018-11-14T08:17:03' System info: host: 'sak-tjt-4927-oppgrader-star-20230509-105719-e2e-run-pod', ip: '10.128.9.195', os.name: 'Linux', os.arch: 'amd64', os.version: '4.18.0-372.52.1.el8_6.x86_64', java.version: '11.0.13' Driver info: org.openqa.selenium.remote.RemoteWebDriver Capabilities {acceptInsecureCerts: false, browserName: chrome, browserVersion: 105.0.5195.52, chrome: {chromedriverVersion: 105.0.5195.19 (b9c217c128c1..., userDataDir: /tmp/.com.google.Chrome.sx4Zaj}, goog:chromeOptions: {debuggerAddress: localhost:33141}, javascriptEnabled: true, networkConnectionEnabled: false, pageLoadStrategy: normal, platform: LINUX, platformName: LINUX, proxy: Proxy(), se:cdp: ws://10.129.12.14:4444/sess..., se:cdpVersion: 105.0.5195.52, se:vnc: ws://10.129.12.14:4444/sess..., se:vncEnabled: true, se:vncLocalAddress: ws://10.129.12.14:7900, setWindowRect: true, strictFileInteractability: false, timeouts: {implicit: 0, pageLoad: 300000, script: 30000}, unhandledPromptBehavior: dismiss and notify, webauthn:extension:credBlob: true, webauthn:extension:largeBlob: true, webauthn:virtualAuthenticators: true} Session ID: 6ac5e2775265c90d61ef4963f6e30631 at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490) at org.openqa.selenium.remote.http.W3CHttpResponseCodec.createException(W3CHttpResponseCodec.java:187) at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:122) at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:49) at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:158) at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:552) at org.openqa.selenium.remote.RemoteWebDriver.executeAsyncScript(RemoteWebDriver.java:506) at no.husbanken.e2e.rammeverk.selenium.driver.ExtendedWebDriver.isPageReady(ExtendedWebDriver.java:38) at e2e.support.Hooks.afterEachScenario(Hooks.java:145) at e2e.support.Hooks.tearDown(Hooks.java:120) at jdk.internal.reflect.GeneratedMethodAccessor73.invoke(Unknown Source) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at cucumber.runtime.Utils$1.call(Utils.java:26) at cucumber.runtime.Timeout.timeout(Timeout.java:16) at cucumber.runtime.Utils.invoke(Utils.java:20) at cucumber.runtime.java.JavaHookDefinition.execute(JavaHookDefinition.java:65) at cucumber.runner.HookDefinitionMatch.runStep(HookDefinitionMatch.java:16) at cucumber.runner.TestStep.executeStep(TestStep.java:65) at cucumber.runner.TestStep.run(TestStep.java:50) at cucumber.runner.TestCase.run(TestCase.java:50) at cucumber.runner.Runner.runPickle(Runner.java:50) at io.cucumber.junit.PickleRunners$NoStepDescriptions.run(PickleRunners.java:146) at io.cucumber.junit.FeatureRunner.runChild(FeatureRunner.java:68) at io.cucumber.junit.FeatureRunner.runChild(FeatureRunner.java:23) at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329) at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293) at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306) at org.junit.runners.ParentRunner.run(ParentRunner.java:413) at io.cucumber.junit.Cucumber.runChild(Cucumber.java:142) at io.cucumber.junit.Cucumber.runChild(Cucumber.java:65) at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329) at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293) at io.cucumber.junit.Cucumber$RunCucumber.evaluate(Cucumber.java:172) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306) at org.junit.runners.ParentRunner.run(ParentRunner.java:413) at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:365) at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:273) at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:238) at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:159) at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:384) at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:345) at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:126) at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:418)
分析与解决方案
- 从错误栈定位:问题出在
afterEachScenario钩子执行isPageReady方法时,调用executeAsyncScript异步脚本时页面已卸载。Angular14的路由切换、页面销毁逻辑比旧版本更高效,可能在测试场景结束后、钩子执行前就完成了页面卸载。 - 修改钩子逻辑:在执行
isPageReady前,先校验页面会话有效性,比如通过driver.getWindowHandles()判断是否还有活跃窗口;或者直接捕获JavascriptException,忽略这类页面卸载导致的错误。 - 升级Selenium版本:当前用的Selenium 3.141.59是2018年的旧版本,对Angular14这类现代前端框架兼容性不足,升级到Selenium 4.x,它修复了大量异步脚本执行的边界问题,对Chrome DevTools Protocol支持更好。
- 调整页面加载策略:将Chrome的
pageLoadStrategy从默认的normal改为eager(等待DOM加载完成即可)或none(不等待页面加载),减少Selenium等待页面完全加载的时间,避免在页面卸载阶段触发脚本错误。 - 优化Angular页面销毁逻辑:检查升级后的路由守卫、组件销毁钩子,是否存在页面快速跳转/销毁的情况;在测试场景结束前,确保页面处于稳定状态后再执行后续清理钩子。
- 增强异步脚本的健壮性:在
isPageReady的异步脚本中增加文档状态判断,仅在文档未卸载时执行逻辑:if (document.readyState !== 'unloaded' && document.readyState !== 'loading') { // 原有页面就绪检查逻辑 callback(true); } else { callback(false); }
内容的提问来源于stack exchange,提问作者kakemonsteret
相关产品推荐
相关产品推荐

