Skip to content

Commit 480fe24

Browse files
nickservben-dyer
andauthored
fix(userEvent): don't select option if select is disabled (#641)
* Exit early from selectOption if select is disabled * fix(userEvent): Port test to dom-testing-library * fix(userEvent): Exit early if options are disabled Co-authored-by: Ben Dyer <dyer.ben@protonmail.com>
1 parent d46f52a commit 480fe24

File tree

3 files changed

+56
-18
lines changed

3 files changed

+56
-18
lines changed

src/user-event/__tests__/helpers/utils.js

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,21 @@ function setup(ui, {eventHandlers} = {}) {
2424
return {element, ...addListeners(element, {eventHandlers})}
2525
}
2626

27-
function setupSelect({multiple = false} = {}) {
27+
function setupSelect({
28+
disabled = false,
29+
disabledOptions = false,
30+
multiple = false,
31+
} = {}) {
2832
const form = document.createElement('form')
2933
form.innerHTML = `
30-
<select name="select" ${multiple ? 'multiple' : ''}>
31-
<option value="1">1</option>
32-
<option value="2">2</option>
33-
<option value="3">3</option>
34+
<select
35+
name="select"
36+
${disabled ? 'disabled' : ''}
37+
${multiple ? 'multiple' : ''}
38+
>
39+
<option value="1" ${disabledOptions ? 'disabled' : ''}>1</option>
40+
<option value="2" ${disabledOptions ? 'disabled' : ''}>2</option>
41+
<option value="3" ${disabledOptions ? 'disabled' : ''}>3</option>
3442
</select>
3543
`
3644
document.body.append(form)

src/user-event/__tests__/select-options.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,3 +107,29 @@ test('throws an error if multiple are passed but not a multiple select', async (
107107
const error = await userEvent.selectOptions(select, ['2', '3']).catch(e => e)
108108
expect(error.message).toMatch(/cannot select multiple/i)
109109
})
110+
111+
test('does not select anything if select is disabled', async () => {
112+
const {select, options, getEventSnapshot} = setupSelect({disabled: true})
113+
await userEvent.selectOptions(select, '2')
114+
expect(getEventSnapshot()).toMatchInlineSnapshot(
115+
`No events were fired on: select[name="select"][value="1"]`,
116+
)
117+
const [o1, o2, o3] = options
118+
expect(o1.selected).toBe(true)
119+
expect(o2.selected).toBe(false)
120+
expect(o3.selected).toBe(false)
121+
})
122+
123+
test('does not select anything if options are disabled', async () => {
124+
const {select, options, getEventSnapshot} = setupSelect({
125+
disabledOptions: true,
126+
})
127+
await userEvent.selectOptions(select, '2')
128+
expect(getEventSnapshot()).toMatchInlineSnapshot(
129+
`No events were fired on: select[name="select"][value=""]`,
130+
)
131+
const [o1, o2, o3] = options
132+
expect(o1.selected).toBe(false)
133+
expect(o2.selected).toBe(false)
134+
expect(o3.selected).toBe(false)
135+
})

src/user-event/select-options.js

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,25 @@ async function selectOptionsBase(newValue, select, values, init) {
1414
}
1515
const valArray = Array.isArray(values) ? values : [values]
1616
const allOptions = Array.from(select.querySelectorAll('option'))
17-
const selectedOptions = valArray.map(val => {
18-
if (allOptions.includes(val)) {
19-
return val
20-
} else {
21-
const matchingOption = allOptions.find(o => o.value === val)
22-
if (matchingOption) {
23-
return matchingOption
17+
const selectedOptions = valArray
18+
.map(val => {
19+
if (allOptions.includes(val)) {
20+
return val
2421
} else {
25-
throw getConfig().getElementError(
26-
`Value "${val}" not found in options`,
27-
select,
28-
)
22+
const matchingOption = allOptions.find(o => o.value === val)
23+
if (matchingOption) {
24+
return matchingOption
25+
} else {
26+
throw getConfig().getElementError(
27+
`Value "${val}" not found in options`,
28+
select,
29+
)
30+
}
2931
}
30-
}
31-
})
32+
})
33+
.filter(option => !option.disabled)
34+
35+
if (select.disabled || !selectedOptions.length) return
3236

3337
if (select.multiple) {
3438
for (const option of selectedOptions) {

0 commit comments

Comments
 (0)