)
})
+ describe.todo('transition with KeepAlive', () => {})
+ describe.todo('transition with Suspense', () => {})
+ describe.todo('transition with Teleport', () => {})
+
describe('transition with v-show', () => {
- test.todo('named transition with v-show', async () => {}, E2E_TIMEOUT)
- test.todo('transition events with v-show', async () => {}, E2E_TIMEOUT)
- test.todo('onLeaveCancelled (v-show only)', async () => {}, E2E_TIMEOUT)
- test.todo('transition on appear with v-show', async () => {}, E2E_TIMEOUT)
+ test(
+ 'named transition with v-show',
+ async () => {
+ const btnSelector = '.show-named > button'
+ const containerSelector = '.show-named > div'
+ const childSelector = `${containerSelector} > div`
+
+ expect(await html(containerSelector)).toBe(
+ '<div class="test">content</div>',
+ )
+ expect(await isVisible(childSelector)).toBe(true)
+
+ // leave
+ expect(
+ (await transitionStart(btnSelector, childSelector)).classNames,
+ ).toStrictEqual(['test', 'test-leave-from', 'test-leave-active'])
+ await nextFrame()
+ expect(await classList(childSelector)).toStrictEqual([
+ 'test',
+ 'test-leave-active',
+ 'test-leave-to',
+ ])
+ await transitionFinish()
+ expect(await isVisible(childSelector)).toBe(false)
+
+ // enter
+ expect(
+ (await transitionStart(btnSelector, childSelector)).classNames,
+ ).toStrictEqual(['test', 'test-enter-from', 'test-enter-active'])
+ await nextFrame()
+ expect(await classList(childSelector)).toStrictEqual([
+ 'test',
+ 'test-enter-active',
+ 'test-enter-to',
+ ])
+ await transitionFinish()
+ expect(await html(containerSelector)).toBe(
+ '<div class="test" style="">content</div>',
+ )
+ },
+ E2E_TIMEOUT,
+ )
+
+ test(
+ 'transition events with v-show',
+ async () => {
+ const btnSelector = '.show-events > button'
+ const containerSelector = '.show-events > div'
+ const childSelector = `${containerSelector} > div`
+
+ expect(await html(containerSelector)).toBe(
+ '<div class="test">content</div>',
+ )
+
+ // leave
+ expect(
+ (await transitionStart(btnSelector, childSelector)).classNames,
+ ).toStrictEqual(['test', 'test-leave-from', 'test-leave-active'])
+
+ let calls = await page().evaluate(() => {
+ return (window as any).getCalls('show')
+ })
+ expect(calls).toStrictEqual(['beforeLeave', 'onLeave'])
+ await nextFrame()
+ expect(await classList(childSelector)).toStrictEqual([
+ 'test',
+ 'test-leave-active',
+ 'test-leave-to',
+ ])
+ calls = await page().evaluate(() => {
+ return (window as any).getCalls('show')
+ })
+ expect(calls).not.contain('afterLeave')
+ await transitionFinish()
+ expect(await isVisible(childSelector)).toBe(false)
+ calls = await page().evaluate(() => {
+ return (window as any).getCalls('show')
+ })
+ expect(calls).toStrictEqual(['beforeLeave', 'onLeave', 'afterLeave'])
+
+ // clear calls
+ await page().evaluate(() => {
+ ;(window as any).resetCalls('show')
+ })
+
+ // enter
+ expect(
+ (await transitionStart(btnSelector, childSelector)).classNames,
+ ).toStrictEqual(['test', 'test-enter-from', 'test-enter-active'])
+ await nextFrame()
+ expect(await classList(childSelector)).toStrictEqual([
+ 'test',
+ 'test-enter-active',
+ 'test-enter-to',
+ ])
+ calls = await page().evaluate(() => {
+ return (window as any).getCalls('show')
+ })
+ expect(calls).toStrictEqual(['beforeEnter', 'onEnter'])
+ await transitionFinish()
+ expect(await html(containerSelector)).toBe(
+ '<div class="test" style="">content</div>',
+ )
+ calls = await page().evaluate(() => {
+ return (window as any).getCalls('show')
+ })
+ expect(calls).toStrictEqual(['beforeEnter', 'onEnter', 'afterEnter'])
+ },
+ E2E_TIMEOUT,
+ )
+
+ test(
+ 'onLeaveCancelled (v-show only)',
+ async () => {
+ const btnSelector = '.show-leave-cancelled > button'
+ const containerSelector = '.show-leave-cancelled > div'
+ const childSelector = `${containerSelector} > div`
+
+ expect(await html(containerSelector)).toBe(
+ '<div class="test">content</div>',
+ )
+
+ // leave
+ expect(
+ (await transitionStart(btnSelector, childSelector)).classNames,
+ ).toStrictEqual(['test', 'test-leave-from', 'test-leave-active'])
+ await nextFrame()
+ expect(await classList(childSelector)).toStrictEqual([
+ 'test',
+ 'test-leave-active',
+ 'test-leave-to',
+ ])
+
+ // cancel (enter)
+ expect(
+ (await transitionStart(btnSelector, childSelector)).classNames,
+ ).toStrictEqual(['test', 'test-enter-from', 'test-enter-active'])
+ let calls = await page().evaluate(() => {
+ return (window as any).getCalls('showLeaveCancel')
+ })
+ expect(calls).toStrictEqual(['leaveCancelled'])
+ await nextFrame()
+ expect(await classList(childSelector)).toStrictEqual([
+ 'test',
+ 'test-enter-active',
+ 'test-enter-to',
+ ])
+ await transitionFinish()
+ expect(await isVisible(childSelector)).toBe(true)
+ },
+ E2E_TIMEOUT,
+ )
+
+ test.todo(
+ 'transition on appear with v-show',
+ async () => {
+ const btnSelector = '.show-appear > button'
+ const containerSelector = '.show-appear > div'
+ const childSelector = `${containerSelector} > div`
+ },
+ E2E_TIMEOUT,
+ )
+
test.todo(
'transition events should not call onEnter with v-show false',
async () => {},
E2E_TIMEOUT,
)
+
test.todo('transition on appear with v-show', async () => {}, E2E_TIMEOUT)
})
describe('explicit durations', () => {
- test.todo('single value', async () => {}, E2E_TIMEOUT)
- test.todo('enter with explicit durations', async () => {}, E2E_TIMEOUT)
- test.todo('leave with explicit durations', async () => {}, E2E_TIMEOUT)
- test.todo('separate enter and leave', async () => {}, E2E_TIMEOUT)
- test.todo('warn invalid durations', async () => {}, E2E_TIMEOUT)
- })
-
- test(
- 'should work with v-show',
- async () => {
- const btnSelector = '.vshow > button'
- const containerSelector = '.vshow > h1'
-
- expect(await text(containerSelector)).toContain('vShow')
+ test(
+ 'single value',
+ async () => {
+ const btnSelector = '.duration-single-value > button'
+ const containerSelector = '.duration-single-value > div'
+ const childSelector = `${containerSelector} > div`
- // leave
- expect(
- (await transitionStart(btnSelector, containerSelector)).classNames,
- ).toStrictEqual(['v-leave-from', 'v-leave-active'])
+ expect(await html(containerSelector)).toBe(
+ '<div class="test">content</div>',
+ )
- await nextFrame()
- expect(await classList(containerSelector)).toStrictEqual([
- 'v-leave-active',
- 'v-leave-to',
- ])
+ // leave
+ expect(
+ (await transitionStart(btnSelector, childSelector)).classNames,
+ ).toStrictEqual(['test', 'test-leave-from', 'test-leave-active'])
+ await nextFrame()
+ expect(await classList(childSelector)).toStrictEqual([
+ 'test',
+ 'test-leave-active',
+ 'test-leave-to',
+ ])
+ await transitionFinish(duration * 2)
+ expect(await html(containerSelector)).toBe('')
- await transitionFinish()
- await nextFrame()
- expect(await isVisible(containerSelector)).toBe(false)
+ // enter
+ expect(
+ (await transitionStart(btnSelector, childSelector)).classNames,
+ ).toStrictEqual(['test', 'test-enter-from', 'test-enter-active'])
+ await nextFrame()
+ expect(await classList(childSelector)).toStrictEqual([
+ 'test',
+ 'test-enter-active',
+ 'test-enter-to',
+ ])
+ await transitionFinish(duration * 2)
+ expect(await html(containerSelector)).toBe(
+ '<div class="test">content</div>',
+ )
+ },
+ E2E_TIMEOUT,
+ )
- // enter
- expect(
- (await transitionStart(btnSelector, containerSelector)).classNames,
- ).toStrictEqual(['v-enter-from', 'v-enter-active'])
+ test(
+ 'enter with explicit durations',
+ async () => {
+ const btnSelector = '.duration-enter > button'
+ const containerSelector = '.duration-enter > div'
+ const childSelector = `${containerSelector} > div`
- await nextFrame()
- expect(await classList(containerSelector)).toStrictEqual([
- 'v-enter-active',
- 'v-enter-to',
- ])
+ expect(await html(containerSelector)).toBe(
+ '<div class="test">content</div>',
+ )
- await transitionFinish()
- await nextFrame()
- expect(await isVisible(containerSelector)).toBe(true)
- },
- E2E_TIMEOUT,
- )
+ // leave
+ expect(
+ (await transitionStart(btnSelector, childSelector)).classNames,
+ ).toStrictEqual(['test', 'test-leave-from', 'test-leave-active'])
+ await nextFrame()
+ expect(await classList(childSelector)).toStrictEqual([
+ 'test',
+ 'test-leave-active',
+ 'test-leave-to',
+ ])
+ await transitionFinish()
+ expect(await html(containerSelector)).toBe('')
- test(
- 'should work with v-if + appear',
- async () => {
- const btnSelector = '.vif > button'
- const containerSelector = '.vif > h1'
+ // enter
+ expect(
+ (await transitionStart(btnSelector, childSelector)).classNames,
+ ).toStrictEqual(['test', 'test-enter-from', 'test-enter-active'])
+ await nextFrame()
+ expect(await classList(childSelector)).toStrictEqual([
+ 'test',
+ 'test-enter-active',
+ 'test-enter-to',
+ ])
+ await transitionFinish(duration * 2)
+ expect(await html(containerSelector)).toBe(
+ '<div class="test">content</div>',
+ )
+ },
+ E2E_TIMEOUT,
+ )
- // appear
- expect(await classList(containerSelector)).contains('v-enter-active')
- expect(await text(containerSelector)).toContain('vIf')
- await transitionFinish()
+ test(
+ 'leave with explicit durations',
+ async () => {
+ const btnSelector = '.duration-leave > button'
+ const containerSelector = '.duration-leave > div'
+ const childSelector = `${containerSelector} > div`
- // leave
- await nextFrame()
- expect(
- (await transitionStart(btnSelector, containerSelector)).classNames,
- ).toStrictEqual(['v-leave-from', 'v-leave-active'])
+ expect(await html(containerSelector)).toBe(
+ '<div class="test">content</div>',
+ )
- await nextFrame()
- expect(await classList(containerSelector)).toStrictEqual([
- 'v-leave-active',
- 'v-leave-to',
- ])
+ // leave
+ expect(
+ (await transitionStart(btnSelector, childSelector)).classNames,
+ ).toStrictEqual(['test', 'test-leave-from', 'test-leave-active'])
+ await nextFrame()
+ expect(await classList(childSelector)).toStrictEqual([
+ 'test',
+ 'test-leave-active',
+ 'test-leave-to',
+ ])
+ await transitionFinish(duration * 2)
+ expect(await html(containerSelector)).toBe('')
- await transitionFinish()
- expect(await count(containerSelector)).toBe(0)
+ // enter
+ expect(
+ (await transitionStart(btnSelector, childSelector)).classNames,
+ ).toStrictEqual(['test', 'test-enter-from', 'test-enter-active'])
+ await nextFrame()
+ expect(await classList(childSelector)).toStrictEqual([
+ 'test',
+ 'test-enter-active',
+ 'test-enter-to',
+ ])
+ await transitionFinish()
+ expect(await html(containerSelector)).toBe(
+ '<div class="test">content</div>',
+ )
+ },
+ E2E_TIMEOUT,
+ )
- // enter
- expect(
- (await transitionStart(btnSelector, containerSelector)).classNames,
- ).toStrictEqual(['v-enter-from', 'v-enter-active'])
+ test(
+ 'separate enter and leave',
+ async () => {
+ const btnSelector = '.duration-enter-leave > button'
+ const containerSelector = '.duration-enter-leave > div'
+ const childSelector = `${containerSelector} > div`
- await nextFrame()
- expect(await classList(containerSelector)).toStrictEqual([
- 'v-enter-active',
- 'v-enter-to',
- ])
+ expect(await html(containerSelector)).toBe(
+ '<div class="test">content</div>',
+ )
- await transitionFinish()
- await nextFrame()
- expect(await isVisible(containerSelector)).toBe(true)
+ // leave
+ expect(
+ (await transitionStart(btnSelector, childSelector)).classNames,
+ ).toStrictEqual(['test', 'test-leave-from', 'test-leave-active'])
+ await nextFrame()
+ expect(await classList(childSelector)).toStrictEqual([
+ 'test',
+ 'test-leave-active',
+ 'test-leave-to',
+ ])
+ await transitionFinish(duration * 2)
+ expect(await html(containerSelector)).toBe('')
- expect(
- await page().evaluate(() => {
- return (window as any).getCalls('basic')
- }),
- ).toStrictEqual([
- 'beforeAppear',
- 'onAppear',
- 'afterAppear',
- 'beforeLeave',
- 'onLeave',
- 'afterLeave',
- 'beforeEnter',
- 'onEnter',
- 'afterEnter',
- ])
- },
- E2E_TIMEOUT,
- )
+ // enter
+ expect(
+ (await transitionStart(btnSelector, childSelector)).classNames,
+ ).toStrictEqual(['test', 'test-enter-from', 'test-enter-active'])
+ await nextFrame()
+ expect(await classList(childSelector)).toStrictEqual([
+ 'test',
+ 'test-enter-active',
+ 'test-enter-to',
+ ])
+ await transitionFinish(duration * 4)
+ expect(await html(containerSelector)).toBe(
+ '<div class="test">content</div>',
+ )
+ },
+ E2E_TIMEOUT,
+ )
+ })
test(
'should work with keyed element',
const count = ref(0)
const timeout = (fn, time) => setTimeout(fn, time)
+const duration = typeof process !== 'undefined' && process.env.CI ? 200 : 50
let calls = {
basic: [],
withAppear: [],
cssFalse: [],
ifInOut: [],
+
+ show: [],
+ showLeaveCancel: [],
+ showAppear: [],
}
window.getCalls = key => calls[key]
window.resetCalls = key => (calls[key] = [])
<template>
<div class="transition-container">
+ <!-- work with vif -->
<div class="if-basic">
<div>
<transition>
</div>
<button @click="changeViewInOut">button</button>
</div>
+ <!-- work with vif end -->
- <div class="vshow">
- <button @click="show = !show">Show</button>
- <Transition>
- <h1 v-show="show">vShow</h1>
- </Transition>
+ <!-- work with vshow -->
+ <div class="show-named">
+ <div>
+ <transition name="test">
+ <div v-show="toggle" class="test">content</div>
+ </transition>
+ </div>
+ <button @click="toggle = !toggle">button</button>
</div>
- <div class="vif">
- <button @click="toggle = !toggle">Toggle</button>
- <Transition
- appear
- @beforeEnter="() => calls.basic.push('beforeEnter')"
- @enter="() => calls.basic.push('onEnter')"
- @afterEnter="() => calls.basic.push('afterEnter')"
- @beforeLeave="() => calls.basic.push('beforeLeave')"
- @leave="() => calls.basic.push('onLeave')"
- @afterLeave="() => calls.basic.push('afterLeave')"
- @beforeAppear="() => calls.basic.push('beforeAppear')"
- @appear="() => calls.basic.push('onAppear')"
- @afterAppear="() => calls.basic.push('afterAppear')"
- >
- <h1 v-if="toggle">vIf</h1>
- </Transition>
+ <div class="show-events">
+ <div>
+ <transition
+ name="test"
+ @beforeEnter="() => calls.show.push('beforeEnter')"
+ @enter="() => calls.show.push('onEnter')"
+ @afterEnter="() => calls.show.push('afterEnter')"
+ @beforeLeave="() => calls.show.push('beforeLeave')"
+ @leave="() => calls.show.push('onLeave')"
+ @afterLeave="() => calls.show.push('afterLeave')"
+ >
+ <div v-show="toggle" class="test">content</div>
+ </transition>
+ </div>
+ <button @click="toggle = !toggle">button</button>
+ </div>
+ <div class="show-leave-cancelled">
+ <div>
+ <transition
+ name="test"
+ @leave-cancelled="() => calls.showLeaveCancel.push('leaveCancelled')"
+ >
+ <div v-show="toggle" class="test">content</div>
+ </transition>
+ </div>
+ <button @click="toggle = !toggle">leave cancelled</button>
+ </div>
+ <div class="show-appear">
+ <div>
+ <transition
+ name="test"
+ appear
+ appear-from-class="test-appear-from"
+ appear-to-class="test-appear-to"
+ appear-active-class="test-appear-active"
+ @beforeEnter="() => calls.showAppear.push('beforeEnter')"
+ @enter="() => calls.showAppear.push('onEnter')"
+ @afterEnter="() => calls.showAppear.push('afterEnter')"
+ >
+ <div v-show="toggle" class="test">content</div>
+ </transition>
+ </div>
+ <button @click="toggle = !toggle">button</button>
+ </div>
+ <!-- work with vshow end -->
+
+ <!-- explicit durations -->
+ <div class="duration-single-value">
+ <div>
+ <transition name="test" :duration="duration * 2">
+ <div v-if="toggle" class="test">content</div>
+ </transition>
+ </div>
+ <button @click="toggle = !toggle">button</button>
</div>
+ <div class="duration-enter">
+ <div>
+ <transition name="test" :duration="{ enter: duration * 2 }">
+ <div v-if="toggle" class="test">content</div>
+ </transition>
+ </div>
+ <button @click="toggle = !toggle">button</button>
+ </div>
+ <div class="duration-leave">
+ <div>
+ <transition name="test" :duration="{ leave: duration * 2 }">
+ <div v-if="toggle" class="test">content</div>
+ </transition>
+ </div>
+ <button @click="toggle = !toggle">button</button>
+ </div>
+ <div class="duration-enter-leave">
+ <div>
+ <transition
+ name="test"
+ :duration="{ enter: duration * 4, leave: duration * 2 }"
+ >
+ <div v-if="toggle" class="test">content</div>
+ </transition>
+ </div>
+ <button @click="toggle = !toggle">button</button>
+ </div>
+ <!-- explicit durations end -->
+
+ <!-- keyed fragment -->
<div class="keyed">
<button @click="count++">inc</button>
<Transition>
<h1 style="position: absolute" :key="count">{{ count }}</h1>
</Transition>
</div>
+ <!-- keyed fragment end -->
+
+ <!-- mode -->
<div class="out-in">
<button @click="toggleComponent">toggle out-in</button>
<div>
</Transition>
</div>
</div>
+ <!-- mode end -->
+
+ <!-- vdom interop -->
<div class="vdom">
<button @click="toggleVdom = !toggleVdom">toggle vdom component</button>
<div>
</Transition>
</div>
</div>
+ <!-- vdom interop end -->
</div>
</template>
<style>