/
index.test.js
132 lines (111 loc) · 3.82 KB
/
index.test.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/* eslint-env jest */
import cheerio from 'cheerio'
import { readdir, readFile, unlink } from 'fs-extra'
import {
nextBuild,
killApp,
nextStart,
findPort,
renderViaHTTP,
} from 'next-test-utils'
import webdriver from 'next-webdriver'
import { join } from 'path'
jest.setTimeout(1000 * 60 * 1)
const appDir = join(__dirname, '../')
let chunks
let stats
let appPort
let app
const existsChunkNamed = (name) => {
return chunks.some((chunk) => new RegExp(name).test(chunk))
}
describe('Chunking', () => {
beforeAll(async () => {
try {
// If a previous build has left chunks behind, delete them
const oldChunks = await readdir(join(appDir, '.next', 'static', 'chunks'))
await Promise.all(
oldChunks.map((chunk) => {
return unlink(join(appDir, '.next', 'static', 'chunks', chunk))
})
)
} catch (e) {
// Error here means old chunks don't exist, so we don't need to do anything
}
await nextBuild(appDir, [])
stats = (await readFile(join(appDir, '.next', 'stats.json'), 'utf8'))
// fixes backslashes in keyNames not being escaped on windows
.replace(/"static\\(.*?":?)/g, (match) => match.replace(/\\/g, '\\\\'))
stats = JSON.parse(stats)
appPort = await findPort()
app = await nextStart(appDir, appPort)
chunks = await readdir(join(appDir, '.next', 'static', 'chunks'))
})
afterAll(() => killApp(app))
it('should use all url friendly names', () => {
expect(chunks).toEqual(chunks.map((name) => encodeURIComponent(name)))
})
it('should create a framework chunk', () => {
expect(existsChunkNamed('framework')).toBe(true)
})
it('should not create a commons chunk', () => {
// This app has no dependency that is required by ALL pages, and should
// therefore not have a commons chunk
expect(existsChunkNamed('commons')).toBe(false)
})
it('should not create a lib chunk for react or react-dom', () => {
// These large dependencies would become lib chunks, except that they
// are preemptively moved into the framework chunk.
expect(existsChunkNamed('react|react-dom')).toBe(false)
})
it('should not preload the build manifest', async () => {
const html = await renderViaHTTP(appPort, '/')
const $ = cheerio.load(html)
expect(
[].slice
.call($('link[rel="preload"][as="script"]'))
.map((e) => e.attribs.href)
.some((entry) => entry.includes('_buildManifest'))
).toBe(false)
})
it('should execute the build manifest', async () => {
const html = await renderViaHTTP(appPort, '/')
const $ = cheerio.load(html)
expect(
Array.from($('script'))
.map((e) => e.attribs.src)
.some((entry) => entry && entry.includes('_buildManifest'))
).toBe(true)
})
it('should not include more than one instance of react-dom', async () => {
const misplacedReactDom = stats.chunks.some((chunk) => {
if (chunk.names.includes('framework')) {
// disregard react-dom in framework--it's supposed to be there
return false
}
return chunk.modules.some((module) => {
return /react-dom/.test(module.name)
})
})
expect(misplacedReactDom).toBe(false)
})
describe('Serving', () => {
it('should hydrate with aggressive chunking', async () => {
const browser = await webdriver(appPort, '/page2')
const text = await browser.elementByCss('#padded-str').text()
expect(text).toBe('__rad__')
await browser.close()
})
it('should load chunks when navigating', async () => {
const browser = await webdriver(appPort, '/page3')
const text = await browser
.elementByCss('#page2-link')
.click()
.waitForElementByCss('#padded-str')
.elementByCss('#padded-str')
.text()
expect(text).toBe('__rad__')
await browser.close()
})
})
})