time-select.test.tsx 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. import { nextTick, ref } from 'vue'
  2. import { mount } from '@vue/test-utils'
  3. import { afterEach, describe, expect, it } from 'vitest'
  4. import dayjs from 'dayjs'
  5. import customParseFormat from 'dayjs/plugin/customParseFormat.js'
  6. import Select from '@element-plus/components/select'
  7. import { ElFormItem } from '@element-plus/components/form'
  8. import TimeSelect from '../src/time-select.vue'
  9. dayjs.extend(customParseFormat)
  10. const { Option } = Select
  11. afterEach(() => {
  12. document.documentElement.innerHTML = ''
  13. })
  14. describe('TimeSelect', () => {
  15. it('create', async () => {
  16. const wrapper = mount(() => (
  17. <TimeSelect style={{ color: 'red' }} class="customClass" />
  18. ))
  19. const outerInput = wrapper.find('.el-select')
  20. expect(outerInput.classes()).toContain('customClass')
  21. expect(outerInput.attributes().style).toBeDefined()
  22. })
  23. it('set default value', async () => {
  24. const value = ref('14:30')
  25. const wrapper = mount(() => <TimeSelect v-model={value.value} />)
  26. const input = wrapper.find('input')
  27. input.trigger('blur')
  28. input.trigger('focus')
  29. await nextTick()
  30. expect(document.querySelector('.selected')).toBeDefined()
  31. expect(document.querySelector('.selected')?.textContent).toBe('14:30')
  32. })
  33. it('set minTime', async () => {
  34. const wrapper = mount(() => <TimeSelect minTime="14:30" />)
  35. const input = wrapper.find('input')
  36. input.trigger('blur')
  37. input.trigger('focus')
  38. await nextTick()
  39. const elms = document.querySelectorAll('.is-disabled')
  40. const elm = elms[elms.length - 1]
  41. expect(elm.textContent).toBe('14:30')
  42. })
  43. it('set maxTime', async () => {
  44. const wrapper = mount(() => <TimeSelect maxTime="14:30" />)
  45. const input = wrapper.find('input')
  46. input.trigger('blur')
  47. input.trigger('focus')
  48. await nextTick()
  49. const elm = document.querySelector('.is-disabled')
  50. expect(elm?.textContent).toBe('14:30')
  51. })
  52. it('set value update', async () => {
  53. const value = ref('10:00')
  54. const wrapper = mount(() => <TimeSelect v-model={value.value} />)
  55. await nextTick()
  56. const input = wrapper.find('input')
  57. expect(input.exists()).toBe(true)
  58. expect(input.element.value).toBe('10:00')
  59. value.value = '10:30'
  60. await nextTick()
  61. expect(wrapper.findComponent({ name: 'ElTimeSelect' }).vm.value).toBe(
  62. '10:30'
  63. )
  64. expect(input.element.value).toBe('10:30')
  65. })
  66. it('update value', async () => {
  67. const value = ref('10:00')
  68. const wrapper = mount(() => <TimeSelect v-model={value.value} />)
  69. await nextTick()
  70. const vm = wrapper.findComponent({ name: 'ElTimeSelect' }).vm
  71. const input = wrapper.find('input')
  72. expect(vm.value).toBe('10:00')
  73. expect(input.element.value).toBe('10:00')
  74. const option = wrapper
  75. .findAllComponents(Option)
  76. .find((w) => w.text().trim() === '11:00')
  77. expect(option?.exists()).toBe(true)
  78. option?.trigger('click')
  79. await nextTick()
  80. expect(vm.value).toBe('11:00')
  81. expect(input.element.value).toBe('11:00')
  82. })
  83. it('set disabled', async () => {
  84. const value = ref('10:00')
  85. const disabled = ref(false)
  86. const wrapper = mount(() => (
  87. <TimeSelect v-model={value.value} disabled={disabled.value} />
  88. ))
  89. const select = wrapper.findComponent({ name: 'ElSelect' })
  90. expect(select.props().disabled).toBe(false)
  91. disabled.value = true
  92. await nextTick()
  93. expect(select.props().disabled).toBe(true)
  94. })
  95. it('set editable', async () => {
  96. const value = ref('10:00')
  97. const editable = ref(false)
  98. const wrapper = mount(() => (
  99. <TimeSelect v-model={value.value} editable={editable.value} />
  100. ))
  101. const select = wrapper.findComponent({ name: 'ElSelect' })
  102. expect(select.props().filterable).toBe(false)
  103. editable.value = true
  104. await nextTick()
  105. expect(select.props().filterable).toBe(true)
  106. })
  107. it('ref focus', async () => {
  108. const wrapper = mount(() => <TimeSelect />, {
  109. attachTo: document.body,
  110. })
  111. wrapper.findComponent(TimeSelect).vm.$.exposed!.focus()
  112. await nextTick()
  113. await nextTick()
  114. const popperEl = document.querySelector('.el-select__popper')
  115. const attr = popperEl?.getAttribute('aria-hidden')
  116. expect(attr).toEqual('false')
  117. })
  118. it('ref blur', async () => {
  119. const wrapper = mount(() => <TimeSelect />, {
  120. attachTo: document.body,
  121. })
  122. wrapper.findComponent(TimeSelect).vm.$.exposed!.focus()
  123. await nextTick()
  124. wrapper.findComponent(TimeSelect).vm.$.exposed!.blur()
  125. await nextTick()
  126. await nextTick()
  127. const popperEl = document.querySelector('.el-select__popper')
  128. const attr = popperEl?.getAttribute('aria-hidden')
  129. expect(attr).toEqual('true')
  130. })
  131. it('set format', async () => {
  132. const value = ref('')
  133. const wrapper = mount(() => (
  134. <TimeSelect
  135. v-model={value.value}
  136. start="13:00"
  137. step="00:30"
  138. end="13:30"
  139. format="hh:mm A"
  140. />
  141. ))
  142. const input = wrapper.find('.el-input__inner')
  143. await input.trigger('click')
  144. await nextTick()
  145. const option = document.querySelector('.el-select-dropdown__item')
  146. expect(option?.textContent).toBe('01:00 PM')
  147. })
  148. describe('form item accessibility integration', () => {
  149. it('automatic id attachment', async () => {
  150. const wrapper = mount(() => (
  151. <ElFormItem label="Foobar" data-test-ref="item">
  152. <TimeSelect />
  153. </ElFormItem>
  154. ))
  155. await nextTick()
  156. const formItem = wrapper.find('[data-test-ref="item"]')
  157. const formItemLabel = formItem.find('.el-form-item__label')
  158. const timeSelectInput = wrapper.find('.el-input__inner')
  159. expect(formItem.attributes().role).toBeFalsy()
  160. expect(formItemLabel.attributes().for).toBe(
  161. timeSelectInput.attributes().id
  162. )
  163. })
  164. it('specified id attachment', async () => {
  165. const wrapper = mount(() => (
  166. <ElFormItem label="Foobar" data-test-ref="item">
  167. <TimeSelect id="foobar" />
  168. </ElFormItem>
  169. ))
  170. await nextTick()
  171. const formItem = wrapper.find('[data-test-ref="item"]')
  172. const formItemLabel = formItem.find('.el-form-item__label')
  173. const timeSelectInput = wrapper.find('.el-input__inner')
  174. expect(formItem.attributes().role).toBeFalsy()
  175. expect(timeSelectInput.attributes().id).toBe('foobar')
  176. expect(formItemLabel.attributes().for).toBe(
  177. timeSelectInput.attributes().id
  178. )
  179. })
  180. it('form item role is group when multiple inputs', async () => {
  181. const wrapper = mount(() => (
  182. <ElFormItem label="Foobar" data-test-ref="item">
  183. <TimeSelect />
  184. <TimeSelect />
  185. </ElFormItem>
  186. ))
  187. await nextTick()
  188. const formItem = wrapper.find('[data-test-ref="item"]')
  189. expect(formItem.attributes().role).toBe('group')
  190. })
  191. })
  192. })