diff --git a/src/__tests__/type.js b/src/__tests__/type.js
index 18fb97d5..9940e78a 100644
--- a/src/__tests__/type.js
+++ b/src/__tests__/type.js
@@ -1121,43 +1121,43 @@ test('can type into an input with type `time`', () => {
const {element, getEventSnapshot} = setup('')
userEvent.type(element, '01:05')
expect(getEventSnapshot()).toMatchInlineSnapshot(`
- Events fired on: input[value="01:05"]
-
- input[value=""] - pointerover
- input[value=""] - pointerenter
- input[value=""] - mouseover: Left (0)
- input[value=""] - mouseenter: Left (0)
- input[value=""] - pointermove
- input[value=""] - mousemove: Left (0)
- input[value=""] - pointerdown
- input[value=""] - mousedown: Left (0)
- input[value=""] - focus
- input[value=""] - focusin
- input[value=""] - pointerup
- input[value=""] - mouseup: Left (0)
- input[value=""] - click: Left (0)
- input[value=""] - keydown: 0 (48)
- input[value=""] - keypress: 0 (48)
- input[value=""] - keyup: 0 (48)
- input[value=""] - keydown: 1 (49)
- input[value=""] - keypress: 1 (49)
- input[value=""] - keyup: 1 (49)
- input[value=""] - keydown: : (58)
- input[value=""] - keypress: : (58)
- input[value=""] - keyup: : (58)
- input[value=""] - keydown: 0 (48)
- input[value=""] - keypress: 0 (48)
- input[value="01:00"] - input
- "{CURSOR}" -> "{CURSOR}01:00"
- input[value="01:00"] - change
- input[value="01:00"] - keyup: 0 (48)
- input[value="01:00"] - keydown: 5 (53)
- input[value="01:00"] - keypress: 5 (53)
- input[value="01:05"] - input
- "{CURSOR}01:00" -> "{CURSOR}01:05"
- input[value="01:05"] - change
- input[value="01:05"] - keyup: 5 (53)
- `)
+ Events fired on: input[value="01:05"]
+
+ input[value=""] - pointerover
+ input[value=""] - pointerenter
+ input[value=""] - mouseover: Left (0)
+ input[value=""] - mouseenter: Left (0)
+ input[value=""] - pointermove
+ input[value=""] - mousemove: Left (0)
+ input[value=""] - pointerdown
+ input[value=""] - mousedown: Left (0)
+ input[value=""] - focus
+ input[value=""] - focusin
+ input[value=""] - pointerup
+ input[value=""] - mouseup: Left (0)
+ input[value=""] - click: Left (0)
+ input[value=""] - keydown: 0 (48)
+ input[value=""] - keypress: 0 (48)
+ input[value=""] - keyup: 0 (48)
+ input[value=""] - keydown: 1 (49)
+ input[value=""] - keypress: 1 (49)
+ input[value=""] - keyup: 1 (49)
+ input[value=""] - keydown: : (58)
+ input[value=""] - keypress: : (58)
+ input[value=""] - keyup: : (58)
+ input[value=""] - keydown: 0 (48)
+ input[value=""] - keypress: 0 (48)
+ input[value="01:00"] - input
+ "{CURSOR}" -> "{CURSOR}01:00"
+ input[value="01:00"] - change
+ input[value="01:00"] - keyup: 0 (48)
+ input[value="01:00"] - keydown: 5 (53)
+ input[value="01:00"] - keypress: 5 (53)
+ input[value="01:05"] - input
+ "{CURSOR}01:00" -> "{CURSOR}01:05"
+ input[value="01:05"] - change
+ input[value="01:05"] - keyup: 5 (53)
+ `)
expect(element).toHaveValue('01:05')
})
@@ -1165,40 +1165,40 @@ test('can type into an input with type `time` without ":"', () => {
const {element, getEventSnapshot} = setup('')
userEvent.type(element, '0105')
expect(getEventSnapshot()).toMatchInlineSnapshot(`
- Events fired on: input[value="01:05"]
-
- input[value=""] - pointerover
- input[value=""] - pointerenter
- input[value=""] - mouseover: Left (0)
- input[value=""] - mouseenter: Left (0)
- input[value=""] - pointermove
- input[value=""] - mousemove: Left (0)
- input[value=""] - pointerdown
- input[value=""] - mousedown: Left (0)
- input[value=""] - focus
- input[value=""] - focusin
- input[value=""] - pointerup
- input[value=""] - mouseup: Left (0)
- input[value=""] - click: Left (0)
- input[value=""] - keydown: 0 (48)
- input[value=""] - keypress: 0 (48)
- input[value=""] - keyup: 0 (48)
- input[value=""] - keydown: 1 (49)
- input[value=""] - keypress: 1 (49)
- input[value=""] - keyup: 1 (49)
- input[value=""] - keydown: 0 (48)
- input[value=""] - keypress: 0 (48)
- input[value="01:00"] - input
- "{CURSOR}" -> "{CURSOR}01:00"
- input[value="01:00"] - change
- input[value="01:00"] - keyup: 0 (48)
- input[value="01:00"] - keydown: 5 (53)
- input[value="01:00"] - keypress: 5 (53)
- input[value="01:05"] - input
- "{CURSOR}01:00" -> "{CURSOR}01:05"
- input[value="01:05"] - change
- input[value="01:05"] - keyup: 5 (53)
- `)
+ Events fired on: input[value="01:05"]
+
+ input[value=""] - pointerover
+ input[value=""] - pointerenter
+ input[value=""] - mouseover: Left (0)
+ input[value=""] - mouseenter: Left (0)
+ input[value=""] - pointermove
+ input[value=""] - mousemove: Left (0)
+ input[value=""] - pointerdown
+ input[value=""] - mousedown: Left (0)
+ input[value=""] - focus
+ input[value=""] - focusin
+ input[value=""] - pointerup
+ input[value=""] - mouseup: Left (0)
+ input[value=""] - click: Left (0)
+ input[value=""] - keydown: 0 (48)
+ input[value=""] - keypress: 0 (48)
+ input[value=""] - keyup: 0 (48)
+ input[value=""] - keydown: 1 (49)
+ input[value=""] - keypress: 1 (49)
+ input[value=""] - keyup: 1 (49)
+ input[value=""] - keydown: 0 (48)
+ input[value=""] - keypress: 0 (48)
+ input[value="01:00"] - input
+ "{CURSOR}" -> "{CURSOR}01:00"
+ input[value="01:00"] - change
+ input[value="01:00"] - keyup: 0 (48)
+ input[value="01:00"] - keydown: 5 (53)
+ input[value="01:00"] - keypress: 5 (53)
+ input[value="01:05"] - input
+ "{CURSOR}01:00" -> "{CURSOR}01:05"
+ input[value="01:05"] - change
+ input[value="01:05"] - keyup: 5 (53)
+ `)
expect(element).toHaveValue('01:05')
})
@@ -1208,7 +1208,7 @@ test('can type more a number higher than 60 minutes into an input `time` and the
expect(getEventSnapshot()).toMatchInlineSnapshot(`
Events fired on: input[value="23:59"]
-
+
input[value=""] - pointerover
input[value=""] - pointerenter
input[value=""] - mouseover: Left (0)
@@ -1254,7 +1254,7 @@ test('can type letters into an input `time` and they are ignored', () => {
expect(getEventSnapshot()).toMatchInlineSnapshot(`
Events fired on: input[value="16:36"]
-
+
input[value=""] - pointerover
input[value=""] - pointerenter
input[value=""] - mouseover: Left (0)
@@ -1495,3 +1495,22 @@ test('{arrowup} fires keyup/keydown events', () => {
input[value=""] - keyup: ArrowUp (38)
`)
})
+
+test('{enter} fires click on links', () => {
+ const {element, getEventSnapshot} = setup('link')
+
+ element?.focus()
+
+ userEvent.type(element, '{enter}', {skipClick: true})
+
+ expect(getEventSnapshot()).toMatchInlineSnapshot(`
+ Events fired on: a
+
+ a - focus
+ a - focusin
+ a - keydown: Enter (13)
+ a - keypress: Enter (13)
+ a - click: Left (0)
+ a - keyup: Enter (13)
+ `)
+})
diff --git a/src/type.js b/src/type.js
index 71fdf1cd..125c1968 100644
--- a/src/type.js
+++ b/src/type.js
@@ -8,13 +8,14 @@ import {
getActiveElement,
calculateNewValue,
setSelectionRangeIfNecessary,
- isClickable,
+ isClickableInput,
isValidDateValue,
getSelectionRange,
getValue,
isContentEditable,
isValidInputTimeValue,
buildTimeValue,
+ isInstanceOfElement,
} from './utils'
import {click} from './click'
import {navigationKey} from './keys/navigation-key'
@@ -321,7 +322,7 @@ function fireInputEventIfNeeded({
const prevValue = getValue(currentElement())
if (
!currentElement().readOnly &&
- !isClickable(currentElement()) &&
+ !isClickableInput(currentElement()) &&
newValue !== prevValue
) {
if (isContentEditable(currentElement())) {
@@ -583,7 +584,12 @@ function handleEnter({currentElement, eventOverrides}) {
})
if (keyPressDefaultNotPrevented) {
- if (isClickable(currentElement())) {
+ if (
+ isClickableInput(currentElement()) ||
+ // Links with href defined should handle Enter the same as a click
+ (isInstanceOfElement(currentElement(), 'HTMLAnchorElement') &&
+ currentElement().href)
+ ) {
fireEvent.click(currentElement(), {
...eventOverrides,
})
@@ -712,7 +718,7 @@ function handleSelectall({currentElement}) {
}
function handleSpace(context) {
- if (isClickable(context.currentElement())) {
+ if (isClickableInput(context.currentElement())) {
handleSpaceOnClickable(context)
return
}
diff --git a/src/utils.js b/src/utils.js
index 96578020..7b96a086 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -5,8 +5,8 @@ import {getWindowFromNode} from '@testing-library/dom/dist/helpers'
/**
* Check if an element is of a given type.
*
- * @param Element The element to test
- * @param string Constructor name. E.g. 'HTMLSelectElement'
+ * @param {Element} element The element to test
+ * @param {string} elementType Constructor name. E.g. 'HTMLSelectElement'
*/
function isInstanceOfElement(element, elementType) {
try {
@@ -285,7 +285,7 @@ const CLICKABLE_INPUT_TYPES = [
'submit',
]
-function isClickable(element) {
+function isClickableInput(element) {
return (
element.tagName === 'BUTTON' ||
(isInstanceOfElement(element, 'HTMLInputElement') &&
@@ -353,7 +353,7 @@ function isValidInputTimeValue(element, timeValue) {
export {
FOCUSABLE_SELECTOR,
isFocusable,
- isClickable,
+ isClickableInput,
getMouseEventOptions,
isLabelWithInternallyDisabledControl,
getActiveElement,