Skip to content

Commit be8a4b3

Browse files
Add failing Cypress test for Suspense reveal of memoized content (#3832)
Co-authored-by: Matt Perry <mattgperry@users.noreply.github.com>
1 parent ef59724 commit be8a4b3

2 files changed

Lines changed: 66 additions & 0 deletions

File tree

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { motion } from "framer-motion"
2+
import { Suspense, useState } from "react"
3+
4+
/**
5+
* The suspending sibling owns the state, so when the boundary reveals the
6+
* motion.div again it bails out of rendering - the same thing happens when
7+
* the React Compiler memoizes JSX (issue #3832).
8+
*/
9+
const Suspender = () => {
10+
const [promise, setPromise] = useState<Promise<void> | null>(null)
11+
12+
if (promise) throw promise
13+
14+
return (
15+
<button
16+
id="suspend"
17+
onClick={() => {
18+
const pending = new Promise<void>((resolve) =>
19+
setTimeout(() => {
20+
setPromise(null)
21+
resolve()
22+
}, 200)
23+
)
24+
setPromise(pending)
25+
}}
26+
>
27+
Suspend
28+
</button>
29+
)
30+
}
31+
32+
export const App = () => (
33+
<Suspense fallback={<div id="fallback">Suspended</div>}>
34+
<Suspender />
35+
<motion.div
36+
id="box"
37+
initial={{ opacity: 0 }}
38+
animate={{ opacity: 1 }}
39+
transition={{ duration: 0.2 }}
40+
style={{ width: 100, height: 100, background: "blue" }}
41+
/>
42+
</Suspense>
43+
)
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
const getOpacity = ([$element]: any) =>
2+
parseFloat(window.getComputedStyle($element).opacity)
3+
4+
describe("Suspense reveal of memoized content", () => {
5+
it("replays the enter animation when a re-suspended boundary reveals", () => {
6+
cy.visit("?test=suspense-reveal-memoized")
7+
.get("#box")
8+
.should(($element: any) => {
9+
expect(getOpacity($element)).to.equal(1)
10+
})
11+
.get("#suspend")
12+
.trigger("click", 1, 1, { force: true })
13+
.get("#fallback")
14+
.should("exist")
15+
.get("#fallback", { timeout: 2000 })
16+
.should("not.exist")
17+
.wait(500)
18+
.get("#box")
19+
.then(($element: any) => {
20+
expect(getOpacity($element)).to.equal(1)
21+
})
22+
})
23+
})

0 commit comments

Comments
 (0)