当前位置: 首页 > news >正文

【Java】使用playwright来实现canvas前端画板UI自动化

网上有很多定位canvas画板实现自动化,参考方法如下:

1. selenium webdriver 实现Canvas画布自动化测试_selenium 定位canvas元素-CSDN博客

2.https://www.zhihu.com/question/544772689

定位方式思路:

我这次尝试了以上方法都未能成功实现,使用SpreadJS的API来实现也失败,原因是公司系统未暴露对象在自动化测试工程无法引用。

于是我尝试使用使用手动计算表格点击位置的行列坐标,再使用playwright模拟鼠标进行点击,可以成功实现点击

实现思路:

1. 首先获取画布的边界框(BoundingBox)

2. 根据自动化测试的浏览器窗口画布的宽高和总行列数,计算每个单元格的宽度(cellWidth)和高度(cellHeight)

注意点:这里的总行列数是指的自动化测试过程中弹出的浏览器窗口中画布的可见的总行列数,不是本地系统的总行列数

3. 根据给定的行号和列号,计算目标单元格的左上角坐标(cellX, cellY)

4. 计算出最终的点击坐标(clickX, clickY)后,使用 page.mouse().dblclick() 模拟双击操作

代码方法封装:

public class CanvasUtils{ public final Page page; public final Locator canvas; public CanvasUtils(Page page, String canvasSelector){ this.page = page; this.canvas = page.locator(canvasSelector); // 等待Canvas元素可见可交互 page.waitForTimeout(5000); } /** * @param row 行号(从0开始) * @param col 列号(从0开始) * @param totalRows 自动化浏览器窗口可见的总行数 * @param totalCols 自动化浏览器窗口可见的总列数 * @param side left 单元格偏左区域 或 right 单元格偏右区域 */ public void clickCellSide(int row, int col, int totalRows, int totalCols, String side){ BoundingBox box = canvas.boundingBox(); if(box == null){ log.info("Canvas画板未渲染出来,点击失败") throw new RuntimeException("Canvas未找到或未渲染"); } // 计算点击位置的坐标x,y double cellWidth = box.width / totalCols; double cellHeight = box.height / totalRows; double cellX = box.x + col * cellWidth; double celly = box.y + col * cellHeight; double clickX; if ("right".equals(side)){ clickX = cellX + cellWidth * 0.75; // 右侧中心 } else { clickX = cellX + cellWidth * 0.25; // 左侧中心 } double clickY = cellY + cellHeight / 2; try{ page.mouse().dblclick(clickX, clickY); log.info("已点击第{}行第{}列单元格的{}侧(坐标:{},{}),点击成功", row, col, side, clickX, clickY); // 等待菜单出现 page.waitForTimeout(2000); log.info("点击成功后的菜单URL:{}", page.url()); } catch(Exception e){ log.info("点击第{}行第{}列单元格的{}侧失败", row, col, side, e.getMessage()); throw e; } } }
http://www.jsqmd.com/news/708033/

相关文章:

  • React TypeScript Cheatsheet:侧边栏配置和文档组织终极指南
  • Meteor性能监控终极指南:实时应用性能指标收集与优化策略
  • Material Design Lite安全考虑:XSS防护与CSRF防御终极指南
  • ChatIDE深度集成指南:在VSCode中高效使用GPT与Claude进行AI编程
  • 别再傻傻配全局变量了!用Python-dotenv + .env文件管理OpenAI API密钥(附避坑指南)
  • ZoroCloud测评:Intel Gold 6138/1GB内存/100Mbps带宽/9929CMIN2/原生双ISP洛杉矶VPS(Debian GNU/Linux 12系统)
  • 如何快速在GCP AI Platform部署TensorFlow模型:完整实践指南
  • AWS机器学习监控终极指南:CloudWatch模型指标完整教程
  • 2026年重庆GEO优化领域3家主流服务商综合分析与企业选型参考报告 - 商业小白条
  • 告别触摸屏!用旋转编码器给STM32+LVGL项目做个复古又实用的物理菜单
  • 深度解析:构建高性能网盘直链解析架构的技术实现方案
  • 高效解密网易云NCM文件:ncmdumpGUI完全指南与实用技巧
  • 手把手教你用RT-Thread Studio点亮STM32F407星火一号开发板(附完整配置流程)
  • React TypeScript Cheatsheet:服务端渲染类型处理终极指南
  • Image-to-LaTeX:10分钟快速上手数学公式识别神器
  • 第二章:GEM与TTM概述:2.2 TTM显存管理
  • 我的花园世界客服服务咨询AI流量赋能,重塑智能体验新标杆 - 速递信息
  • Dripsy进阶技巧:如何实现动态主题切换和深色模式
  • lichobile项目迁移指南:从已弃用版本到Flutter重写的平滑过渡
  • EZCard:告别手动排版,桌游设计师的批量卡牌生成神器
  • 从‘纸上系数’到‘真实效果’:手把手教你用freqz/freqs对比分析IIR与FIR滤波器的频率响应
  • 3分钟快速掌握KeymouseGo:免费开源鼠标键盘自动化终极指南
  • NCM音乐文件解密转换:突破格式限制实现音乐自由播放
  • 保姆级教程:在RK3588 Android 12/11上抓取硬件编解码码流(含Codec2/OMX框架命令详解)
  • 如何使用Yew框架打造高效Web音频应用:Web Audio API集成完整指南
  • PPH管覆盖工业全场景需求推荐厂家镇江苏一塑业有限公司 - 苏一塑业13914572689
  • 终极指南:ColorJizz PHP颜色转换库如何实现跨颜色空间的无缝转换
  • DLSS Swapper:解锁游戏画质与性能的隐藏开关
  • 终极指南:OWASP Cheat Sheet Series教你掌握错误处理与日志记录的安全实践
  • GAN实现MNIST手写数字生成:从原理到实践