(`.el-select-dropdown__option-item.is-disabled`)
expect(options.length).toBe(2)
expect(options.item(1).textContent).toBe(vm.options[2].label)
options.item(1).click()
await nextTick
expect(vm.value).toBe('')
expect(placeholder.text()).toBe(DEFAULT_PLACEHOLDER)
})
it('disabled select', async () => {
const wrapper = createSelect({
data: () => {
return {
disabled: true,
}
},
})
await nextTick
expect(wrapper.find(`.${WRAPPER_CLASS_NAME}`).classes()).toContain('is-disabled')
})
it('visible event', async () => {
const wrapper = createSelect({
data: () => {
return {
visible: false,
}
},
methods: {
onVisibleChange(visible) {
this.visible = visible
},
},
})
await nextTick
const vm = wrapper.vm as any
await wrapper.trigger('click')
expect(vm.visible).toBeTruthy()
})
it('clearable', async () => {
const wrapper = createSelect({
data: () => ({ clearable: true }),
})
const vm = wrapper.vm as any
vm.value = vm.options[1].value
await nextTick
await clickClearButton(wrapper)
expect(vm.value).toBe('')
const placeholder = wrapper.find(`.${PLACEHOLDER_CLASS_NAME}`)
expect(placeholder.text()).toBe(DEFAULT_PLACEHOLDER)
})
describe('multiple', () => {
it('multiple select', async () => {
const wrapper = createSelect({
data: () => {
return {
multiple: true,
value: [],
}
},
})
await nextTick
const vm = wrapper.vm as any
const options = getOptions()
options[1].click()
await nextTick
expect(vm.value.length).toBe(1)
expect(vm.value[0]).toBe(vm.options[1].value)
options[3].click()
await nextTick
expect(vm.value.length).toBe(2)
expect(vm.value[1]).toBe(vm.options[3].value)
const tagIcon = wrapper.find('.el-tag__close')
await tagIcon.trigger('click')
expect(vm.value.length).toBe(1)
})
it('remove-tag', async () => {
const wrapper = createSelect({
data() {
return {
removeTag: '',
multiple: true,
}
},
methods: {
onRemoveTag(tag) {
this.removeTag = tag
},
},
})
await nextTick
const vm = wrapper.vm as any
const options = getOptions()
options[0].click()
await nextTick()
options[1].click()
await nextTick()
options[2].click()
await nextTick()
expect(vm.value.length).toBe(3)
const tagCloseIcons = wrapper.findAll('.el-tag__close')
await tagCloseIcons[1].trigger('click')
expect(vm.value.length).toBe(2)
await tagCloseIcons[0].trigger('click')
expect(vm.value.length).toBe(1)
})
it('limit', async () => {
const wrapper = createSelect({
data() {
return {
multiple: true,
multipleLimit: 2,
value: [],
}
},
})
await nextTick
const vm = wrapper.vm as any
const options = getOptions()
options[1].click()
await nextTick
options[2].click()
await nextTick
expect(vm.value.length).toBe(2)
options[3].click()
await nextTick
expect(vm.value.length).toBe(2)
})
})
describe('event', () => {
it('focus & blur', async () => {
const onFocus = jest.fn()
const onBlur = jest.fn()
const wrapper = createSelect({
methods: {
onFocus,
onBlur,
},
})
const input = wrapper.find('input')
const select = wrapper.findComponent(Select)
await input.trigger('focus')
const selectVm = select.vm as any
// Simulate focus state to trigger menu multiple times
selectVm.toggleMenu()
await nextTick
selectVm.toggleMenu()
await nextTick
// Simulate click the outside
selectVm.handleClickOutside()
await nextTick
expect(onFocus).toHaveBeenCalledTimes(1)
expect(onBlur).toHaveBeenCalled()
})
it('focus & blur for multiple & filterable select', async () => {
const onFocus = jest.fn()
const onBlur = jest.fn()
const wrapper = createSelect({
data() {
return {
multiple: true,
filterable: true,
value: [],
}
},
methods: {
onFocus,
onBlur,
},
})
const input = wrapper.find('input')
const select = wrapper.findComponent(Select)
await input.trigger('focus')
const selectVm = select.vm as any
// Simulate focus state to trigger menu multiple times
selectVm.toggleMenu()
await nextTick
selectVm.toggleMenu()
await nextTick
// Select multiple items in multiple mode without triggering focus
const options = getOptions()
options[1].click()
await nextTick
options[2].click()
await nextTick
expect(onFocus).toHaveBeenCalledTimes(1)
// Simulate click the outside
selectVm.handleClickOutside()
await nextTick
await nextTick
expect(onBlur).toHaveBeenCalled()
})
it('only emit change on user input', async () => {
const handleChanged = jest.fn()
const wrapper = createSelect({
methods: {
onChange: handleChanged,
},
})
await nextTick
const vm = wrapper.vm as any
vm.value = 'option_2'
await nextTick
expect(handleChanged).toHaveBeenCalledTimes(0)
const options = getOptions()
options[4].click()
await nextTick
expect(handleChanged).toHaveBeenCalled()
})
})
describe('allow-create', () => {
it('single select', async() => {
const wrapper = createSelect({
data: () => {
return {
allowCreate: true,
filterable: true,
clearable: true,
options: [
{
value: '1',
label: 'option 1',
},
{
value: '2',
label: 'option 2',
},
{
value: '3',
label: 'option 3',
},
],
}
},
})
await nextTick
const vm = wrapper.vm as any
const input = wrapper.find('input')
await wrapper.trigger('click')
// create a new option
await input.trigger('compositionupdate', {
data: '1111',
})
const options = getOptions()
const select = wrapper.findComponent(Select)
const selectVm = select.vm as any
expect(selectVm.filteredOptions.length).toBe(1)
// selected the new option
await options[0].click()
expect(vm.value).toBe('1111')
// closed the menu
await wrapper.trigger('click')
expect(selectVm.filteredOptions.length).toBe(4)
selectVm.handleClear()
expect(selectVm.filteredOptions.length).toBe(3)
})
it('multiple', async () => {
const wrapper = createSelect({
data: () => {
return {
allowCreate: true,
filterable: true,
clearable: true,
multiple: true,
options: [
{
value: '1',
label: 'option 1',
},
{
value: '2',
label: 'option 2',
},
{
value: '3',
label: 'option 3',
},
],
}
},
})
await nextTick
const vm = wrapper.vm as any
await wrapper.trigger('click')
await wrapper.find('input').trigger('compositionupdate', {
data: '1111',
})
const options = getOptions()
const select = wrapper.findComponent(Select)
const selectVm = select.vm as any
expect(selectVm.filteredOptions.length).toBe(1)
// selected the new option
await options[0].click()
// closed the menu
await wrapper.trigger('click')
await wrapper.find('input').trigger('compositionupdate', {
data: '2222',
})
await getOptions()[0].click()
expect(JSON.stringify(vm.value)).toBe(JSON.stringify(['1111', '2222']))
await wrapper.trigger('click')
expect(selectVm.filteredOptions.length).toBe(5)
// remove tag
const tagCloseIcons = wrapper.findAll('.el-tag__close')
await tagCloseIcons[1].trigger('click')
expect(selectVm.filteredOptions.length).toBe(4)
// simulate backspace
await wrapper.find('input').trigger('keydown', {
key: EVENT_CODE.backspace,
})
expect(selectVm.filteredOptions.length).toBe(3)
})
})
it('render empty slot', async () => {
const wrapper = createSelect({
data () {
return {
options: [],
popperAppendToBody: false,
}
},
slots: {
empty: 'EmptySlot
',
},
})
await nextTick
expect(wrapper.find('.empty-slot').exists()).toBeTruthy()
})
it('should set placeholder to label of selected option when filterable is true and multiple is false', async () => {
const wrapper = createSelect({
data () {
return {
options: [
{
value: '1',
label: 'option 1',
},
{
value: '2',
label: 'option 2',
},
{
value: '3',
label: 'option 3',
},
],
filterable: true,
multiple: false,
}
},
})
await nextTick
const vm = wrapper.vm as any
const placeholder = wrapper.find(`.${PLACEHOLDER_CLASS_NAME}`)
vm.value = '2'
await nextTick
const select = wrapper.findComponent(Select)
const selectVm = select.vm as any
selectVm.toggleMenu()
const input = wrapper.find('input')
await input.trigger('focus')
expect(placeholder.text()).toBe('option 2')
})
it('default value is null or undefined', async () => {
const wrapper = createSelect({
data() {
return {
value: null,
}
},
})
await nextTick
const vm = wrapper.vm as any
const placeholder = wrapper.find(`.${PLACEHOLDER_CLASS_NAME}`)
expect(placeholder.text()).toBe(DEFAULT_PLACEHOLDER)
vm.value = undefined
await nextTick
expect(placeholder.text()).toBe(DEFAULT_PLACEHOLDER)
})
it('emptyText error show', async () => {
const wrapper = createSelect({
data () {
return {
value: `${Math.random()}`,
}
},
})
await nextTick
const vm = wrapper.vm as any
const placeholder = wrapper.find(`.${PLACEHOLDER_CLASS_NAME}`)
expect(placeholder.text()).toBe(vm.value)
})
it('customized option renderer', async () => {
const wrapper = createSelect({
data () {
return {
popperAppendToBody: false,
}
},
slots: {
default: `
{{ item.label }}
{{ item.value }}
`,
},
})
await nextTick
expect(wrapper.findAll('.custom-renderer').length).toBeGreaterThan(0)
})
it('tag of disabled option is not closable', async () => {
const wrapper = createSelect({
data () {
return {
multiple: true,
options: [
{
value: 1,
lable: 'option 1',
disabled: true,
},
{
value: 2,
lable: 'option 2',
disabled: true,
},
{
value: 3,
lable: 'option 3',
},
],
value: [2, 3],
}
},
})
await nextTick
expect(wrapper.findAll('.el-tag').length).toBe(2)
const tagCloseIcons = wrapper.findAll('.el-tag__close')
expect(tagCloseIcons.length).toBe(1)
await tagCloseIcons[0].trigger('click')
expect(wrapper.findAll('.el-tag__close').length).toBe(0)
expect(wrapper.findAll('.el-tag').length).toBe(1)
})
it('modelValue should be deep reactive in multiple mode', async () => {
const wrapper = createSelect({
data () {
return {
multiple: true,
value: ['option_1', 'option_2', 'option_3'],
}
},
})
await nextTick
expect(wrapper.findAll('.el-tag').length).toBe(3)
const vm = wrapper.vm as any
vm.value.splice(0, 1)
await nextTick
expect(wrapper.findAll('.el-tag').length).toBe(2)
})
it('should reset placeholder after clear when both multiple and filterable are true', async () => {
const wrapper = createSelect({
data () {
return {
value: ['option_1'],
clearable: true,
filterable: true,
multiple: true,
}
},
})
await nextTick
expect(wrapper.find(`.${PLACEHOLDER_CLASS_NAME}`).exists()).toBeFalsy()
// When all tags are removed, the placeholder should be displayed
const tagCloseIcon = wrapper.find('.el-tag__close')
await tagCloseIcon.trigger('click')
expect(wrapper.find(`.${PLACEHOLDER_CLASS_NAME}`).text()).toBe(DEFAULT_PLACEHOLDER)
// The placeholder should disappear after it is selected again
const options = getOptions()
options[0].click()
await nextTick
expect(wrapper.find(`.${PLACEHOLDER_CLASS_NAME}`).exists()).toBeFalsy()
// Simulate keyboard events
const selectInput = wrapper.find('input')
selectInput.trigger('keydown', {
key: EVENT_CODE.backspace,
})
await nextTick
expect(wrapper.find(`.${PLACEHOLDER_CLASS_NAME}`).text()).toBe(DEFAULT_PLACEHOLDER)
})
})