diff --git a/addon-test-support/@ember/test-helpers/dom/type-in.ts b/addon-test-support/@ember/test-helpers/dom/type-in.ts index 6b437fe50..e8d3743a9 100644 --- a/addon-test-support/@ember/test-helpers/dom/type-in.ts +++ b/addon-test-support/@ember/test-helpers/dom/type-in.ts @@ -7,6 +7,7 @@ import isFocusable from './-is-focusable'; import { Promise } from 'rsvp'; import fireEvent from './fire-event'; import Target from './-target'; +import triggerKeyEvent from './trigger-key-event'; export interface Options { delay?: number; @@ -69,26 +70,18 @@ function fillOut(element: FormControl, text: string, delay: number) { // eslint-disable-next-line require-jsdoc function keyEntry(element: FormControl, character: string): () => void { - const charCode = character.charCodeAt(0); - - const eventOptions = { - bubbles: true, - cancellable: true, - charCode, - }; - - const keyEvents = { - down: new KeyboardEvent('keydown', eventOptions), - press: new KeyboardEvent('keypress', eventOptions), - up: new KeyboardEvent('keyup', eventOptions), - }; + let shiftKey = character === character.toUpperCase() && character !== character.toLowerCase(); + let options = { shiftKey }; + let characterKey = character.toUpperCase(); return function() { - element.dispatchEvent(keyEvents.down); - element.dispatchEvent(keyEvents.press); - element.value = element.value + character; - fireEvent(element, 'input'); - element.dispatchEvent(keyEvents.up); + return triggerKeyEvent(element, 'keydown', characterKey, options) + .then(() => triggerKeyEvent(element, 'keypress', characterKey, options)) + .then(() => { + element.value = element.value + character; + fireEvent(element, 'input'); + }) + .then(() => triggerKeyEvent(element, 'keyup', characterKey, options)); }; } diff --git a/tests/unit/dom/type-in-test.js b/tests/unit/dom/type-in-test.js index 807c87196..de725c1fe 100644 --- a/tests/unit/dom/type-in-test.js +++ b/tests/unit/dom/type-in-test.js @@ -77,6 +77,27 @@ module('DOM Helper: typeIn', function(hooks) { assert.equal(element.value, 'foo'); }); + test('it triggers key events with correct arguments', async function(assert) { + element = buildInstrumentedElement('input', ['key', 'shiftKey']); + await typeIn(element, 'F o'); + + let chars = ['F', ' ', 'o']; + let shiftKeys = [true, false, false]; + let expectedEventsWithArguments = expectedEvents.map(eventName => { + // Only key events get the key arguments + if (!['keydown', 'keypress', 'keyup'].includes(eventName)) { + return `${eventName} undefined undefined`; + } + // After each keyup, the next character comes up + let char = eventName === 'keyup' ? chars.shift() : chars[0]; + let shiftKey = eventName === 'keyup' ? shiftKeys.shift() : shiftKeys[0]; + + return `${eventName} ${char.toUpperCase()} ${shiftKey}`; + }); + + assert.verifySteps(expectedEventsWithArguments); + }); + test('filling in an input with a delay', async function(assert) { element = buildInstrumentedElement('input'); await typeIn(element, 'foo', { delay: 150 });