loading.test.tsx 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. import { nextTick, ref } from 'vue'
  2. import { mount } from '@vue/test-utils'
  3. import { afterEach, describe, expect, test, vi } from 'vitest'
  4. import { Loading } from '../src/service'
  5. import { vLoading } from '../src/directive'
  6. import ElInput from '../../input'
  7. import type { VNode } from 'vue'
  8. import type { LoadingInstance } from '../src/loading'
  9. function destroyLoadingInstance(loadingInstance: LoadingInstance) {
  10. if (!loadingInstance) return
  11. loadingInstance.close()
  12. loadingInstance.$el &&
  13. loadingInstance.$el.parentNode &&
  14. loadingInstance.$el.parentNode.removeChild(loadingInstance.$el)
  15. }
  16. const _mount = (render?: () => VNode | null) => {
  17. return mount(render, {
  18. global: {
  19. directives: { loading: vLoading },
  20. },
  21. })
  22. }
  23. describe('Loading', () => {
  24. let loadingInstance: LoadingInstance, loadingInstance2: LoadingInstance
  25. afterEach(() => {
  26. destroyLoadingInstance(loadingInstance)
  27. destroyLoadingInstance(loadingInstance2)
  28. })
  29. test('create directive', async () => {
  30. const loading = ref(true)
  31. const wrapper = _mount(() => <div v-loading={loading.value} />)
  32. await nextTick()
  33. const maskWrapper = wrapper.find('.el-loading-mask')
  34. expect(maskWrapper.exists()).toBeTruthy()
  35. vi.useFakeTimers()
  36. loading.value = false
  37. // Trigger update event for dispatching close event.
  38. await nextTick()
  39. vi.runAllTimers()
  40. vi.useRealTimers()
  41. await nextTick()
  42. expect(wrapper.find('.el-loading-mask').exists()).toBeFalsy()
  43. })
  44. test('unmounted directive', async () => {
  45. const loading1 = ref(true)
  46. const show1 = ref(true)
  47. const loading2 = ref(true)
  48. const show2 = ref(true)
  49. _mount(() => (show1.value ? <div v-loading={loading1.value} /> : null))
  50. _mount(() => (show2.value ? <div v-loading={loading2.value} /> : null))
  51. await nextTick()
  52. loading1.value = false
  53. loading2.value = false
  54. await nextTick()
  55. show1.value = false
  56. show2.value = false
  57. await nextTick()
  58. expect(document.querySelector('.el-loading-mask')).toBeFalsy()
  59. })
  60. test('body directive', async () => {
  61. const loading = ref(true)
  62. const wrapper = _mount(() => <div v-loading_body={loading.value} />)
  63. await nextTick()
  64. const mask = document.querySelector('.el-loading-mask')!
  65. expect(mask.parentNode === document.body).toBeTruthy()
  66. wrapper.vm.loading = false
  67. document.body.removeChild(mask)
  68. })
  69. test('fullscreen directive', async () => {
  70. const loading = ref(true)
  71. _mount(() => <div v-loading_fullscreen={loading.value} />)
  72. await nextTick()
  73. const mask = document.querySelector('.el-loading-mask')!
  74. expect(mask.parentNode === document.body).toBeTruthy()
  75. expect(mask.classList.contains('is-fullscreen')).toBeTruthy()
  76. loading.value = false
  77. document.body.removeChild(mask)
  78. })
  79. test('lock directive', async () => {
  80. const loading = ref(true)
  81. _mount(() => <div v-loading_fullscreen_lock={loading.value} />)
  82. await nextTick()
  83. expect(
  84. document.body.classList.contains('el-loading-parent--hidden')
  85. ).toBeTruthy()
  86. loading.value = false
  87. document.body.removeChild(document.querySelector('.el-loading-mask')!)
  88. })
  89. test('text directive', async () => {
  90. const loading = ref(true)
  91. const wrapper = _mount(() => (
  92. <div v-loading={loading.value} element-loading-text="loading..." />
  93. ))
  94. await nextTick()
  95. expect(wrapper.find('.el-loading-text').text()).toEqual('loading...')
  96. })
  97. test('customClass directive', async () => {
  98. const loading = ref(true)
  99. const wrapper = _mount(() => (
  100. <div
  101. v-loading={loading.value}
  102. element-loading-custom-class="loading-custom-class"
  103. />
  104. ))
  105. await nextTick()
  106. expect(wrapper.find('.loading-custom-class').exists()).toBeTruthy()
  107. })
  108. test('customSvg directive', async () => {
  109. const loading = ref(true)
  110. const svg = '<path class="custom-path" d="M 30 15"/>'
  111. const wrapper = _mount(() => (
  112. <div v-loading={loading.value} element-loading-svg={svg} />
  113. ))
  114. await nextTick()
  115. expect(wrapper.find('.custom-path').attributes().d).toEqual('M 30 15')
  116. })
  117. test('create service', async () => {
  118. loadingInstance = Loading()
  119. expect(document.querySelector('.el-loading-mask')).toBeTruthy()
  120. })
  121. test('close service', async () => {
  122. loadingInstance = Loading()
  123. loadingInstance.close()
  124. expect(loadingInstance.visible.value).toBeFalsy()
  125. })
  126. test('target service', async () => {
  127. const container = document.createElement('div')
  128. container.className = 'loading-container'
  129. document.body.appendChild(container)
  130. loadingInstance = Loading({ target: '.loading-container' })
  131. const mask = container.querySelector('.el-loading-mask')!
  132. expect(mask).toBeTruthy()
  133. expect(mask.parentNode).toEqual(container)
  134. expect(
  135. container.classList.contains('el-loading-parent--relative')
  136. ).toBeTruthy()
  137. vi.useFakeTimers()
  138. loadingInstance.close()
  139. vi.runAllTimers()
  140. vi.useRealTimers()
  141. await nextTick()
  142. expect(
  143. container.classList.contains('el-loading-parent--relative')
  144. ).toBeFalsy()
  145. })
  146. test('body service', async () => {
  147. const container = document.createElement('div')
  148. container.className = 'loading-container'
  149. document.body.appendChild(container)
  150. loadingInstance = Loading({ target: '.loading-container', body: true })
  151. const mask = document.querySelector('.el-loading-mask')!
  152. expect(mask).toBeTruthy()
  153. expect(mask.parentNode).toEqual(document.body)
  154. })
  155. test('fullscreen service', async () => {
  156. loadingInstance = Loading({ fullscreen: true })
  157. const mask = document.querySelector('.el-loading-mask')!
  158. expect(mask.parentNode).toEqual(document.body)
  159. expect(mask.classList.contains('is-fullscreen')).toBeTruthy()
  160. })
  161. test('fullscreen singleton service', async () => {
  162. vi.useFakeTimers()
  163. loadingInstance = Loading({ fullscreen: true })
  164. vi.runAllTimers()
  165. await nextTick()
  166. loadingInstance2 = Loading({ fullscreen: true })
  167. vi.runAllTimers()
  168. await nextTick()
  169. let masks = document.querySelectorAll('.el-loading-mask')
  170. expect(loadingInstance).toEqual(loadingInstance2)
  171. expect(masks.length).toEqual(1)
  172. loadingInstance2.close()
  173. vi.runAllTimers()
  174. vi.useRealTimers()
  175. await nextTick()
  176. masks = document.querySelectorAll('.el-loading-mask')
  177. expect(masks.length).toEqual(0)
  178. })
  179. test('lock service', async () => {
  180. loadingInstance = Loading({ lock: true })
  181. expect(
  182. document.body.classList.contains('el-loading-parent--hidden')
  183. ).toBeTruthy()
  184. })
  185. test('text service', async () => {
  186. loadingInstance = Loading({ text: 'Loading...' })
  187. const text = document.querySelector('.el-loading-text')!
  188. expect(text).toBeTruthy()
  189. expect(text.textContent).toEqual('Loading...')
  190. })
  191. test('customClass service', async () => {
  192. loadingInstance = Loading({ customClass: 'el-loading-custom-class' })
  193. const customClass = document.querySelector('.el-loading-custom-class')
  194. expect(customClass).toBeTruthy()
  195. })
  196. test("parent's display is not block", async () => {
  197. const loading = ref(true)
  198. const wrapper = _mount(() => (
  199. <ElInput
  200. v-loading={loading.value}
  201. v-slots={{
  202. append: () => 'Loading Text',
  203. }}
  204. />
  205. ))
  206. await nextTick()
  207. await nextTick()
  208. const maskDisplay = getComputedStyle(
  209. wrapper.find('.el-loading-mask').element
  210. ).display
  211. expect(maskDisplay).toBe('block')
  212. })
  213. })