diff --git a/README.md b/README.md index 3e9796a..b310d27 100644 --- a/README.md +++ b/README.md @@ -850,8 +850,11 @@ of all cases covered: unchecked. - if there's more than one checkbox with the same `name` attribute, they are all treated collectively as a single form control, which returns the value - as an **array** containing all the values of the selected checkboxes in the + as an **array** containing all the values of the checkboxes in the collection. + - a hidden input with same name before the checkbox is allowed which is a + common workaround to allow browsers to send `false` for unchecked + checkboxes. - `` elements are all grouped by the `name` attribute, and such a group treated as a single form control. This form control returns the value as a **string** corresponding to the `value` attribute of the selected diff --git a/src/__tests__/to-have-form-values.js b/src/__tests__/to-have-form-values.js index fa206a1..2bdc958 100644 --- a/src/__tests__/to-have-form-values.js +++ b/src/__tests__/to-have-form-values.js @@ -192,13 +192,15 @@ describe('.toHaveFormValues', () => { it('allows a checkbox and a hidden input which is a common workaround so forms can send "false" for a checkbox', () => { const {container} = render(`
- - + +
`) const form = container.querySelector('form') expect(() => { - expect(form).toHaveFormValues({ "sample-checkbox": 1}) + expect(form).toHaveFormValues({ + 'checkbox-with-hidden-false': ['0', '1'], + }) }).not.toThrowError() }) diff --git a/src/to-have-form-values.js b/src/to-have-form-values.js index cd479d6..5bcc82d 100644 --- a/src/to-have-form-values.js +++ b/src/to-have-form-values.js @@ -11,9 +11,18 @@ import { function getMultiElementValue(elements) { const types = [...new Set(elements.map(element => element.type))] if (types.length !== 1) { - throw new Error( - 'Multiple form elements with the same name must be of the same type', - ) + if ( + types.length === 2 && + types[0] === 'hidden' && + types[1] === 'checkbox' + ) { + // Allow the special case where there's a 'checkbox' input, and a matching 'hidden' input + // before it, which works around browser forms so a 'false' value is submitted. + } else { + throw new Error( + 'Multiple form elements with the same name must be of the same type', + ) + } } switch (types[0]) { case 'radio': {