Skip to content

Commit 4d152d5

Browse files
akfm.satoAkifumiSato
authored andcommitted
scroll restoration bug fix test add
1 parent facd33a commit 4d152d5

File tree

3 files changed

+196
-0
lines changed

3 files changed

+196
-0
lines changed
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
import { createNext, FileRef } from 'e2e-utils'
2+
import { NextInstance } from 'test/lib/next-modes/base'
3+
import { check } from 'next-test-utils'
4+
import { join } from 'path'
5+
import webdriver from 'next-webdriver'
6+
7+
describe('reload-scroll-back-restoration', () => {
8+
let next: NextInstance
9+
10+
beforeAll(async () => {
11+
next = await createNext({
12+
files: {
13+
pages: new FileRef(join(__dirname, 'pages')),
14+
'next.config.js': new FileRef(join(__dirname, 'next.config.js')),
15+
},
16+
dependencies: {},
17+
})
18+
})
19+
afterAll(() => next.destroy())
20+
21+
it('should restore the scroll position on navigating back', async () => {
22+
const browser = await webdriver(next.url, '/0')
23+
await browser.eval(() => document.querySelector('#link').scrollIntoView())
24+
25+
// check browser restoration setting
26+
const scrollRestoration = await browser.eval(
27+
() => window.history.scrollRestoration
28+
)
29+
expect(scrollRestoration).toBe('manual')
30+
31+
const scrollPositionMemories: Array<{ x: number; y: number }> = []
32+
scrollPositionMemories.push({
33+
x: Math.floor(await browser.eval(() => window.scrollX)),
34+
y: Math.floor(await browser.eval(() => window.scrollY)),
35+
})
36+
37+
// check initial value
38+
expect(scrollPositionMemories[0].x).not.toBe(0)
39+
expect(scrollPositionMemories[0].y).not.toBe(0)
40+
41+
await browser.eval(`window.next.router.push('/1')`)
42+
await browser.eval(() => document.querySelector('#link').scrollIntoView())
43+
scrollPositionMemories.push({
44+
x: Math.floor(await browser.eval(() => window.scrollX)),
45+
y: Math.floor(await browser.eval(() => window.scrollY)),
46+
})
47+
await browser.eval(`window.next.router.push('/2')`)
48+
49+
// check restore value on history index: 1
50+
await browser.eval(() => window.history.back())
51+
await check(
52+
() => browser.eval(() => document.documentElement.innerHTML),
53+
/hydrated/
54+
)
55+
56+
expect(scrollPositionMemories[1].x).toBe(
57+
Math.floor(await browser.eval(() => window.scrollX))
58+
)
59+
expect(scrollPositionMemories[1].y).toBe(
60+
Math.floor(await browser.eval(() => window.scrollY))
61+
)
62+
63+
await browser.eval(`window.next.router.reload()`)
64+
65+
// check restore value on history index: 0
66+
await browser.eval(() => window.history.back())
67+
await check(
68+
() => browser.eval(() => document.documentElement.innerHTML),
69+
/hydrated/
70+
)
71+
72+
expect(scrollPositionMemories[0].x).toBe(
73+
Math.floor(await browser.eval(() => window.scrollX))
74+
)
75+
expect(scrollPositionMemories[0].y).toBe(
76+
Math.floor(await browser.eval(() => window.scrollY))
77+
)
78+
})
79+
80+
it('should restore the scroll position on navigating forward', async () => {
81+
const browser = await webdriver(next.url, '/0')
82+
await browser.eval(() => document.querySelector('#link').scrollIntoView())
83+
84+
// check browser restoration setting
85+
const scrollRestoration = await browser.eval(
86+
() => window.history.scrollRestoration
87+
)
88+
expect(scrollRestoration).toBe('manual')
89+
90+
const scrollPositionMemories: Array<{ x: number; y: number }> = []
91+
scrollPositionMemories.push({
92+
x: Math.floor(await browser.eval(() => window.scrollX)),
93+
y: Math.floor(await browser.eval(() => window.scrollY)),
94+
})
95+
96+
// check initial value
97+
expect(scrollPositionMemories[0].x).not.toBe(0)
98+
expect(scrollPositionMemories[0].y).not.toBe(0)
99+
100+
await browser.eval(`window.next.router.push('/1')`)
101+
await browser.eval(() => document.querySelector('#link').scrollIntoView())
102+
scrollPositionMemories.push({
103+
x: Math.floor(await browser.eval(() => window.scrollX)),
104+
y: Math.floor(await browser.eval(() => window.scrollY)),
105+
})
106+
await browser.eval(`window.next.router.push('/2')`)
107+
await browser.eval(() => document.querySelector('#link').scrollIntoView())
108+
scrollPositionMemories.push({
109+
x: Math.floor(await browser.eval(() => window.scrollX)),
110+
y: Math.floor(await browser.eval(() => window.scrollY)),
111+
})
112+
113+
// check restore value on history index: 1
114+
await browser.eval(() => window.history.back())
115+
await browser.eval(() => window.history.back())
116+
await browser.eval(() => window.history.forward())
117+
await check(
118+
() => browser.eval(() => document.documentElement.innerHTML),
119+
/hydrated/
120+
)
121+
122+
expect(scrollPositionMemories[1].x).toBe(
123+
Math.floor(await browser.eval(() => window.scrollX))
124+
)
125+
expect(scrollPositionMemories[1].y).toBe(
126+
Math.floor(await browser.eval(() => window.scrollY))
127+
)
128+
129+
await browser.eval(`window.next.router.reload()`)
130+
131+
// check restore value on history index: 2
132+
await browser.eval(() => window.history.forward())
133+
await check(
134+
() => browser.eval(() => document.documentElement.innerHTML),
135+
/hydrated/
136+
)
137+
138+
expect(scrollPositionMemories[2].x).toBe(
139+
Math.floor(await browser.eval(() => window.scrollX))
140+
)
141+
expect(scrollPositionMemories[2].y).toBe(
142+
Math.floor(await browser.eval(() => window.scrollY))
143+
)
144+
})
145+
})
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module.exports = {
2+
experimental: {
3+
scrollRestoration: true,
4+
},
5+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { useState, useEffect } from 'react'
2+
import Link from 'next/link'
3+
4+
const Page = ({ id }) => {
5+
const [hydrate, setHydrate] = useState(false)
6+
useEffect(() => {
7+
setHydrate(true)
8+
}, [hydrate, setHydrate])
9+
10+
return (
11+
<>
12+
<div
13+
style={{
14+
width: 10000,
15+
height: 10000,
16+
background: 'blue',
17+
}}
18+
/>
19+
<p>{hydrate ? 'hydrated' : 'loading'}</p>
20+
<Link href={`/${id + 1}`}>
21+
<a
22+
id="link"
23+
style={{
24+
marginLeft: 5000,
25+
width: 95000,
26+
display: 'block',
27+
}}
28+
>
29+
next page
30+
</a>
31+
</Link>
32+
<div id="end-el">hello, world</div>
33+
</>
34+
)
35+
}
36+
37+
export default Page
38+
39+
export const getServerSideProps = (context) => {
40+
const { id = 0 } = context.query
41+
return {
42+
props: {
43+
id,
44+
},
45+
}
46+
}

0 commit comments

Comments
 (0)