-
Notifications
You must be signed in to change notification settings - Fork 61.6k
/
Copy pathtest-local-dev.ts
executable file
·179 lines (157 loc) · 5.22 KB
/
test-local-dev.ts
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
import assert from 'node:assert/strict'
import fs from 'fs'
import cheerio from 'cheerio'
import got from 'got'
/**
* A very basic script that tests the local dev server.
*
* We use this in CI to make sure the local development server works.
* There are certain things that only work and happen when in
* local dev, that don't make sense to test in regular end-to-end tests
* such as `vitest` rendering.
*
* For engineers to test this locally do the following:
*
* 1. Start `npm run dev` in one terminal
* 2. Run `src/workflows/test-local-dev.ts` in another terminal
*
*/
main()
async function get(path: string, options?: Record<string, any>) {
// By default, got() will use retries and follow redirects.
const t0 = new Date()
const response = await got(makeURL(path), options)
const took = new Date().getTime() - t0.getTime()
console.log(`GET ${path} => ${response.statusCode} (${took}ms)`)
return response
}
function makeURL(path: string) {
return `http://localhost:4000${path}`
}
async function main() {
// Edit a page's content and expect to see that change when viewed
await testEditingPage()
// Only in local dev is the `?json=...` query string working
await testJSONParameters()
// In local development, it depends on proxying the search to prod
// because if you haven't set up ELASTICSEARCH_URL.
await testSiteSearch()
await testViewingPages()
// Next.js uses just-in-time compilation to compile pages on demand.
// But once the server is up it should *not crash* to request these things.
await testNextJsSpecialURLs()
}
async function testEditingPage() {
const string = `Today's date is ${new Date().toString()}`
const filePath = 'content/get-started/start-your-journey/hello-world.md'
const content = fs.readFileSync(filePath, 'utf-8')
try {
fs.appendFileSync(filePath, string, 'utf-8')
const res = await get('/get-started/start-your-journey/hello-world')
if (!res.body.includes(string)) {
throw new Error(`Couldn't find the string '${string}' in the response body`)
}
} finally {
fs.writeFileSync(filePath, content, 'utf-8')
}
}
async function testJSONParameters() {
// currentVersion should be free-pro-team@latest
{
const res = await get('/get-started/start-your-journey/hello-world?json=currentVersion')
const info = JSON.parse(res.body)
assert(info === 'free-pro-team@latest')
}
// currentVersion should be free-pro-team@latest
{
const res = await get('/enterprise-server@latest/admin?json=currentVersion')
const info = JSON.parse(res.body)
assert(/enterprise-server@\d/.test(info))
}
// currentProduct (home page)
{
const res = await get('/en?json=currentProduct')
const currentProduct = JSON.parse(res.body)
assert(currentProduct === 'homepage')
}
// currentProduct (actions)
{
const res = await get('/en/actions?json=currentProduct')
const currentProduct = JSON.parse(res.body)
assert(currentProduct === 'actions')
}
// page
{
const res = await get('/en?json=page')
const info = JSON.parse(res.body)
assert(info.title === 'GitHub.com Help Documentation')
}
// Just ?json
{
const res = await get('/en?json')
const info = JSON.parse(res.body)
assert(info.message)
assert(info.keys && Array.isArray(info.keys))
}
// Featured links
{
const res = await get('/en?json=featuredLinks.gettingStarted')
const links = JSON.parse(res.body)
assert(links && Array.isArray(links))
assert(links[0].href)
assert(links[0].page)
}
}
async function testSiteSearch() {
// Find something on free-pro-team@latest
{
const res = await get('/en/search?query=github')
const $ = cheerio.load(res.body)
// The [\d,]+ is because we use thousands separators in the number
assert(/[\d,]+ Search results for "github"/.test($('h1').text()))
assert($('[data-testid="search-result"]').length > 0)
}
// Find 0 things on enterprise-cloud@latest
{
const res = await get('/en/enterprise-cloud@latest/search?query=gobligook')
const $ = cheerio.load(res.body)
assert(/0 Search results for "gobligook"/.test($('h1').text()))
assert($('[data-testid="search-result"]').length === 0)
}
// Using the search API
{
const res = await get('/api/search?query=github')
const results = JSON.parse(res.body)
assert(results.meta)
assert(results.hits)
}
// Using the autocomplete search API
{
const res = await get('/api/search/autocomplete?query=gi')
const results = JSON.parse(res.body)
assert(results.meta)
assert(results.hits)
}
}
async function testViewingPages() {
// Getting a 404 page with an /en/ prefix should be a 404 HTML page
const res = await get('/en/never/heard/of', {
throwHttpErrors: false,
})
assert(res.statusCode === 404)
// console.log(res.body)
const $ = cheerio.load(res.body)
assert(/It looks like this page doesn't exist./.test($('article').text()))
}
async function testNextJsSpecialURLs() {
// _next/webpack-hmr
{
const res = await get('/_next/webpack-hmr')
assert(res.statusCode === 200)
}
// _next/static/webpack/HASH.webpack.hot-update.json
{
const res = await get('/_next/static/webpack/deadbeefdeadbeef.webpack.hot-update.json')
assert(res.statusCode === 200)
}
}