Protractor使用actions类键盘操作报sendKeysToActiveElement错误如何解决
问题根因
该报错由WebDriver协议不匹配直接导致:Chrome 100及以上版本默认强制启用W3C WebDriver标准,而当前使用的Selenium 3.141.59内置的actions类键盘操作逻辑基于旧版JSON Wire Protocol实现,调用sendKeysToActiveElement这个非W3C标准接口时,新版ChromeDriver无法识别该指令,直接抛出UnsupportedOperationError。
之前添加w3c: false配置失效的原因是:Chrome 102对应版本的ChromeDriver已经移除了对非W3C模式的完整支持,强制关闭W3C模式会触发驱动初始化异常,出现多chromedriver实例启动、所有执行指令无响应的问题。
可行解决方案
按改造成本从低到高排序,可按需选择:
- 方案1:回退浏览器版本(零代码修改)
将Chrome浏览器回退至94及以下大版本,同时下载对应版本的ChromeDriver。该版本区间的Chrome默认保留对旧JSON Wire Protocol的完整支持,和Selenium 3.141.59、Protractor原生browser.actions()逻辑完全兼容,不需要额外修改配置或业务代码即可正常运行Ctrl多选这类组合键盘操作。 - 方案2:替换键盘操作实现(不降级浏览器)
放弃使用存在兼容问题的browser.actions()链式键盘调用,通过两种方式实现同等效果:- 元素聚焦后直接调用
sendKeys方法发送控制键 - 通过
browser.executeScript注入原生鼠标/键盘事件,直接触发页面的多选逻辑,示例代码如下:
- 元素聚焦后直接调用
it(' Tests to handle keyboard actions in Protractor ', async () => { // 所有异步操作统一加await,避免SELENIUM_PROMISE_MANAGER和async/await混用时的时序错乱问题 await browser.manage().timeouts().implicitlyWait(15000); await browser.get("https://letcode.in/selectable") await browser.sleep(5000) const elem_1 = element(by.xpath("(//h3[@id='clour'])[2]")) const elem_2 = element(by.xpath("(//h3[@id='clour'])[4]")) await elem_1.click(); // 注入带ctrlKey标记的点击事件,模拟按住Ctrl点击的多选效果 await browser.executeScript(` const target = arguments[0]; const ctrlClickEvent = new MouseEvent('click', { bubbles: true, cancelable: true, ctrlKey: true }); target.dispatchEvent(ctrlClickEvent); `, await elem_2.getWebElement()); });
- 方案3:升级依赖适配W3C标准
将Selenium依赖升级至4.x版本,同时升级Protractor到最新正式版。Selenium 4的actions类完全遵循W3C WebDriver标准实现,不需要调整w3c相关配置,即可在Chrome 100+版本上正常调用keyDown、keyUp等键盘操作方法。注意Protractor已停止官方维护,升级后可能需要处理部分周边依赖的兼容问题。
避坑提示
不要在Chrome 100+版本的chromeOptions中强制配置w3c: false,从Chrome 98版本开始,ChromeDriver已经逐步移除非W3C模式的相关支持,强行开启该配置除了多实例启动问题外,还会触发元素定位失败、截图接口异常、Cookie操作失效等连锁报错。
内容的提问来源于stack exchange,提问作者Koustav Das
相关产品推荐
相关产品推荐

