123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652 |
- import { nextTick, ref } from 'vue'
- import { mount } from '@vue/test-utils'
- import { describe, expect, test } from 'vitest'
- import { ElFormItem } from '@element-plus/components/form'
- import Checkbox from '../src/checkbox.vue'
- import CheckboxButton from '../src/checkbox-button.vue'
- import CheckboxGroup from '../src/checkbox-group.vue'
- import type { CheckboxValueType } from '../src/checkbox'
- describe('Checkbox', () => {
- test('create', async () => {
- const checked = ref(false)
- const wrapper = mount(() => <Checkbox v-model={checked.value} label="a" />)
- expect(wrapper.classes()).toContain('el-checkbox')
- expect(wrapper.classes()).not.toContain('is-disabled')
- await wrapper.trigger('click')
- expect(wrapper.classes()).toContain('is-checked')
- await wrapper.trigger('click')
- expect(wrapper.classes('is-checked')).toBe(false)
- })
- describe('no v-model', () => {
- test('checkbox without label', async () => {
- const checked = ref(false)
- const wrapper = mount(() => <Checkbox checked={checked.value} />)
- expect(wrapper.classes('is-checked')).toBe(false)
- })
- test('checkbox with label attribute', async () => {
- const checked = ref(false)
- const wrapper = mount(() => (
- <Checkbox checked={checked.value} label="a" />
- ))
- expect(wrapper.classes('is-checked')).toBe(false)
- })
- })
- describe('disabled', () => {
- test('checkbox without label', async () => {
- const checked = ref(false)
- const wrapper = mount(() => (
- <ElFormItem label="test">
- <Checkbox v-model={checked.value} disabled />
- </ElFormItem>
- ))
- const checkbox = wrapper.findComponent(Checkbox)
- expect(checkbox.classes()).toContain('is-disabled')
- expect(checked.value).toBe(false)
- await checkbox.trigger('click')
- await nextTick()
- expect(checkbox.classes()).toContain('is-disabled')
- expect(checked.value).toBe(false)
- })
- test('checkbox with label attribute', async () => {
- const checked = ref(false)
- const wrapper = mount(() => (
- <Checkbox v-model={checked.value} disabled label="a" />
- ))
- expect(wrapper.classes()).toContain('is-disabled')
- expect(checked.value).toBe(false)
- await wrapper.trigger('click')
- await nextTick()
- expect(wrapper.classes()).toContain('is-disabled')
- expect(checked.value).toBe(false)
- })
- })
- describe('change event', () => {
- test('checkbox without label', async () => {
- const checked = ref(false)
- const data = ref()
- const onChange = (val: CheckboxValueType) => (data.value = val)
- const wrapper = mount(() => (
- <ElFormItem label="test">
- <Checkbox v-model={checked.value} onChange={onChange} />
- </ElFormItem>
- ))
- await wrapper.findComponent(Checkbox).trigger('click')
- expect(data.value).toBe(true)
- })
- test('checkbox with label attribute', async () => {
- const checked = ref(false)
- const data = ref()
- const onChange = (val: CheckboxValueType) => (data.value = val)
- const wrapper = mount(() => (
- <Checkbox v-model={checked.value} onChange={onChange} label="Foobar" />
- ))
- await wrapper.trigger('click')
- expect(data.value).toBe(true)
- })
- test('checkbox with label as slot content', async () => {
- const checked = ref(false)
- const data = ref()
- const onChange = (val: CheckboxValueType) => (data.value = val)
- const wrapper = mount(() => (
- <Checkbox v-model={checked.value} onChange={onChange}>
- Foobar
- </Checkbox>
- ))
- await wrapper.trigger('click')
- expect(data.value).toBe(true)
- })
- test('checkbox is wrapped in label', async () => {
- const checked = ref(true)
- const data = ref()
- const onChange = (val: CheckboxValueType) => (data.value = val)
- const wrapper = mount(() => (
- <ElFormItem label="test">
- <label>
- <Checkbox v-model={checked.value} onChange={onChange} />
- </label>
- </ElFormItem>
- ))
- await wrapper.findComponent(Checkbox).trigger('click')
- expect(data.value).toBe(false)
- })
- })
- test('checkbox group', async () => {
- const checkList = ref([])
- const wrapper = mount({
- setup() {
- return () => (
- <CheckboxGroup v-model={checkList.value}>
- <Checkbox label="a" ref="a" />
- <Checkbox label="b" ref="b" />
- <Checkbox label="c" ref="c" />
- <Checkbox label="d" ref="d" />
- </CheckboxGroup>
- )
- },
- })
- expect(checkList.value.length).toBe(0)
- await wrapper.findComponent({ ref: 'a' }).trigger('click')
- expect(checkList.value.length).toBe(1)
- expect(checkList.value).toContain('a')
- await wrapper.findComponent({ ref: 'b' }).trigger('click')
- expect(checkList.value.length).toBe(2)
- expect(checkList.value).toContain('a')
- expect(checkList.value).toContain('b')
- })
- test('checkbox group without modelValue', async () => {
- const checkList = ref([])
- const wrapper = mount({
- setup() {
- return () => (
- <CheckboxGroup v-model={checkList.value}>
- <Checkbox label="a" ref="a" />
- <Checkbox label="b" ref="b" />
- <Checkbox label="c" ref="c" />
- <Checkbox label="d" ref="d" />
- </CheckboxGroup>
- )
- },
- })
- await wrapper.findComponent({ ref: 'a' }).trigger('click')
- expect(checkList.value.length).toBe(1)
- expect(checkList.value).toContain('a')
- })
- test('checkbox group change', async () => {
- const checkList = ref([])
- const data = ref<CheckboxValueType[]>([])
- const onChange = (val: CheckboxValueType[]) => (data.value = val)
- const wrapper = mount({
- setup() {
- return () => (
- <CheckboxGroup v-model={checkList.value} onChange={onChange}>
- <Checkbox label="a" ref="a" />
- <Checkbox label="b" ref="b" />
- </CheckboxGroup>
- )
- },
- })
- await wrapper.findComponent({ ref: 'a' }).trigger('click')
- await nextTick()
- expect(data.value.length).toBe(1)
- expect(data.value).toEqual(['a'])
- })
- test('nested group', async () => {
- const checkList = ref([])
- const wrapper = mount({
- setup() {
- return () => (
- <CheckboxGroup v-model={checkList.value}>
- <Checkbox label="a" ref="a" />
- <Checkbox label="b" ref="b" />
- <Checkbox label="c" ref="c" />
- <Checkbox label="d" ref="d" />
- </CheckboxGroup>
- )
- },
- })
- expect(checkList.value.length).toBe(0)
- await wrapper.findComponent({ ref: 'a' }).trigger('click')
- expect(checkList.value).toEqual(['a'])
- })
- describe('true false label', () => {
- test('without label', async () => {
- const checked = ref('a')
- const wrapper = mount(() => (
- <ElFormItem label="test">
- <Checkbox true-label="a" false-label={3} v-model={checked.value} />
- </ElFormItem>
- ))
- const checkbox = wrapper.findComponent(Checkbox)
- await checkbox.trigger('click')
- await nextTick()
- expect(checked.value).toBe(3)
- await checkbox.trigger('click')
- await nextTick()
- expect(checked.value).toBe('a')
- })
- test('with label attribute', async () => {
- const checked = ref('a')
- const wrapper = mount(() => (
- <Checkbox
- label="Foobar"
- true-label="a"
- false-label={3}
- v-model={checked.value}
- />
- ))
- await wrapper.trigger('click')
- await nextTick()
- expect(checked.value).toBe(3)
- await wrapper.trigger('click')
- await nextTick()
- expect(checked.value).toBe('a')
- })
- test('with label as slot content', async () => {
- const checked = ref('a')
- const wrapper = mount(() => (
- <Checkbox true-label="a" false-label={3} v-model={checked.value}>
- Foobar
- </Checkbox>
- ))
- await wrapper.trigger('click')
- await nextTick()
- expect(checked.value).toBe(3)
- await wrapper.trigger('click')
- await nextTick()
- expect(checked.value).toBe('a')
- })
- })
- test('check', () => {
- const checked = ref(false)
- const checklist = ref([])
- mount(() => (
- <div>
- <Checkbox v-model={checked.value} checked />
- <CheckboxGroup v-model={checklist.value}>
- <Checkbox checked label="a" />
- </CheckboxGroup>
- </div>
- ))
- expect(checked.value).toBe(true)
- expect(checklist.value).toEqual(['a'])
- })
- test('label', async () => {
- const checklist = ref([])
- const wrapper = mount(() => (
- <CheckboxGroup v-model={checklist.value}>
- <Checkbox label="">all</Checkbox>
- <Checkbox label="a">a</Checkbox>
- <Checkbox label="b">b</Checkbox>
- </CheckboxGroup>
- ))
- const checkbox = wrapper.find('.el-checkbox')
- await checkbox.trigger('click')
- expect(checklist.value[0]).toEqual('')
- })
- test('label is object', async () => {
- const checklist = ref([])
- const wrapper = mount(() => (
- <CheckboxGroup v-model={checklist.value}>
- <Checkbox label={{ a: 1 }}>all</Checkbox>
- <Checkbox label={{ a: 2 }}>a</Checkbox>
- <Checkbox label={{ b: 1 }}>b</Checkbox>
- </CheckboxGroup>
- ))
- const checkbox = wrapper.find('.el-checkbox')
- await checkbox.trigger('click')
- expect(checklist.value[0]).toEqual({ a: 1 })
- expect(checkbox.classes()).contains('is-checked')
- })
- test('label is object with initial values', async () => {
- const checklist = ref([{ a: 1 }])
- const wrapper = mount({
- setup() {
- return () => (
- <CheckboxGroup v-model={checklist.value}>
- <Checkbox label={{ a: 1 }} ref="a1">
- a1
- </Checkbox>
- <Checkbox label={{ a: 2 }} ref="a2">
- a2
- </Checkbox>
- <Checkbox label={{ b: 1 }} ref="b1">
- b1
- </Checkbox>
- </CheckboxGroup>
- )
- },
- })
- expect(checklist.value.length).toBe(1)
- const checkboxA1 = wrapper.findComponent({ ref: 'a1' })
- const checkboxA2 = wrapper.findComponent({ ref: 'a2' })
- await checkboxA2.trigger('click')
- expect(checklist.value).toEqual([{ a: 1 }, { a: 2 }])
- expect(checkboxA1.classes()).contains('is-checked')
- expect(checkboxA2.classes()).contains('is-checked')
- await checkboxA1.trigger('click')
- expect(checklist.value).toEqual([{ a: 2 }])
- expect(checkboxA1.classes()).not.contains('is-checked')
- })
- })
- describe('check-button', () => {
- test('create', async () => {
- const checked = ref(false)
- const wrapper = mount(() => (
- <CheckboxButton v-model={checked.value} label="a" />
- ))
- expect(wrapper.classes()).toContain('el-checkbox-button')
- await wrapper.trigger('click')
- expect(wrapper.classes()).toContain('is-checked')
- await wrapper.trigger('click')
- expect(wrapper.classes('is-checked')).toBe(false)
- })
- test('disabled', async () => {
- const checked = ref(false)
- const wrapper = mount(() => (
- <CheckboxButton v-model={checked.value} disabled label="a" />
- ))
- expect(wrapper.classes()).toContain('is-disabled')
- await wrapper.trigger('click')
- expect(wrapper.classes()).toContain('is-disabled')
- })
- test('change event', async () => {
- const checked = ref(false)
- const data = ref()
- const onChange = (val: CheckboxValueType) => (data.value = val)
- const wrapper = mount(() => (
- <CheckboxButton v-model={checked.value} onChange={onChange} />
- ))
- await wrapper.trigger('click')
- expect(data.value).toBe(true)
- })
- test('button group change', async () => {
- const checkList = ref([])
- const data = ref<CheckboxValueType[]>([])
- const onChange = (val: CheckboxValueType[]) => (data.value = val)
- const wrapper = mount({
- setup() {
- return () => (
- <CheckboxGroup v-model={checkList.value} onChange={onChange}>
- <CheckboxButton label="a" ref="a" />
- <CheckboxButton label="b" ref="b" />
- <CheckboxButton label="c" ref="c" />
- <CheckboxButton label="d" ref="d" />
- </CheckboxGroup>
- )
- },
- })
- await wrapper.findComponent({ ref: 'a' }).trigger('click')
- expect(data.value).toEqual(['a'])
- await wrapper.findComponent({ ref: 'b' }).trigger('click')
- expect(data.value).toEqual(['a', 'b'])
- })
- test('button group props', () => {
- const checkList = ref(['a', 'b'])
- const wrapper = mount({
- setup() {
- return () => (
- <CheckboxGroup
- v-model={checkList.value}
- size="large"
- fill="#ff0000"
- text-color="#000"
- >
- <CheckboxButton label="a" ref="a" />
- <CheckboxButton label="b" ref="b" />
- <CheckboxButton label="c" ref="c" />
- <CheckboxButton label="d" ref="d" />
- </CheckboxGroup>
- )
- },
- })
- const checkbox = wrapper.findComponent({ ref: 'a' })
- expect(checkList.value.length).toBe(2)
- expect(checkbox.classes()).contains('is-checked')
- expect(
- checkbox.find('.el-checkbox-button__inner').attributes('style')
- ).contains('border-color: #ff0000;')
- })
- test('button group tag', () => {
- const checkList = ref(['a', 'b'])
- const wrapper = mount(() => (
- <CheckboxGroup v-model={checkList.value} tag="tr">
- <CheckboxButton label="a" ref="a" />
- <CheckboxButton label="b" ref="b" />
- <CheckboxButton label="c" ref="c" />
- <CheckboxButton label="d" ref="d" />
- </CheckboxGroup>
- ))
- expect(wrapper.find('tr').classes('el-checkbox-group')).toBeTruthy()
- })
- test('button group min and max', async () => {
- const checkList = ref(['a', 'b'])
- const wrapper = mount({
- setup() {
- return () => (
- <CheckboxGroup v-model={checkList.value} min={2} max={3}>
- <CheckboxButton label="a" ref="a" />
- <CheckboxButton label="b" ref="b" />
- <CheckboxButton label="c" ref="c" />
- <CheckboxButton label="d" ref="d" />
- <CheckboxButton label="e" ref="e" />
- </CheckboxGroup>
- )
- },
- })
- expect(checkList.value.length).toBe(2)
- await wrapper.findComponent({ ref: 'a' }).trigger('click')
- expect(checkList.value.length).toBe(2)
- await wrapper.findComponent({ ref: 'c' }).trigger('click')
- expect(checkList.value.length).toBe(3)
- expect(checkList.value).toEqual(['a', 'b', 'c'])
- expect(wrapper.findComponent({ ref: 'd' }).vm.isDisabled).toBe(true)
- expect(wrapper.findComponent({ ref: 'e' }).vm.isDisabled).toBe(true)
- checkList.value = []
- await nextTick()
- await wrapper.findComponent({ ref: 'a' }).trigger('click')
- await wrapper.findComponent({ ref: 'd' }).trigger('click')
- expect(checkList.value).toEqual(['a', 'd'])
- await wrapper.findComponent({ ref: 'a' }).trigger('click')
- expect(checkList.value).toEqual(['a', 'd'])
- expect(wrapper.findComponent({ ref: 'a' }).vm.isDisabled).toBe(true)
- })
- test('nested group', async () => {
- const checkList = ref([])
- const wrapper = mount({
- setup() {
- return () => (
- <CheckboxGroup v-model={checkList.value}>
- <CheckboxButton label="a" ref="a" />
- <CheckboxButton label="b" ref="b" />
- <CheckboxButton label="c" ref="c" />
- <CheckboxButton label="d" ref="d" />
- </CheckboxGroup>
- )
- },
- })
- expect(checkList.value.length).toBe(0)
- await wrapper.findComponent({ ref: 'a' }).trigger('click')
- expect(checkList.value).toEqual(['a'])
- })
- describe('checked prop', () => {
- test('check', () => {
- const checked = ref(false)
- const checklist = ref([])
- mount(() => (
- <div>
- <Checkbox v-model={checked.value} checked />
- <CheckboxGroup v-model={checklist.value}>
- <CheckboxButton checked label="a" />
- </CheckboxGroup>
- </div>
- ))
- expect(checked.value).toBe(true)
- expect(checklist.value).toEqual(['a'])
- })
- test('checked', () => {
- const wrapper = mount(() => <Checkbox checked />)
- expect(wrapper.find('.el-checkbox').classes()).contains('is-checked')
- })
- })
- describe('form item accessibility integration', () => {
- test('checkbox, no label, automatic label attachment', async () => {
- const wrapper = mount(() => (
- <ElFormItem label="test">
- <Checkbox />
- </ElFormItem>
- ))
- const formItem = await wrapper.findComponent(ElFormItem)
- const checkbox = await wrapper.findComponent(Checkbox)
- const formItemLabel = formItem.find('.el-form-item__label')
- const checkboxInput = checkbox.find('.el-checkbox__original')
- expect(checkboxInput.attributes('id')).toBe(
- formItemLabel.attributes('for')
- )
- })
- test('checkbox with label, form item is group', async () => {
- const wrapper = mount(() => (
- <ElFormItem label="test">
- <Checkbox label="Foo" />
- </ElFormItem>
- ))
- const formItem = await wrapper.findComponent(ElFormItem)
- const checkbox = await wrapper.findComponent(Checkbox)
- const checkboxLabel = checkbox.find('.el-checkbox__label')
- const checkboxInput = checkbox.find('.el-checkbox__original')
- expect(checkboxLabel.element.textContent).toBe('Foo')
- expect(checkboxInput.attributes('id')).toBeFalsy()
- expect(formItem.attributes('role')).toBe('group')
- })
- test('single checkbox group in form item', async () => {
- const wrapper = mount(() => (
- <ElFormItem label="test">
- <CheckboxGroup>
- <Checkbox label="Foo" />
- <Checkbox label="Bar" />
- </CheckboxGroup>
- </ElFormItem>
- ))
- const formItem = await wrapper.findComponent(ElFormItem)
- const checkboxGroup = await wrapper.findComponent(CheckboxGroup)
- const formItemLabel = formItem.find('.el-form-item__label')
- expect(formItem.attributes('role')).toBeFalsy()
- expect(checkboxGroup.attributes('role')).toBe('group')
- expect(formItemLabel.attributes('for')).toBe(
- checkboxGroup.attributes('id')
- )
- expect(formItemLabel.attributes('id')).toBe(
- checkboxGroup.attributes('aria-labelledby')
- )
- })
- test('single checkbox group in form item, override label', async () => {
- const wrapper = mount(() => (
- <ElFormItem label="test">
- <CheckboxGroup label="Foo">
- <Checkbox label="Foo" />
- <Checkbox label="Bar" />
- </CheckboxGroup>
- </ElFormItem>
- ))
- const formItem = await wrapper.findComponent(ElFormItem)
- const checkboxGroup = await wrapper.findComponent(CheckboxGroup)
- const formItemLabel = formItem.find('.el-form-item__label')
- expect(formItemLabel.attributes('for')).toBe(
- checkboxGroup.attributes('id')
- )
- expect(checkboxGroup.attributes('role')).toBe('group')
- expect(checkboxGroup.attributes()['aria-label']).toBe('Foo')
- expect(checkboxGroup.attributes()['aria-labelledby']).toBeFalsy()
- })
- test('multiple checkbox groups in form item', async () => {
- const wrapper = mount({
- setup() {
- return () => (
- <ElFormItem label="test">
- <CheckboxGroup label="Foo" ref="checkboxGroup1">
- <Checkbox label="Foo" />
- <Checkbox label="Bar" />
- </CheckboxGroup>
- <CheckboxGroup label="Bar" ref="checkboxGroup2">
- <Checkbox label="Foo" />
- <Checkbox label="Bar" />
- </CheckboxGroup>
- </ElFormItem>
- )
- },
- })
- const formItem = await wrapper.findComponent(ElFormItem)
- const checkboxGroup1 = await wrapper.findComponent({
- ref: 'checkboxGroup1',
- })
- const checkboxGroup2 = await wrapper.findComponent({
- ref: 'checkboxGroup2',
- })
- const formItemLabel = formItem.find('.el-form-item__label')
- expect(formItem.attributes('role')).toBe('group')
- expect(formItem.attributes()['aria-labelledby']).toBe(
- formItemLabel.attributes('id')
- )
- expect(checkboxGroup1.attributes('role')).toBe('group')
- expect(checkboxGroup1.attributes()['aria-label']).toBe('Foo')
- expect(checkboxGroup1.attributes()['aria-labelledby']).toBeFalsy()
- expect(checkboxGroup2.attributes('role')).toBe('group')
- expect(checkboxGroup2.attributes()['aria-label']).toBe('Bar')
- expect(checkboxGroup2.attributes()['aria-labelledby']).toBeFalsy()
- })
- })
- })
|