Selenium鼠标移出页面再返回的Chrome高版本兼容问题求助
鼠标移出页面检测的自动化测试兼容问题解决
问题背景
被测系统会记录用户鼠标是否移出页面,以此判断填写表单时是否存在复制/粘贴用户名、密码的行为,需在多浏览器及不同版本中完成该测试。
遇到的问题
使用Selenium的Actions类实现自动化测试时,代码在Chrome 90.0及以下版本运行正常,但在Chrome更高版本中抛出org.openqa.selenium.interactions.MoveTargetOutOfBoundsException: move target out of bounds异常。尝试使用Robot类也无法解决,鼠标无法移动到指定位置。
尝试过的代码
Actions类实现代码
Action mouseOffUserid = builder.moveToElement(userid).click().sendKeys(userid, "senkeytestOFFPAGE").moveByOffset(0, -1 * 120).moveByOffset(0, 120).build(); Action mouseOffPsw = builder.moveToElement(psw).click().sendKeys(psw, "senkeytestOFFPAGE").moveByOffset(0, -1 * (150 + adjustYOffset)).moveByOffset(0, 150 + adjustYOffset).build(); Action mouseClickUserid = builder.moveToElement(userid).click().sendKeys(userid, "senkeytest").build(); // 从用户名输入框移出页面 mouseOffUserid.perform(); QueryManager.giveDelay(1000); // 从密码输入框移出页面 mouseOffPsw.perform(); QueryManager.giveDelay(1000);
Robot类尝试代码
userid.sendKeys("ABC"); for (int i = 1; i < 3; i++) { robot.mouseMove(0, 0); System.out.println("第"+i+"次尝试:"+ MouseInfo.getPointerInfo().getLocation().getX() + " , " + MouseInfo.getPointerInfo().getLocation().getY()); } userid.click(); userid.sendKeys("123");
解决方案
针对Actions类的兼容修复
Chrome高版本对moveByOffset的边界检测更严格,直接偏移到页面外会触发异常。可先获取浏览器窗口的位置和尺寸,计算出页面外的安全坐标再移动:
// 获取浏览器窗口的位置和尺寸 Rectangle windowRect = driver.manage().window().getRect(); // 计算页面外的坐标(窗口左上角外侧) int offPageX = windowRect.getX() - 10; int offPageY = windowRect.getY() - 10; // 修改Actions操作,直接移动到页面外坐标 Action mouseOffUserid = builder.moveToElement(userid) .click() .sendKeys(userid, "senkeytestOFFPAGE") .moveToPoint(offPageX, offPageY) // 直接移动到页面外 .moveToElement(userid) // 移回输入框 .build(); mouseOffUserid.perform(); QueryManager.giveDelay(1000);
针对Robot类的修复
Robot类的mouseMove使用屏幕绝对坐标,Selenium在不同显示缩放比例下坐标会不匹配,需先获取系统显示缩放比例再调整坐标:
// 获取系统显示缩放比例(Windows系统) GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration(); double scaleX = gc.getDefaultTransform().getScaleX(); double scaleY = gc.getDefaultTransform().getScaleY(); // 计算缩放后的目标坐标 int targetX = (int) (0 / scaleX); int targetY = (int) (0 / scaleY); userid.sendKeys("ABC"); for (int i = 1; i < 3; i++) { robot.mouseMove(targetX, targetY); System.out.println("第"+i+"次尝试:"+ MouseInfo.getPointerInfo().getLocation().getX() + " , " + MouseInfo.getPointerInfo().getLocation().getY()); } userid.click(); userid.sendKeys("123");
通用跨浏览器兼容方案
若需跨浏览器兼容,推荐使用JavascriptExecutor直接模拟鼠标移出事件,绕开坐标计算问题:
// 模拟鼠标离开页面全局事件 JavascriptExecutor js = (JavascriptExecutor) driver; js.executeScript("document.dispatchEvent(new MouseEvent('mouseout', { bubbles: true, clientX: -10, clientY: -10 }));"); // 针对输入框的mouseleave事件(若系统监听输入框的移出行为) js.executeScript("arguments[0].dispatchEvent(new MouseEvent('mouseleave', { bubbles: true }));", userid); QueryManager.giveDelay(1000); js.executeScript("arguments[0].dispatchEvent(new MouseEvent('mouseleave', { bubbles: true }));", psw); QueryManager.giveDelay(1000);
内容的提问来源于stack exchange,提问作者Divya
相关产品推荐
相关产品推荐

