Skip to content

Commit ee1be1c

Browse files
authored
fix: button trigger space (testing-library#409)
1 parent e284462 commit ee1be1c

11 files changed

+720
-327
lines changed

README.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ test('double click', () => {
149149
const checkbox = screen.getByTestId('checkbox')
150150
userEvent.dblClick(checkbox)
151151
expect(onChange).toHaveBeenCalledTimes(2)
152-
expect(checkbox).toHaveProperty('checked', false)
152+
expect(checkbox).not.toBeChecked()
153153
})
154154
```
155155

@@ -185,6 +185,7 @@ The following special character strings are supported:
185185
| Text string | Key | Modifier | Notes |
186186
| ------------- | --------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
187187
| `{enter}` | Enter | N/A | Will insert a newline character (`<textarea />` only). |
188+
| `{space}` | `' '` | N/A | |
188189
| `{esc}` | Escape | N/A | |
189190
| `{backspace}` | Backspace | N/A | Will delete the previous character (or the characters within the `selectedRange`). |
190191
| `{del}` | Delete | N/A | Will delete the next character (or the characters within the `selectedRange`) |
@@ -558,6 +559,7 @@ Thanks goes to these people ([emoji key][emojis]):
558559

559560
<!-- markdownlint-enable -->
560561
<!-- prettier-ignore-end -->
562+
561563
<!-- ALL-CONTRIBUTORS-LIST:END -->
562564

563565
This project follows the [all-contributors][all-contributors] specification.

package.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,14 @@
4141
"@babel/runtime": "^7.10.2"
4242
},
4343
"devDependencies": {
44-
"@testing-library/dom": "^7.16.0",
45-
"@testing-library/jest-dom": "^5.10.1",
44+
"@testing-library/dom": "^7.21.4",
45+
"@testing-library/jest-dom": "^5.11.1",
4646
"is-ci": "^2.0.0",
4747
"jest-serializer-ansi": "^1.0.3",
4848
"kcd-scripts": "^6.2.3"
4949
},
5050
"peerDependencies": {
51-
"@testing-library/dom": ">=7.16.0"
51+
"@testing-library/dom": ">=7.21.4"
5252
},
5353
"eslintConfig": {
5454
"extends": "./node_modules/kcd-scripts/eslint.js",

src/__tests__/click.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ test('clicking a disabled checkbox only fires pointer events', () => {
7979
input[checked=false] - pointerup
8080
`)
8181
expect(element).toBeDisabled()
82-
expect(element).toHaveProperty('checked', false)
82+
expect(element).not.toBeChecked()
8383
})
8484

