我有一种情况,在窗体上的一个按钮,动画到视图中,如果在动画正在进行中发生element.click(),它不起作用.
element.click()不会抛出错误,不会返回失败的状态(它返回undefined)它只是默默地不起作用.
我已经尝试确保没有禁用被点击的元素,并且显示(可见),但即使这两个测试都成功,点击也会失败.
如果我在点击前等待0.4秒,它会起作用,因为动画已经完成.
如果我可以检测到点击工作的时间,如果没有自动重试,我不想要添加延迟(这是不可靠的,并且是坦率的躲避).
是否有一种通用的方法来检测click()是否实际上已经被操作,所以我可以使用重试循环直到它呢?
Aus*_*nce 11
我已确定正在发生的事情,为什么没有收到错误以及如何解决该问题。
主要问题在于element.click()工作方式。使用DEBUG="puppeteer:*"我能够看到内部发生了什么。什么element.click()实际上做的是: -
const box = element.boundingBox();
const x = box.x + (box.width/2);
const y = box.y + (box.height/2);
page.mouse.move(x,y);
page.mouse.down();
sleep(delay);
page.mouse.up();
Run Code Online (Sandbox Code Playgroud)
问题在于,因为视图(div)使元素的boundingBox()处于动画状态,并且在询问框位置和完成click()的时间之间,元素已移动或不可单击。
不会引发错误(承诺被拒绝),因为它只是用鼠标单击视口中的一个点,而不链接到任何元素。鼠标事件被发送,只是没有响应。
一种解决方法是添加足够的延迟以允许动画完成。另一个是在测试期间禁用动画。
对我来说,解决方案是等待元素的位置稳定在其目标位置,即我旋转查询boundingBox()并等待x,y报告先前确定的元素的位置。
就我而言,这at 10,10就像单击之前添加到我的测试脚本中一样简单,或者
test-id "form1.button3" at 10,10 click
Run Code Online (Sandbox Code Playgroud)
实际上,它的工作方式如下,在这种情况下,视图是从左侧向后动画化的。
00.571 [selector.test,61] at 8,410 以-84,410大小显示的test-id“ main.add”信息标签按钮大小116,33启用未选中检查“ Add” 显示为-11,410大小的test-id“ main.add”信息标签按钮启用了116,33尺寸未选中检查“ Add” 以8,410大小显示的test-id“ main.add”信息标签按钮116,33启用未选中检查“ Add” 00.947 [selector.test,61]点击
对于持续移动的元素或被其他东西覆盖的元素,它将不起作用。对于这些情况,请尝试page.evaluate(el => el.click(), element)。
具有超时功能的通用点击,灵感来自 Andrea 的答案。一旦元素可点击,这个就会返回,因此不会减慢测试速度。
click: async function (page, selector, timeout = 30000) {
await page.waitForSelector(selector, { visible: true, timeout })
let error;
while (timeout > 0) {
try {
await page.click(selector);
return;
} catch (e) {
await page.waitFor(100);
timeout -= 100;
error = e;
}
}
throw error;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6122 次 |
| 最近记录: |