mirror of https://github.com/vuejs/core.git
wip: add vapor transition e2e tests
This commit is contained in:
parent
41c258903e
commit
b65db59169
|
@ -0,0 +1,238 @@
|
||||||
|
import path from 'node:path'
|
||||||
|
import {
|
||||||
|
E2E_TIMEOUT,
|
||||||
|
setupPuppeteer,
|
||||||
|
} from '../../../packages/vue/__tests__/e2e/e2eUtils'
|
||||||
|
import connect from 'connect'
|
||||||
|
import sirv from 'sirv'
|
||||||
|
const {
|
||||||
|
page,
|
||||||
|
click,
|
||||||
|
classList,
|
||||||
|
text,
|
||||||
|
nextFrame,
|
||||||
|
timeout,
|
||||||
|
isVisible,
|
||||||
|
count,
|
||||||
|
html,
|
||||||
|
} = setupPuppeteer()
|
||||||
|
|
||||||
|
const duration = process.env.CI ? 200 : 50
|
||||||
|
const buffer = process.env.CI ? 50 : 20
|
||||||
|
const transitionFinish = (time = duration) => timeout(time + buffer)
|
||||||
|
|
||||||
|
describe('vapor transition', () => {
|
||||||
|
let server: any
|
||||||
|
const port = '8195'
|
||||||
|
beforeAll(() => {
|
||||||
|
server = connect()
|
||||||
|
.use(sirv(path.resolve(import.meta.dirname, '../dist')))
|
||||||
|
.listen(port)
|
||||||
|
process.on('SIGTERM', () => server && server.close())
|
||||||
|
})
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
server.close()
|
||||||
|
})
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
const baseUrl = `http://localhost:${port}/transition/`
|
||||||
|
await page().goto(baseUrl)
|
||||||
|
await page().waitForSelector('#app')
|
||||||
|
})
|
||||||
|
|
||||||
|
const classWhenTransitionStart = async (
|
||||||
|
btnSelector: string,
|
||||||
|
containerSelector: string,
|
||||||
|
) => {
|
||||||
|
return page().evaluate(
|
||||||
|
([btnSel, containerSel]) => {
|
||||||
|
;(document.querySelector(btnSel) as HTMLElement)!.click()
|
||||||
|
return Promise.resolve().then(() => {
|
||||||
|
return document.querySelector(containerSel)!.className.split(/\s+/g)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
[btnSelector, containerSelector],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
test(
|
||||||
|
'should work with v-show',
|
||||||
|
async () => {
|
||||||
|
const btnSelector = '.vshow > button'
|
||||||
|
const containerSelector = '.vshow > h1'
|
||||||
|
|
||||||
|
expect(await text(containerSelector)).toContain('vShow')
|
||||||
|
|
||||||
|
// leave
|
||||||
|
expect(
|
||||||
|
await classWhenTransitionStart(btnSelector, containerSelector),
|
||||||
|
).toStrictEqual(['v-leave-from', 'v-leave-active'])
|
||||||
|
|
||||||
|
await nextFrame()
|
||||||
|
expect(await classList(containerSelector)).toStrictEqual([
|
||||||
|
'v-leave-active',
|
||||||
|
'v-leave-to',
|
||||||
|
])
|
||||||
|
|
||||||
|
await transitionFinish()
|
||||||
|
expect(await isVisible(containerSelector)).toBe(false)
|
||||||
|
|
||||||
|
// enter
|
||||||
|
expect(
|
||||||
|
await classWhenTransitionStart(btnSelector, containerSelector),
|
||||||
|
).toStrictEqual(['v-enter-from', 'v-enter-active'])
|
||||||
|
|
||||||
|
await nextFrame()
|
||||||
|
expect(await classList(containerSelector)).toStrictEqual([
|
||||||
|
'v-enter-active',
|
||||||
|
'v-enter-to',
|
||||||
|
])
|
||||||
|
|
||||||
|
await transitionFinish()
|
||||||
|
expect(await isVisible(containerSelector)).toBe(true)
|
||||||
|
},
|
||||||
|
E2E_TIMEOUT,
|
||||||
|
)
|
||||||
|
|
||||||
|
test(
|
||||||
|
'should work with v-if + appear',
|
||||||
|
async () => {
|
||||||
|
const btnSelector = '.vif > button'
|
||||||
|
const containerSelector = '.vif > h1'
|
||||||
|
|
||||||
|
// appear
|
||||||
|
expect(await classList(containerSelector)).toStrictEqual([
|
||||||
|
'v-enter-from',
|
||||||
|
'v-enter-active',
|
||||||
|
])
|
||||||
|
expect(await text(containerSelector)).toContain('vIf')
|
||||||
|
await transitionFinish()
|
||||||
|
|
||||||
|
// leave
|
||||||
|
expect(
|
||||||
|
await classWhenTransitionStart(btnSelector, containerSelector),
|
||||||
|
).toStrictEqual(['v-leave-from', 'v-leave-active'])
|
||||||
|
|
||||||
|
await nextFrame()
|
||||||
|
expect(await classList(containerSelector)).toStrictEqual([
|
||||||
|
'v-leave-active',
|
||||||
|
'v-leave-to',
|
||||||
|
])
|
||||||
|
|
||||||
|
await transitionFinish()
|
||||||
|
expect(await count(containerSelector)).toBe(0)
|
||||||
|
|
||||||
|
// enter
|
||||||
|
expect(
|
||||||
|
await classWhenTransitionStart(btnSelector, containerSelector),
|
||||||
|
).toStrictEqual(['v-enter-from', 'v-enter-active'])
|
||||||
|
|
||||||
|
await nextFrame()
|
||||||
|
expect(await classList(containerSelector)).toStrictEqual([
|
||||||
|
'v-enter-active',
|
||||||
|
'v-enter-to',
|
||||||
|
])
|
||||||
|
|
||||||
|
await transitionFinish()
|
||||||
|
expect(await isVisible(containerSelector)).toBe(true)
|
||||||
|
},
|
||||||
|
E2E_TIMEOUT,
|
||||||
|
)
|
||||||
|
|
||||||
|
test(
|
||||||
|
'should work with keyed element',
|
||||||
|
async () => {
|
||||||
|
const btnSelector = '.keyed > button'
|
||||||
|
const containerSelector = '.keyed > h1'
|
||||||
|
|
||||||
|
expect(await text(containerSelector)).toContain('0')
|
||||||
|
|
||||||
|
// change key
|
||||||
|
expect(
|
||||||
|
await classWhenTransitionStart(btnSelector, containerSelector),
|
||||||
|
).toStrictEqual(['v-leave-from', 'v-leave-active'])
|
||||||
|
|
||||||
|
await nextFrame()
|
||||||
|
expect(await classList(containerSelector)).toStrictEqual([
|
||||||
|
'v-leave-active',
|
||||||
|
'v-leave-to',
|
||||||
|
])
|
||||||
|
|
||||||
|
await transitionFinish()
|
||||||
|
expect(await text(containerSelector)).toContain('1')
|
||||||
|
|
||||||
|
// change key again
|
||||||
|
expect(
|
||||||
|
await classWhenTransitionStart(btnSelector, containerSelector),
|
||||||
|
).toStrictEqual(['v-leave-from', 'v-leave-active'])
|
||||||
|
|
||||||
|
await nextFrame()
|
||||||
|
expect(await classList(containerSelector)).toStrictEqual([
|
||||||
|
'v-leave-active',
|
||||||
|
'v-leave-to',
|
||||||
|
])
|
||||||
|
|
||||||
|
await transitionFinish()
|
||||||
|
expect(await text(containerSelector)).toContain('2')
|
||||||
|
},
|
||||||
|
E2E_TIMEOUT,
|
||||||
|
)
|
||||||
|
|
||||||
|
test(
|
||||||
|
'should work with out-in mode',
|
||||||
|
async () => {
|
||||||
|
const btnSelector = '.out-in > button'
|
||||||
|
const containerSelector = '.out-in > div'
|
||||||
|
|
||||||
|
expect(await html(containerSelector)).toBe(`<div>vapor compB</div>`)
|
||||||
|
|
||||||
|
// compB -> compA
|
||||||
|
await click(btnSelector)
|
||||||
|
expect(await html(containerSelector)).toBe(
|
||||||
|
`<div class="fade-leave-from fade-leave-active">vapor compB</div>`,
|
||||||
|
)
|
||||||
|
|
||||||
|
await nextFrame()
|
||||||
|
expect(await html(containerSelector)).toBe(
|
||||||
|
`<div class="fade-leave-active fade-leave-to">vapor compB</div>`,
|
||||||
|
)
|
||||||
|
|
||||||
|
await transitionFinish()
|
||||||
|
await nextFrame()
|
||||||
|
expect(await html(containerSelector)).toBe(
|
||||||
|
`<div class="fade-enter-active fade-enter-to">vapor compA</div>`,
|
||||||
|
)
|
||||||
|
|
||||||
|
await transitionFinish()
|
||||||
|
expect(await html(containerSelector)).toBe(
|
||||||
|
`<div class="">vapor compA</div>`,
|
||||||
|
)
|
||||||
|
|
||||||
|
// compA -> compB
|
||||||
|
await click(btnSelector)
|
||||||
|
expect(await html(containerSelector)).toBe(
|
||||||
|
`<div class="fade-leave-from fade-leave-active">vapor compA</div>`,
|
||||||
|
)
|
||||||
|
|
||||||
|
await nextFrame()
|
||||||
|
expect(await html(containerSelector)).toBe(
|
||||||
|
`<div class="fade-leave-active fade-leave-to">vapor compA</div>`,
|
||||||
|
)
|
||||||
|
|
||||||
|
await transitionFinish()
|
||||||
|
await nextFrame()
|
||||||
|
expect(await html(containerSelector)).toBe(
|
||||||
|
`<div class="fade-enter-active fade-enter-to">vapor compB</div>`,
|
||||||
|
)
|
||||||
|
|
||||||
|
await transitionFinish()
|
||||||
|
expect(await html(containerSelector)).toBe(
|
||||||
|
`<div class="">vapor compB</div>`,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
E2E_TIMEOUT,
|
||||||
|
)
|
||||||
|
|
||||||
|
test.todo('should work with in-out mode', async () => {}, E2E_TIMEOUT)
|
||||||
|
})
|
|
@ -1,2 +1,3 @@
|
||||||
<a href="/interop/">VDOM / Vapor interop</a>
|
<a href="/interop/">VDOM / Vapor interop</a>
|
||||||
<a href="/todomvc/">Vapor TodoMVC</a>
|
<a href="/todomvc/">Vapor TodoMVC</a>
|
||||||
|
<a href="/transition/">Vapor Transition</a>
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
<script vapor>
|
||||||
|
import { ref, shallowRef } from 'vue'
|
||||||
|
const show = ref(true)
|
||||||
|
const toggle = ref(true)
|
||||||
|
const count = ref(0)
|
||||||
|
|
||||||
|
import VaporCompA from './components/VaporCompA.vue'
|
||||||
|
import VaporCompB from './components/VaporCompB.vue'
|
||||||
|
const activeComponent = shallowRef(VaporCompA)
|
||||||
|
function toggleComponent() {
|
||||||
|
activeComponent.value = activeComponent.value === VaporCompA ? VaporCompB : VaporCompA
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="vshow">
|
||||||
|
<button @click="show = !show">Show</button>
|
||||||
|
<Transition>
|
||||||
|
<h1 v-show="show">vShow</h1>
|
||||||
|
</Transition>
|
||||||
|
</div>
|
||||||
|
<div class="vif">
|
||||||
|
<button @click="toggle = !toggle">Toggle</button>
|
||||||
|
<Transition appear>
|
||||||
|
<h1 v-if="toggle">vIf</h1>
|
||||||
|
</Transition>
|
||||||
|
</div>
|
||||||
|
<div class="keyed">
|
||||||
|
<button @click="count++">inc</button>
|
||||||
|
<Transition>
|
||||||
|
<h1 style="position: absolute" :key="count">{{ count }}</h1>
|
||||||
|
</Transition>
|
||||||
|
</div>
|
||||||
|
<div class="out-in">
|
||||||
|
<button @click="toggleComponent">toggle component</button>
|
||||||
|
<div>
|
||||||
|
<Transition name="fade" mode="out-in">
|
||||||
|
<component :is="activeComponent"></component>
|
||||||
|
</Transition>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<style>
|
||||||
|
.keyed {
|
||||||
|
height: 100px
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,6 @@
|
||||||
|
<script vapor>
|
||||||
|
const msg = 'vapor compB'
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<div>{{ msg }}</div>
|
||||||
|
</template>
|
|
@ -0,0 +1,6 @@
|
||||||
|
<script vapor>
|
||||||
|
const msg = 'vapor compA'
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<div>{{ msg }}</div>
|
||||||
|
</template>
|
|
@ -0,0 +1,2 @@
|
||||||
|
<script type="module" src="./main.ts"></script>
|
||||||
|
<div id="app"></div>
|
|
@ -0,0 +1,5 @@
|
||||||
|
import { createVaporApp } from 'vue'
|
||||||
|
import App from './App.vue'
|
||||||
|
import './style.css'
|
||||||
|
|
||||||
|
createVaporApp(App).mount('#app')
|
|
@ -0,0 +1,19 @@
|
||||||
|
.v-enter-active,
|
||||||
|
.v-leave-active {
|
||||||
|
transition: opacity 50ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v-enter-from,
|
||||||
|
.v-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-enter-active,
|
||||||
|
.fade-leave-active {
|
||||||
|
transition: opacity 50ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-enter-from,
|
||||||
|
.fade-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
|
@ -14,6 +14,7 @@ export default defineConfig({
|
||||||
input: {
|
input: {
|
||||||
interop: resolve(import.meta.dirname, 'interop/index.html'),
|
interop: resolve(import.meta.dirname, 'interop/index.html'),
|
||||||
todomvc: resolve(import.meta.dirname, 'todomvc/index.html'),
|
todomvc: resolve(import.meta.dirname, 'todomvc/index.html'),
|
||||||
|
transition: resolve(import.meta.dirname, 'transition/index.html'),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue