You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 18:23:25