diff --git a/packages/test-utils/src/wrapper.js b/packages/test-utils/src/wrapper.js index cf127f496..569269894 100644 --- a/packages/test-utils/src/wrapper.js +++ b/packages/test-utils/src/wrapper.js @@ -829,6 +829,33 @@ export default class Wrapper implements BaseWrapper { return this.element.textContent.trim() } + /** + * Simulates event triggering + */ + __simulateTrigger(type: string, options?: Object): void { + const regularEventTrigger = (type, options) => { + const event = createDOMEvent(type, options) + return this.element.dispatchEvent(event) + } + + const focusEventTrigger = (type, options) => { + if (this.element instanceof HTMLElement) { + return this.element.focus() + } + + regularEventTrigger(type, options) + } + + const triggerProcedureMap = { + focus: focusEventTrigger, + __default: regularEventTrigger + } + + const triggerFn = triggerProcedureMap[type] || triggerProcedureMap.__default + + return triggerFn(type, options) + } + /** * Dispatches a DOM event on wrapper */ @@ -869,8 +896,7 @@ export default class Wrapper implements BaseWrapper { return nextTick() } - const event = createDOMEvent(type, options) - this.element.dispatchEvent(event) + this.__simulateTrigger(type, options) return nextTick() } } diff --git a/test/resources/components/component-with-multiple-inputs.vue b/test/resources/components/component-with-multiple-inputs.vue new file mode 100644 index 000000000..bd8bbbaf5 --- /dev/null +++ b/test/resources/components/component-with-multiple-inputs.vue @@ -0,0 +1,57 @@ + + + + + diff --git a/test/specs/wrapper-array/trigger.spec.js b/test/specs/wrapper-array/trigger.spec.js index 9ef116678..648adba1c 100644 --- a/test/specs/wrapper-array/trigger.spec.js +++ b/test/specs/wrapper-array/trigger.spec.js @@ -1,7 +1,11 @@ import { compileToFunctions } from 'vue-template-compiler' import ComponentWithEvents from '~resources/components/component-with-events.vue' +import ComponentWithMultipleInputs from '~resources/components/component-with-multiple-inputs.vue' import { describeWithShallowAndMount } from '~resources/utils' +const assertElementIsFocused = element => + expect(document.activeElement.id).toEqual(element.id) + describeWithShallowAndMount('trigger', mountingMethod => { it('causes click handler to fire when wrapper.trigger("click") is called on a Component', async () => { const clickHandler = jest.fn() @@ -34,6 +38,26 @@ describeWithShallowAndMount('trigger', mountingMethod => { expect(keydownHandler).toHaveBeenCalled() }) + it('should really focus element when trigger focus was called', async () => { + const wrapper = mountingMethod(ComponentWithMultipleInputs, { + attachTo: document.body + }) + + assertElementIsFocused(wrapper.get('[data-test-position="2"]').element) + + await wrapper.get('[data-test-position="4"]').trigger('focus') + + assertElementIsFocused(wrapper.get('[data-test-position="4"]').element) + + await wrapper.get('[data-test-position="3"]').trigger('focus') + + assertElementIsFocused(wrapper.get('[data-test-position="4"]').element) + + await wrapper.get('[data-test-position="2"]').trigger('focus') + + assertElementIsFocused(wrapper.get('[data-test-position="2"]').element) + }) + it('throws an error if type is not a string', () => { const wrapper = mountingMethod(ComponentWithEvents) const invalidSelectors = [