8585
test('clicking a radio button', () => {
@@ -107,7 +107,7 @@ test('clicking a radio button', () => {
107107
input[checked=true] - change
108108
`)
109109

110-
expect(element).toHaveProperty('checked', true)
110+
expect(element).toBeChecked()
111111
})
112112

113113
test('clicking a disabled radio button only fires pointer events', () => {
@@ -125,7 +125,7 @@ test('clicking a disabled radio button only fires pointer events', () => {
125125
`)
126126
expect(element).toBeDisabled()
127127

128-
expect(element).toHaveProperty('checked', false)
128+
expect(element).not.toBeChecked()
129129
})
130130

131131
test('should fire the correct events for <div>', () => {

src/__tests__/deselect-options.js

+1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ test('blurs previously focused element', () => {
5252
option[value="1"][selected=false] - mousemove: Left (0)
5353
option[value="1"][selected=false] - pointerdown
5454
option[value="1"][selected=false] - mousedown: Left (0)
55+
button - focusout
5556
select[name="select"][value=[]] - focusin
5657
option[value="1"][selected=false] - pointerup
5758
option[value="1"][selected=false] - mouseup: Left (0)

src/__tests__/paste.js

+3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ test('should paste text in input', () => {
1111
Events fired on: input[value="Hello, world!"]
1212
1313
input[value=""] - focus
14+
input[value=""] - focusin
1415
input[value=""] - paste
1516
input[value="Hello, world!"] - input
1617
"{CURSOR}" -> "Hello, world!{CURSOR}"
@@ -28,6 +29,7 @@ test('should paste text in textarea', () => {
2829
Events fired on: textarea[value="Hello, world!"]
2930
3031
textarea[value=""] - focus
32+
textarea[value=""] - focusin
3133
textarea[value=""] - paste
3234
textarea[value="Hello, world!"] - input
3335
"{CURSOR}" -> "Hello, world!{CURSOR}"
@@ -43,6 +45,7 @@ test('does not paste when readOnly', () => {
4345
Events fired on: input[value=""]
4446
4547
input[value=""] - focus
48+
input[value=""] - focusin
4649
input[value=""] - paste
4750
`)
4851
})

src/__tests__/type-modifiers.js

+206
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,212 @@ test('{enter} on a button', () => {
443443
`)
444444
})
445445

446+
test('{space} on a button', () => {
447+
const {element, getEventSnapshot} = setup('<button />')
448+
449+
userEvent.type(element, '{space}')
450+
451+
expect(getEventSnapshot()).toMatchInlineSnapshot(`
452+
Events fired on: button
453+
454+
button - pointerover
455+
button - pointerenter
456+
button - mouseover: Left (0)
457+
button - mouseenter: Left (0)
458+
button - pointermove
459+
button - mousemove: Left (0)
460+
button - pointerdown
461+
button - mousedown: Left (0)
462+
button - focus
463+
button - focusin
464+
button - pointerup
465+
button - mouseup: Left (0)
466+
button - click: Left (0)
467+
button - keydown: (32)
468+
button - keypress: (32)
469+
button - keyup: (32)
470+
button - click: Left (0)
471+
`)
472+
})
473+
474+
test('{space} with preventDefault keydown on button', () => {
475+
const {element, getEventSnapshot} = setup('<button />', {
476+
eventHandlers: {
477+
keyDown: e => e.preventDefault(),
478+
},
479+
})
480+
481+
userEvent.type(element, '{space}')
482+
483+
expect(getEventSnapshot()).toMatchInlineSnapshot(`
484+
Events fired on: button
485+
486+
button - pointerover
487+
button - pointerenter
488+
button - mouseover: Left (0)
489+
button - mouseenter: Left (0)
490+
button - pointermove
491+
button - mousemove: Left (0)
492+
button - pointerdown
493+
button - mousedown: Left (0)
494+
button - focus
495+
button - focusin
496+
button - pointerup
497+
button - mouseup: Left (0)
498+
button - click: Left (0)
499+
button - keydown: (32)
500+
button - keyup: (32)
501+
button - click: Left (0)
502+
`)
503+
})
504+
505+
test(`' ' on a button`, () => {
506+
const {element, getEventSnapshot} = setup('<button />')
507+
508+
userEvent.type(element, ' ')
509+
510+
expect(getEventSnapshot()).toMatchInlineSnapshot(`
511+
Events fired on: button
512+
513+
button - pointerover
514+
button - pointerenter
515+
button - mouseover: Left (0)
516+
button - mouseenter: Left (0)
517+
button - pointermove
518+
button - mousemove: Left (0)
519+
button - pointerdown
520+
button - mousedown: Left (0)
521+
button - focus
522+
button - focusin
523+
button - pointerup
524+
button - mouseup: Left (0)
525+
button - click: Left (0)
526+
button - keydown: (32)
527+
button - keypress: (32)
528+
button - keyup: (32)
529+
button - click: Left (0)
530+
`)
531+
})
532+
533+
test('{space} on an input', () => {
534+
const {element, getEventSnapshot} = setup(`<input value="" />`)
535+
536+
userEvent.type(element, '{space}')
537+
538+
expect(getEventSnapshot()).toMatchInlineSnapshot(`
539+
Events fired on: input[value=" "]
540+
541+
input[value=""] - pointerover
542+
input[value=""] - pointerenter
543+
input[value=""] - mouseover: Left (0)
544+
input[value=""] - mouseenter: Left (0)
545+
input[value=""] - pointermove
546+
input[value=""] - mousemove: Left (0)
547+
input[value=""] - pointerdown
548+
input[value=""] - mousedown: Left (0)
549+
input[value=""] - focus
550+
input[value=""] - focusin
551+
input[value=""] - pointerup
552+
input[value=""] - mouseup: Left (0)
553+
input[value=""] - click: Left (0)
554+
input[value=""] - keydown: (32)
555+
input[value=""] - keypress: (32)
556+
input[value=" "] - input
557+
"{CURSOR}" -> " {CURSOR}"
558+
input[value=" "] - keyup: (32)
559+
`)
560+
})
561+
562+
test('{enter} on an input type="color"', () => {
563+
const {element, getEventSnapshot} = setup(
564+
`<input value="#ffffff" type="color" />`,
565+
)
566+
567+
userEvent.type(element, '{enter}')
568+
569+
expect(getEventSnapshot()).toMatchInlineSnapshot(`
570+
Events fired on: input[value="#ffffff"]
571+
572+
input[value="#ffffff"] - pointerover
573+
input[value="#ffffff"] - pointerenter
574+
input[value="#ffffff"] - mouseover: Left (0)
575+
input[value="#ffffff"] - mouseenter: Left (0)
576+
input[value="#ffffff"] - pointermove
577+
input[value="#ffffff"] - mousemove: Left (0)
578+
input[value="#ffffff"] - pointerdown
579+
input[value="#ffffff"] - mousedown: Left (0)
580+
input[value="#ffffff"] - focus
581+
input[value="#ffffff"] - focusin
582+
input[value="#ffffff"] - pointerup
583+
input[value="#ffffff"] - mouseup: Left (0)
584+
input[value="#ffffff"] - click: Left (0)
585+
input[value="#ffffff"] - keydown: Enter (13)
586+
input[value="#ffffff"] - keypress: Enter (13)
587+
input[value="#ffffff"] - click: Left (0)
588+
input[value="#ffffff"] - keyup: Enter (13)
589+
`)
590+
})
591+
592+
test('{space} on an input type="color"', () => {
593+
const {element, getEventSnapshot} = setup(
594+
`<input value="#ffffff" type="color" />`,
595+
)
596+
597+
userEvent.type(element, '{space}')
598+
599+
expect(getEventSnapshot()).toMatchInlineSnapshot(`
600+
Events fired on: input[value="#ffffff"]
601+
602+
input[value="#ffffff"] - pointerover
603+
input[value="#ffffff"] - pointerenter
604+
input[value="#ffffff"] - mouseover: Left (0)
605+
input[value="#ffffff"] - mouseenter: Left (0)
606+
input[value="#ffffff"] - pointermove
607+
input[value="#ffffff"] - mousemove: Left (0)
608+
input[value="#ffffff"] - pointerdown
609+
input[value="#ffffff"] - mousedown: Left (0)
610+
input[value="#ffffff"] - focus
611+
input[value="#ffffff"] - focusin
612+
input[value="#ffffff"] - pointerup
613+
input[value="#ffffff"] - mouseup: Left (0)
614+
input[value="#ffffff"] - click: Left (0)
615+
input[value="#ffffff"] - keydown: (32)
616+
input[value="#ffffff"] - keypress: (32)
617+
input[value="#ffffff"] - keyup: (32)
618+
input[value="#ffffff"] - click: Left (0)
619+
`)
620+
})
621+
622+
test('" " on an input type="color"', () => {
623+
const {element, getEventSnapshot} = setup(
624+
`<input value="#ffffff" type="color" />`,
625+
)
626+
627+
userEvent.type(element, ' ')
628+
629+
expect(getEventSnapshot()).toMatchInlineSnapshot(`
630+
Events fired on: input[value="#ffffff"]
631+
632+
input[value="#ffffff"] - pointerover
633+
input[value="#ffffff"] - pointerenter
634+
input[value="#ffffff"] - mouseover: Left (0)
635+
input[value="#ffffff"] - mouseenter: Left (0)
636+
input[value="#ffffff"] - pointermove
637+
input[value="#ffffff"] - mousemove: Left (0)
638+
input[value="#ffffff"] - pointerdown
639+
input[value="#ffffff"] - mousedown: Left (0)
640+
input[value="#ffffff"] - focus
641+
input[value="#ffffff"] - focusin
642+
input[value="#ffffff"] - pointerup
643+
input[value="#ffffff"] - mouseup: Left (0)
644+
input[value="#ffffff"] - click: Left (0)
645+
input[value="#ffffff"] - keydown: (32)
646+
input[value="#ffffff"] - keypress: (32)
647+
input[value="#ffffff"] - keyup: (32)
648+
input[value="#ffffff"] - click: Left (0)
649+
`)
650+
})
651+
446652
test('{enter} on a textarea', () => {
447653
const {element, getEventSnapshot} = setup('<textarea></textarea>')
448654

src/__tests__/type.js

+45
Original file line numberDiff line numberDiff line change
@@ -715,3 +715,48 @@ test('should give error if we are trying to call type on an invalid element', as
715715
`"the current element is of type BODY and doesn't have a valid value"`,
716716
)
717717
})
718+
719+
test('typing on button should not alter its value', () => {
720+
const {element} = setup('<button value="foo" />')
721+
userEvent.type(element, 'bar')
722+
expect(element).toHaveValue('foo')
723+
})
724+
725+
test('typing on input type button should not alter its value', () => {
726+
const {element} = setup('<input type="button" value="foo" />')
727+
userEvent.type(element, 'bar')
728+
expect(element).toHaveValue('foo')
729+
})
730+
731+
test('typing on input type color should not alter its value', () => {
732+
const {element} = setup('<input type="color" value="#ffffff" />')
733+
userEvent.type(element, 'bar')
734+
expect(element).toHaveValue('#ffffff')
735+
})
736+
737+
test('typing on input type image should not alter its value', () => {
738+
const {element} = setup('<input type="image" value="foo" />')
739+
userEvent.type(element, 'bar')
740+
expect(element).toHaveValue('foo')
741+
})
742+
743+
test('typing on input type reset should not alter its value', () => {
744+
const {element} = setup('<input type="reset" value="foo" />')
745+
userEvent.type(element, 'bar')
746+
expect(element).toHaveValue('foo')
747+
})
748+
749+
test('typing on input type submit should not alter its value', () => {
750+
const {element} = setup('<input type="submit" value="foo" />')
751+
userEvent.type(element, 'bar')
752+
expect(element).toHaveValue('foo')
753+
})
754+
755+
test('typing on input type file should not trigger input event', () => {
756+
const inputHandler = jest.fn()
757+
const {element} = setup('<input type="file" />', {
758+
eventHandlers: {input: inputHandler},
759+
})
760+
userEvent.type(element, 'bar')
761+
expect(inputHandler).toHaveBeenCalledTimes(0)
762+
})

src/blur.js

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
1-
import {fireEvent} from '@testing-library/dom'
21
import {getActiveElement, isFocusable, eventWrapper} from './utils'
32

4-
function blur(element, init) {
3+
function blur(element) {
54
if (!isFocusable(element)) return
65

76
const wasActive = getActiveElement(element.ownerDocument) === element
87
if (!wasActive) return
98

109
eventWrapper(() => element.blur())
11-
fireEvent.focusOut(element, init)
1210
}
1311

1412
export {blur}

src/focus.js

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
1-
import {fireEvent} from '@testing-library/dom'
21
import {getActiveElement, isFocusable, eventWrapper} from './utils'
32

4-
function focus(element, init) {
3+
function focus(element) {
54
if (!isFocusable(element)) return
65

76
const isAlreadyActive = getActiveElement(element.ownerDocument) === element
87
if (isAlreadyActive) return
98

109
eventWrapper(() => element.focus())
11-
fireEvent.focusIn(element, init)
1210
}
1311

1412
export {focus}

0 commit comments

Comments
 (0)