Skip to content

Commit 8d0a9b9

Browse files
committed
test: Add scroll test
1 parent bf56cb7 commit 8d0a9b9

File tree

16 files changed

+125
-0
lines changed

16 files changed

+125
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { testScroll } from 'e2e-shared/specs/scroll.cy'
2+
3+
testScroll({
4+
path: '/app/scroll',
5+
nextJsRouter: 'app'
6+
})
7+
8+
testScroll({
9+
path: '/pages/scroll',
10+
nextJsRouter: 'pages'
11+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { Scroll } from 'e2e-shared/specs/scroll'
2+
import { Suspense } from 'react'
3+
4+
export default function Page() {
5+
return (
6+
<Suspense>
7+
<Scroll />
8+
</Suspense>
9+
)
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { Scroll } from 'e2e-shared/specs/scroll'
2+
3+
export default Scroll
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { testScroll } from 'e2e-shared/specs/scroll.cy'
2+
3+
testScroll({ path: '/scroll' })

packages/e2e/react-router/v6/src/react-router.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ const router = createBrowserRouter(
4545
<Route path="fog-of-war/result" lazy={load(import('./routes/fog-of-war.result'))} />
4646
<Route path="conditional-rendering/useQueryState" lazy={load(import('./routes/conditional-rendering.useQueryState'))} />
4747
<Route path="conditional-rendering/useQueryStates" lazy={load(import('./routes/conditional-rendering.useQueryStates'))} />
48+
<Route path="scroll" lazy={load(import('./routes/scroll'))} />
4849

4950
<Route path="render-count/:hook/:shallow/:history/:startTransition/no-loader" lazy={load(import('./routes/render-count.$hook.$shallow.$history.$startTransition.no-loader'))} />
5051
<Route path="render-count/:hook/:shallow/:history/:startTransition/sync-loader" lazy={load(import('./routes/render-count.$hook.$shallow.$history.$startTransition.sync-loader'))} />
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { Scroll } from 'e2e-shared/specs/scroll'
2+
3+
export default Scroll

packages/e2e/react-router/v7/app/routes.ts

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export default [
2828
route('/fog-of-war/result', './routes/fog-of-war.result.tsx'),
2929
route('/conditional-rendering/useQueryState', './routes/conditional-rendering.useQueryState.tsx'),
3030
route('/conditional-rendering/useQueryStates', './routes/conditional-rendering.useQueryStates.tsx'),
31+
route('/scroll', './routes/scroll.tsx'),
3132

3233
route('/render-count/:hook/:shallow/:history/:startTransition/no-loader', './routes/render-count.$hook.$shallow.$history.$startTransition.no-loader.tsx'),
3334
route('/render-count/:hook/:shallow/:history/:startTransition/sync-loader', './routes/render-count.$hook.$shallow.$history.$startTransition.sync-loader.tsx'),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { Scroll } from 'e2e-shared/specs/scroll'
2+
3+
export default Scroll
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { testScroll } from 'e2e-shared/specs/scroll.cy'
2+
3+
testScroll({ path: '/scroll' })
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { testScroll } from 'e2e-shared/specs/scroll.cy'
2+
3+
testScroll({ path: '/scroll' })

packages/e2e/react/src/routes.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ const routes: Record<string, React.LazyExoticComponent<() => JSX.Element>> = {
2323
'/referential-stability/useQueryStates': lazy(() => import('./routes/referential-stability.useQueryStates')),
2424
'/conditional-rendering/useQueryState': lazy(() => import('./routes/conditional-rendering.useQueryState')),
2525
'/conditional-rendering/useQueryStates': lazy(() => import('./routes/conditional-rendering.useQueryStates')),
26+
'/scroll': lazy(() => import('./routes/scroll')),
2627

2728
'/render-count/useQueryState/true/replace/false': lazy(() => import('./routes/render-count')),
2829
'/render-count/useQueryState/true/replace/true': lazy(() => import('./routes/render-count')),
+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { Scroll } from 'e2e-shared/specs/scroll'
2+
3+
export default Scroll
+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { Scroll } from 'e2e-shared/specs/scroll'
2+
3+
export default Scroll
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { testScroll } from 'e2e-shared/specs/scroll.cy'
2+
3+
testScroll({ path: '/scroll' })
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { createTest } from '../create-test'
2+
3+
export const testScroll = createTest('scroll', ({ path }) => {
4+
it('does not scroll to the top of the page by default (scroll: false)', () => {
5+
cy.visit(path + '?scroll=false')
6+
cy.contains('#hydration-marker', 'hydrated').should('be.hidden')
7+
cy.get('#not-at-the-top').should('be.visible')
8+
cy.get('button').click()
9+
cy.get('#not-at-the-top').should('be.visible')
10+
})
11+
it('scrolls to the top of the page when setting scroll: true', () => {
12+
cy.visit(path + '?scroll=true')
13+
cy.contains('#hydration-marker', 'hydrated').should('be.hidden')
14+
cy.get('#not-at-the-top').should('be.visible')
15+
cy.get('button').click()
16+
cy.get('#at-the-top').should('be.visible')
17+
})
18+
})

packages/e2e/shared/specs/scroll.tsx

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
'use client'
2+
3+
import { parseAsBoolean, useQueryState } from 'nuqs'
4+
import { useEffect, useState } from 'react'
5+
6+
export function Scroll() {
7+
return (
8+
<>
9+
<ScrollDetector />
10+
<div style={{ height: '200vh' }} />
11+
<ScrollAction />
12+
</>
13+
)
14+
}
15+
16+
function ScrollDetector() {
17+
const [atTheTop, setAtTheTop] = useState(false)
18+
19+
useEffect(() => {
20+
const controller = new AbortController()
21+
window.addEventListener('scroll', () => setAtTheTop(window.scrollY === 0), {
22+
signal: controller.signal
23+
})
24+
return () => controller.abort()
25+
}, [])
26+
27+
return (
28+
<span
29+
id={atTheTop ? 'at-the-top' : 'not-at-the-top'}
30+
style={{ position: 'fixed', top: 8 }}
31+
>
32+
{atTheTop ? null : 'not '}at the top
33+
</span>
34+
)
35+
}
36+
37+
function ScrollAction() {
38+
const [scroll] = useQueryState('scroll', parseAsBoolean.withDefault(false))
39+
const [, setState] = useQueryState('test', {
40+
scroll
41+
})
42+
43+
useEffect(() => {
44+
document.getElementById('scroll-to-me')?.scrollIntoView()
45+
}, [])
46+
47+
return (
48+
<button
49+
id="scroll-to-me"
50+
onClick={() => setState('pass')}
51+
style={{ marginInline: 'auto', display: 'block' }}
52+
>
53+
Test
54+
</button>
55+
)
56+
}

0 commit comments

Comments
 (0)