]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
test: add more tests
authordaiwei <daiwei521@126.com>
Thu, 13 Mar 2025 08:00:51 +0000 (16:00 +0800)
committerdaiwei <daiwei521@126.com>
Thu, 13 Mar 2025 08:00:51 +0000 (16:00 +0800)
packages-private/vapor-e2e-test/__tests__/transition.spec.ts
packages-private/vapor-e2e-test/transition/App.vue

index 52b3bb95049da861203355403e44ab1366480642..dde8e33540df3246ebad54224e70fe1516d8a9d5 100644 (file)
@@ -231,7 +231,7 @@ describe('vapor transition', () => {
         ).toStrictEqual(['test', 'test-leave-from', 'test-leave-active'])
 
         let calls = await page().evaluate(() => {
-          return (window as any).getCalls('withOutAppear')
+          return (window as any).getCalls('withoutAppear')
         })
         expect(calls).toStrictEqual(['beforeLeave', 'onLeave'])
         await nextFrame()
@@ -243,19 +243,19 @@ describe('vapor transition', () => {
 
         expect(
           await page().evaluate(() => {
-            return (window as any).getCalls('withOutAppear')
+            return (window as any).getCalls('withoutAppear')
           }),
         ).not.contain('afterLeave')
         await transitionFinish()
         expect(await html(containerSelector)).toBe('')
         expect(
           await page().evaluate(() => {
-            return (window as any).getCalls('withOutAppear')
+            return (window as any).getCalls('withoutAppear')
           }),
         ).toStrictEqual(['beforeLeave', 'onLeave', 'afterLeave'])
 
         await page().evaluate(() => {
-          ;(window as any).resetCalls('withOutAppear')
+          ;(window as any).resetCalls('withoutAppear')
         })
 
         // enter
@@ -264,7 +264,7 @@ describe('vapor transition', () => {
         ).toStrictEqual(['test', 'test-enter-from', 'test-enter-active'])
 
         calls = await page().evaluate(() => {
-          return (window as any).getCalls('withOutAppear')
+          return (window as any).getCalls('withoutAppear')
         })
         expect(calls).toStrictEqual(['beforeEnter', 'onEnter'])
         await nextFrame()
@@ -275,7 +275,7 @@ describe('vapor transition', () => {
         ])
         expect(
           await page().evaluate(() => {
-            return (window as any).getCalls('withOutAppear')
+            return (window as any).getCalls('withoutAppear')
           }),
         ).not.contain('afterEnter')
         await transitionFinish()
@@ -284,7 +284,7 @@ describe('vapor transition', () => {
         )
         expect(
           await page().evaluate(() => {
-            return (window as any).getCalls('withOutAppear')
+            return (window as any).getCalls('withoutAppear')
           }),
         ).toStrictEqual(['beforeEnter', 'onEnter', 'afterEnter'])
       },
@@ -389,30 +389,395 @@ describe('vapor transition', () => {
       E2E_TIMEOUT,
     )
 
-    test.todo(
+    test(
       'transition on appear',
       async () => {
         const btnSelector = '.if-appear > button'
         const containerSelector = '.if-appear > div'
         const childSelector = `${containerSelector} > div`
+
+        // appear
+        expect(await classList(childSelector)).contains('test-appear-active')
+        await transitionFinish()
+        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',
+        ])
+        await transitionFinish()
+        expect(await html(containerSelector)).toBe('')
+
+        // 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,
     )
-    test.todo('transition events with appear', async () => {}, E2E_TIMEOUT)
-    test.todo('no transition detected', async () => {}, E2E_TIMEOUT)
-    test.todo('animations', async () => {}, E2E_TIMEOUT)
-    test.todo('explicit transition type', async () => {}, E2E_TIMEOUT)
+
+    test(
+      'transition events with appear',
+      async () => {
+        const btnSelector = '.if-events-with-appear > button'
+        const containerSelector = '.if-events-with-appear > div'
+        const childSelector = `${containerSelector} > div`
+        // appear
+        expect(await classList(childSelector)).contains('test-appear-active')
+        let calls = await page().evaluate(() => {
+          return (window as any).getCalls('withAppear')
+        })
+        expect(calls).toStrictEqual(['beforeAppear', 'onAppear'])
+
+        await transitionFinish()
+        expect(await html(containerSelector)).toBe(
+          '<div class="test">content</div>',
+        )
+        calls = await page().evaluate(() => {
+          return (window as any).getCalls('withAppear')
+        })
+        expect(calls).toStrictEqual(['beforeAppear', 'onAppear', 'afterAppear'])
+
+        await page().evaluate(() => {
+          ;(window as any).resetCalls('withAppear')
+        })
+
+        // leave
+        expect(
+          (await transitionStart(btnSelector, childSelector)).classNames,
+        ).toStrictEqual(['test', 'test-leave-from', 'test-leave-active'])
+
+        calls = await page().evaluate(() => {
+          return (window as any).getCalls('withAppear')
+        })
+        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('withAppear')
+        })
+        expect(calls).not.contain('afterLeave')
+
+        await transitionFinish()
+        expect(await html(containerSelector)).toBe('')
+        calls = await page().evaluate(() => {
+          return (window as any).getCalls('withAppear')
+        })
+        expect(calls).toStrictEqual(['beforeLeave', 'onLeave', 'afterLeave'])
+
+        await page().evaluate(() => {
+          ;(window as any).resetCalls('withAppear')
+        })
+
+        // enter
+        expect(
+          (await transitionStart(btnSelector, childSelector)).classNames,
+        ).toStrictEqual(['test', 'test-enter-from', 'test-enter-active'])
+        calls = await page().evaluate(() => {
+          return (window as any).getCalls('withAppear')
+        })
+        expect(calls).toStrictEqual(['beforeEnter', 'onEnter'])
+        await nextFrame()
+        expect(await classList(childSelector)).toStrictEqual([
+          'test',
+          'test-enter-active',
+          'test-enter-to',
+        ])
+        calls = await page().evaluate(() => {
+          return (window as any).getCalls('withAppear')
+        })
+        expect(calls).not.contain('afterEnter')
+        await transitionFinish()
+        expect(await html(containerSelector)).toBe(
+          '<div class="test">content</div>',
+        )
+        calls = await page().evaluate(() => {
+          return (window as any).getCalls('withAppear')
+        })
+        expect(calls).toStrictEqual(['beforeEnter', 'onEnter', 'afterEnter'])
+      },
+      E2E_TIMEOUT,
+    )
+    test(
+      'css: false',
+      async () => {
+        const btnSelector = '.if-css-false > button'
+        const containerSelector = '.if-css-false > div'
+        const childSelector = `${containerSelector} > div`
+        expect(await html(containerSelector)).toBe(
+          '<div class="test">content</div>',
+        )
+
+        // leave
+        await click(btnSelector)
+        let calls = await page().evaluate(() => {
+          return (window as any).getCalls('cssFalse')
+        })
+        expect(calls).toStrictEqual(['beforeLeave', 'onLeave', 'afterLeave'])
+        expect(await html(containerSelector)).toBe('')
+
+        await page().evaluate(() => {
+          ;(window as any).resetCalls('cssFalse')
+        })
+
+        // enter
+        await transitionStart(btnSelector, childSelector)
+        calls = await page().evaluate(() => {
+          return (window as any).getCalls('cssFalse')
+        })
+        expect(calls).toStrictEqual(['beforeEnter', 'onEnter', 'afterEnter'])
+        expect(await html(containerSelector)).toBe(
+          '<div class="test">content</div>',
+        )
+      },
+      E2E_TIMEOUT,
+    )
+
+    test(
+      'no transition detected',
+      async () => {
+        const btnSelector = '.if-no-trans > button'
+        const containerSelector = '.if-no-trans > div'
+        const childSelector = `${containerSelector} > div`
+
+        expect(await html(containerSelector)).toBe('<div>content</div>')
+        // leave
+        expect(
+          (await transitionStart(btnSelector, childSelector)).classNames,
+        ).toStrictEqual(['noop-leave-from', 'noop-leave-active'])
+        await nextFrame()
+        expect(await html(containerSelector)).toBe('')
+
+        // enter
+        expect(
+          (await transitionStart(btnSelector, childSelector)).classNames,
+        ).toStrictEqual(['noop-enter-from', 'noop-enter-active'])
+        await nextFrame()
+        expect(await html(containerSelector)).toBe(
+          '<div class="">content</div>',
+        )
+      },
+      E2E_TIMEOUT,
+    )
+
+    test(
+      'animations',
+      async () => {
+        const btnSelector = '.if-ani > button'
+        const containerSelector = '.if-ani > div'
+        const childSelector = `${containerSelector} > div`
+
+        expect(await html(containerSelector)).toBe('<div>content</div>')
+
+        // leave
+        expect(
+          (await transitionStart(btnSelector, childSelector)).classNames,
+        ).toStrictEqual(['test-anim-leave-from', 'test-anim-leave-active'])
+        await nextFrame()
+        expect(await classList(childSelector)).toStrictEqual([
+          'test-anim-leave-active',
+          'test-anim-leave-to',
+        ])
+        await transitionFinish(duration * 2)
+        expect(await html(containerSelector)).toBe('')
+
+        // enter
+        expect(
+          (await transitionStart(btnSelector, childSelector)).classNames,
+        ).toStrictEqual(['test-anim-enter-from', 'test-anim-enter-active'])
+        await nextFrame()
+        expect(await classList(childSelector)).toStrictEqual([
+          'test-anim-enter-active',
+          'test-anim-enter-to',
+        ])
+        await transitionFinish()
+        expect(await html(containerSelector)).toBe(
+          '<div class="">content</div>',
+        )
+      },
+      E2E_TIMEOUT,
+    )
+
+    test(
+      'explicit transition type',
+      async () => {
+        const btnSelector = '.if-ani-explicit-type > button'
+        const containerSelector = '.if-ani-explicit-type > div'
+        const childSelector = `${containerSelector} > div`
+
+        expect(await html(containerSelector)).toBe('<div>content</div>')
+
+        // leave
+        expect(
+          (await transitionStart(btnSelector, childSelector)).classNames,
+        ).toStrictEqual([
+          'test-anim-long-leave-from',
+          'test-anim-long-leave-active',
+        ])
+        await nextFrame()
+        expect(await classList(childSelector)).toStrictEqual([
+          'test-anim-long-leave-active',
+          'test-anim-long-leave-to',
+        ])
+
+        if (!process.env.CI) {
+          await new Promise(r => {
+            setTimeout(r, duration - buffer)
+          })
+          expect(await classList(childSelector)).toStrictEqual([
+            'test-anim-long-leave-active',
+            'test-anim-long-leave-to',
+          ])
+        }
+
+        await transitionFinish(duration * 2)
+        expect(await html(containerSelector)).toBe('')
+
+        // enter
+        expect(
+          (await transitionStart(btnSelector, childSelector)).classNames,
+        ).toStrictEqual([
+          'test-anim-long-enter-from',
+          'test-anim-long-enter-active',
+        ])
+        await nextFrame()
+        expect(await classList(childSelector)).toStrictEqual([
+          'test-anim-long-enter-active',
+          'test-anim-long-enter-to',
+        ])
+
+        if (!process.env.CI) {
+          await new Promise(r => {
+            setTimeout(r, duration - buffer)
+          })
+          expect(await classList(childSelector)).toStrictEqual([
+            'test-anim-long-enter-active',
+            'test-anim-long-enter-to',
+          ])
+        }
+
+        await transitionFinish(duration * 2)
+        expect(await html(containerSelector)).toBe(
+          '<div class="">content</div>',
+        )
+      },
+      E2E_TIMEOUT,
+    )
+
     test.todo('transition on SVG elements', async () => {}, E2E_TIMEOUT)
-    test.todo(
+
+    test(
       'custom transition higher-order component',
-      async () => {},
+      async () => {
+        const btnSelector = '.if-high-order > button'
+        const containerSelector = '.if-high-order > 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',
+        ])
+        await transitionFinish()
+        expect(await html(containerSelector)).toBe('')
+
+        // 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,
     )
-    test.todo(
+
+    test(
       'transition on child components with empty root node',
-      async () => {},
+      async () => {
+        const btnSelector = '.if-empty-root > button.toggle'
+        const btnChangeSelector = '.if-empty-root > button.change'
+        const containerSelector = '.if-empty-root > div'
+        const childSelector = `${containerSelector} > div`
+
+        expect(await html(containerSelector)).toBe('')
+
+        // change view -> 'two'
+        await click(btnChangeSelector)
+
+        // 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">two</div>',
+        )
+
+        // change view -> 'one'
+        await click(btnChangeSelector)
+
+        // 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('')
+      },
       E2E_TIMEOUT,
     )
+
     test.todo(
       'transition with v-if at component root-level',
       async () => {},
index 1ccc6a452b6e65d00861a5f095f2c67aef48c3c7..ade9c08dc5e47e05218356752fa6760b4de29a2d 100644 (file)
@@ -1,5 +1,13 @@
 <script vapor>
-import { ref, shallowRef } from 'vue'
+import {
+  createComponent,
+  defineVaporComponent,
+  ref,
+  shallowRef,
+  VaporTransition,
+  createIf,
+  template,
+} from 'vue'
 const show = ref(true)
 const toggle = ref(true)
 const count = ref(0)
@@ -8,9 +16,11 @@ const timeout = (fn, time) => setTimeout(fn, time)
 
 let calls = {
   basic: [],
-  withOutAppear: [],
+  withoutAppear: [],
   withArgs: [],
   enterCancel: [],
+  withAppear: [],
+  cssFalse: [],
 }
 window.getCalls = key => calls[key]
 window.resetCalls = key => (calls[key] = [])
@@ -33,6 +43,28 @@ function toggleInteropComponent() {
 }
 
 const name = ref('test')
+const MyTransition = defineVaporComponent((props, { slots }) => {
+  return createComponent(VaporTransition, { name: () => 'test' }, slots)
+})
+
+const One = defineVaporComponent({
+  setup() {
+    return createIf(
+      () => false,
+      () => template('<div>one</div>', true)(),
+    )
+  },
+})
+
+const Two = defineVaporComponent({
+  setup() {
+    return template('<div>two</div>', true)()
+  },
+})
+const view = shallowRef(One)
+function changeView() {
+  view.value = view.value === One ? Two : One
+}
 </script>
 
 <template>
@@ -81,12 +113,12 @@ const name = ref('test')
       <div>
         <transition
           name="test"
-          @before-enter="() => calls.withOutAppear.push('beforeEnter')"
-          @enter="() => calls.withOutAppear.push('onEnter')"
-          @after-enter="() => calls.withOutAppear.push('afterEnter')"
-          @beforeLeave="() => calls.withOutAppear.push('beforeLeave')"
-          @leave="() => calls.withOutAppear.push('onLeave')"
-          @afterLeave="() => calls.withOutAppear.push('afterLeave')"
+          @before-enter="() => calls.withoutAppear.push('beforeEnter')"
+          @enter="() => calls.withoutAppear.push('onEnter')"
+          @after-enter="() => calls.withoutAppear.push('afterEnter')"
+          @beforeLeave="() => calls.withoutAppear.push('beforeLeave')"
+          @leave="() => calls.withoutAppear.push('onLeave')"
+          @afterLeave="() => calls.withoutAppear.push('afterLeave')"
         >
           <div v-if="toggle" class="test">content</div>
         </transition>
@@ -139,7 +171,7 @@ const name = ref('test')
           <div v-if="toggle" class="test">content</div>
         </transition>
       </div>
-      <button id="toggleBtn" @click="toggle = !toggle">button</button>
+      <button @click="toggle = !toggle">button</button>
     </div>
     <div class="if-enter-cancelled">
       <div>
@@ -170,6 +202,87 @@ const name = ref('test')
       </div>
       <button @click="toggle = !toggle">button</button>
     </div>
+    <div class="if-events-with-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.withAppear.push('beforeEnter')"
+          @enter="() => calls.withAppear.push('onEnter')"
+          @afterEnter="() => calls.withAppear.push('afterEnter')"
+          @beforeLeave="() => calls.withAppear.push('beforeLeave')"
+          @leave="() => calls.withAppear.push('onLeave')"
+          @afterLeave="() => calls.withAppear.push('afterLeave')"
+          @beforeAppear="() => calls.withAppear.push('beforeAppear')"
+          @appear="() => calls.withAppear.push('onAppear')"
+          @afterAppear="() => calls.withAppear.push('afterAppear')"
+        >
+          <div v-if="toggle" class="test">content</div>
+        </transition>
+      </div>
+      <button @click="toggle = !toggle">button</button>
+    </div>
+    <div class="if-css-false">
+      <div>
+        <transition
+          :css="false"
+          name="test"
+          @beforeEnter="() => calls.cssFalse.push('beforeEnter')"
+          @enter="() => calls.cssFalse.push('onEnter')"
+          @afterEnter="() => calls.cssFalse.push('afterEnter')"
+          @beforeLeave="() => calls.cssFalse.push('beforeLeave')"
+          @leave="() => calls.cssFalse.push('onLeave')"
+          @afterLeave="() => calls.cssFalse.push('afterLeave')"
+        >
+          <div v-if="toggle" class="test">content</div>
+        </transition>
+      </div>
+      <button @click="toggle = !toggle"></button>
+    </div>
+    <div class="if-no-trans">
+      <div>
+        <transition name="noop">
+          <div v-if="toggle">content</div>
+        </transition>
+      </div>
+      <button @click="toggle = !toggle">button</button>
+    </div>
+    <div class="if-ani">
+      <div>
+        <transition name="test-anim">
+          <div v-if="toggle">content</div>
+        </transition>
+      </div>
+      <button @click="toggle = !toggle">button</button>
+    </div>
+    <div class="if-ani-explicit-type">
+      <div>
+        <transition name="test-anim-long" type="animation">
+          <div v-if="toggle">content</div>
+        </transition>
+      </div>
+      <button @click="toggle = !toggle">button</button>
+    </div>
+    <div class="if-high-order">
+      <div>
+        <MyTransition>
+          <div v-if="toggle" class="test">content</div>
+        </MyTransition>
+      </div>
+      <button @click="toggle = !toggle">button</button>
+    </div>
+    <div class="if-empty-root">
+      <div>
+        <transition name="test">
+          <component class="test" :is="view"></component>
+        </transition>
+      </div>
+      <button class="toggle" @click="toggle = !toggle">button</button>
+      <button class="change" @click="changeView">changeView button</button>
+    </div>
 
     <div class="vshow">
       <button @click="show = !show">Show</button>