节点WebDriverJS的executeScript行为

我有一个WebDriverJS节点脚本在应用程序的全局范围内具有以下内容:

var helperFunctions = { 'getElementEssentials': function get(orig, tmp, level) { var tmp = tmp || {}; var level = level || 0; for(var i in orig) { if(!orig[i]) { continue; } if(typeof(orig[i]) === 'function' || typeof(orig[i]) === 'object' || level > 1) { continue; } if(typeof(orig[i]) === 'array') { level++; get(orig[i], tmp, level); continue; } tmp[i] = orig[i]; continue; } return tmp; } }; 

我想通过这样的函数传递给driver.executeScript

 var evalSelectAll = function(selector, getElementEssentials) { var els = document.querySelectorAll(selector); var els2 = []; for(var i in els) { els2.push(getElementEssentials(els[i])); } var elsStringified = JSON.stringify(els2); return elsStringified; }; driver.executeScript(evalSelectAll, selector, helperFunctions.getElementEssentials).then( function(data) { // things }); 

selector涉及一个CSSselect器expression式,例如“a”或“div> h1”。

我对executeScript的理解是,对于第一个参数,它可以接受一个string或一个函数 – 一个string将在目标页面上进行评估,一个函数将在目标页面上执行,并且所有后续参数是附加数据?

尝试运行时出现以下错误(请注意,为了保持简单,我只传入了{test: true}的testing对象:

 D:\Git\mateserver\node_modules\selenium-webdriver\lib\webdriver\promise.js:1643 throw error; ^ UnknownError: {"errorMessage":"'function get(orig, tmp, level) {\r\n\t var tmp = tmp || {};\r\n\t var level = level || 0;\r\n\t for(var i in orig) {\r\n\t if(!orig[i]) { continue; }\r\n\t if(typeof(orig[i]) === 'function' || typeof(orig[i]) === 'object' || level > 1) { continue; }\r\n\t if(typeof(orig[i]) === 'array') { level++; get(orig[i], tmp, level); continue; }\r\n\t tmp[i] = orig[i]; continue;\r\n\t }\r\n\t return tmp;\r\n\t}' is not a function (evaluating 'getElementEssentials({test: true})')","request":{"headers":{"Accept":"application/json; charset=utf-8","Connection":"keep-alive","Content-Length":"903","Content-Type":"application/json;charset=UTF-8","Host":"192.168.0.7:56849"},"httpVersion":"1.1","method":"POST","post":"{\"script\":\"return (function (selector, getElementEssentials) {\\r\\n\\r\\n\\t\\t\\treturn getElementEssentials({test: true});\\r\\n\\r\\n\\t\\t\\tvar els = document.querySelectorAll(selector);\\r\\n\\t\\t\\t\\r\\n\\t\\t\\t/*var els2 = [];\\r\\n\\t\\t\\tfor(var i in els) {\\r\\n\\t\\t\\t\\tels2.push(getElementEssentials(els[i]));\\r\\n\\t\\t\\t}\\r\\n\\r\\n\\t\\t\\tvar elsStringified = JSON.stringify(els2);\\r\\n\\r\\n\\t\\t\\treturn elsStringified;*/\\r\\n\\r\\n\\t\\t}).apply(null, arguments);\",\"args\":[\"h1\",\"function get(orig, tmp, level) {\\r\\n\\t var tmp = tmp || {};\\r\\n\\t var level = level || 0;\\r\\n\\t for(var i in orig) {\\r\\n\\t if(!orig[i]) { continue; }\\r\\n\\t if(typeof(orig[i]) === 'function' || typeof(orig[i]) === 'object' || level > 1) { continue; }\\r\\n\\t if(typeof(orig[i]) === 'array') { level++; get(orig[i], tmp, level); continue; }\\r\\n\\t tmp[i] = orig[i]; continue;\\r\\n\\t }\\r\\n\\t return tmp;\\r\\n\\t}\"]}","url":"/execute","urlParsed":{"anchor":"","query":"","file":"execute","directory":"/","path":"/execute","relative":"/execute","port":"","host":"","password":"","user":"","userInfo":"","authority":"","protocol":"","source":"/execute","queryKey":{},"chunks":["execute"]},"urlOriginal":"/session/c18c1ff0-0f25-11e4-a90e-a36273e3866b/execute"}} at new bot.Error (D:\Git\mateserver\node_modules\selenium-webdriver\lib\atoms\error.js:109:18) at Object.bot.response.checkResponse (D:\Git\mateserver\node_modules\selenium-webdriver\lib\atoms\response.js:106:9) at D:\Git\mateserver\node_modules\selenium-webdriver\lib\webdriver\webdriver.js:277:20 at D:\Git\mateserver\node_modules\selenium-webdriver\lib\goog\base.js:1243:15 at webdriver.promise.ControlFlow.runInNewFrame_ (D:\Git\mateserver\node_modules\selenium-webdriver\lib\webdriver\promise.js:1539:20) at notify (D:\Git\mateserver\node_modules\selenium-webdriver\lib\webdriver\promise.js:362:12) at notifyAll (D:\Git\mateserver\node_modules\selenium-webdriver\lib\webdriver\promise.js:331:7) at resolve (D:\Git\mateserver\node_modules\selenium-webdriver\lib\webdriver\promise.js:309:7) at fulfill (D:\Git\mateserver\node_modules\selenium-webdriver\lib\webdriver\promise.js:429:5) at D:\Git\mateserver\node_modules\selenium-webdriver\lib\webdriver\promise.js:1406:10 ==== async task ==== WebDriver.executeScript() at webdriver.WebDriver.schedule (D:\Git\mateserver\node_modules\selenium-webdriver\lib\webdriver\webdriver.js:268:15) at webdriver.WebDriver.executeScript (D:\Git\mateserver\node_modules\selenium-webdriver\lib\webdriver\webdriver.js:404:15) at D:\Git\mateserver\main.js:174:11 at D:\Git\mateserver\node_modules\selenium-webdriver\lib\goog\base.js:1243:15 at webdriver.promise.ControlFlow.runInNewFrame_ (D:\Git\mateserver\node_modules\selenium-webdriver\lib\webdriver\promise.js:1539:20) at notify (D:\Git\mateserver\node_modules\selenium-webdriver\lib\webdriver\promise.js:362:12) at notifyAll (D:\Git\mateserver\node_modules\selenium-webdriver\lib\webdriver\promise.js:331:7) at resolve (D:\Git\mateserver\node_modules\selenium-webdriver\lib\webdriver\promise.js:309:7) at fulfill (D:\Git\mateserver\node_modules\selenium-webdriver\lib\webdriver\promise.js:429:5) 

对此有何想法? 我正确使用executeScript吗? 谢谢。

更新:看来,如果我把get函数在evalSelectAll函数内,那么它的工作原理。 看起来好像传递函数作为executeScript参数是不被支持的。 有人可以证实这一点吗? 留在eval函数之外,让代码更可重用是很好的。