Skip to content

Commit 0e68999

Browse files
committed
wip: port tests and fix bugs
1 parent e7300a0 commit 0e68999

File tree

5 files changed

+295
-7
lines changed

5 files changed

+295
-7
lines changed

packages-private/vapor-e2e-test/__tests__/transition.spec.ts

+229
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ const {
1616
html,
1717
transitionStart,
1818
waitForElement,
19+
click,
1920
} = setupPuppeteer()
2021

2122
const duration = process.env.CI ? 200 : 50
@@ -42,6 +43,234 @@ describe('vapor transition', () => {
4243
await page().waitForSelector('#app')
4344
})
4445

46+
describe('transition with v-if', () => {
47+
test(
48+
'basic transition',
49+
async () => {
50+
const btnSelector = '.if-basic > button'
51+
const containerSelector = '.if-basic > div'
52+
const childSelector = `${containerSelector} > div`
53+
54+
expect(await html(containerSelector)).toBe(
55+
`<div class="test">content</div>`,
56+
)
57+
58+
// leave
59+
expect(
60+
(await transitionStart(btnSelector, childSelector)).classNames,
61+
).toStrictEqual(['test', 'v-leave-from', 'v-leave-active'])
62+
63+
await nextFrame()
64+
expect(await classList(childSelector)).toStrictEqual([
65+
'test',
66+
'v-leave-active',
67+
'v-leave-to',
68+
])
69+
await transitionFinish()
70+
expect(await html(containerSelector)).toBe('')
71+
72+
// enter
73+
expect(
74+
(await transitionStart(btnSelector, childSelector)).classNames,
75+
).toStrictEqual(['test', 'v-enter-from', 'v-enter-active'])
76+
await nextFrame()
77+
expect(await classList(childSelector)).toStrictEqual([
78+
'test',
79+
'v-enter-active',
80+
'v-enter-to',
81+
])
82+
await transitionFinish()
83+
expect(await html(containerSelector)).toBe(
84+
'<div class="test">content</div>',
85+
)
86+
},
87+
E2E_TIMEOUT,
88+
)
89+
90+
test(
91+
'named transition',
92+
async () => {
93+
const btnSelector = '.if-named > button'
94+
const containerSelector = '.if-named > div'
95+
const childSelector = `${containerSelector} > div`
96+
97+
expect(await html(containerSelector)).toBe(
98+
'<div class="test">content</div>',
99+
)
100+
101+
// leave
102+
expect(
103+
(await transitionStart(btnSelector, childSelector)).classNames,
104+
).toStrictEqual(['test', 'test-leave-from', 'test-leave-active'])
105+
await nextFrame()
106+
expect(await classList(childSelector)).toStrictEqual([
107+
'test',
108+
'test-leave-active',
109+
'test-leave-to',
110+
])
111+
112+
await transitionFinish()
113+
expect(await html(containerSelector)).toBe('')
114+
115+
// enter
116+
expect(
117+
(await transitionStart(btnSelector, childSelector)).classNames,
118+
).toStrictEqual(['test', 'test-enter-from', 'test-enter-active'])
119+
await nextFrame()
120+
expect(await classList(childSelector)).toStrictEqual([
121+
'test',
122+
'test-enter-active',
123+
'test-enter-to',
124+
])
125+
await transitionFinish()
126+
expect(await html(containerSelector)).toBe(
127+
'<div class="test">content</div>',
128+
)
129+
},
130+
E2E_TIMEOUT,
131+
)
132+
133+
test(
134+
'custom transition classes',
135+
async () => {
136+
const btnSelector = '.if-custom-classes > button'
137+
const containerSelector = '.if-custom-classes > div'
138+
const childSelector = `${containerSelector} > div`
139+
140+
expect(await html(containerSelector)).toBe(
141+
'<div class="test">content</div>',
142+
)
143+
// leave
144+
expect(
145+
(await transitionStart(btnSelector, childSelector)).classNames,
146+
).toStrictEqual(['test', 'bye-from', 'bye-active'])
147+
await nextFrame()
148+
expect(await classList(childSelector)).toStrictEqual([
149+
'test',
150+
'bye-active',
151+
'bye-to',
152+
])
153+
await transitionFinish()
154+
expect(await html(containerSelector)).toBe('')
155+
156+
// enter
157+
expect(
158+
(await transitionStart(btnSelector, childSelector)).classNames,
159+
).toStrictEqual(['test', 'hello-from', 'hello-active'])
160+
await nextFrame()
161+
expect(await classList(childSelector)).toStrictEqual([
162+
'test',
163+
'hello-active',
164+
'hello-to',
165+
])
166+
await transitionFinish()
167+
expect(await html(containerSelector)).toBe(
168+
'<div class="test">content</div>',
169+
)
170+
},
171+
E2E_TIMEOUT,
172+
)
173+
174+
test(
175+
'transition with dynamic name',
176+
async () => {
177+
const btnSelector = '.if-dynamic-name > button.toggle'
178+
const btnChangeNameSelector = '.if-dynamic-name > button.change'
179+
const containerSelector = '.if-dynamic-name > div'
180+
const childSelector = `${containerSelector} > div`
181+
182+
expect(await html(containerSelector)).toBe(
183+
'<div class="test">content</div>',
184+
)
185+
186+
// leave
187+
expect(
188+
(await transitionStart(btnSelector, childSelector)).classNames,
189+
).toStrictEqual(['test', 'test-leave-from', 'test-leave-active'])
190+
await nextFrame()
191+
expect(await classList(childSelector)).toStrictEqual([
192+
'test',
193+
'test-leave-active',
194+
'test-leave-to',
195+
])
196+
await transitionFinish()
197+
expect(await html(containerSelector)).toBe('')
198+
199+
// enter
200+
await click(btnChangeNameSelector)
201+
expect(
202+
(await transitionStart(btnSelector, childSelector)).classNames,
203+
).toStrictEqual(['test', 'changed-enter-from', 'changed-enter-active'])
204+
await nextFrame()
205+
expect(await classList(childSelector)).toStrictEqual([
206+
'test',
207+
'changed-enter-active',
208+
'changed-enter-to',
209+
])
210+
await transitionFinish()
211+
expect(await html(containerSelector)).toBe(
212+
'<div class="test">content</div>',
213+
)
214+
},
215+
E2E_TIMEOUT,
216+
)
217+
test.todo('transition events without appear', async () => {}, E2E_TIMEOUT)
218+
test.todo('events with arguments', async () => {}, E2E_TIMEOUT)
219+
test.todo('onEnterCancelled', async () => {}, E2E_TIMEOUT)
220+
test.todo('transition on appear', async () => {}, E2E_TIMEOUT)
221+
test.todo('transition events with appear', async () => {}, E2E_TIMEOUT)
222+
test.todo('no transition detected', async () => {}, E2E_TIMEOUT)
223+
test.todo('animations', async () => {}, E2E_TIMEOUT)
224+
test.todo('explicit transition type', async () => {}, E2E_TIMEOUT)
225+
test.todo('transition on SVG elements', async () => {}, E2E_TIMEOUT)
226+
test.todo(
227+
'custom transition higher-order component',
228+
async () => {},
229+
E2E_TIMEOUT,
230+
)
231+
test.todo(
232+
'transition on child components with empty root node',
233+
async () => {},
234+
E2E_TIMEOUT,
235+
)
236+
test.todo(
237+
'transition with v-if at component root-level',
238+
async () => {},
239+
E2E_TIMEOUT,
240+
)
241+
test.todo(
242+
'wrapping transition + fallthrough attrs',
243+
async () => {},
244+
E2E_TIMEOUT,
245+
)
246+
test.todo(
247+
'transition + fallthrough attrs (in-out mode)',
248+
async () => {},
249+
E2E_TIMEOUT,
250+
)
251+
})
252+
253+
describe('transition with v-show', () => {
254+
test.todo('named transition with v-show', async () => {}, E2E_TIMEOUT)
255+
test.todo('transition events with v-show', async () => {}, E2E_TIMEOUT)
256+
test.todo('onLeaveCancelled (v-show only)', async () => {}, E2E_TIMEOUT)
257+
test.todo('transition on appear with v-show', async () => {}, E2E_TIMEOUT)
258+
test.todo(
259+
'transition events should not call onEnter with v-show false',
260+
async () => {},
261+
E2E_TIMEOUT,
262+
)
263+
test.todo('transition on appear with v-show', async () => {}, E2E_TIMEOUT)
264+
})
265+
266+
describe('explicit durations', () => {
267+
test.todo('single value', async () => {}, E2E_TIMEOUT)
268+
test.todo('enter with explicit durations', async () => {}, E2E_TIMEOUT)
269+
test.todo('leave with explicit durations', async () => {}, E2E_TIMEOUT)
270+
test.todo('separate enter and leave', async () => {}, E2E_TIMEOUT)
271+
test.todo('warn invalid durations', async () => {}, E2E_TIMEOUT)
272+
})
273+
45274
test(
46275
'should work with v-show',
47276
async () => {

packages-private/vapor-e2e-test/transition/App.vue

+43
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,53 @@ function toggleInteropComponent() {
2323
interopComponent.value =
2424
interopComponent.value === VaporCompA ? VDomComp : VaporCompA
2525
}
26+
27+
const name = ref('test')
2628
</script>
2729

2830
<template>
2931
<div class="transition-container">
32+
<div class="if-basic">
33+
<div>
34+
<transition>
35+
<div v-if="toggle" class="test">content</div>
36+
</transition>
37+
</div>
38+
<button @click="toggle = !toggle">basic toggle</button>
39+
</div>
40+
<div class="if-named">
41+
<div>
42+
<transition name="test">
43+
<div v-if="toggle" class="test">content</div>
44+
</transition>
45+
</div>
46+
<button @click="toggle = !toggle">button</button>
47+
</div>
48+
<div class="if-custom-classes">
49+
<div>
50+
<transition
51+
enter-from-class="hello-from"
52+
enter-active-class="hello-active"
53+
enter-to-class="hello-to"
54+
leave-from-class="bye-from"
55+
leave-active-class="bye-active"
56+
leave-to-class="bye-to"
57+
>
58+
<div v-if="toggle" class="test">content</div>
59+
</transition>
60+
</div>
61+
<button @click="toggle = !toggle">button</button>
62+
</div>
63+
<div class="if-dynamic-name">
64+
<div>
65+
<transition :name="name">
66+
<div v-if="toggle" class="test">content</div>
67+
</transition>
68+
</div>
69+
<button class="toggle" @click="toggle = !toggle">button</button>
70+
<button class="change" @click="name = 'changed'">{{ name }}</button>
71+
</div>
72+
3073
<div class="vshow">
3174
<button @click="show = !show">Show</button>
3275
<Transition>

packages-private/vapor-e2e-test/transition/style.css

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,4 @@
3232

3333
.test-leave-active {
3434
position: absolute;
35-
}
35+
}

packages/runtime-core/src/components/BaseTransition.ts

+8-2
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ const BaseTransitionImpl: ComponentOptions = {
168168
const rawProps = toRaw(props)
169169
const { mode } = rawProps
170170
// check mode
171-
__DEV__ && checkTransitionMode(mode)
171+
checkTransitionMode(mode)
172172

173173
if (state.isLeaving) {
174174
return emptyPlaceholder(child)
@@ -619,7 +619,13 @@ export function getTransitionRawChildren(
619619
* dev-only
620620
*/
621621
export function checkTransitionMode(mode: string | undefined): void {
622-
if (mode && mode !== 'in-out' && mode !== 'out-in' && mode !== 'default') {
622+
if (
623+
__DEV__ &&
624+
mode &&
625+
mode !== 'in-out' &&
626+
mode !== 'out-in' &&
627+
mode !== 'default'
628+
) {
623629
warn(`invalid <transition> mode: ${mode}`)
624630
}
625631
}

packages/runtime-vapor/src/components/Transition.ts

+14-4
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import {
2323
} from '../block'
2424
import { type VaporComponentInstance, isVaporComponent } from '../component'
2525
import { isArray } from '@vue/shared'
26+
import { renderEffect } from '../renderEffect'
2627

2728
const decorate = (t: typeof VaporTransition) => {
2829
t.displayName = 'VaporTransition'
@@ -37,12 +38,21 @@ export const VaporTransition: FunctionalComponent<TransitionProps> =
3738
if (!children) return
3839

3940
const { mode } = props
40-
__DEV__ && checkTransitionMode(mode)
41+
checkTransitionMode(mode)
4142

42-
applyTransitionEnterHooks(children, {
43+
let resolvedProps
44+
renderEffect(() => {
45+
resolvedProps = resolveTransitionProps(props)
46+
if (isFragment(children) && children.$transition) {
47+
children.$transition.props = resolvedProps
48+
}
49+
})
50+
51+
const hooks = {
4352
state: useTransitionState(),
44-
props: resolveTransitionProps(props),
45-
} as VaporTransitionHooks)
53+
props: resolvedProps!,
54+
} as VaporTransitionHooks
55+
applyTransitionEnterHooks(children, hooks)
4656

4757
return children
4858
})

0 commit comments

Comments
 (0)