diff --git a/src/__tests__/keyboard/plugin/functional.ts b/src/__tests__/keyboard/plugin/functional.ts
index cc72f8e0..68650e0b 100644
--- a/src/__tests__/keyboard/plugin/functional.ts
+++ b/src/__tests__/keyboard/plugin/functional.ts
@@ -117,6 +117,36 @@ test('trigger click event on [Enter] keypress on HTMLButtonElement', () => {
`)
})
+test.each`
+ elementType | submit | hasForm
+ ${'checkbox'} | ${'input'} | ${true}
+ ${'checkbox'} | ${'button'} | ${true}
+ ${'radio'} | ${'input'} | ${true}
+ ${'radio'} | ${'button'} | ${true}
+ ${'checkbox'} | ${'input'} | ${false}
+ ${'checkbox'} | ${'button'} | ${false}
+ ${'radio'} | ${'input'} | ${false}
+ ${'radio'} | ${'button'} | ${false}
+`(
+ 'trigger submit event on [Enter] keypress on HTMLInputElement type=$elementType with submit $submit and hasForm=$hasForm',
+ ({elementType, submit, hasForm}) => {
+ const {element, getEvents} = setup(
+ `<${hasForm ? 'form' : 'div'}>
+
+ ${submit === 'button' && ''}
+ ${submit === 'input' && ''}
+ ${hasForm ? 'form' : ''}>`,
+ )
+
+ element.querySelector('input')?.focus()
+
+ userEvent.keyboard('[Enter]')
+
+ expect(getEvents('click')).toHaveLength(0)
+ expect(getEvents('submit')).toHaveLength(hasForm ? 1 : 0)
+ },
+)
+
test('trigger click event on [Space] keyup on HTMLButtonElement', () => {
const {element, getEventSnapshot, getEvents} = setup(``)
element.focus()
diff --git a/src/keyboard/plugins/functional.ts b/src/keyboard/plugins/functional.ts
index bfbc0a89..564b0a70 100644
--- a/src/keyboard/plugins/functional.ts
+++ b/src/keyboard/plugins/functional.ts
@@ -6,6 +6,7 @@
import {fireEvent} from '@testing-library/dom'
import {
calculateNewValue,
+ hasFormSubmit,
isClickableInput,
isCursorAtStart,
isEditable,
@@ -81,6 +82,19 @@ export const keydownBehavior: behaviorPlugin[] = [
]
export const keypressBehavior: behaviorPlugin[] = [
+ {
+ matches: (keyDef, element) =>
+ keyDef.key === 'Enter' &&
+ isElementType(element, 'input') &&
+ ['checkbox', 'radio'].includes(element.type),
+ handle: (keyDef, element) => {
+ const form = (element as HTMLInputElement).form
+
+ if (hasFormSubmit(form)) {
+ fireEvent.submit(form)
+ }
+ },
+ },
{
matches: (keyDef, element) =>
keyDef.key === 'Enter' &&
@@ -99,9 +113,7 @@ export const keypressBehavior: behaviorPlugin[] = [
if (
form &&
- (form.querySelectorAll('input').length === 1 ||
- form.querySelector('input[type="submit"]') ||
- form.querySelector('button[type="submit"]'))
+ (form.querySelectorAll('input').length === 1 || hasFormSubmit(form))
) {
fireEvent.submit(form)
}
diff --git a/src/utils/index.ts b/src/utils/index.ts
index 3a15cff0..560be5eb 100644
--- a/src/utils/index.ts
+++ b/src/utils/index.ts
@@ -25,3 +25,4 @@ export * from './misc/isDisabled'
export * from './misc/isDocument'
export * from './misc/wait'
export * from './misc/hasPointerEvents'
+export * from './misc/hasFormSubmit'
diff --git a/src/utils/misc/hasFormSubmit.ts b/src/utils/misc/hasFormSubmit.ts
new file mode 100644
index 00000000..3e70d036
--- /dev/null
+++ b/src/utils/misc/hasFormSubmit.ts
@@ -0,0 +1,8 @@
+export const hasFormSubmit = (
+ form: HTMLFormElement | null,
+): form is HTMLFormElement =>
+ !!(
+ form &&
+ (form.querySelector('input[type="submit"]') ||
+ form.querySelector('button[type="submit"]'))
+ )