TestCafe弹出模态框后点击事件异常问题求助
解决TestCafe中点击按钮后模态遮罩导致持续触发mousedown的问题
问题描述
在测试场景中,需要点击“+”按钮增加输入框数值,点击后会弹出模态窗口,需点击确认按钮完成操作。使用while循环重复操作以达到输入框目标值,但点击按钮后模态窗口的DOM遮罩覆盖页面元素,导致点击动作停留在“+”按钮上触发mousedown事件,输入框数值不断增加。
原测试代码如下:
const inputField = Selector(`[data-test-id="${inputId}"]`).find('input'); // 将输入框当前值存入inputFieldValue变量 let inputFieldValue: string = await inputField.value; // value变量是输入框需要达到的目标值 while (inputFieldValue !== value) { // 问题出在这里 await t .click(Selector(`[data-test-id="${inputId}"]`).find('button').withText('+')) inputFieldValue = await inputField.value; // 确认模态窗口出现后点击确认按钮 await t.click(this.confirmBtnModalWindow); } // 验证输入框值是否符合预期 await t .expect(inputFieldValue).eql(value) .catch(() => { throw new Error(`Error: expected ${value} in input field but got ${inputFieldValue}`) })
已尝试的无效方案:
- 在多处添加
await t.wait(1000)固定延迟; - 点击“+”按钮后点击body偏移位置,循环执行时问题仍存在;
- 添加模态窗口存在性检查,仅在模态窗口未出现时点击“+”按钮,未解决问题。
可行解决方案
1. 手动拆分点击事件,确保完整触发
TestCafe的click动作默认会模拟mousedown→mouseup→click的完整流程,但如果模态窗口在mousedown后立即弹出,可能会中断后续的mouseup事件,导致按钮处于持续按下状态。可以手动分步骤触发事件,确保每个事件都执行完成:
const plusButton = Selector(`[data-test-id="${inputId}"]`).find('button').withText('+'); while (inputFieldValue !== value) { // 手动触发完整的点击事件链 await t .dispatchEvent(plusButton, 'mousedown') .dispatchEvent(plusButton, 'mouseup') .dispatchEvent(plusButton, 'click'); // 等待模态窗口确认按钮可点击后再操作 await t.wait(this.confirmBtnModalWindow.with({ visibilityCheck: true }).exists); await t.click(this.confirmBtnModalWindow); // 等待模态窗口关闭后,再获取输入框新值 await t.wait(this.confirmBtnModalWindow.exists.not); inputFieldValue = await inputField.value; }
2. 严格控制元素交互时机
确保在每次循环中,只有当“+”按钮可点击、模态窗口确认按钮出现并可点击、模态窗口关闭后,才进行下一步操作,避免异步时序问题:
const plusButton = Selector(`[data-test-id="${inputId}"]`).find('button').withText('+'); const confirmBtn = this.confirmBtnModalWindow; while (inputFieldValue !== value) { // 等待“+”按钮可见且可点击 await t.expect(plusButton.with({ visibilityCheck: true }).exists).ok(); await t.click(plusButton); // 等待确认按钮出现并可点击 await t.expect(confirmBtn.with({ visibilityCheck: true }).exists).ok(); await t.click(confirmBtn); // 等待模态窗口完全关闭 await t.expect(confirmBtn.exists).notOk(); // 更新输入框值 inputFieldValue = await inputField.value; }
3. 直接设置输入框值(若测试场景允许)
如果测试不需要验证点击“+”按钮的交互流程,可直接设置输入框的value属性,跳过重复点击的步骤,从根源避免问题:
// 直接设置输入框值并触发change事件 await t .setProperty(inputField, 'value', value) .dispatchEvent(inputField, 'change'); // 若设置后仍需触发模态窗口确认,可手动触发相关逻辑(视页面实现而定) // await t.click(...) // 最后验证值是否正确 await t.expect(inputField.value).eql(value);
内容的提问来源于stack exchange,提问作者Kostiantyn Pavlenko
相关产品推荐
相关产品推荐

