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

如何用Testcafe触发number类型input的ArrowUp事件监听器?

解决Testcafe中ArrowUp事件无法触发输入框监听函数的问题

问题背景

项目中的输入框代码:

<input id="min-days" type="number" onchange="javascript=onRefresh();" oninput="validity.valid||(value='');" placeholder="0 days" min="0" max="99999" />

对应的事件监听代码:

var durationInput = document.getElementById("min-days");
durationInput.addEventListener("keydown", function (event) {
    if (event.code == "ArrowUp") {
        durationInput.value = parseInt(durationInput.value || 0) + 364;
    }
    // 省略其他代码
});

功能正常,但使用Testcafe测试ArrowUp触发逻辑时,无论是pressKey('up')还是手动dispatch事件的方法都失败,断言报错:

1) AssertionError: expected '' to deeply equal '365'
    
    + expected - actual
    
    -''
    +365

尝试过的两种测试方法均无效:

方法1

test('Date up arrow increments by 365 from 0 on up arrow', 
    async t => {

        await t.eval(() => {
            const input = document.querySelector('#min-days');
            const event = new KeyboardEvent('keydown', { key: 'ArrowUp' });
            input.dispatchEvent(event);
        });

        await t.expect(Selector('#min-days').value).eql('365');
    });

方法2

test('Date up arrow increments by 365 from 0 on up arrow',
    async t => {
        const minDays = Selector('#min-days');
        const getInputNode = ClientFunction(() =>
            document.querySelector('#min-days'));

        await t.eval(() => {
            const input = document.querySelector('#min-days');
            const event = new KeyboardEvent('keyup', { key: 'ArrowUp' });
            input.dispatchEvent(event);
        });
        await t.expect(minDays.value).eql('365');
    });

问题原因

  1. 事件属性不匹配:监听函数判断的是event.code === "ArrowUp",但手动构造事件时只设置了key属性,未设置code,导致条件不成立。
  2. 事件类型错误:方法2中使用了keyup事件,但监听的是keydown,事件类型不匹配。
  3. 期望值错误:代码中逻辑是+364,但测试期望的是365,数值不符。
  4. 输入框未聚焦:使用pressKey('up')时,如果输入框未获得焦点,键盘事件不会被捕获。

解决方法

方案1:修正手动dispatch事件的测试代码

确保构造keydown事件时设置code属性,同时修正期望值:

test('Date up arrow increments by 364 from 0 on up arrow', 
    async t => {
        await t.eval(() => {
            const input = document.querySelector('#min-days');
            // 构造事件时同时设置code和key属性
            const event = new KeyboardEvent('keydown', { 
                code: 'ArrowUp',
                key: 'ArrowUp',
                bubbles: true,
                cancelable: true
            });
            input.dispatchEvent(event);
        });

        await t.expect(Selector('#min-days').value).eql('364');
    });

方案2:使用Testcafe的pressKey方法(推荐)

先聚焦输入框,再触发按键事件,同时修正期望值:

import { Selector } from 'testcafe';

test('Date up arrow increments by 364 from 0 on up arrow', async t => {
    const minDaysInput = Selector('#min-days');
    
    // 先聚焦输入框
    await t.click(minDaysInput);
    // 触发ArrowUp按键
    await t.pressKey('up');
    
    // 断言期望值为364
    await t.expect(minDaysInput.value).eql('364');
});

关键注意点

  • 始终确保事件类型(keydown/keyup/keypress)与监听的类型一致。
  • 手动构造键盘事件时,要匹配监听函数中判断的事件属性(如code而非仅key)。
  • 测试期望值必须与业务逻辑的计算结果一致,这里业务逻辑是加364,所以期望值应为'364'而非'365'。
  • 使用pressKey时,目标元素必须处于聚焦状态,否则事件无法被捕获。

内容的提问来源于stack exchange,提问作者Carl

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 16:15:34