carousel.test.tsx 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. import { nextTick, reactive } from 'vue'
  2. import { mount } from '@vue/test-utils'
  3. import { afterEach, describe, expect, it } from 'vitest'
  4. import Carousel from '../src/carousel.vue'
  5. import CarouselItem from '../src/carousel-item.vue'
  6. import type { VueWrapper } from '@vue/test-utils'
  7. import type { CarouselInstance } from '../src/instance'
  8. const wait = (ms = 100) =>
  9. new Promise((resolve) => setTimeout(() => resolve(0), ms))
  10. const generateCarouselItems = (count = 3, hasLabel = false) => {
  11. const list = Array.from({ length: count }, (_, index) => index + 1)
  12. return list.map((i) =>
  13. hasLabel ? <CarouselItem key={i} label={i} /> : <CarouselItem key={i} />
  14. )
  15. }
  16. describe('Carousel', () => {
  17. let wrapper: VueWrapper<any>
  18. const createComponent = (
  19. props: any = {},
  20. count?: number,
  21. hasLabel?: boolean
  22. ) => {
  23. return mount({
  24. setup() {
  25. return () => (
  26. <div>
  27. <Carousel {...props}>
  28. {generateCarouselItems(count, hasLabel)}
  29. </Carousel>
  30. </div>
  31. )
  32. },
  33. })
  34. }
  35. afterEach(() => {
  36. wrapper.unmount()
  37. })
  38. it('create', () => {
  39. wrapper = createComponent({
  40. ref: 'carousel',
  41. })
  42. const carousel = wrapper.findComponent({ ref: 'carousel' })
  43. .vm as CarouselInstance
  44. expect(carousel.direction).toBe('horizontal')
  45. expect(wrapper.findAll('.el-carousel__item').length).toEqual(3)
  46. })
  47. it('auto play', async () => {
  48. wrapper = createComponent({
  49. interval: 50,
  50. })
  51. await nextTick()
  52. await wait(10)
  53. const items = wrapper.vm.$el.querySelectorAll('.el-carousel__item')
  54. expect(items[0].classList.contains('is-active')).toBeTruthy()
  55. await wait(60)
  56. expect(items[1].classList.contains('is-active')).toBeTruthy()
  57. })
  58. it('initial index', async () => {
  59. wrapper = createComponent({
  60. autoplay: false,
  61. 'initial-index': 1,
  62. })
  63. await nextTick()
  64. await wait(10)
  65. expect(
  66. wrapper.vm.$el
  67. .querySelectorAll('.el-carousel__item')[1]
  68. .classList.contains('is-active')
  69. ).toBeTruthy()
  70. })
  71. it('reset timer', async () => {
  72. wrapper = createComponent({
  73. interval: 500,
  74. })
  75. await nextTick()
  76. const items = wrapper.vm.$el.querySelectorAll('.el-carousel__item')
  77. await wrapper.trigger('mouseenter')
  78. await nextTick()
  79. expect(items[0].classList.contains('is-active')).toBeTruthy()
  80. await wrapper.trigger('mouseleave')
  81. await nextTick()
  82. await wait(700)
  83. expect(items[1].classList.contains('is-active')).toBeTruthy()
  84. })
  85. it('change', async () => {
  86. const state = reactive({
  87. val: -1,
  88. oldVal: -1,
  89. })
  90. wrapper = createComponent({
  91. onChange(val: number, prevVal: number) {
  92. state.val = val
  93. state.oldVal = prevVal
  94. },
  95. interval: 50,
  96. })
  97. await nextTick()
  98. await wait(50)
  99. expect(state.val).toBe(1)
  100. expect(state.oldVal).toBe(0)
  101. })
  102. it('label', async () => {
  103. wrapper = createComponent(undefined, 3, true)
  104. await nextTick()
  105. expect(wrapper.find('.el-carousel__button span').text()).toBe('1')
  106. })
  107. describe('manual control', () => {
  108. it('hover', async () => {
  109. wrapper = createComponent({
  110. autoplay: false,
  111. })
  112. await nextTick()
  113. await wait()
  114. await wrapper.findAll('.el-carousel__indicator')[1].trigger('mouseenter')
  115. await nextTick()
  116. await wait()
  117. expect(
  118. wrapper.vm.$el
  119. .querySelectorAll('.el-carousel__item')[1]
  120. .classList.contains('is-active')
  121. ).toBeTruthy()
  122. })
  123. })
  124. it('card', async () => {
  125. wrapper = createComponent(
  126. {
  127. autoplay: false,
  128. type: 'card',
  129. },
  130. 7
  131. )
  132. await nextTick()
  133. await wait()
  134. const items = wrapper.vm.$el.querySelectorAll('.el-carousel__item')
  135. expect(items[0].classList.contains('is-active')).toBeTruthy()
  136. expect(items[1].classList.contains('is-in-stage')).toBeTruthy()
  137. expect(items[6].classList.contains('is-in-stage')).toBeTruthy()
  138. await items[1].click()
  139. await wait()
  140. expect(items[1].classList.contains('is-active')).toBeTruthy()
  141. await wrapper.vm.$el.querySelector('.el-carousel__arrow--left').click()
  142. await wait()
  143. expect(items[0].classList.contains('is-active')).toBeTruthy()
  144. await items[6].click()
  145. await wait()
  146. expect(items[6].classList.contains('is-active')).toBeTruthy()
  147. })
  148. it('vertical direction', () => {
  149. wrapper = createComponent({
  150. ref: 'carousel',
  151. autoplay: false,
  152. direction: 'vertical',
  153. height: '100px',
  154. })
  155. const items = wrapper.vm.$el.querySelectorAll('.el-carousel__item')
  156. const carousel = wrapper.findComponent({ ref: 'carousel' })
  157. .vm as CarouselInstance
  158. expect(carousel.direction).toBe('vertical')
  159. expect(items[0].style.transform.includes('translateY')).toBeTruthy()
  160. })
  161. it('pause auto play on hover', async () => {
  162. wrapper = createComponent({
  163. interval: 50,
  164. 'pause-on-hover': false,
  165. })
  166. await nextTick()
  167. await wrapper.find('.el-carousel').trigger('mouseenter')
  168. const items = wrapper.vm.$el.querySelectorAll('.el-carousel__item')
  169. await nextTick()
  170. await wait(60)
  171. expect(items[1].classList.contains('is-active')).toBeTruthy()
  172. })
  173. it('should guarantee order of indicators', async () => {
  174. const data = reactive([1, 2, 3, 4])
  175. wrapper = mount({
  176. setup() {
  177. return () => (
  178. <div>
  179. <Carousel>
  180. {data.map((value) => (
  181. <CarouselItem label={value} key={value}>
  182. {value}
  183. </CarouselItem>
  184. ))}
  185. </Carousel>
  186. </div>
  187. )
  188. },
  189. })
  190. await nextTick()
  191. data.splice(1, 0, 5)
  192. await nextTick()
  193. const indicators = wrapper.findAll('.el-carousel__button')
  194. data.forEach((value, index) => {
  195. expect(indicators[index].element.textContent).toEqual(value.toString())
  196. })
  197. })
  198. })