ember-test-helpers
ember-test-helpers copied to clipboard
typeIn helper triggers all key-related events, even if preventDefault is called
The typeIn
helper always triggers all of the key-related events (keydown
, keypress
, input
, and keyup
) regardless of whether event.preventDefault()
was called. This makes the helper work differently than actual browser input in a few cases:
- When a
keydown
handler callspreventDefault
, only thekeydown
andkeyup
events are triggered - When a
keypress
handler callspreventDefault
, aninput
event is not triggered
Calling preventDefault
in a keyup
or input
handler has no effect on which events are triggered.
(Tested with Chrome 84.0.4147.105 and Firefox 79.0.)
This definitely seems good to fix, though I think it will be somewhat difficult to do.
@pgengler - I had some success rolling my own from a combination of the internal __triggerKeyEvent__
/ fireEvent
/ buildKeyboardEvent
functions.
My needs were quite specific in that I didn't need to enter any alphabetic characters, so didn't need to worry about detecting or setting the shiftKey
property on the event data. There's also not a great deal of error checking, max length checking, etc., and I had no need to support older browsers, so didn't try all the KeyboardEvent
/ KeyboardEvents
/ KeyEvent
combinations.
Try this for size with numeric data... your mileage may vary 🙂 .
import { find, settled } from '@ember/test-helpers';
function buildNumberKeyEvent(eventType, key) {
const keyCode = key.charCodeAt(0);
const keyEventProps = { keyCode, which: keyCode, key, ctrlKey: false, altKey: false, shiftKey: false, metaKey: false, bubbles: true, cancelable: true };
const keyEvent = new KeyboardEvent(eventType, keyEventProps);
Object.defineProperty(keyEvent, 'keyCode', {
get() {
return parseInt(keyCode, 10); // buildKeyboardEvent is missing the ,10... and the radix doesn't default to 10
},
});
Object.defineProperty(keyEvent, 'which', {
get() {
return parseInt(keyCode, 10); // buildKeyboardEvent is missing the ,10... and the radix doesn't default to 10
},
});
return keyEvent;
}
async function preventableNumericTypeIn(selector, string) {
const element = find(selector);
if (!element) {
throw new Error(`Cannot find selector ${selector}`);
}
for (const key of [...string]) {
const keyDownEvent = buildNumberKeyEvent('keydown', key);
element.dispatchEvent(keyDownEvent);
await settled();
if (keyDownEvent.defaultPrevented) {
return;
}
const keyPressEvent = buildNumberKeyEvent('keypress', key);
element.dispatchEvent(keyPressEvent);
await settled();
if (keyPressEvent.defaultPrevented) {
return;
}
element.value += key;
const inputEvent = document.createEvent('Events');
inputEvent.initEvent('input', true, true);
element.dispatchEvent(inputEvent);
await settled();
const keyUpEvent = buildNumberKeyEvent('keyup', key);
element.dispatchEvent(keyUpEvent);
await settled();
if (keyUpEvent.defaultPrevented) {
return;
}
const changeEvent = document.createEvent('Events');
changeEvent.initEvent('change', true, true);
element.dispatchEvent(inputEvent);
await settled();
}
}
await preventableNumericTypeIn('input', '1.2345');