transition.spec.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565
  1. import Vue from 'vue'
  2. import injectStyles from './inject-styles'
  3. import { isIE9 } from 'web/util/index'
  4. import { nextFrame } from 'web/runtime/modules/transition'
  5. if (!isIE9) {
  6. describe('Transition system', () => {
  7. const duration = injectStyles()
  8. let el
  9. beforeEach(() => {
  10. el = document.createElement('div')
  11. document.body.appendChild(el)
  12. })
  13. it('basic transition', done => {
  14. const vm = new Vue({
  15. template: '<div><div v-if="ok" class="test" transition>foo</div></div>',
  16. data: { ok: true }
  17. }).$mount(el)
  18. // should not apply transition on initial render by default
  19. expect(vm.$el.innerHTML).toBe('<div class="test">foo</div>')
  20. vm.ok = false
  21. waitForUpdate(() => {
  22. expect(vm.$el.children[0].className).toBe('test v-leave v-leave-active')
  23. }).thenWaitFor(nextFrame).then(() => {
  24. expect(vm.$el.children[0].className).toBe('test v-leave-active')
  25. }).thenWaitFor(duration + 10).then(() => {
  26. expect(vm.$el.children.length).toBe(0)
  27. vm.ok = true
  28. }).then(() => {
  29. expect(vm.$el.children[0].className).toBe('test v-enter v-enter-active')
  30. }).thenWaitFor(nextFrame).then(() => {
  31. expect(vm.$el.children[0].className).toBe('test v-enter-active')
  32. }).thenWaitFor(duration + 10).then(() => {
  33. expect(vm.$el.children[0].className).toBe('test')
  34. }).then(done)
  35. })
  36. it('named transition', done => {
  37. const vm = new Vue({
  38. template: '<div><div v-if="ok" class="test" transition="test">foo</div></div>',
  39. data: { ok: true }
  40. }).$mount(el)
  41. // should not apply transition on initial render by default
  42. expect(vm.$el.innerHTML).toBe('<div class="test">foo</div>')
  43. vm.ok = false
  44. waitForUpdate(() => {
  45. expect(vm.$el.children[0].className).toBe('test test-leave test-leave-active')
  46. }).thenWaitFor(nextFrame).then(() => {
  47. expect(vm.$el.children[0].className).toBe('test test-leave-active')
  48. }).thenWaitFor(duration + 10).then(() => {
  49. expect(vm.$el.children.length).toBe(0)
  50. vm.ok = true
  51. }).then(() => {
  52. expect(vm.$el.children[0].className).toBe('test test-enter test-enter-active')
  53. }).thenWaitFor(nextFrame).then(() => {
  54. expect(vm.$el.children[0].className).toBe('test test-enter-active')
  55. }).thenWaitFor(duration + 10).then(() => {
  56. expect(vm.$el.children[0].className).toBe('test')
  57. }).then(done)
  58. })
  59. it('custom transition classes', done => {
  60. const vm = new Vue({
  61. template: '<div><div v-if="ok" class="test" transition="test">foo</div></div>',
  62. data: { ok: true },
  63. transitions: {
  64. test: {
  65. enterClass: 'hello',
  66. enterActiveClass: 'hello-active',
  67. leaveClass: 'bye',
  68. leaveActiveClass: 'byebye active' // testing multi classes
  69. }
  70. }
  71. }).$mount(el)
  72. // should not apply transition on initial render by default
  73. expect(vm.$el.innerHTML).toBe('<div class="test">foo</div>')
  74. vm.ok = false
  75. waitForUpdate(() => {
  76. expect(vm.$el.children[0].className).toBe('test bye byebye active')
  77. }).thenWaitFor(nextFrame).then(() => {
  78. expect(vm.$el.children[0].className).toBe('test byebye active')
  79. }).thenWaitFor(duration + 10).then(() => {
  80. expect(vm.$el.children.length).toBe(0)
  81. vm.ok = true
  82. }).then(() => {
  83. expect(vm.$el.children[0].className).toBe('test hello hello-active')
  84. }).thenWaitFor(nextFrame).then(() => {
  85. expect(vm.$el.children[0].className).toBe('test hello-active')
  86. }).thenWaitFor(duration + 10).then(() => {
  87. expect(vm.$el.children[0].className).toBe('test')
  88. }).then(done)
  89. })
  90. it('dynamic transition', done => {
  91. const vm = new Vue({
  92. template: '<div><div v-if="ok" class="test" :transition="trans">foo</div></div>',
  93. data: {
  94. ok: true,
  95. trans: 'test'
  96. }
  97. }).$mount(el)
  98. // should not apply transition on initial render by default
  99. expect(vm.$el.innerHTML).toBe('<div class="test">foo</div>')
  100. vm.ok = false
  101. waitForUpdate(() => {
  102. expect(vm.$el.children[0].className).toBe('test test-leave test-leave-active')
  103. }).thenWaitFor(nextFrame).then(() => {
  104. expect(vm.$el.children[0].className).toBe('test test-leave-active')
  105. }).thenWaitFor(duration + 10).then(() => {
  106. expect(vm.$el.children.length).toBe(0)
  107. vm.ok = true
  108. vm.trans = 'changed'
  109. }).then(() => {
  110. expect(vm.$el.children[0].className).toBe('test changed-enter changed-enter-active')
  111. }).thenWaitFor(nextFrame).then(() => {
  112. expect(vm.$el.children[0].className).toBe('test changed-enter-active')
  113. }).thenWaitFor(duration + 10).then(() => {
  114. expect(vm.$el.children[0].className).toBe('test')
  115. }).then(done)
  116. })
  117. it('inline transition object', done => {
  118. const enter = jasmine.createSpy('enter')
  119. const leave = jasmine.createSpy('leave')
  120. const vm = new Vue({
  121. template: `<div><div v-if="ok" class="test" :transition="{
  122. name: 'inline',
  123. enterClass: 'hello',
  124. enterActiveClass: 'hello-active',
  125. leaveClass: 'bye',
  126. leaveActiveClass: 'byebye active'
  127. }">foo</div></div>`,
  128. data: { ok: true },
  129. transitions: {
  130. inline: {
  131. enter,
  132. leave
  133. }
  134. }
  135. }).$mount(el)
  136. // should not apply transition on initial render by default
  137. expect(vm.$el.innerHTML).toBe('<div class="test">foo</div>')
  138. vm.ok = false
  139. waitForUpdate(() => {
  140. expect(vm.$el.children[0].className).toBe('test bye byebye active')
  141. expect(leave).toHaveBeenCalled()
  142. }).thenWaitFor(nextFrame).then(() => {
  143. expect(vm.$el.children[0].className).toBe('test byebye active')
  144. }).thenWaitFor(duration + 10).then(() => {
  145. expect(vm.$el.children.length).toBe(0)
  146. vm.ok = true
  147. }).then(() => {
  148. expect(vm.$el.children[0].className).toBe('test hello hello-active')
  149. expect(enter).toHaveBeenCalled()
  150. }).thenWaitFor(nextFrame).then(() => {
  151. expect(vm.$el.children[0].className).toBe('test hello-active')
  152. }).thenWaitFor(duration + 10).then(() => {
  153. expect(vm.$el.children[0].className).toBe('test')
  154. }).then(done)
  155. })
  156. it('transition with JavaScript hooks', done => {
  157. const onLeaveSpy = jasmine.createSpy('leave')
  158. const onEnterSpy = jasmine.createSpy('enter')
  159. const beforeLeaveSpy = jasmine.createSpy('beforeLeave')
  160. const beforeEnterSpy = jasmine.createSpy('beforeEnter')
  161. const afterLeaveSpy = jasmine.createSpy('afterLeave')
  162. const afterEnterSpy = jasmine.createSpy('afterEnter')
  163. const vm = new Vue({
  164. template: '<div><div v-if="ok" class="test" transition="test">foo</div></div>',
  165. data: { ok: true },
  166. transitions: {
  167. test: {
  168. beforeLeave: (el, vm) => {
  169. expect(el).toBe(vm.$el.children[0])
  170. expect(el.className).toBe('test')
  171. beforeLeaveSpy(el, vm)
  172. },
  173. leave: (el, vm) => onLeaveSpy(el, vm),
  174. afterLeave: (el, vm) => afterLeaveSpy(el, vm),
  175. beforeEnter: (el, vm) => {
  176. expect(vm.$el.contains(el)).toBe(false)
  177. expect(el.className).toBe('test')
  178. beforeEnterSpy(el, vm)
  179. },
  180. enter: (el, vm) => onEnterSpy(el, vm),
  181. afterEnter: (el, vm) => afterEnterSpy(el, vm)
  182. }
  183. }
  184. }).$mount(el)
  185. // should not apply transition on initial render by default
  186. expect(vm.$el.innerHTML).toBe('<div class="test">foo</div>')
  187. let _el = vm.$el.children[0]
  188. vm.ok = false
  189. waitForUpdate(() => {
  190. expect(beforeLeaveSpy).toHaveBeenCalledWith(_el, vm)
  191. expect(onLeaveSpy).toHaveBeenCalledWith(_el, vm)
  192. expect(vm.$el.children[0].className).toBe('test test-leave test-leave-active')
  193. }).thenWaitFor(nextFrame).then(() => {
  194. expect(afterLeaveSpy).not.toHaveBeenCalled()
  195. expect(vm.$el.children[0].className).toBe('test test-leave-active')
  196. }).thenWaitFor(duration + 10).then(() => {
  197. expect(afterLeaveSpy).toHaveBeenCalledWith(_el, vm)
  198. expect(vm.$el.children.length).toBe(0)
  199. vm.ok = true
  200. }).then(() => {
  201. _el = vm.$el.children[0]
  202. expect(beforeEnterSpy).toHaveBeenCalledWith(_el, vm)
  203. expect(onEnterSpy).toHaveBeenCalledWith(_el, vm)
  204. expect(vm.$el.children[0].className).toBe('test test-enter test-enter-active')
  205. }).thenWaitFor(nextFrame).then(() => {
  206. expect(afterEnterSpy).not.toHaveBeenCalled()
  207. expect(vm.$el.children[0].className).toBe('test test-enter-active')
  208. }).thenWaitFor(duration + 10).then(() => {
  209. expect(afterEnterSpy).toHaveBeenCalledWith(_el, vm)
  210. expect(vm.$el.children[0].className).toBe('test')
  211. }).then(done)
  212. })
  213. it('explicit user callback in JavaScript hooks', done => {
  214. let next
  215. const vm = new Vue({
  216. template: '<div><div v-if="ok" class="test" transition="test">foo</div></div>',
  217. data: { ok: true },
  218. transitions: {
  219. test: {
  220. enter: (el, vm, cb) => {
  221. next = cb
  222. },
  223. leave: (el, vm, cb) => {
  224. next = cb
  225. }
  226. }
  227. }
  228. }).$mount(el)
  229. vm.ok = false
  230. waitForUpdate(() => {
  231. expect(vm.$el.children[0].className).toBe('test test-leave test-leave-active')
  232. }).thenWaitFor(nextFrame).then(() => {
  233. expect(vm.$el.children[0].className).toBe('test test-leave-active')
  234. }).thenWaitFor(duration + 10).then(() => {
  235. expect(vm.$el.children[0].className).toBe('test test-leave-active')
  236. expect(next).toBeTruthy()
  237. next()
  238. expect(vm.$el.children.length).toBe(0)
  239. }).then(() => {
  240. vm.ok = true
  241. }).then(() => {
  242. expect(vm.$el.children[0].className).toBe('test test-enter test-enter-active')
  243. }).thenWaitFor(nextFrame).then(() => {
  244. expect(vm.$el.children[0].className).toBe('test test-enter-active')
  245. }).thenWaitFor(duration + 10).then(() => {
  246. expect(vm.$el.children[0].className).toBe('test test-enter-active')
  247. expect(next).toBeTruthy()
  248. next()
  249. expect(vm.$el.children[0].className).toBe('test')
  250. }).then(done)
  251. })
  252. it('css: false', done => {
  253. const enterSpy = jasmine.createSpy('enter')
  254. const leaveSpy = jasmine.createSpy('leave')
  255. const vm = new Vue({
  256. template: '<div><div v-if="ok" class="test" transition="test">foo</div></div>',
  257. data: { ok: true },
  258. transitions: {
  259. test: {
  260. css: false,
  261. enter: enterSpy,
  262. leave: leaveSpy
  263. }
  264. }
  265. }).$mount(el)
  266. vm.ok = false
  267. waitForUpdate(() => {
  268. expect(leaveSpy).toHaveBeenCalled()
  269. expect(vm.$el.innerHTML).toBe('')
  270. vm.ok = true
  271. }).then(() => {
  272. expect(enterSpy).toHaveBeenCalled()
  273. expect(vm.$el.innerHTML).toBe('<div class="test">foo</div>')
  274. }).then(done)
  275. })
  276. it('no transition detected', done => {
  277. const enterSpy = jasmine.createSpy('enter')
  278. const leaveSpy = jasmine.createSpy('leave')
  279. const vm = new Vue({
  280. template: '<div><div v-if="ok" transition="nope">foo</div></div>',
  281. data: { ok: true },
  282. transitions: {
  283. nope: {
  284. enter: enterSpy,
  285. leave: leaveSpy
  286. }
  287. }
  288. }).$mount(el)
  289. vm.ok = false
  290. waitForUpdate(() => {
  291. expect(leaveSpy).toHaveBeenCalled()
  292. expect(vm.$el.innerHTML).toBe('<div class="nope-leave nope-leave-active">foo</div>')
  293. }).thenWaitFor(nextFrame).then(() => {
  294. expect(vm.$el.innerHTML).toBe('')
  295. vm.ok = true
  296. }).then(() => {
  297. expect(enterSpy).toHaveBeenCalled()
  298. expect(vm.$el.innerHTML).toBe('<div class="nope-enter nope-enter-active">foo</div>')
  299. }).thenWaitFor(nextFrame).then(() => {
  300. expect(vm.$el.innerHTML).toMatch(/<div( class="")?>foo<\/div>/)
  301. }).then(done)
  302. })
  303. it('enterCancelled', done => {
  304. const spy = jasmine.createSpy('enterCancelled')
  305. const vm = new Vue({
  306. template: '<div><div v-if="ok" class="test" transition="test">foo</div></div>',
  307. data: { ok: false },
  308. transitions: {
  309. test: {
  310. enterCancelled: spy
  311. }
  312. }
  313. }).$mount(el)
  314. expect(vm.$el.innerHTML).toBe('')
  315. vm.ok = true
  316. waitForUpdate(() => {
  317. expect(vm.$el.children[0].className).toBe('test test-enter test-enter-active')
  318. }).thenWaitFor(duration / 2).then(() => {
  319. vm.ok = false
  320. }).then(() => {
  321. expect(spy).toHaveBeenCalled()
  322. expect(vm.$el.children[0].className).toBe('test test-leave test-leave-active')
  323. }).thenWaitFor(nextFrame).then(() => {
  324. expect(vm.$el.children[0].className).toBe('test test-leave-active')
  325. }).thenWaitFor(duration + 10).then(() => {
  326. expect(vm.$el.children.length).toBe(0)
  327. }).then(done)
  328. })
  329. it('transition with v-show', done => {
  330. const vm = new Vue({
  331. template: '<div><div v-show="ok" class="test" transition="test">foo</div></div>',
  332. data: { ok: true }
  333. }).$mount(el)
  334. // should not apply transition on initial render by default
  335. expect(vm.$el.textContent).toBe('foo')
  336. expect(vm.$el.children[0].style.display).toBe('')
  337. vm.ok = false
  338. waitForUpdate(() => {
  339. expect(vm.$el.children[0].className).toBe('test test-leave test-leave-active')
  340. }).thenWaitFor(nextFrame).then(() => {
  341. expect(vm.$el.children[0].className).toBe('test test-leave-active')
  342. }).thenWaitFor(duration + 10).then(() => {
  343. expect(vm.$el.children[0].style.display).toBe('none')
  344. vm.ok = true
  345. }).then(() => {
  346. expect(vm.$el.children[0].style.display).toBe('')
  347. expect(vm.$el.children[0].className).toBe('test test-enter test-enter-active')
  348. }).thenWaitFor(nextFrame).then(() => {
  349. expect(vm.$el.children[0].className).toBe('test test-enter-active')
  350. }).thenWaitFor(duration + 10).then(() => {
  351. expect(vm.$el.children[0].className).toBe('test')
  352. }).then(done)
  353. })
  354. it('leaveCancelled (v-show only)', done => {
  355. const spy = jasmine.createSpy('leaveCancelled')
  356. const vm = new Vue({
  357. template: '<div><div v-show="ok" class="test" transition="test">foo</div></div>',
  358. data: { ok: true },
  359. transitions: {
  360. test: {
  361. leaveCancelled: spy
  362. }
  363. }
  364. }).$mount(el)
  365. expect(vm.$el.children[0].style.display).toBe('')
  366. vm.ok = false
  367. waitForUpdate(() => {
  368. expect(vm.$el.children[0].className).toBe('test test-leave test-leave-active')
  369. }).thenWaitFor(nextFrame).then(() => {
  370. expect(vm.$el.children[0].className).toBe('test test-leave-active')
  371. }).thenWaitFor(10).then(() => {
  372. vm.ok = true
  373. }).then(() => {
  374. expect(spy).toHaveBeenCalled()
  375. expect(vm.$el.children[0].className).toBe('test test-enter test-enter-active')
  376. }).thenWaitFor(nextFrame).then(() => {
  377. expect(vm.$el.children[0].className).toBe('test test-enter-active')
  378. }).thenWaitFor(duration + 10).then(() => {
  379. expect(vm.$el.children[0].style.display).toBe('')
  380. }).then(done)
  381. })
  382. it('animations', done => {
  383. const vm = new Vue({
  384. template: '<div><div v-if="ok" class="test" transition="test-anim">foo</div></div>',
  385. data: { ok: true }
  386. }).$mount(el)
  387. // should not apply transition on initial render by default
  388. expect(vm.$el.innerHTML).toBe('<div class="test">foo</div>')
  389. vm.ok = false
  390. waitForUpdate(() => {
  391. expect(vm.$el.children[0].className).toBe('test test-anim-leave test-anim-leave-active')
  392. }).thenWaitFor(nextFrame).then(() => {
  393. expect(vm.$el.children[0].className).toBe('test test-anim-leave-active')
  394. }).thenWaitFor(duration + 10).then(() => {
  395. expect(vm.$el.children.length).toBe(0)
  396. vm.ok = true
  397. }).then(() => {
  398. expect(vm.$el.children[0].className).toBe('test test-anim-enter test-anim-enter-active')
  399. }).thenWaitFor(nextFrame).then(() => {
  400. expect(vm.$el.children[0].className).toBe('test test-anim-enter-active')
  401. }).thenWaitFor(duration + 10).then(() => {
  402. expect(vm.$el.children[0].className).toBe('test')
  403. }).then(done)
  404. })
  405. it('transition on appear (inline)', done => {
  406. const vm = new Vue({
  407. template: `
  408. <div>
  409. <div v-if="ok"
  410. class="test"
  411. :transition="{
  412. name:'test',
  413. appear:true,
  414. appearClass: 'test-appear',
  415. appearActiveClass: 'test-appear-active'
  416. }">foo</div>
  417. </div>
  418. `,
  419. data: { ok: true }
  420. }).$mount(el)
  421. waitForUpdate(() => {
  422. expect(vm.$el.children[0].className).toBe('test test-appear test-appear-active')
  423. }).thenWaitFor(nextFrame).then(() => {
  424. expect(vm.$el.children[0].className).toBe('test test-appear-active')
  425. }).thenWaitFor(duration + 10).then(() => {
  426. expect(vm.$el.children[0].className).toBe('test')
  427. }).then(done)
  428. })
  429. it('transition on appear (resolved)', done => {
  430. const vm = new Vue({
  431. template: `
  432. <div>
  433. <div v-if="ok"
  434. class="test"
  435. transition="test">foo</div>
  436. </div>
  437. `,
  438. data: { ok: true },
  439. transitions: {
  440. test: {
  441. appear: true,
  442. appearClass: 'test-appear',
  443. appearActiveClass: 'test-appear-active'
  444. }
  445. }
  446. }).$mount(el)
  447. waitForUpdate(() => {
  448. expect(vm.$el.children[0].className).toBe('test test-appear test-appear-active')
  449. }).thenWaitFor(nextFrame).then(() => {
  450. expect(vm.$el.children[0].className).toBe('test test-appear-active')
  451. }).thenWaitFor(duration + 10).then(() => {
  452. expect(vm.$el.children[0].className).toBe('test')
  453. }).then(done)
  454. })
  455. it('transition on appear with v-show', done => {
  456. const vm = new Vue({
  457. template: `
  458. <div>
  459. <div v-show="ok"
  460. class="test"
  461. :transition="{name:'test',appear:true}">foo</div>
  462. </div>
  463. `,
  464. data: { ok: true }
  465. }).$mount(el)
  466. waitForUpdate(() => {
  467. expect(vm.$el.children[0].className).toBe('test test-enter test-enter-active')
  468. }).thenWaitFor(nextFrame).then(() => {
  469. expect(vm.$el.children[0].className).toBe('test test-enter-active')
  470. }).thenWaitFor(duration + 10).then(() => {
  471. expect(vm.$el.children[0].className).toBe('test')
  472. }).then(done)
  473. })
  474. it('transition on SVG elements', done => {
  475. const vm = new Vue({
  476. template: '<svg><circle cx="0" cy="0" r="10" v-if="ok" class="test" transition></circle></svg>',
  477. data: { ok: true }
  478. }).$mount(el)
  479. // should not apply transition on initial render by default
  480. expect(vm.$el.childNodes[0].getAttribute('class')).toBe('test')
  481. vm.ok = false
  482. waitForUpdate(() => {
  483. expect(vm.$el.childNodes[0].getAttribute('class')).toBe('test v-leave v-leave-active')
  484. }).thenWaitFor(nextFrame).then(() => {
  485. expect(vm.$el.childNodes[0].getAttribute('class')).toBe('test v-leave-active')
  486. }).thenWaitFor(duration + 10).then(() => {
  487. expect(vm.$el.childNodes.length).toBe(0)
  488. vm.ok = true
  489. }).then(() => {
  490. expect(vm.$el.childNodes[0].getAttribute('class')).toBe('test v-enter v-enter-active')
  491. }).thenWaitFor(nextFrame).then(() => {
  492. expect(vm.$el.childNodes[0].getAttribute('class')).toBe('test v-enter-active')
  493. }).thenWaitFor(duration + 10).then(() => {
  494. expect(vm.$el.childNodes[0].getAttribute('class')).toBe('test')
  495. }).then(done)
  496. })
  497. it('transition on child components', done => {
  498. const vm = new Vue({
  499. template: '<div><test v-if="ok" class="test" transition></test></div>',
  500. data: { ok: true },
  501. components: {
  502. test: {
  503. template: '<div transition="test">foo</div>' // test transition override from parent
  504. }
  505. }
  506. }).$mount(el)
  507. // should not apply transition on initial render by default
  508. expect(vm.$el.innerHTML).toBe('<div class="test">foo</div>')
  509. vm.ok = false
  510. waitForUpdate(() => {
  511. expect(vm.$el.children[0].className).toBe('test v-leave v-leave-active')
  512. }).thenWaitFor(nextFrame).then(() => {
  513. expect(vm.$el.children[0].className).toBe('test v-leave-active')
  514. }).thenWaitFor(duration + 10).then(() => {
  515. expect(vm.$el.children.length).toBe(0)
  516. vm.ok = true
  517. }).then(() => {
  518. expect(vm.$el.children[0].className).toBe('test v-enter v-enter-active')
  519. }).thenWaitFor(nextFrame).then(() => {
  520. expect(vm.$el.children[0].className).toBe('test v-enter-active')
  521. }).thenWaitFor(duration + 10).then(() => {
  522. expect(vm.$el.children[0].className).toBe('test')
  523. }).then(done)
  524. })
  525. })
  526. }