From 14a35b7b9848798ef16c20dd6fb3ffc5c588a9b9 Mon Sep 17 00:00:00 2001
From: likui <2218301630@qq.com>
Date: Wed, 13 May 2020 22:44:54 +0800
Subject: [PATCH 1/6] test(Transition): more test transition
---
.../__tests__/transition/Transition.spec.ts | 1331 ++++++++++++++++-
.../{index.html => transition.html} | 15 +-
2 files changed, 1292 insertions(+), 54 deletions(-)
rename packages/vue/examples/transition/{index.html => transition.html} (76%)
diff --git a/packages/vue/examples/__tests__/transition/Transition.spec.ts b/packages/vue/examples/__tests__/transition/Transition.spec.ts
index 650919d16d9..5ac85b3bcb9 100644
--- a/packages/vue/examples/__tests__/transition/Transition.spec.ts
+++ b/packages/vue/examples/__tests__/transition/Transition.spec.ts
@@ -1,17 +1,27 @@
import { E2E_TIMEOUT, setupPuppeteer } from '../e2eUtils'
import path from 'path'
+import { mockWarn } from '@vue/shared'
+import { h, createApp, Transition } from 'vue'
describe('e2e: Transition', () => {
- const { page, html, classList } = setupPuppeteer()
+ mockWarn()
+ const { page, html, classList, isVisible } = setupPuppeteer()
const baseUrl = `file://${path.resolve(
__dirname,
- '../../transition/index.html'
+ '../../transition/transition.html'
)}`
- const container = '#test'
-
const duration = 50
const buffer = 10
+
+ const classWhenTransitionStart = () =>
+ page().evaluate(() => {
+ document.querySelector('button')!.click()
+ return Promise.resolve().then(() => {
+ return document.querySelector('#container div')!.className.split(/\s+/g)
+ })
+ })
+
const transitionFinish = () =>
new Promise(r => {
setTimeout(r, duration + buffer)
@@ -27,59 +37,1300 @@ describe('e2e: Transition', () => {
})
}
- test(
- 'basic transition',
- async () => {
- await page().goto(baseUrl)
- await page().waitFor('#app')
- expect(await html(container)).toBe('
content
')
+ beforeEach(async () => {
+ await page().goto(baseUrl)
+ await page().waitFor('#app')
+ })
- const leaveStartClasses = await page().evaluate(() => {
- document.querySelector('button')!.click()
- return Promise.resolve().then(() => {
- return document.querySelector('#test div')!.className.split(/\s+/g)
+ describe('transition with v-if', () => {
+ test(
+ 'basic transition',
+ async () => {
+ await page().evaluate(() => {
+ const { createApp, ref } = (window as any).Vue
+ createApp({
+ template: `
+
+
+ `,
+ setup: () => {
+ const toggle = ref(true)
+ const click = () => (toggle.value = !toggle.value)
+ return { toggle, click }
+ }
+ }).mount('#app')
})
- })
+ expect(await html('#container')).toBe('content
')
- expect(leaveStartClasses).toStrictEqual([
- 'test',
- 'v-leave-active',
- 'v-leave-from'
- ])
+ // leave
+ expect(await classWhenTransitionStart()).toStrictEqual([
+ 'test',
+ 'v-leave-active',
+ 'v-leave-from'
+ ])
+ await nextFrame()
+ expect(await classList('.test')).toStrictEqual([
+ 'test',
+ 'v-leave-active',
+ 'v-leave-to'
+ ])
+ await transitionFinish()
+ expect(await html('#container')).toBe('')
- await nextFrame()
- expect(await classList('#test div')).toStrictEqual([
- 'test',
- 'v-leave-active',
- 'v-leave-to'
- ])
+ // enter
+ expect(await classWhenTransitionStart()).toStrictEqual([
+ 'test',
+ 'v-enter-active',
+ 'v-enter-from'
+ ])
+ await nextFrame()
+ expect(await classList('.test')).toStrictEqual([
+ 'test',
+ 'v-enter-active',
+ 'v-enter-to'
+ ])
+ await transitionFinish()
+ expect(await html('#container')).toBe('content
')
+ },
+ E2E_TIMEOUT
+ )
- await transitionFinish()
- expect(await html('#test')).toBe('')
+ test(
+ 'named transition',
+ async () => {
+ await page().evaluate(() => {
+ const { createApp, ref } = (window as any).Vue
+ createApp({
+ template: `
+
+
+ `,
+ setup: () => {
+ const toggle = ref(true)
+ const click = () => (toggle.value = !toggle.value)
+ return { toggle, click }
+ }
+ }).mount('#app')
+ })
+ expect(await html('#container')).toBe('content
')
+
+ // leave
+ expect(await classWhenTransitionStart()).toStrictEqual([
+ 'test',
+ 'test-leave-active',
+ 'test-leave-from'
+ ])
+ await nextFrame()
+ expect(await classList('.test')).toStrictEqual([
+ 'test',
+ 'test-leave-active',
+ 'test-leave-to'
+ ])
+ await transitionFinish()
+ expect(await html('#container')).toBe('')
+
+ // enter
+ expect(await classWhenTransitionStart()).toStrictEqual([
+ 'test',
+ 'test-enter-active',
+ 'test-enter-from'
+ ])
+ await nextFrame()
+ expect(await classList('.test')).toStrictEqual([
+ 'test',
+ 'test-enter-active',
+ 'test-enter-to'
+ ])
+ await transitionFinish()
+ expect(await html('#container')).toBe('content
')
+ },
+ E2E_TIMEOUT
+ )
+
+ test(
+ 'custom transition classes',
+ async () => {
+ await page().evaluate(() => {
+ const { createApp, ref } = (window as any).Vue
+ createApp({
+ template: `
+
+
+ `,
+ setup: () => {
+ const toggle = ref(true)
+ const click = () => (toggle.value = !toggle.value)
+ return { toggle, click }
+ }
+ }).mount('#app')
+ })
+ expect(await html('#container')).toBe('content
')
+
+ // leave
+ expect(await classWhenTransitionStart()).toStrictEqual([
+ 'test',
+ 'bye-active',
+ 'bye-from'
+ ])
+ await nextFrame()
+ expect(await classList('.test')).toStrictEqual([
+ 'test',
+ 'bye-active',
+ 'bye-to'
+ ])
+ await transitionFinish()
+ expect(await html('#container')).toBe('')
+
+ // enter
+ expect(await classWhenTransitionStart()).toStrictEqual([
+ 'test',
+ 'hello-active',
+ 'hello-from'
+ ])
+ await nextFrame()
+ expect(await classList('.test')).toStrictEqual([
+ 'test',
+ 'hello-active',
+ 'hello-to'
+ ])
+ await transitionFinish()
+ expect(await html('#container')).toBe('content
')
+ },
+ E2E_TIMEOUT
+ )
+
+ test(
+ 'transition with dynamic name',
+ async () => {
+ await page().evaluate(() => {
+ const { createApp, ref } = (window as any).Vue
+ createApp({
+ template: `
+
+
+
+ `,
+ setup: () => {
+ const name = ref('test')
+ const toggle = ref(true)
+ const click = () => (toggle.value = !toggle.value)
+ const changeName = () => {
+ name.value = 'changed'
+ click()
+ }
+ return { toggle, click, name, changeName }
+ }
+ }).mount('#app')
+ })
+ expect(await html('#container')).toBe('content
')
+
+ // leave
+ const leaveClass = await page().evaluate(() => {
+ ;(document.querySelector('#toggleBtn') as any).click()
+ return Promise.resolve().then(() => {
+ return document.querySelector('.test')!.className.split(/\s+/g)
+ })
+ })
+ expect(leaveClass).toStrictEqual([
+ 'test',
+ 'test-leave-active',
+ 'test-leave-from'
+ ])
+ await nextFrame()
+ expect(await classList('.test')).toStrictEqual([
+ 'test',
+ 'test-leave-active',
+ 'test-leave-to'
+ ])
+ await transitionFinish()
+ expect(await html('#container')).toBe('')
+
+ // enter
+ const enterClass = await page().evaluate(() => {
+ ;(document.querySelector('#changeNameBtn') as any).click()
+ return Promise.resolve().then(() => {
+ return document.querySelector('.test')!.className.split(/\s+/g)
+ })
+ })
+ expect(enterClass).toStrictEqual([
+ 'test',
+ 'changed-enter-active',
+ 'changed-enter-from'
+ ])
+ await nextFrame()
+ expect(await classList('.test')).toStrictEqual([
+ 'test',
+ 'changed-enter-active',
+ 'changed-enter-to'
+ ])
+ await transitionFinish()
+ expect(await html('#container')).toBe('content
')
+ },
+ E2E_TIMEOUT
+ )
+
+ test(
+ 'transition events without appear',
+ async () => {
+ const beforeLeaveSpy = jest.fn()
+ const onLeaveSpy = jest.fn()
+ const afterLeaveSpy = jest.fn()
+ const beforeEnterSpy = jest.fn()
+ const onEnterSpy = jest.fn()
+ const afterEnterSpy = jest.fn()
- const enterStartClasses = await page().evaluate(() => {
- document.querySelector('button')!.click()
- return Promise.resolve().then(() => {
- return document.querySelector('#test div')!.className.split(/\s+/g)
+ await page().exposeFunction('onLeaveSpy', onLeaveSpy)
+ await page().exposeFunction('onEnterSpy', onEnterSpy)
+ await page().exposeFunction('beforeLeaveSpy', beforeLeaveSpy)
+ await page().exposeFunction('beforeEnterSpy', beforeEnterSpy)
+ await page().exposeFunction('afterLeaveSpy', afterLeaveSpy)
+ await page().exposeFunction('afterEnterSpy', afterEnterSpy)
+
+ await page().evaluate(() => {
+ const {
+ beforeEnterSpy,
+ onEnterSpy,
+ afterEnterSpy,
+ beforeLeaveSpy,
+ onLeaveSpy,
+ afterLeaveSpy
+ } = window as any
+ const { createApp, ref } = (window as any).Vue
+ createApp({
+ template: `
+
+
+ `,
+ setup: () => {
+ const toggle = ref(true)
+ const click = () => (toggle.value = !toggle.value)
+ return {
+ toggle,
+ click,
+ beforeEnterSpy,
+ onEnterSpy,
+ afterEnterSpy,
+ beforeLeaveSpy,
+ onLeaveSpy,
+ afterLeaveSpy
+ }
+ }
+ }).mount('#app')
})
+ expect(await html('#container')).toBe('content
')
+
+ // leave
+ expect(await classWhenTransitionStart()).toStrictEqual([
+ 'test',
+ 'test-leave-active',
+ 'test-leave-from'
+ ])
+ // todo test event with arguments. Note: not get dom, get object. '{}'
+ expect(beforeLeaveSpy).toBeCalled()
+ expect(onLeaveSpy).not.toBeCalled()
+ expect(afterLeaveSpy).not.toBeCalled()
+ await nextFrame()
+ expect(await classList('.test')).toStrictEqual([
+ 'test',
+ 'test-leave-active',
+ 'test-leave-to'
+ ])
+ expect(beforeLeaveSpy).toBeCalled()
+ expect(afterLeaveSpy).not.toBeCalled()
+ await transitionFinish()
+ expect(await html('#container')).toBe('')
+ expect(afterLeaveSpy).toBeCalled()
+
+ // enter
+ expect(await classWhenTransitionStart()).toStrictEqual([
+ 'test',
+ 'test-enter-active',
+ 'test-enter-from'
+ ])
+ expect(beforeEnterSpy).toBeCalled()
+ expect(onEnterSpy).not.toBeCalled()
+ expect(afterEnterSpy).not.toBeCalled()
+ await nextFrame()
+ expect(await classList('.test')).toStrictEqual([
+ 'test',
+ 'test-enter-active',
+ 'test-enter-to'
+ ])
+ expect(onEnterSpy).toBeCalled()
+ expect(afterEnterSpy).not.toBeCalled()
+ await transitionFinish()
+ expect(await html('#container')).toBe('content
')
+ expect(afterEnterSpy).toBeCalled()
+ },
+ E2E_TIMEOUT
+ )
+
+ test('onEnterCancelled', async () => {
+ const enterCancelledSpy = jest.fn()
+
+ await page().exposeFunction('enterCancelledSpy', enterCancelledSpy)
+
+ await page().evaluate(() => {
+ const { enterCancelledSpy } = window as any
+ const { createApp, ref } = (window as any).Vue
+ createApp({
+ template: `
+
+
+ `,
+ setup: () => {
+ const toggle = ref(false)
+ const click = () => (toggle.value = !toggle.value)
+ return {
+ toggle,
+ click,
+ enterCancelledSpy
+ }
+ }
+ }).mount('#app')
})
+ expect(await html('#container')).toBe('')
- expect(enterStartClasses).toStrictEqual([
+ // enter
+ expect(await classWhenTransitionStart()).toStrictEqual([
'test',
- 'v-enter-active',
- 'v-enter-from'
+ 'test-enter-active',
+ 'test-enter-from'
])
-
await nextFrame()
- expect(await classList('#test div')).toStrictEqual([
+ expect(await classList('.test')).toStrictEqual([
'test',
- 'v-enter-active',
- 'v-enter-to'
+ 'test-enter-active',
+ 'test-enter-to'
])
+ // cancel (leave)
+ expect(await classWhenTransitionStart()).toStrictEqual([
+ 'test',
+ 'test-leave-active',
+ 'test-leave-from'
+ ])
+ // fixme
+ expect(enterCancelledSpy).not.toBeCalled()
+ await nextFrame()
+ expect(await classList('.test')).toStrictEqual([
+ 'test',
+ 'test-leave-active',
+ 'test-leave-to'
+ ])
await transitionFinish()
- expect(await html('#test')).toBe('content
')
+ expect(await html('#container')).toBe('')
+ })
+
+ test(
+ 'transition on appear',
+ async () => {
+ await page().evaluate(async () => {
+ const { createApp, ref } = (window as any).Vue
+ createApp({
+ template: `
+
+
+ `,
+ setup: () => {
+ const toggle = ref(true)
+ const click = () => (toggle.value = !toggle.value)
+ return { toggle, click }
+ }
+ }).mount('#app')
+ })
+ // appear
+ expect(await classList('.test')).toStrictEqual([
+ 'test',
+ 'test-appear-active',
+ 'test-appear-from'
+ ])
+ await nextFrame()
+ expect(await classList('.test')).toStrictEqual([
+ 'test',
+ 'test-appear-active',
+ 'test-appear-to'
+ ])
+ await transitionFinish()
+ expect(await html('#container')).toBe('content
')
+
+ // leave
+ expect(await classWhenTransitionStart()).toStrictEqual([
+ 'test',
+ 'test-leave-active',
+ 'test-leave-from'
+ ])
+ await nextFrame()
+ expect(await classList('.test')).toStrictEqual([
+ 'test',
+ 'test-leave-active',
+ 'test-leave-to'
+ ])
+ await transitionFinish()
+ expect(await html('#container')).toBe('')
+
+ // enter
+ expect(await classWhenTransitionStart()).toStrictEqual([
+ 'test',
+ 'test-enter-active',
+ 'test-enter-from'
+ ])
+ await nextFrame()
+ expect(await classList('.test')).toStrictEqual([
+ 'test',
+ 'test-enter-active',
+ 'test-enter-to'
+ ])
+ await transitionFinish()
+ expect(await html('#container')).toBe('content
')
+ },
+ E2E_TIMEOUT
+ )
+
+ test(
+ 'transition events with appear',
+ async () => {
+ const onLeaveSpy = jest.fn()
+ const onEnterSpy = jest.fn()
+ const onAppearSpy = jest.fn()
+ const beforeLeaveSpy = jest.fn()
+ const beforeEnterSpy = jest.fn()
+ const beforeAppearSpy = jest.fn()
+ const afterLeaveSpy = jest.fn()
+ const afterEnterSpy = jest.fn()
+ const afterAppearSpy = jest.fn()
+
+ await page().exposeFunction('onLeaveSpy', onLeaveSpy)
+ await page().exposeFunction('onEnterSpy', onEnterSpy)
+ await page().exposeFunction('onAppearSpy', onAppearSpy)
+ await page().exposeFunction('beforeLeaveSpy', beforeLeaveSpy)
+ await page().exposeFunction('beforeEnterSpy', beforeEnterSpy)
+ await page().exposeFunction('beforeAppearSpy', beforeAppearSpy)
+ await page().exposeFunction('afterLeaveSpy', afterLeaveSpy)
+ await page().exposeFunction('afterEnterSpy', afterEnterSpy)
+ await page().exposeFunction('afterAppearSpy', afterAppearSpy)
+
+ await page().evaluate(async () => {
+ const {
+ beforeAppearSpy,
+ onAppearSpy,
+ afterAppearSpy,
+ beforeEnterSpy,
+ onEnterSpy,
+ afterEnterSpy,
+ beforeLeaveSpy,
+ onLeaveSpy,
+ afterLeaveSpy
+ } = window as any
+ const { createApp, ref } = (window as any).Vue
+ createApp({
+ template: `
+
+
+ `,
+ setup: () => {
+ const toggle = ref(true)
+ const click = () => (toggle.value = !toggle.value)
+ return {
+ toggle,
+ click,
+ beforeAppearSpy,
+ onAppearSpy,
+ afterAppearSpy,
+ beforeEnterSpy,
+ onEnterSpy,
+ afterEnterSpy,
+ beforeLeaveSpy,
+ onLeaveSpy,
+ afterLeaveSpy
+ }
+ }
+ }).mount('#app')
+ })
+ // appear fixme spy called
+ expect(await classList('.test')).toStrictEqual([
+ 'test',
+ 'test-appear-active',
+ 'test-appear-from'
+ ])
+ expect(beforeAppearSpy).not.toBeCalled()
+ expect(onAppearSpy).not.toBeCalled()
+ expect(afterAppearSpy).not.toBeCalled()
+ await nextFrame()
+ expect(await classList('.test')).toStrictEqual([
+ 'test',
+ 'test-appear-active',
+ 'test-appear-to'
+ ])
+ expect(onAppearSpy).not.toBeCalled()
+ expect(afterAppearSpy).not.toBeCalled()
+ await transitionFinish()
+ expect(await html('#container')).toBe('content
')
+ expect(afterAppearSpy).not.toBeCalled()
+
+ // leave
+ expect(await classWhenTransitionStart()).toStrictEqual([
+ 'test',
+ 'test-leave-active',
+ 'test-leave-from'
+ ])
+ expect(beforeLeaveSpy).toBeCalled()
+ expect(onLeaveSpy).not.toBeCalled()
+ expect(afterLeaveSpy).not.toBeCalled()
+ await nextFrame()
+ expect(await classList('.test')).toStrictEqual([
+ 'test',
+ 'test-leave-active',
+ 'test-leave-to'
+ ])
+ expect(onLeaveSpy).toBeCalled()
+ expect(afterLeaveSpy).not.toBeCalled()
+ await transitionFinish()
+ expect(await html('#container')).toBe('')
+ expect(afterLeaveSpy).toBeCalled()
+
+ // enter fixme spy called
+ expect(await classWhenTransitionStart()).toStrictEqual([
+ 'test',
+ 'test-enter-active',
+ 'test-enter-from'
+ ])
+ expect(beforeEnterSpy).toBeCalled()
+ expect(onEnterSpy).toBeCalled()
+ expect(afterEnterSpy).toBeCalled()
+ await nextFrame()
+ expect(await classList('.test')).toStrictEqual([
+ 'test',
+ 'test-enter-active',
+ 'test-enter-to'
+ ])
+ expect(onEnterSpy).toBeCalled()
+ expect(afterEnterSpy).toBeCalled()
+ await transitionFinish()
+ expect(await html('#container')).toBe('content
')
+ expect(afterEnterSpy).toBeCalled()
+ },
+ E2E_TIMEOUT
+ )
+
+ // fixme
+ test(
+ 'css: false',
+ async () => {
+ const onLeaveSpy = jest.fn()
+ const onEnterSpy = jest.fn()
+
+ await page().exposeFunction('onLeaveSpy', onLeaveSpy)
+ await page().exposeFunction('onEnterSpy', onEnterSpy)
+
+ await page().evaluate(() => {
+ const { onLeaveSpy, onEnterSpy } = window as any
+ const { createApp, ref } = (window as any).Vue
+ createApp({
+ template: `
+
+
+ `,
+ setup: () => {
+ const toggle = ref(true)
+ const click = () => (toggle.value = !toggle.value)
+ return { toggle, click, onLeaveSpy, onEnterSpy }
+ }
+ }).mount('#app')
+ })
+ expect(await html('#container')).toBe('content
')
+
+ // leave
+ await classWhenTransitionStart()
+ expect(onLeaveSpy).toBeCalled()
+ expect(await html('#container')).toBe(
+ 'content
'
+ )
+ // enter
+ await classWhenTransitionStart()
+ expect(onEnterSpy).toBeCalled()
+ expect(await html('#container')).toBe('content
')
+ },
+ E2E_TIMEOUT
+ )
+
+ test(
+ 'no transition detected',
+ async () => {
+ await page().evaluate(() => {
+ const { createApp, ref } = (window as any).Vue
+ createApp({
+ template: `
+
+
+ `,
+ setup: () => {
+ const toggle = ref(true)
+ const click = () => (toggle.value = !toggle.value)
+ return { toggle, click }
+ }
+ }).mount('#app')
+ })
+ expect(await html('#container')).toBe('content
')
+
+ // leave
+ expect(await classWhenTransitionStart()).toStrictEqual([
+ 'noop-leave-active',
+ 'noop-leave-from'
+ ])
+ await nextFrame()
+ expect(await html('#container')).toBe('')
+
+ // enter
+ expect(await classWhenTransitionStart()).toStrictEqual([
+ 'noop-enter-active',
+ 'noop-enter-from'
+ ])
+ await nextFrame()
+ expect(await html('#container')).toBe('content
')
+ },
+ E2E_TIMEOUT
+ )
+
+ test(
+ 'animations',
+ async () => {
+ await page().evaluate(() => {
+ const { createApp, ref } = (window as any).Vue
+ createApp({
+ template: `
+
+
+ `,
+ setup: () => {
+ const toggle = ref(true)
+ const click = () => (toggle.value = !toggle.value)
+ return { toggle, click }
+ }
+ }).mount('#app')
+ })
+ expect(await html('#container')).toBe('content
')
+
+ // leave
+ expect(await classWhenTransitionStart()).toStrictEqual([
+ 'test',
+ 'test-anim-leave-active',
+ 'test-anim-leave-from'
+ ])
+ await nextFrame()
+ expect(await classList('.test')).toStrictEqual([
+ 'test',
+ 'test-anim-leave-active',
+ 'test-anim-leave-to'
+ ])
+ await transitionFinish()
+ expect(await html('#container')).toBe('')
+
+ // enter
+ expect(await classWhenTransitionStart()).toStrictEqual([
+ 'test',
+ 'test-anim-enter-active',
+ 'test-anim-enter-from'
+ ])
+ await nextFrame()
+ expect(await classList('.test')).toStrictEqual([
+ 'test',
+ 'test-anim-enter-active',
+ 'test-anim-enter-to'
+ ])
+ await transitionFinish()
+ expect(await html('#container')).toBe('content
')
+ },
+ E2E_TIMEOUT
+ )
+
+ test(
+ 'explicit transition type',
+ async () => {
+ await page().evaluate(() => {
+ const { createApp, ref } = (window as any).Vue
+ createApp({
+ template: `
+
+
+ `,
+ setup: () => {
+ const toggle = ref(true)
+ const click = () => (toggle.value = !toggle.value)
+ return { toggle, click }
+ }
+ }).mount('#app')
+ })
+ expect(await html('#container')).toBe('content
')
+
+ // leave
+ expect(await classWhenTransitionStart()).toStrictEqual([
+ 'test',
+ 'test-anim-long-leave-active',
+ 'test-anim-long-leave-from'
+ ])
+ await nextFrame()
+ expect(await classList('.test')).toStrictEqual([
+ 'test',
+ 'test-anim-long-leave-active',
+ 'test-anim-long-leave-to'
+ ])
+ await new Promise(r => {
+ setTimeout(r, duration + 5)
+ })
+ expect(await classList('.test')).toStrictEqual([
+ 'test',
+ 'test-anim-long-leave-active',
+ 'test-anim-long-leave-to'
+ ])
+ await new Promise(r => {
+ setTimeout(r, duration + 5)
+ })
+ expect(await html('#container')).toBe('')
+
+ // enter
+ expect(await classWhenTransitionStart()).toStrictEqual([
+ 'test',
+ 'test-anim-long-enter-active',
+ 'test-anim-long-enter-from'
+ ])
+ await nextFrame()
+ expect(await classList('.test')).toStrictEqual([
+ 'test',
+ 'test-anim-long-enter-active',
+ 'test-anim-long-enter-to'
+ ])
+ await new Promise(r => {
+ setTimeout(r, duration + 5)
+ })
+ expect(await classList('.test')).toStrictEqual([
+ 'test',
+ 'test-anim-long-enter-active',
+ 'test-anim-long-enter-to'
+ ])
+ await new Promise(r => {
+ setTimeout(r, duration + 5)
+ })
+ expect(await html('#container')).toBe('content
')
+ },
+ E2E_TIMEOUT
+ )
+
+ test(
+ 'transition on SVG elements',
+ async () => {
+ await page().evaluate(() => {
+ const { createApp, ref } = (window as any).Vue
+ createApp({
+ template: `
+
+
+ `,
+ setup: () => {
+ const toggle = ref(true)
+ const click = () => (toggle.value = !toggle.value)
+ return { toggle, click }
+ }
+ }).mount('#app')
+ })
+ expect(await html('#container')).toBe(
+ ''
+ )
+
+ const svgTransitionStart = () =>
+ page().evaluate(() => {
+ document.querySelector('button')!.click()
+ return Promise.resolve().then(() => {
+ return document
+ .querySelector('.test')!
+ .getAttribute('class')!
+ .split(/\s+/g)
+ })
+ })
+
+ // leave
+ expect(await svgTransitionStart()).toStrictEqual([
+ 'test',
+ 'test-leave-active',
+ 'test-leave-from'
+ ])
+ await nextFrame()
+ expect(await classList('.test')).toStrictEqual([
+ 'test',
+ 'test-leave-active',
+ 'test-leave-to'
+ ])
+ await transitionFinish()
+ expect(await html('#container')).toBe('')
+
+ // enter
+ expect(await svgTransitionStart()).toStrictEqual([
+ 'test',
+ 'test-enter-active',
+ 'test-enter-from'
+ ])
+ await nextFrame()
+ expect(await classList('.test')).toStrictEqual([
+ 'test',
+ 'test-enter-active',
+ 'test-enter-to'
+ ])
+ await transitionFinish()
+ expect(await html('#container')).toBe(
+ ''
+ )
+ },
+ E2E_TIMEOUT
+ )
+
+ test(
+ 'custom transition higher-order component',
+ async () => {
+ await page().evaluate(() => {
+ const { createApp, ref, h, Transition } = (window as any).Vue
+ createApp({
+ template: `
+
+
+ `,
+ components: {
+ 'my-transition': (props: any, { slots }: any) => {
+ return h(Transition, { name: 'test' }, slots)
+ }
+ },
+ setup: () => {
+ const toggle = ref(true)
+ const click = () => (toggle.value = !toggle.value)
+ return { toggle, click }
+ }
+ }).mount('#app')
+ })
+ expect(await html('#container')).toBe('content
')
+
+ // leave
+ expect(await classWhenTransitionStart()).toStrictEqual([
+ 'test',
+ 'test-leave-active',
+ 'test-leave-from'
+ ])
+ await nextFrame()
+ expect(await classList('.test')).toStrictEqual([
+ 'test',
+ 'test-leave-active',
+ 'test-leave-to'
+ ])
+ await transitionFinish()
+ expect(await html('#container')).toBe('')
+
+ // enter
+ expect(await classWhenTransitionStart()).toStrictEqual([
+ 'test',
+ 'test-enter-active',
+ 'test-enter-from'
+ ])
+ await nextFrame()
+ expect(await classList('.test')).toStrictEqual([
+ 'test',
+ 'test-enter-active',
+ 'test-enter-to'
+ ])
+ await transitionFinish()
+ expect(await html('#container')).toBe('content
')
+ },
+ E2E_TIMEOUT
+ )
+ })
+
+ describe('transition with v-show', () => {
+ test(
+ 'named transition with v-show',
+ async () => {
+ await page().evaluate(() => {
+ const { createApp, ref } = (window as any).Vue
+ createApp({
+ template: `
+
+
+ `,
+ setup: () => {
+ const toggle = ref(true)
+ const click = () => (toggle.value = !toggle.value)
+ return { toggle, click }
+ }
+ }).mount('#app')
+ })
+ expect(await html('#container')).toBe('content
')
+ expect(await isVisible('.test')).toBe(true)
+
+ // leave
+ expect(await classWhenTransitionStart()).toStrictEqual([
+ 'test',
+ 'test-leave-active',
+ 'test-leave-from'
+ ])
+ await nextFrame()
+ expect(await classList('.test')).toStrictEqual([
+ 'test',
+ 'test-leave-active',
+ 'test-leave-to'
+ ])
+ await transitionFinish()
+ expect(await isVisible('.test')).toBe(false)
+
+ // enter
+ expect(await classWhenTransitionStart()).toStrictEqual([
+ 'test',
+ 'test-enter-active',
+ 'test-enter-from'
+ ])
+ await nextFrame()
+ expect(await classList('.test')).toStrictEqual([
+ 'test',
+ 'test-enter-active',
+ 'test-enter-to'
+ ])
+ await transitionFinish()
+ expect(await html('#container')).toBe(
+ 'content
'
+ )
+ },
+ E2E_TIMEOUT
+ )
+
+ test(
+ 'transition events with v-show',
+ async () => {
+ const beforeLeaveSpy = jest.fn()
+ const onLeaveSpy = jest.fn()
+ const afterLeaveSpy = jest.fn()
+ const beforeEnterSpy = jest.fn()
+ const onEnterSpy = jest.fn()
+ const afterEnterSpy = jest.fn()
+
+ await page().exposeFunction('onLeaveSpy', onLeaveSpy)
+ await page().exposeFunction('onEnterSpy', onEnterSpy)
+ await page().exposeFunction('beforeLeaveSpy', beforeLeaveSpy)
+ await page().exposeFunction('beforeEnterSpy', beforeEnterSpy)
+ await page().exposeFunction('afterLeaveSpy', afterLeaveSpy)
+ await page().exposeFunction('afterEnterSpy', afterEnterSpy)
+
+ await page().evaluate(() => {
+ const {
+ beforeEnterSpy,
+ onEnterSpy,
+ afterEnterSpy,
+ beforeLeaveSpy,
+ onLeaveSpy,
+ afterLeaveSpy
+ } = window as any
+ const { createApp, ref } = (window as any).Vue
+ createApp({
+ template: `
+
+
+ `,
+ setup: () => {
+ const toggle = ref(true)
+ const click = () => (toggle.value = !toggle.value)
+ return {
+ toggle,
+ click,
+ beforeEnterSpy,
+ onEnterSpy,
+ afterEnterSpy,
+ beforeLeaveSpy,
+ onLeaveSpy,
+ afterLeaveSpy
+ }
+ }
+ }).mount('#app')
+ })
+ expect(await html('#container')).toBe('content
')
+
+ // leave
+ expect(await classWhenTransitionStart()).toStrictEqual([
+ 'test',
+ 'test-leave-active',
+ 'test-leave-from'
+ ])
+ expect(beforeLeaveSpy).toBeCalled()
+ expect(onLeaveSpy).not.toBeCalled()
+ expect(afterLeaveSpy).not.toBeCalled()
+ await nextFrame()
+ expect(await classList('.test')).toStrictEqual([
+ 'test',
+ 'test-leave-active',
+ 'test-leave-to'
+ ])
+ expect(beforeLeaveSpy).toBeCalled()
+ expect(afterLeaveSpy).not.toBeCalled()
+ await transitionFinish()
+ expect(await isVisible('.test')).toBe(false)
+ expect(afterLeaveSpy).toBeCalled()
+
+ // enter
+ expect(await classWhenTransitionStart()).toStrictEqual([
+ 'test',
+ 'test-enter-active',
+ 'test-enter-from'
+ ])
+ expect(beforeEnterSpy).toBeCalled()
+ expect(onEnterSpy).not.toBeCalled()
+ expect(afterEnterSpy).not.toBeCalled()
+ await nextFrame()
+ expect(await classList('.test')).toStrictEqual([
+ 'test',
+ 'test-enter-active',
+ 'test-enter-to'
+ ])
+ expect(onEnterSpy).toBeCalled()
+ expect(afterEnterSpy).not.toBeCalled()
+ await transitionFinish()
+ expect(await html('#container')).toBe(
+ 'content
'
+ )
+ expect(afterEnterSpy).toBeCalled()
+ },
+ E2E_TIMEOUT
+ )
+
+ test(
+ 'onLeaveCancelled (v-show only)',
+ async () => {
+ const onLeaveCancelledSpy = jest.fn()
+
+ await page().exposeFunction('onLeaveCancelledSpy', onLeaveCancelledSpy)
+ await page().evaluate(() => {
+ const { onLeaveCancelledSpy } = window as any
+ const { createApp, ref } = (window as any).Vue
+ createApp({
+ template: `
+
+
+ `,
+ setup: () => {
+ const toggle = ref(true)
+ const click = () => (toggle.value = !toggle.value)
+ return { toggle, click, onLeaveCancelledSpy }
+ }
+ }).mount('#app')
+ })
+ expect(await html('#container')).toBe('content
')
+ expect(await isVisible('.test')).toBe(true)
+
+ // leave
+ expect(await classWhenTransitionStart()).toStrictEqual([
+ 'test',
+ 'test-leave-active',
+ 'test-leave-from'
+ ])
+ await nextFrame()
+ expect(await classList('.test')).toStrictEqual([
+ 'test',
+ 'test-leave-active',
+ 'test-leave-to'
+ ])
+
+ // cancel (enter)
+ expect(await classWhenTransitionStart()).toStrictEqual([
+ 'test',
+ 'test-enter-active',
+ 'test-enter-from'
+ ])
+ // fixme
+ expect(onLeaveCancelledSpy).not.toBeCalled()
+ await nextFrame()
+ expect(await classList('.test')).toStrictEqual([
+ 'test',
+ 'test-enter-active',
+ 'test-enter-to'
+ ])
+ await transitionFinish()
+ expect(await html('#container')).toBe(
+ 'content
'
+ )
+ },
+ E2E_TIMEOUT
+ )
+
+ test(
+ 'transition on appear with v-show',
+ async () => {
+ await page().evaluate(async () => {
+ const { createApp, ref } = (window as any).Vue
+ createApp({
+ template: `
+
+
+ `,
+ setup: () => {
+ const toggle = ref(true)
+ const click = () => (toggle.value = !toggle.value)
+ return { toggle, click }
+ }
+ }).mount('#app')
+ })
+ // appear
+ expect(await classList('.test')).toStrictEqual([
+ 'test',
+ 'test-appear-active',
+ 'test-appear-from'
+ ])
+ await nextFrame()
+ expect(await classList('.test')).toStrictEqual([
+ 'test',
+ 'test-appear-active',
+ 'test-appear-to'
+ ])
+ await transitionFinish()
+ expect(await html('#container')).toBe('content
')
+
+ // leave
+ expect(await classWhenTransitionStart()).toStrictEqual([
+ 'test',
+ 'test-leave-active',
+ 'test-leave-from'
+ ])
+ await nextFrame()
+ expect(await classList('.test')).toStrictEqual([
+ 'test',
+ 'test-leave-active',
+ 'test-leave-to'
+ ])
+ await transitionFinish()
+ expect(await isVisible('.test')).toBe(false)
+
+ // enter
+ expect(await classWhenTransitionStart()).toStrictEqual([
+ 'test',
+ 'test-enter-active',
+ 'test-enter-from'
+ ])
+ await nextFrame()
+ expect(await classList('.test')).toStrictEqual([
+ 'test',
+ 'test-enter-active',
+ 'test-enter-to'
+ ])
+ await transitionFinish()
+ expect(await html('#container')).toBe(
+ 'content
'
+ )
+ },
+ E2E_TIMEOUT
+ )
+ })
+
+ test(
+ 'warn when used on multiple elements',
+ async () => {
+ createApp({
+ render() {
+ return h(Transition, null, {
+ default: () => [h('div'), h('div')]
+ })
+ }
+ }).mount(document.createElement('div'))
+ expect(
+ ' can only be used on a single element or component'
+ ).toHaveBeenWarned()
},
E2E_TIMEOUT
)
+
+ test.todo('explicit durations -')
+ test.todo('transition on child components with empty root node')
})
diff --git a/packages/vue/examples/transition/index.html b/packages/vue/examples/transition/transition.html
similarity index 76%
rename from packages/vue/examples/transition/index.html
rename to packages/vue/examples/transition/transition.html
index af66e19df85..2a794234103 100644
--- a/packages/vue/examples/transition/index.html
+++ b/packages/vue/examples/transition/transition.html
@@ -1,19 +1,6 @@
-
-
+