WebdriverIO集成Anime.js实现鼠标动画时遇多类报错
问题分析与解决方案
第一个错误:ReferenceError: NodeList is not defined
这个错误的核心原因是anime.js是浏览器端库,不能直接在WebdriverIO的Node.js进程中调用。你当前的代码在Node环境里执行anime(),但Node环境没有浏览器的DOM API(比如NodeList),因此触发报错。
修复方案
必须把anime的动画逻辑放到browser.execute()中,让代码在浏览器上下文运行。同时要确保anime.js已加载到测试页面中(可通过测试前注入脚本的方式引入)。
修改functions.js中的animateMouse方法:
export async function animateMouse() { await browser.addCommand('animateMouse', async function() { await this.waitForExist(); // 获取元素的视口坐标 const rect = await this.getBoundingClientRect(); // 在浏览器上下文执行动画逻辑 await browser.execute(async (targetX, targetY) => { // 确保anime已加载,若未加载则动态引入 if (typeof anime === 'undefined') { const script = document.createElement('script'); script.src = 'https://cdn.jsdelivr.net/npm/animejs@3.2.1/lib/anime.min.js'; await new Promise(resolve => script.onload = resolve); document.head.appendChild(script); } // 获取鼠标元素 const mouseElem = document.getElementById('webdriver-mouse'); if (!mouseElem) throw new Error('鼠标元素#webdriver-mouse未找到'); // 执行动画,修正坐标(加上页面滚动偏移) anime({ targets: mouseElem, left: `${targetX + window.scrollX}px`, top: `${targetY + window.scrollY}px`, duration: 1000, easing: 'linear' }); }, rect.x, rect.y); }, true); }
更新后的错误:TypeError: Cannot read properties of null (reading 'style')
这个错误说明浏览器上下文里找不到#webdriver-mouse元素,即使调用了createMouse(),可能存在以下问题:
createMouse()创建元素的时机太晚,或元素未被正确插入DOMcreateMouse()中的元素创建逻辑有问题- 页面跳转/刷新后,元素被销毁
排查与修复建议
- 验证鼠标元素的存在:在调用
animateMouse前,通过browser.execute()确认元素状态:
const mouseExists = await browser.execute(() => !!document.getElementById('webdriver-mouse')); console.log('鼠标元素是否存在:', mouseExists);
- 确保
createMouse()逻辑正确:检查mouse.js中的代码,确保元素被添加到<body>且样式设置合理:
// 示例createMouse逻辑 export async function createMouse() { await browser.execute(() => { if (!document.getElementById('webdriver-mouse')) { const mouse = document.createElement('div'); mouse.id = 'webdriver-mouse'; mouse.style.position = 'fixed'; mouse.style.width = '20px'; mouse.style.height = '20px'; mouse.style.borderRadius = '50%'; mouse.style.backgroundColor = 'rgba(255,0,0,0.5)'; mouse.style.pointerEvents = 'none'; // 避免干扰真实交互 mouse.style.zIndex = '999999'; document.body.appendChild(mouse); } }); }
- 修正坐标计算:
getBoundingClientRect()返回的x/y是视口相对位置,若鼠标元素用position: absolute,需加上window.scrollX/window.scrollY修正为文档坐标;若用position: fixed,直接使用x/y即可。
额外注意事项
- 测试开始前就调用
createMouse(),页面跳转后需重新调用(若页面刷新) - 动态引入anime.js时固定版本号,避免兼容性问题
- 若需等待动画完成后再执行后续测试,可在
browser.execute()中返回Promise并在Node端等待:
// 在browser.execute中返回动画完成的Promise await browser.execute(async (targetX, targetY) => { // ... 前面的代码 return new Promise(resolve => { anime({ // ... 动画配置 complete: resolve }); }); }, rect.x, rect.y);
内容的提问来源于stack exchange,提问作者Steve
相关产品推荐
相关产品推荐

