fix(transition): preserve placeholder for conditional explicit default slots#14748
Conversation
📝 WalkthroughWalkthroughFixes a null-reference during rapid toggles of a by returning a comment VNode when the slot is empty but an existing instance subtree is present, and adds an e2e test reproducing the quick-toggle scenario. Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Size ReportBundles
Usages
|
@vue/compiler-core
@vue/compiler-dom
@vue/compiler-sfc
@vue/compiler-ssr
@vue/reactivity
@vue/runtime-core
@vue/runtime-dom
@vue/server-renderer
@vue/shared
vue
@vue/compat
commit: |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/vue/__tests__/e2e/Transition.spec.ts`:
- Around line 1438-1478: Wrap the code between currentPage.on('pageerror', spy)
and currentPage.off('pageerror', spy) in a try/finally so the listener is always
removed; specifically, after calling currentPage.on('pageerror', spy) create a
try block that contains the page().evaluate setup, the assertions (expects), the
clicks/nextTick/nextFrame/transitionFinish calls, and then place
currentPage.off('pageerror', spy) in the finally block to guarantee cleanup even
if an assertion fails; ensure the spy variable remains in scope and no other
logic is moved outside the try so behavior of click, nextTick, transitionFinish,
html, and $$eval remains unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 230207e7-c32c-4ed7-b60a-d957118c3506
📒 Files selected for processing (2)
packages/runtime-core/src/components/BaseTransition.tspackages/vue/__tests__/e2e/Transition.spec.ts
There was a problem hiding this comment.
♻️ Duplicate comments (1)
packages/vue/__tests__/e2e/Transition.spec.ts (1)
1438-1477:⚠️ Potential issue | 🟡 MinorAlways detach
pageerrorlistener viatry/finally.If any assertion throws before Line 1477, the listener remains attached and can leak into subsequent tests.
Proposed fix
const spy = vi.fn() const currentPage = page() currentPage.on('pageerror', spy) - await page().evaluate(() => { + try { + await page().evaluate(() => { const { createApp, ref } = (window as any).Vue createApp({ template: ` <div id="container"> <transition name="test"> <template v-if="show" #> <div class="test">text</div> </template> </transition> </div> <button id="toggleBtn" `@click`="show = !show">button</button> `, setup: () => { const show = ref(true) return { show } }, }).mount('#app') - }) + }) - expect(await html('#container')).toBe('<div class="test">text</div>') + expect(await html('#container')).toBe('<div class="test">text</div>') - await click('#toggleBtn') - await nextTick() - await click('#toggleBtn') + await click('#toggleBtn') + await nextTick() + await click('#toggleBtn') - expect( - await page().$$eval('#container .test', nodes => - nodes.map(node => node.className), - ), - ).toStrictEqual(['test test-enter-from test-enter-active']) + expect( + await page().$$eval('#container .test', nodes => + nodes.map(node => node.className), + ), + ).toStrictEqual(['test test-enter-from test-enter-active']) - await nextFrame() - await transitionFinish() - await nextFrame() + await nextFrame() + await transitionFinish() + await nextFrame() - expect(spy).not.toHaveBeenCalled() - currentPage.off('pageerror', spy) - expect(await html('#container')).toBe('<div class="test">text</div>') + expect(spy).not.toHaveBeenCalled() + expect(await html('#container')).toBe('<div class="test">text</div>') + } finally { + currentPage.off('pageerror', spy) + }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/vue/__tests__/e2e/Transition.spec.ts` around lines 1438 - 1477, Wrap the lifecycle of the pageerror listener (currentPage.on('pageerror', spy)) in a try/finally inside the test so the listener is always removed with currentPage.off('pageerror', spy) in the finally block; update the test around the lines that call currentPage.on/currentPage.off and assertions (where spy is used) to ensure the try contains the evaluate/click/expect/transition steps and the finally calls currentPage.off('pageerror', spy) to avoid leaking the listener into other tests.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@packages/vue/__tests__/e2e/Transition.spec.ts`:
- Around line 1438-1477: Wrap the lifecycle of the pageerror listener
(currentPage.on('pageerror', spy)) in a try/finally inside the test so the
listener is always removed with currentPage.off('pageerror', spy) in the finally
block; update the test around the lines that call currentPage.on/currentPage.off
and assertions (where spy is used) to ensure the try contains the
evaluate/click/expect/transition steps and the finally calls
currentPage.off('pageerror', spy) to avoid leaking the listener into other
tests.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: dcc2a8a0-4eb3-4d93-a22a-ec3fc1102117
📒 Files selected for processing (1)
packages/vue/__tests__/e2e/Transition.spec.ts
|
/ecosystem-ci run |
|
📝 Ran ecosystem CI: Open
|
close #14727
Summary by CodeRabbit
Bug Fixes
Tests