Node.js WebdriverIO中driver.execute() TypeError问题:元素高亮失败求助
我是Node.js初学者,尝试用WebdriverIO实现元素高亮功能,编写了Utilities类、Stepdef及PageObjects相关代码,但运行时出现TypeError: elem[prop] is not a function错误,附带详细错误日志。
代码片段
Utilities类
class Utilities { async highlight(element){ await browser.execute((userelement)=>{ userelement.style.backgroundColor="red"; },element); } } module.exports = new Utilities();
Stepdef
Utilities.highlight(LoginPage.getusername);
PageObjects
class LoginPage{ get getusername(){ return $('#username'); } }
错误信息
TypeError: elem[prop] is not a function at \node_modules\@wdio\utils\build\shim.js:253:38 at processTicksAndRejections (node:internal/process/task_queues:96:5)..
详细错误日志
[0-0] 2022-07-18T12:50:08.380Z INFO webdriver: DATA { [0-0] script:
'return ((userelement)=>{
' + [0-0] '
userelement.style.backgroundColor="red";
' + [0-0] '
}).apply(null, arguments)', [0-0] args: [ Promise { } ]
[0-0] } [0-0] 2022-07-18T12:50:08.398Z INFO webdriver: RESULT { [0-0]
'element-6066-11e4-a52e-4f735466cecf':
'be8745a8-6499-482b-af98-8dc191b88452' [0-0] } [0-0] Error in "0: When
I login with nithildani and asdas123" TypeError: elem[prop] is not a
function
at C:\Users\nitarula\Documents\Sample2\node_modules@wdio\utils\build\shim.js:253:38
at processTicksAndRejections (node:internal/process/task_queues:96:5) [0-0]
2022-07-18T12:50:08.417Z INFO webdriver: COMMAND deleteSession() [0-0]
2022-07-18T12:50:08.417Z INFO webdriver: [DELETE]
http://localhost:9515/session/36ae82293a3b853a2965d478c51f4235 [0-0]
2022-07-18T12:50:08.425Z INFO webdriver: RESULT { [0-0]
'element-6066-11e4-a52e-4f735466cecf':
'66da9a07-388f-445c-90ef-9c7a12c29856' [0-0] } [0-0]
2022-07-18T12:50:08.429Z INFO webdriver: COMMAND
elementClear("66da9a07-388f-445c-90ef-9c7a12c29856") [0-0]
2022-07-18T12:50:08.429Z INFO webdriver: [POST]
http://localhost:9515/session/36ae82293a3b853a2965d478c51f4235/element/66da9a07-388f-445c-90ef-9c7a12c29856/clear
[0-0] 2022-07-18T12:50:08.438Z WARN webdriver: Request failed with
status 500 due to javascript error: Cannot set properties of undefined
(setting 'backgroundColor') [0-0] (Session info:
chrome=103.0.5060.114) [0-0] 2022-07-18T12:50:08.439Z INFO webdriver:
Retrying 1/3 [0-0] 2022-07-18T12:50:08.439Z INFO webdriver: [POST]
http://localhost:9515/session/36ae82293a3b853a2965d478c51f4235/execute/sync
[0-0] 2022-07-18T12:50:08.440Z INFO webdriver: DATA { [0-0] script:
'return ((userelement)=>{
' + [0-0] '
userelement.style.backgroundColor="red";
' + [0-0] '
}).apply(null, arguments)', [0-0] args: [ Promise { [Element] } ]
[0-0] } [0-0]
C:\Users\nitarula\Documents\Sample2\node_modules@wdio\utils\build\shim.js:253
[0-0] return elem[prop]; [0-0]
^ [0-0] [0-0] TypeError: elem[prop] is not a function [0-0] at
C:\Users\nitarula\Documents\Sample2\node_modules@wdio\utils\build\shim.js:253:38
[0-0] at processTicksAndRejections
(node:internal/process/task_queues:96:5) { [0-0]
[Symbol(originalCallSite)]: [ CallSite {}, CallSite {} ], [0-0]
[Symbol(mutatedCallSite)]: [ CallSite {}, CallSite {} ] [0-0] } [0-0]
FAILED in chrome -
C:\Users\nitarula\Documents\Sample2\features\login.feature
2022-07-18T12:50:08.499Z INFO @wdio/cli:launcher: Run onWorkerEnd hook
2022-07-18T12:50:08.502Z INFO @wdio/cli:launcher: Run onComplete hook
核心问题有两个:
- 未处理元素Promise:PageObject中
getusername是getter属性,返回的是$('#username'),这是一个WebdriverIO的ElementPromise对象,并非直接的DOM元素或已解析的元素实例。直接将Promise传入browser.execute会导致序列化失败,触发elem[prop] is not a function错误。 - 未等待异步方法执行:
highlight是异步函数,但Stepdef中调用时没有加await,导致函数未正确执行就继续后续逻辑。
提供两种可行的修改方案:
方案一:在Utilities中处理元素Promise
修改Utilities类的highlight方法,先等待元素Promise解析,再执行高亮逻辑:
class Utilities { async highlight(element) { // 等待元素Promise解析为实际的WDIO元素实例 const elem = await element; await browser.execute((userelement) => { userelement.style.backgroundColor = "red"; }, elem); } } module.exports = new Utilities();
然后在Stepdef中添加await调用异步方法:
await Utilities.highlight(LoginPage.getusername);
方案二:使用WDIO元素自身的execute方法
直接利用WebdriverIO元素实例的execute方法,逻辑更简洁,无需手动处理Promise传递:
class Utilities { async highlight(element) { const elem = await element; // 调用元素自身的execute方法,自动传入DOM元素作为参数 await elem.execute((el) => { el.style.backgroundColor = "red"; }); } } module.exports = new Utilities();
Stepdef调用方式同上:
await Utilities.highlight(LoginPage.getusername);
额外优化(可选)
如果希望高亮效果更明显,可以同时修改边框样式:
await elem.execute((el) => { el.style.backgroundColor = "red"; el.style.border = "2px solid yellow"; });
内容的提问来源于stack exchange,提问作者Nithilan

