transition-group.spec.ts 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. import path from 'node:path'
  2. import {
  3. E2E_TIMEOUT,
  4. setupPuppeteer,
  5. } from '../../../packages/vue/__tests__/e2e/e2eUtils'
  6. import connect from 'connect'
  7. import sirv from 'sirv'
  8. import { expect } from 'vitest'
  9. const { page, html, transitionStart, waitForInnerHTML } = setupPuppeteer()
  10. describe('vapor transition-group', () => {
  11. let server: any
  12. const port = '8196'
  13. beforeAll(() => {
  14. server = connect()
  15. .use(sirv(path.resolve(import.meta.dirname, '../dist')))
  16. .listen(port)
  17. process.on('SIGTERM', () => server && server.close())
  18. })
  19. afterAll(() => {
  20. server.close()
  21. })
  22. beforeEach(async () => {
  23. const baseUrl = `http://localhost:${port}/transition-group/`
  24. await page().goto(baseUrl)
  25. await page().waitForSelector('#app')
  26. })
  27. test(
  28. 'enter',
  29. async () => {
  30. const btnSelector = '.enter > button'
  31. const containerSelector = '.enter > div'
  32. expect(await html(containerSelector)).toBe(
  33. `<div class="test">a</div>` +
  34. `<div class="test">b</div>` +
  35. `<div class="test">c</div>`,
  36. )
  37. expect(
  38. (await transitionStart(btnSelector, containerSelector)).innerHTML,
  39. ).toBe(
  40. `<div class="test">a</div>` +
  41. `<div class="test">b</div>` +
  42. `<div class="test">c</div>` +
  43. `<div class="test test-enter-from test-enter-active">d</div>` +
  44. `<div class="test test-enter-from test-enter-active">e</div>`,
  45. )
  46. await waitForInnerHTML(
  47. containerSelector,
  48. `<div class="test">a</div>` +
  49. `<div class="test">b</div>` +
  50. `<div class="test">c</div>` +
  51. `<div class="test test-enter-active test-enter-to">d</div>` +
  52. `<div class="test test-enter-active test-enter-to">e</div>`,
  53. )
  54. await waitForInnerHTML(
  55. containerSelector,
  56. `<div class="test">a</div>` +
  57. `<div class="test">b</div>` +
  58. `<div class="test">c</div>` +
  59. `<div class="test">d</div>` +
  60. `<div class="test">e</div>`,
  61. )
  62. },
  63. E2E_TIMEOUT,
  64. )
  65. test(
  66. 'leave',
  67. async () => {
  68. const btnSelector = '.leave > button'
  69. const containerSelector = '.leave > div'
  70. expect(await html(containerSelector)).toBe(
  71. `<div class="test">a</div>` +
  72. `<div class="test">b</div>` +
  73. `<div class="test">c</div>`,
  74. )
  75. expect(
  76. (await transitionStart(btnSelector, containerSelector)).innerHTML,
  77. ).toBe(
  78. `<div class="test test-leave-from test-leave-active">a</div>` +
  79. `<div class="test">b</div>` +
  80. `<div class="test test-leave-from test-leave-active">c</div>`,
  81. )
  82. await waitForInnerHTML(
  83. containerSelector,
  84. `<div class="test test-leave-active test-leave-to">a</div>` +
  85. `<div class="test">b</div>` +
  86. `<div class="test test-leave-active test-leave-to">c</div>`,
  87. )
  88. await waitForInnerHTML(containerSelector, `<div class="test">b</div>`)
  89. },
  90. E2E_TIMEOUT,
  91. )
  92. test(
  93. 'enter + leave',
  94. async () => {
  95. const btnSelector = '.enter-leave > button'
  96. const containerSelector = '.enter-leave > div'
  97. expect(await html(containerSelector)).toBe(
  98. `<div class="test">a</div>` +
  99. `<div class="test">b</div>` +
  100. `<div class="test">c</div>`,
  101. )
  102. expect(
  103. (await transitionStart(btnSelector, containerSelector)).innerHTML,
  104. ).toBe(
  105. `<div class="test test-leave-from test-leave-active">a</div>` +
  106. `<div class="test">b</div>` +
  107. `<div class="test">c</div>` +
  108. `<div class="test test-enter-from test-enter-active">d</div>`,
  109. )
  110. await waitForInnerHTML(
  111. containerSelector,
  112. `<div class="test test-leave-active test-leave-to">a</div>` +
  113. `<div class="test">b</div>` +
  114. `<div class="test">c</div>` +
  115. `<div class="test test-enter-active test-enter-to">d</div>`,
  116. )
  117. await waitForInnerHTML(
  118. containerSelector,
  119. `<div class="test">b</div>` +
  120. `<div class="test">c</div>` +
  121. `<div class="test">d</div>`,
  122. )
  123. },
  124. E2E_TIMEOUT,
  125. )
  126. test(
  127. 'appear',
  128. async () => {
  129. const btnSelector = '.appear > button'
  130. const containerSelector = '.appear > div'
  131. expect(await html('.appear')).toBe(`<button>appear button</button>`)
  132. await page().evaluate(() => {
  133. return (window as any).setAppear()
  134. })
  135. // appear
  136. expect(await html(containerSelector)).toBe(
  137. `<div class="test test-appear-from test-appear-active">a</div>` +
  138. `<div class="test test-appear-from test-appear-active">b</div>` +
  139. `<div class="test test-appear-from test-appear-active">c</div>`,
  140. )
  141. await waitForInnerHTML(
  142. containerSelector,
  143. `<div class="test test-appear-active test-appear-to">a</div>` +
  144. `<div class="test test-appear-active test-appear-to">b</div>` +
  145. `<div class="test test-appear-active test-appear-to">c</div>`,
  146. )
  147. await waitForInnerHTML(
  148. containerSelector,
  149. `<div class="test">a</div>` +
  150. `<div class="test">b</div>` +
  151. `<div class="test">c</div>`,
  152. )
  153. // enter
  154. expect(
  155. (await transitionStart(btnSelector, containerSelector)).innerHTML,
  156. ).toBe(
  157. `<div class="test">a</div>` +
  158. `<div class="test">b</div>` +
  159. `<div class="test">c</div>` +
  160. `<div class="test test-enter-from test-enter-active">d</div>` +
  161. `<div class="test test-enter-from test-enter-active">e</div>`,
  162. )
  163. await waitForInnerHTML(
  164. containerSelector,
  165. `<div class="test">a</div>` +
  166. `<div class="test">b</div>` +
  167. `<div class="test">c</div>` +
  168. `<div class="test test-enter-active test-enter-to">d</div>` +
  169. `<div class="test test-enter-active test-enter-to">e</div>`,
  170. )
  171. await waitForInnerHTML(
  172. containerSelector,
  173. `<div class="test">a</div>` +
  174. `<div class="test">b</div>` +
  175. `<div class="test">c</div>` +
  176. `<div class="test">d</div>` +
  177. `<div class="test">e</div>`,
  178. )
  179. },
  180. E2E_TIMEOUT,
  181. )
  182. test(
  183. 'move',
  184. async () => {
  185. const btnSelector = '.move > button'
  186. const containerSelector = '.move > div'
  187. expect(await html(containerSelector)).toBe(
  188. `<div class="test">a</div>` +
  189. `<div class="test">b</div>` +
  190. `<div class="test">c</div>`,
  191. )
  192. expect(
  193. (await transitionStart(btnSelector, containerSelector)).innerHTML,
  194. ).toBe(
  195. `<div class="test group-enter-from group-enter-active">d</div>` +
  196. `<div class="test">b</div>` +
  197. `<div class="test group-move" style="">a</div>` +
  198. `<div class="test group-leave-from group-leave-active group-move" style="">c</div>`,
  199. )
  200. await waitForInnerHTML(
  201. containerSelector,
  202. `<div class="test group-enter-active group-enter-to">d</div>` +
  203. `<div class="test">b</div>` +
  204. `<div class="test group-move" style="">a</div>` +
  205. `<div class="test group-leave-active group-move group-leave-to" style="">c</div>`,
  206. )
  207. await waitForInnerHTML(
  208. containerSelector,
  209. `<div class="test">d</div>` +
  210. `<div class="test">b</div>` +
  211. `<div class="test" style="">a</div>`,
  212. )
  213. },
  214. E2E_TIMEOUT,
  215. )
  216. test('dynamic name', async () => {
  217. const btnSelector = '.dynamic-name button.toggleBtn'
  218. const btnChangeName = '.dynamic-name button.changeNameBtn'
  219. const containerSelector = '.dynamic-name > div'
  220. expect(await html(containerSelector)).toBe(
  221. `<div>a</div>` + `<div>b</div>` + `<div>c</div>`,
  222. )
  223. // invalid name
  224. expect(
  225. (await transitionStart(btnSelector, containerSelector)).innerHTML,
  226. ).toBe(`<div>b</div>` + `<div>c</div>` + `<div>a</div>`)
  227. // change name
  228. expect(
  229. (await transitionStart(btnChangeName, containerSelector)).innerHTML,
  230. ).toBe(
  231. `<div class="group-move" style="">a</div>` +
  232. `<div class="group-move" style="">b</div>` +
  233. `<div class="group-move" style="">c</div>`,
  234. )
  235. await waitForInnerHTML(
  236. containerSelector,
  237. `<div class="" style="">a</div>` +
  238. `<div class="" style="">b</div>` +
  239. `<div class="" style="">c</div>`,
  240. )
  241. })
  242. test('events', async () => {
  243. const btnSelector = '.events > button'
  244. const containerSelector = '.events > div'
  245. expect(await html('.events')).toBe(`<button>events button</button>`)
  246. await page().evaluate(() => {
  247. return (window as any).setAppear()
  248. })
  249. // appear
  250. expect(await html(containerSelector)).toBe(
  251. `<div class="test test-appear-from test-appear-active">a</div>` +
  252. `<div class="test test-appear-from test-appear-active">b</div>` +
  253. `<div class="test test-appear-from test-appear-active">c</div>`,
  254. )
  255. await waitForInnerHTML(
  256. containerSelector,
  257. `<div class="test test-appear-active test-appear-to">a</div>` +
  258. `<div class="test test-appear-active test-appear-to">b</div>` +
  259. `<div class="test test-appear-active test-appear-to">c</div>`,
  260. )
  261. let calls = await page().evaluate(() => {
  262. return (window as any).getCalls()
  263. })
  264. expect(calls).toContain('beforeAppear')
  265. expect(calls).toContain('onAppear')
  266. expect(calls).not.toContain('afterAppear')
  267. await waitForInnerHTML(
  268. containerSelector,
  269. `<div class="test">a</div>` +
  270. `<div class="test">b</div>` +
  271. `<div class="test">c</div>`,
  272. )
  273. expect(
  274. await page().evaluate(() => {
  275. return (window as any).getCalls()
  276. }),
  277. ).toContain('afterAppear')
  278. // enter + leave
  279. expect(
  280. (await transitionStart(btnSelector, containerSelector)).innerHTML,
  281. ).toBe(
  282. `<div class="test test-leave-from test-leave-active">a</div>` +
  283. `<div class="test">b</div>` +
  284. `<div class="test">c</div>` +
  285. `<div class="test test-enter-from test-enter-active">d</div>`,
  286. )
  287. calls = await page().evaluate(() => {
  288. return (window as any).getCalls()
  289. })
  290. expect(calls).toContain('beforeLeave')
  291. expect(calls).toContain('onLeave')
  292. expect(calls).not.toContain('afterLeave')
  293. expect(calls).toContain('beforeEnter')
  294. expect(calls).toContain('onEnter')
  295. expect(calls).not.toContain('afterEnter')
  296. await waitForInnerHTML(
  297. containerSelector,
  298. `<div class="test test-leave-active test-leave-to">a</div>` +
  299. `<div class="test">b</div>` +
  300. `<div class="test">c</div>` +
  301. `<div class="test test-enter-active test-enter-to">d</div>`,
  302. )
  303. calls = await page().evaluate(() => {
  304. return (window as any).getCalls()
  305. })
  306. expect(calls).not.toContain('afterLeave')
  307. expect(calls).not.toContain('afterEnter')
  308. await waitForInnerHTML(
  309. containerSelector,
  310. `<div class="test">b</div>` +
  311. `<div class="test">c</div>` +
  312. `<div class="test">d</div>`,
  313. )
  314. calls = await page().evaluate(() => {
  315. return (window as any).getCalls()
  316. })
  317. expect(calls).toContain('afterLeave')
  318. expect(calls).toContain('afterEnter')
  319. })
  320. test(
  321. 'reusable transition group',
  322. async () => {
  323. const btnSelector = '.reusable-transition-group > button'
  324. const containerSelector = '.reusable-transition-group > div'
  325. expect(await html(containerSelector)).toBe(
  326. `<div class="test">a</div>` +
  327. `<div class="test">b</div>` +
  328. `<div class="test">c</div>`,
  329. )
  330. expect(
  331. (await transitionStart(btnSelector, containerSelector)).innerHTML,
  332. ).toBe(
  333. `<div class="test group-enter-from group-enter-active">d</div>` +
  334. `<div class="test">b</div>` +
  335. `<div class="test group-move" style="">a</div>` +
  336. `<div class="test group-leave-from group-leave-active group-move" style="">c</div>`,
  337. )
  338. await waitForInnerHTML(
  339. containerSelector,
  340. `<div class="test group-enter-active group-enter-to">d</div>` +
  341. `<div class="test">b</div>` +
  342. `<div class="test group-move" style="">a</div>` +
  343. `<div class="test group-leave-active group-move group-leave-to" style="">c</div>`,
  344. )
  345. await waitForInnerHTML(
  346. containerSelector,
  347. `<div class="test">d</div>` +
  348. `<div class="test">b</div>` +
  349. `<div class="test" style="">a</div>`,
  350. )
  351. },
  352. E2E_TIMEOUT,
  353. )
  354. test('interop: render vdom component', async () => {
  355. const btnSelector = '.interop > button'
  356. const containerSelector = '.interop > div'
  357. expect(await html(containerSelector)).toBe(
  358. `<div><div>a</div></div>` +
  359. `<div><div>b</div></div>` +
  360. `<div><div>c</div></div>`,
  361. )
  362. expect(
  363. (await transitionStart(btnSelector, containerSelector)).innerHTML,
  364. ).toBe(
  365. `<div class="test-leave-from test-leave-active"><div>a</div></div>` +
  366. `<div class="test-move" style=""><div>b</div></div>` +
  367. `<div class="test-move" style=""><div>c</div></div>` +
  368. `<div class="test-enter-from test-enter-active"><div>d</div></div>`,
  369. )
  370. await waitForInnerHTML(
  371. containerSelector,
  372. `<div class="test-leave-active test-leave-to"><div>a</div></div>` +
  373. `<div class="test-move" style=""><div>b</div></div>` +
  374. `<div class="test-move" style=""><div>c</div></div>` +
  375. `<div class="test-enter-active test-enter-to"><div>d</div></div>`,
  376. )
  377. await waitForInnerHTML(
  378. containerSelector,
  379. `<div class="" style=""><div>b</div></div>` +
  380. `<div class="" style=""><div>c</div></div>` +
  381. `<div class=""><div>d</div></div>`,
  382. )
  383. })
  384. })