如何用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'); });
问题原因
- 事件属性不匹配:监听函数判断的是
event.code === "ArrowUp",但手动构造事件时只设置了key属性,未设置code,导致条件不成立。 - 事件类型错误:方法2中使用了
keyup事件,但监听的是keydown,事件类型不匹配。 - 期望值错误:代码中逻辑是
+364,但测试期望的是365,数值不符。 - 输入框未聚焦:使用
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
相关产品推荐
相关产品推荐

