tagui之click功能在Linux下无效的问题
侧边栏壁纸
博主昵称
yuc

  • 累计撰写 291 篇文章
  • 累计收到 0 条评论

tagui之click功能在Linux下无效的问题

yuc
yuc
2024-05-27 / 最后修改: 2024-10-09 03:05 / 0 评论 / 10 阅读 / 正在检测是否收录...
问题

这个问题与之前的 select功能无法正常使用类似,表现为在 linux 下,特别是在 iframe 中交互元素的时候,经常无法正常点击到元素。

以前猜测过是系统某些软件或者服务依赖存在问题导致的,但是在长大几个月的使用 tagui 中发现,只安装了 tagui 的 centos、ubuntu 同样存在此问题。

原因

直到现在仍然没有排查到原因,对 tagui 的整个代码和执行逻辑还没有太了解。但是通过查看成功与不成功的场景,发现 tagui_chrome.log 中的日志有一些的区别,并且验证了在多个不同 centos、ubuntu 中可能存在同样的问题

排查过程

click成功的日志输出:

[tagui] INPUT  - 
[7] {"id":7,"method":"Runtime.evaluate","params":{"expression":"document.evaluate('(//frame|//iframe)[@name=\"MFrame\" or @id=\"MFrame\"]',document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null).snapshotLength"}}
[tagui] OUTPUT - 
[7] {"id":7,"result":{"result":{"type":"number","value":1,"description":"1"}}}

[tagui] INPUT  - 
[8] {"id":8,"method":"Runtime.evaluate","params":{"expression":"var result_bounds = document.evaluate('(//frame|//iframe)[@name=\"MFrame\" or @id=\"MFrame\"]',document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null).snapshotItem(0).getBoundingClientRect(); var result_rect = {top: Math.round(result_bounds.top), left: Math.round(result_bounds.left), width: Math.round(result_bounds.width), height: Math.round(result_bounds.height)}; result_rect","returnByValue":true}}
[tagui] OUTPUT - 
[8] {"id":8,"result":{"result":{"type":"object","value":{"top":110,"left":240,"width":1080,"height":601}}}}

[tagui] INPUT  - 
[9] {"id":9,"method":"Runtime.evaluate","params":{"expression":"mainframe_context = document.evaluate('(//frame|//iframe)[@name=\"MFrame\" or @id=\"MFrame\"]',document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null).snapshotItem(0).contentDocument"}}
[tagui] OUTPUT - 
[9] {"id":9,"result":{"result":{"type":"object","subtype":"node","className":"HTMLDocument","description":"#document","objectId":"-211116244302657272.5.1"}}}

[tagui] INPUT  - 
[10] {"id":10,"method":"Runtime.evaluate","params":{"expression":"(function (dom_json) {document.querySelector('iframe').contentWindow.dlClick.call(document.querySelector('iframe').contentDocument.querySelectorAll('.tdlist > div')[0]);})({})"}}
[tagui] OUTPUT - 
[10] {"id":10,"result":{"result":{"type":"undefined"}}}

click 不成功的日志输出

[tagui] INPUT  - 
[66] {"id":66,"method":"Runtime.evaluate","params":{"expression":"document.evaluate('(//frame|//iframe)[@name=\"MFrame\" or @id=\"MFrame\"]',document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null).snapshotLength"}}
[tagui] OUTPUT - 
[66] {"id":66,"result":{"result":{"type":"number","value":1,"description":"1"}}}

[tagui] INPUT  - 
[67] {"id":67,"method":"Runtime.evaluate","params":{"expression":"var result_bounds = document.evaluate('(//frame|//iframe)[@name=\"MFrame\" or @id=\"MFrame\"]',document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null).snapshotItem(0).getBoundingClientRect(); var result_rect = {top: Math.round(result_bounds.top), left: Math.round(result_bounds.left), width: Math.round(result_bounds.width), height: Math.round(result_bounds.height)}; result_rect","returnByValue":true}}
[tagui] OUTPUT - 
[67] {"id":67,"result":{"result":{"type":"object","value":{"top":110,"left":240,"width":1080,"height":601}}}}

[tagui] INPUT  - 
[68] {"id":68,"method":"Runtime.evaluate","params":{"expression":"mainframe_context = document.evaluate('(//frame|//iframe)[@name=\"MFrame\" or @id=\"MFrame\"]',document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null).snapshotItem(0).contentDocument"}}
[tagui] OUTPUT - 
[68] {"id":68,"result":{"result":{"type":"object","subtype":"node","className":"HTMLDocument","description":"#document","objectId":"6526965194935895727.5.2"}}}

通过日志最后几行可以看到,click不成功的时候最后在定位到 元素 后根本没有输出点击这个元素的日志。这个到底是什么原因我们排查手段有限,也许在后续有时间更加熟悉 tagui 代码后能够帮助它排查出来,但是现在我们不得而知。

这个现象与其他 click 或者 select 点击不了有很大的类似,也有一些不同。目前观察到的问题,只要在linux下无法click或者select元素,那么基本上都是通过坐标来定位的。有时候是坐标点击出现了误差,有些(这次)是根本没有执行代码。

所以我们解决的办法是通过 js 来操作,目前经过了这多次测试验证,基本上只要通过了控制台执行,那么 rpa 的 js 调用也可以成功。

但是 js 执行对于我们来说比较复杂,因为有时候浏览器本身提供的功能无法满足,还需要查看网站是否提供了内部的方法,比如下面这个

r.dom(f"document.querySelector('iframe').contentWindow.dlClick.call(document.querySelector('iframe').contentDocument.querySelectorAll('.tdlist > div')[-1])")

这里主要是想双击iframe内的元素,实测进入 iframe 后通过 dclick 不稳定,经常有很多案件进入不了,所以这里一整行都是为了 双击 进入某个案件。 前面一部分是定位到此 iframe ,中间一部分是调用此 iframe 中的 dlClick.call 方法,这是站点提供的双击方法,在 top 中不存在,所以需要第一部分定位到 iframe 中,接着我们在这个方法内还需要定位到此元素,又需要从 top 开始找,所以第一部分 定位 iframe 的代码仍然需要,最后一部分就是定位元素具体的代码,这个了解即可

PS. 方案汇总

后续一些场景下 click 点击不到的解决方案汇总:

  1. 123xx 环境点击案件详细页面的关闭按钮无效
r.frame()
r.dom('MFrame.contentWindow.document.querySelector("#btnBack").click()')
# 其中 MFrame 是元素所在的 iframe 名,当然在点击之前需要回到此 iframe 的上层
0

评论

博主关闭了当前页面的评论