英文:
WebDriver throws Exception: TypeError: JSON.stringify is not a function
问题
我正在使用Java进行Selenium自动化测试。使用的Selenium版本是4.10.0。
尽管我看到有两个标签(1. 父标签主页面和2. 子标签),但是当我通过下面的代码切换到子标签时,我没有看到任何异常抛出。但是当我在子窗口中执行任何操作,比如点击任何按钮时,会抛出异常"TypeError: JSON.stringify不是一个函数"。
以下是代码片段。
// 循环直到找到新的窗口句柄
for (String windowHandle : driver.getWindowHandles()) {
if (!originalWindow.contentEquals(windowHandle)) {
System.out.println("Child win : " + windowHandle);
driver.switchTo().window(windowHandle);
break;
}
}
driver.findElement(By.name("aspnetForm")).click();
请问有人可以建议我为什么会出现这个错误"Exception in thread "main" org.openqa.selenium.WebDriverException: unknown error: Runtime.callFunctionOn threw exception: TypeError: JSON.stringify不是一个函数"吗?
控制台日志如下:
Child win : DEFC56C2E255CB00E7CF1C779B81E7EE
Exception in thread "main" org.openqa.selenium.WebDriverException: unknown error: Runtime.callFunctionOn threw exception: TypeError: JSON.stringify不是一个函数
at buildError (
(Session info: chrome=114.0.5735.199)
Build info: version: '4.10.0', revision: 'c14d967899'
System info: os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '11.0.18'
Driver info: org.openqa.selenium.chrome.ChromeDriver
Command: [748156ce82a3898c61c8bc461a5ecbbb, findElement {using=name, value=aspnetForm}]
Capabilities {acceptInsecureCerts: false, browserName: chrome, browserVersion: 114.0.5735.199, chrome: {chromedriverVersion: 114.0.5735.90 (386bc09e8f4f..., userDataDir: C:\Users\baluz\AppData\Loca...}, goog:chromeOptions: {debuggerAddress: localhost:58574}, networkConnectionEnabled: false, pageLoadStrategy: normal, platformName: windows, proxy: Proxy(), se:cdp: ws://localhost:58574/devtoo..., se:cdpVersion: 114.0.5735.199, setWindowRect: true, strictFileInteractability: false, timeouts: {implicit: 0, pageLoad: 300000, script: 30000}, unhandledPromptBehavior: dismiss and notify, webauthn:extension:credBlob: true, webauthn:extension:largeBlob: true, webauthn:extension:minPinLength: true, webauthn:extension:prf: true, webauthn:virtualAuthenticators: true}
Session ID: 748156ce82a3898c61c8bc461a5ecbbb
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.codec.w3c.W3CHttpResponseCodec.createException(W3CHttpResponseCodec.java:199)
at org.openqa.selenium.remote.codec.w3c.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:132)
at org.openqa.selenium.remote.codec.w3c.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:51)
at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:191)
at org.openqa.selenium.remote.service.DriverCommandExecutor.invokeExecute(DriverCommandExecutor.java:196)
at org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:171)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:531)
at org.openqa.selenium.remote.ElementLocation$ElementFinder$2.findElement(ElementLocation.java:165)
at org.openqa.selenium.remote.ElementLocation.findElement(ElementLocation.java:66)
at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:350)
at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:344)
at com.basePage.EX3.main(EX3.java:91)
注意:我已经将双引号中的HTML实体代码(如")还原为正常的双引号。
<details>
<summary>英文:</summary>
I am working on selenium automation using java. Selenium version used : 4.10.0
Though I see two tabs ( 1. parent tab main page and 2. is the child tab) but when I switch to child through below code I don`t see any kind of exception thrown. But when I perform any operations like click on any button in child window it throws an exception "TypeError: JSON.stringify is not a function".
Below is the code snippet.
==========================
//Loop through until we find a new window handle
for (String windowHandle : driver.getWindowHandles()) {
if(!originalWindow.contentEquals(windowHandle)) {
System.out.println("Child win : "+windowHandle);
driver.switchTo().window(windowHandle);
break;
}
}
driver.findElement(By.name("aspnetForm")).click();
Can somebody please advise me here why i should be getting this error "Exception in thread "main" org.openqa.selenium.WebDriverException: unknown error: Runtime.callFunctionOn threw exception: TypeError: JSON.stringify is not a function"
Consloe log below :
====================
Child win : DEFC56C2E255CB00E7CF1C779B81E7EE
Exception in thread "main" org.openqa.selenium.WebDriverException: unknown error: Runtime.callFunctionOn threw exception: TypeError: JSON.stringify is not a function
at buildError (<anonymous>:323:18)
(Session info: chrome=114.0.5735.199)
Build info: version: '4.10.0', revision: 'c14d967899'
System info: os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '11.0.18'
Driver info: org.openqa.selenium.chrome.ChromeDriver
Command: [748156ce82a3898c61c8bc461a5ecbbb, findElement {using=name, value=aspnetForm}]
Capabilities {acceptInsecureCerts: false, browserName: chrome, browserVersion: 114.0.5735.199, chrome: {chromedriverVersion: 114.0.5735.90 (386bc09e8f4f..., userDataDir: C:\Users\baluz\AppData\Loca...}, goog:chromeOptions: {debuggerAddress: localhost:58574}, networkConnectionEnabled: false, pageLoadStrategy: normal, platformName: windows, proxy: Proxy(), se:cdp: ws://localhost:58574/devtoo..., se:cdpVersion: 114.0.5735.199, setWindowRect: true, strictFileInteractability: false, timeouts: {implicit: 0, pageLoad: 300000, script: 30000}, unhandledPromptBehavior: dismiss and notify, webauthn:extension:credBlob: true, webauthn:extension:largeBlob: true, webauthn:extension:minPinLength: true, webauthn:extension:prf: true, webauthn:virtualAuthenticators: true}
Session ID: 748156ce82a3898c61c8bc461a5ecbbb
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.codec.w3c.W3CHttpResponseCodec.createException(W3CHttpResponseCodec.java:199)
at org.openqa.selenium.remote.codec.w3c.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:132)
at org.openqa.selenium.remote.codec.w3c.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:51)
at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:191)
at org.openqa.selenium.remote.service.DriverCommandExecutor.invokeExecute(DriverCommandExecutor.java:196)
at org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:171)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:531)
at org.openqa.selenium.remote.ElementLocation$ElementFinder$2.findElement(ElementLocation.java:165)
at org.openqa.selenium.remote.ElementLocation.findElement(ElementLocation.java:66)
at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:350)
at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:344)
at com.basePage.EX3.main(EX3.java:91)
</details>
# 答案1
**得分**: 0
该网站必须对顶级 JSON 对象进行了某些更改。
例如,如果页面上的脚本在全局范围内执行以下操作:
JSON = "{}";
那么 JSON.stringify 将为未定义。显然,Selenium 依赖它来在 Python 和网页之间传递信息。
<details>
<summary>英文:</summary>
The site must have done something to the top-level JSON object.
For example if a script on that page does this in global scope:
JSON = "{}"
Then JSON.stringify will be undefined. Apparently Selenium is counting on it for passing things back and forth to Python
</details>
# 答案2
**得分**: 0
这是最新版Chrome浏览器的问题。
经过一些分析,发现了三种解决方法:
1) 使用较旧版本的Chrome
步骤1:卸载Chrome
步骤2:从以下路径删除Chrome数据
%LOCALAPPDATA%\Google\Chrome\User Data
步骤3:通过FileHippo、Chromium Cypress、SlimJet等下载较旧的Chrome版本
现在你可以使用Chromium浏览器运行你的脚本,它将按预期工作。
2) 情况2:使用JavaScript文件
基本上你应该运行一段JS代码来定义JSON.stringify方法,然后再执行任何查找元素或发送键动作,对于我的解决方案,我使用(JavascriptExecutor)webdrive.execute()来做到这一点,你需要的JS代码就像下面这样,你也可以在JSON-js/json2.js中找到它
保存这个JavaScript文件并使用javascriptexecutor执行它
JavascriptExecutor obj = (JavascriptExecutor) driver;
obj.executeScript("json2.js", args);
3) 使用Firefox浏览器,我能够顺利运行我的自动化脚本,使用下面的代码等待然后执行操作,对我来说效果很好。
new WebDriverWait(driver, 20).until(driver -> ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("complete"));
问题出在Chrome浏览器的最新版本,我希望它会在未来版本中得到修复。
<details>
<summary>英文:</summary>
This is the issue with latest chrome browser.
After few analysis just found three ways of doing things
1) By using older chrome versions
Step1: Uninstall Chrome
Step2: Delete Chrome Data from below path
%LOCALAPPDATA%\Google\Chrome\User Data
Step3: Download Older Chrome version via FileHippo,Chromium Cypress, SlimJet. etc
[![Steps to install older chrome browser versions][1]][1]
Now you run your scripts with chromium browser it will work as expected.
2) Case 2: Using javascript file
Basically you should do is run a snippet of JS code to define the JSON.stringify method before you perform any find element or send key action, for my solution is using (JavascriptExecutor)webdrive.execute() to do this, the JS code you need just like following, also you can find this in JSON-js/json2.js
save this javascript file and execute it using javascriptexecutor
JavascriptExecutor obj = (JavascriptExecutor) driver;
obj.executeScript("json2.js", args);
3) Using Firefox browser i was able to run my automation scripts smoothly using below code which use to wait and then perform actions and it worked fine for me.
new WebDriverWait(driver, 20).until(driver -> ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("complete"));
The problem was with chrome browser latest version i hope it would be fixed in coming versions.
[1]: https://i.stack.imgur.com/bgXVg.png
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论