next.js
next.js copied to clipboard
Encode the host and path when redirecting
If the hostname or path contains anything other than ascii, setHeader('Location', newUrl) will throw an exception. Encode it to avoid it.
Bug
- [ ] Related issues linked using
fixes #number - [x] Integration tests added
- [ ] Errors have helpful link attached, see
contributing.md
~~Feature~~
- ~~Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.~~
- ~~Related issues linked using
fixes #number~~ - ~~Integration tests added~~
- ~~Documentation added~~
- ~~Telemetry added. In case of a feature if it's used or not.~~
- ~~Errors have helpful link attached, see
contributing.md~~
~~Documentation / Examples~~
- ~~Make sure the linting passes by running
yarn lint~~
Failing test suites
Commit: f829537aaed75616461975e8a06fff10e45319ef
test/integration/app-document-add-hmr/test/index.test.js
- _app/_document add HMR > should HMR when _document is added
Expand output
● _app/_document add HMR › should HMR when _document is added
expect(received).toContain(expected) // indexOf
Expected substring: "index page"
Received string: "<head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width\"><meta name=\"next-head-count\" content=\"2\"><noscript data-n-css=\"\"></noscript><script defer=\"\" nomodule=\"\" src=\"/_next/static/chunks/polyfills.js?ts=1638806045827\"></script><script src=\"/_next/static/chunks/fallback/webpack.js?ts=1638806045827\" defer=\"\"></script><script src=\"/_next/static/chunks/fallback/main.js?ts=1638806045827\" defer=\"\"></script><script src=\"/_next/static/chunks/fallback/pages/_app.js?ts=1638806045827\" defer=\"\"></script><script src=\"/_next/static/chunks/fallback/pages/_error.js?ts=1638806045827\" defer=\"\"></script><noscript id=\"__next_css__DO_NOT_USE__\"></noscript></head><body style=\"overflow: hidden;\"><div id=\"__next\" data-reactroot=\"\"></div><script src=\"/_next/static/chunks/fallback/react-refresh.js?ts=1638806045827\"></script><script id=\"__NEXT_DATA__\" type=\"application/json\">{\"props\":{\"pageProps\":{\"statusCode\":500}},\"page\":\"/_error\",\"query\":{},\"buildId\":\"development\",\"isFallback\":false,\"err\":{\"name\":\"ModuleBuildError\",\"message\":\"Module build failed (from ../../../packages/next/dist/build/webpack/loaders/next-swc-loader.js):\\nError: Failed to read source code from /home/runner/work/next.js/next.js/test/integration/app-document-add-hmr/pages/_app.js\\n\\nCaused by:\\n No such file or directory (os error 2)\",\"stack\":\"ModuleBuildError: Module build failed (from ../../../packages/next/dist/build/webpack/loaders/next-swc-loader.js):\\nError: Failed to read source code from /home/runner/work/next.js/next.js/test/integration/app-document-add-hmr/pages/_app.js\\n\\nCaused by:\\n No such file or directory (os error 2)\\n at processResult (/home/runner/work/next.js/next.js/packages/next/dist/compiled/webpack/bundle5.js:54691:19)\\n at /home/runner/work/next.js/next.js/packages/next/dist/compiled/webpack/bundle5.js:54793:5\\n at /home/runner/work/next.js/next.js/packages/next/dist/compiled/webpack/bundle5.js:140664:11\\n at /home/runner/work/next.js/next.js/packages/next/dist/compiled/webpack/bundle5.js:140460:20\\n at context.callback (/home/runner/work/next.js/next.js/packages/next/dist/compiled/webpack/bundle5.js:140389:13)\"},\"gip\":true,\"scriptLoader\":[]}</script><div id=\"__next-build-watcher\" style=\"position: fixed; bottom: 10px; right: 20px; width: 0px; height: 0px; z-index: 99999;\"></div><next-route-announcer><p aria-live=\"assertive\" id=\"__next-route-announcer__\" role=\"alert\" style=\"border: 0px; clip: rect(0px, 0px, 0px, 0px); height: 1px; margin: -1px; overflow: hidden; padding: 0px; position: absolute; width: 1px; white-space: nowrap; overflow-wrap: normal;\"></p></next-route-announcer><nextjs-portal></nextjs-portal></body>"
54 | await fs.remove(appPage)
55 | }
> 56 | })
| ^
57 |
58 | it('should HMR when _document is added', async () => {
59 | let indexContent = await fs.readFile(indexPage)
at Object.<anonymous> (integration/app-document-add-hmr/test/index.test.js:56:27)
test/production/required-server-files-i18n.test.ts
- should set-up next > should handle bad request correctly with rewrite
Expand output
● should set-up next › should handle bad request correctly with rewrite
expect(received).toBe(expected) // Object.is equality
Expected: 400
Received: 200
403 | const $2 = cheerio.load(html2)
404 | const data2 = JSON.parse($2('#props').text())
> 405 |
| ^
406 | expect($2('#catch-all').text()).toBe('optional catch-all page')
407 | expect(data2.params).toEqual({ rest: ['hello'] })
408 | expect(isNaN(data2.random)).toBe(false)
at Object.<anonymous> (production/required-server-files-i18n.test.ts:405:28)
test/development/basic-basepath/misc.test.ts
- misc basic dev tests > With Security Related Issues > should handle encoded / value for trailing slash correctly
Expand output
● misc basic dev tests › With Security Related Issues › should handle encoded / value for trailing slash correctly
expect(received).toBe(expected) // Object.is equality
Expected: "/docs/%2fexample.com"
Received: "/docs/%252fexample.com"
60 | '/docs/%2fexample.com/',
61 | undefined,
> 62 | { redirect: 'manual' }
| ^
63 | )
64 |
65 | const { pathname, hostname } = url.parse(
at Object.<anonymous> (development/basic-basepath/misc.test.ts:62:30)
test/integration/document-functional-render-prop/tests/index.test.js
- Functional Custom Document > development mode > supports render props
Expand output
● Functional Custom Document › development mode › supports render props
thrown: "Exceeded timeout of 90000 ms for a test.
Use jest.setTimeout(newTimeout) to increase the timeout value, if this is a long-running test."
19 |
20 | it('supports render props', async () => {
> 21 | const html = await renderViaHTTP(appPort, '/')
| ^
22 | expect(html).toMatch(/<span>from render prop<\/span>/)
23 | })
24 | })
at integration/document-functional-render-prop/tests/index.test.js:21:9
at integration/document-functional-render-prop/tests/index.test.js:12:5
at Object.<anonymous> (integration/document-functional-render-prop/tests/index.test.js:11:1)
test/integration/middleware/hmr/test/index.test.js
- HMR with middleware > works for pages when middleware is compiled
- HMR with middleware > refreshes the page when middleware changes
Expand output
● HMR with middleware › works for pages when middleware is compiled
expect(received).toEqual(expected) // deep equality
Expected: true
Received: false
34 | it('works for pages when middleware is compiled', async () => {
35 | const browser = await webdriver(context.appPort, `/`)
> 36 |
| ^
37 | try {
38 | await browser.eval('window.itdidnotrefresh = "hello"')
39 | await fetchViaHTTP(context.appPort, `/about`)
at Object.<anonymous> (integration/middleware/hmr/test/index.test.js:36:58)
● HMR with middleware › refreshes the page when middleware changes
expect(received).toEqual(expected) // deep equality
Expected: "AboutA"
Received: "Unhandled Runtime Error"
44 | } finally {
45 | await browser.close()
> 46 | }
| ^
47 | })
48 |
49 | it('refreshes the page when middleware changes ', async () => {
at Object.<anonymous> (integration/middleware/hmr/test/index.test.js:46:22)
test/integration/middleware/with-base-path/test/index.test.js
- Middleware base tests > dev mode > should execute from absolute paths
- Middleware base tests > production mode > should execute from absolute paths
- Middleware base tests > production mode > should redirect via preflight middleware request
Expand output
● Middleware base tests › dev mode › should execute from absolute paths
expect(received).toBe(expected) // Object.is equality
Expected: "/root/redirect-with-basepath"
Received: "/redirect-with-basepath"
39 | })
40 | })
> 41 |
| ^
42 | function runTests() {
43 | it('should execute from absolute paths', async () => {
44 | const browser = await webdriver(context.appPort, '/redirect-with-basepath')
at Object.<anonymous> (integration/middleware/with-base-path/test/index.test.js:41:68)
● Middleware base tests › production mode › should execute from absolute paths
expect(received).toBe(expected) // Object.is equality
Expected: "/root/redirect-with-basepath"
Received: "/redirect-with-basepath"
39 | })
40 | })
> 41 |
| ^
42 | function runTests() {
43 | it('should execute from absolute paths', async () => {
44 | const browser = await webdriver(context.appPort, '/redirect-with-basepath')
at Object.<anonymous> (integration/middleware/with-base-path/test/index.test.js:41:68)
● Middleware base tests › production mode › should redirect via preflight middleware request
expect(received).toBe(expected) // Object.is equality
Expected: "/root/about"
Received: null
55 | '/root/redirect-with-basepath'
56 | )
> 57 | const html = await res.text()
| ^
58 | const $ = cheerio.load(html)
59 | expect($('.title').text()).toBe('About Page')
60 | })
at Object.<anonymous> (integration/middleware/with-base-path/test/index.test.js:57:30)
Stats from current PR
Default Build (Decrease detected ✓)
General Overall increase ⚠️
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| buildDuration | 17.3s | 17s | -309ms |
| buildDurationCached | 3.2s | 3.3s | ⚠️ +117ms |
| nodeModulesSize | 347 MB | 347 MB | ⚠️ +228 B |
Page Load Tests Overall decrease ⚠️
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| / failed reqs | 0 | 0 | ✓ |
| / total time (seconds) | 2.722 | 2.869 | ⚠️ +0.15 |
| / avg req/sec | 918.38 | 871.5 | ⚠️ -46.88 |
| /error-in-render failed reqs | 0 | 0 | ✓ |
| /error-in-render total time (seconds) | 1.274 | 1.285 | ⚠️ +0.01 |
| /error-in-render avg req/sec | 1962.03 | 1944.92 | ⚠️ -17.11 |
Client Bundles (main, webpack, commons)
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| 450.HASH.js gzip | 179 B | 179 B | ✓ |
| framework-HASH.js gzip | 42.2 kB | 42.2 kB | ✓ |
| main-HASH.js gzip | 28.4 kB | 28.4 kB | ✓ |
| webpack-HASH.js gzip | 1.45 kB | 1.45 kB | ✓ |
| Overall change | 72.3 kB | 72.3 kB | ✓ |
Legacy Client Bundles (polyfills)
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| polyfills-HASH.js gzip | 31 kB | 31 kB | ✓ |
| Overall change | 31 kB | 31 kB | ✓ |
Client Pages
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| _app-HASH.js gzip | 1.37 kB | 1.37 kB | ✓ |
| _error-HASH.js gzip | 194 B | 194 B | ✓ |
| amp-HASH.js gzip | 312 B | 312 B | ✓ |
| css-HASH.js gzip | 326 B | 326 B | ✓ |
| dynamic-HASH.js gzip | 2.38 kB | 2.38 kB | ✓ |
| head-HASH.js gzip | 350 B | 350 B | ✓ |
| hooks-HASH.js gzip | 635 B | 635 B | ✓ |
| image-HASH.js gzip | 4.49 kB | 4.49 kB | ✓ |
| index-HASH.js gzip | 263 B | 263 B | ✓ |
| link-HASH.js gzip | 1.87 kB | 1.87 kB | ✓ |
| routerDirect..HASH.js gzip | 321 B | 321 B | ✓ |
| script-HASH.js gzip | 383 B | 383 B | ✓ |
| withRouter-HASH.js gzip | 318 B | 318 B | ✓ |
| 85e02e95b279..7e3.css gzip | 107 B | 107 B | ✓ |
| Overall change | 13.3 kB | 13.3 kB | ✓ |
Client Build Manifests
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| _buildManifest.js gzip | 460 B | 460 B | ✓ |
| Overall change | 460 B | 460 B | ✓ |
Rendered Page Sizes
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| index.html gzip | 531 B | 531 B | ✓ |
| link.html gzip | 544 B | 544 B | ✓ |
| withRouter.html gzip | 526 B | 526 B | ✓ |
| Overall change | 1.6 kB | 1.6 kB | ✓ |
Default Build with SWC (Increase detected ⚠️)
General Overall increase ⚠️
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| buildDuration | 19.4s | 18.5s | -913ms |
| buildDurationCached | 3.3s | 3.2s | -73ms |
| nodeModulesSize | 347 MB | 347 MB | ⚠️ +228 B |
Page Load Tests Overall increase ✓
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| / failed reqs | 0 | 0 | ✓ |
| / total time (seconds) | 2.766 | 2.732 | -0.03 |
| / avg req/sec | 903.73 | 914.96 | +11.23 |
| /error-in-render failed reqs | 0 | 0 | ✓ |
| /error-in-render total time (seconds) | 1.35 | 1.258 | -0.09 |
| /error-in-render avg req/sec | 1851.9 | 1987.77 | +135.87 |
Client Bundles (main, webpack, commons)
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| 450.HASH.js gzip | 179 B | 179 B | ✓ |
| framework-HASH.js gzip | 42.3 kB | 42.3 kB | ✓ |
| main-HASH.js gzip | 28.6 kB | 28.6 kB | ✓ |
| webpack-HASH.js gzip | 1.44 kB | 1.44 kB | ✓ |
| Overall change | 72.5 kB | 72.5 kB | ✓ |
Legacy Client Bundles (polyfills)
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| polyfills-HASH.js gzip | 31 kB | 31 kB | ✓ |
| Overall change | 31 kB | 31 kB | ✓ |
Client Pages
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| _app-HASH.js gzip | 1.35 kB | 1.35 kB | ✓ |
| _error-HASH.js gzip | 180 B | 180 B | ✓ |
| amp-HASH.js gzip | 305 B | 305 B | ✓ |
| css-HASH.js gzip | 321 B | 321 B | ✓ |
| dynamic-HASH.js gzip | 2.37 kB | 2.37 kB | ✓ |
| head-HASH.js gzip | 342 B | 342 B | ✓ |
| hooks-HASH.js gzip | 622 B | 622 B | ✓ |
| image-HASH.js gzip | 4.53 kB | 4.53 kB | ✓ |
| index-HASH.js gzip | 256 B | 256 B | ✓ |
| link-HASH.js gzip | 1.9 kB | 1.9 kB | ✓ |
| routerDirect..HASH.js gzip | 314 B | 314 B | ✓ |
| script-HASH.js gzip | 375 B | 375 B | ✓ |
| withRouter-HASH.js gzip | 309 B | 309 B | ✓ |
| 85e02e95b279..7e3.css gzip | 107 B | 107 B | ✓ |
| Overall change | 13.3 kB | 13.3 kB | ✓ |
Client Build Manifests
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| _buildManifest.js gzip | 458 B | 458 B | ✓ |
| Overall change | 458 B | 458 B | ✓ |
Rendered Page Sizes
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| index.html gzip | 530 B | 530 B | ✓ |
| link.html gzip | 545 B | 545 B | ✓ |
| withRouter.html gzip | 526 B | 526 B | ✓ |
| Overall change | 1.6 kB | 1.6 kB | ✓ |
Failing test suites
Commit: a9c8dddbda2cdd0854dea4358d91535b97dfb15d
test/production/required-server-files-i18n.test.ts
- should set-up next > should handle bad request correctly with rewrite
Expand output
● should set-up next › should handle bad request correctly with rewrite
expect(received).toBe(expected) // Object.is equality
Expected: 400
Received: 200
400 | )
401 | const $2 = cheerio.load(html2)
> 402 | const data2 = JSON.parse($2('#props').text())
| ^
403 |
404 | expect($2('#catch-all').text()).toBe('optional catch-all page')
405 | expect(data2.params).toEqual({ rest: ['hello'] })
at Object.<anonymous> (production/required-server-files-i18n.test.ts:402:28)
test/development/basic-basepath/misc.test.ts
- misc basic dev tests > With Security Related Issues > should handle encoded / value for trailing slash correctly
Expand output
● misc basic dev tests › With Security Related Issues › should handle encoded / value for trailing slash correctly
expect(received).toBe(expected) // Object.is equality
Expected: "/docs/%2fexample.com"
Received: "/docs/%252fexample.com"
60 | '/docs/%2fexample.com/',
61 | undefined,
> 62 | { redirect: 'manual' }
| ^
63 | )
64 |
65 | const { pathname, hostname } = url.parse(
at Object.<anonymous> (development/basic-basepath/misc.test.ts:62:30)
test/integration/custom-routes/test/index.test.js
- Custom routes > dev mode > should handle has query encoding correctly
- Custom routes > dev mode > should handle encoded value in the pathname correctly
- Custom routes > dev mode > should handle named regex parameters with multi-match successfully
- Custom routes > dev mode > should match has hostname redirect with encoded query value
- Custom routes > server mode > should handle has query encoding correctly
- Custom routes > server mode > should handle encoded value in the pathname correctly
- Custom routes > server mode > should handle named regex parameters with multi-match successfully
- Custom routes > server mode > should match has hostname redirect with encoded query value
- Custom routes > serverless mode > should handle has query encoding correctly
- Custom routes > serverless mode > should handle encoded value in the pathname correctly
- Custom routes > serverless mode > should handle named regex parameters with multi-match successfully
- Custom routes > serverless mode > should match has hostname redirect with encoded query value
Expand output
● Custom routes › dev mode › should handle has query encoding correctly
expect(received).toEqual(expected) // deep equality
- Expected - 2
+ Received + 1
Object {
"params": Object {
"slug": Array [
- "hello",
- "world",
+ "hello/world",
],
},
}
63 | appPort,
64 | '/has-rewrite-8',
> 65 | `?post=${post}`,
| ^
66 | {
67 | redirect: 'manual',
68 | }
at Object.<anonymous> (integration/custom-routes/test/index.test.js:65:56)
● Custom routes › dev mode › should handle encoded value in the pathname correctly
expect(received).toBe(expected) // Object.is equality
Expected: "/%5Cgoogle.com/about"
Received: "/%255Cgoogle.com/about"
570 | expect(html).toMatch(/post:.*?post-2/)
571 | })
> 572 |
| ^
573 | it('should match public file after rewrite', async () => {
574 | const data = await renderViaHTTP(appPort, '/blog/data.json')
575 | expect(JSON.parse(data)).toEqual({ hello: 'world' })
at Object.<anonymous> (integration/custom-routes/test/index.test.js:572:26)
at runMicrotasks (<anonymous>)
● Custom routes › dev mode › should handle named regex parameters with multi-match successfully
expect(received).toBe(expected) // Object.is equality
Expected: "/integrations/-some/thing"
Received: "/integrations/-some%2Fthing"
588 | const res = await fetchViaHTTP(appPort, '/to-external', undefined, {
589 | redirect: 'manual',
> 590 | })
| ^
591 | const location = res.headers.get('location')
592 | expect(res.status).toBe(307)
593 | expect(location).toBe('https://google.com/')
at Object.<anonymous> (integration/custom-routes/test/index.test.js:590:26)
at runMicrotasks (<anonymous>)
● Custom routes › dev mode › should match has hostname redirect with encoded query value
expect(received).toBe(expected) // Object.is equality
Expected: "https://xn--bck9bsh7a3b.example.com/"
Received: "xn--bck9bsh7a3b.example.com"
847 | headers: {
848 | host: 'example.com',
> 849 | },
| ^
850 | })
851 |
852 | expect(res.status).toBe(200)
at Object.<anonymous> (integration/custom-routes/test/index.test.js:849:33)
at runMicrotasks (<anonymous>)
● Custom routes › server mode › should handle has query encoding correctly
expect(received).toEqual(expected) // deep equality
- Expected - 2
+ Received + 1
Object {
"params": Object {
"slug": Array [
- "hello",
- "world",
+ "hello/world",
],
},
}
63 | appPort,
64 | '/has-rewrite-8',
> 65 | `?post=${post}`,
| ^
66 | {
67 | redirect: 'manual',
68 | }
at Object.<anonymous> (integration/custom-routes/test/index.test.js:65:56)
at runMicrotasks (<anonymous>)
● Custom routes › server mode › should handle encoded value in the pathname correctly
expect(received).toBe(expected) // Object.is equality
Expected: "/%5Cgoogle.com/about"
Received: "/%255Cgoogle.com/about"
570 | expect(html).toMatch(/post:.*?post-2/)
571 | })
> 572 |
| ^
573 | it('should match public file after rewrite', async () => {
574 | const data = await renderViaHTTP(appPort, '/blog/data.json')
575 | expect(JSON.parse(data)).toEqual({ hello: 'world' })
at Object.<anonymous> (integration/custom-routes/test/index.test.js:572:26)
at runMicrotasks (<anonymous>)
● Custom routes › server mode › should handle named regex parameters with multi-match successfully
expect(received).toBe(expected) // Object.is equality
Expected: "/integrations/-some/thing"
Received: "/integrations/-some%2Fthing"
588 | const res = await fetchViaHTTP(appPort, '/to-external', undefined, {
589 | redirect: 'manual',
> 590 | })
| ^
591 | const location = res.headers.get('location')
592 | expect(res.status).toBe(307)
593 | expect(location).toBe('https://google.com/')
at Object.<anonymous> (integration/custom-routes/test/index.test.js:590:26)
at runMicrotasks (<anonymous>)
● Custom routes › server mode › should match has hostname redirect with encoded query value
expect(received).toBe(expected) // Object.is equality
Expected: "https://xn--bck9bsh7a3b.example.com/"
Received: "xn--bck9bsh7a3b.example.com"
847 | headers: {
848 | host: 'example.com',
> 849 | },
| ^
850 | })
851 |
852 | expect(res.status).toBe(200)
at Object.<anonymous> (integration/custom-routes/test/index.test.js:849:33)
at runMicrotasks (<anonymous>)
● Custom routes › serverless mode › should handle has query encoding correctly
expect(received).toEqual(expected) // deep equality
- Expected - 2
+ Received + 1
Object {
"params": Object {
"slug": Array [
- "hello",
- "world",
+ "hello/world",
],
},
}
63 | appPort,
64 | '/has-rewrite-8',
> 65 | `?post=${post}`,
| ^
66 | {
67 | redirect: 'manual',
68 | }
at Object.<anonymous> (integration/custom-routes/test/index.test.js:65:56)
at runMicrotasks (<anonymous>)
● Custom routes › serverless mode › should handle encoded value in the pathname correctly
expect(received).toBe(expected) // Object.is equality
Expected: "/%5Cgoogle.com/about"
Received: "/%255Cgoogle.com/about"
570 | expect(html).toMatch(/post:.*?post-2/)
571 | })
> 572 |
| ^
573 | it('should match public file after rewrite', async () => {
574 | const data = await renderViaHTTP(appPort, '/blog/data.json')
575 | expect(JSON.parse(data)).toEqual({ hello: 'world' })
at Object.<anonymous> (integration/custom-routes/test/index.test.js:572:26)
at runMicrotasks (<anonymous>)
● Custom routes › serverless mode › should handle named regex parameters with multi-match successfully
expect(received).toBe(expected) // Object.is equality
Expected: "/integrations/-some/thing"
Received: "/integrations/-some%2Fthing"
588 | const res = await fetchViaHTTP(appPort, '/to-external', undefined, {
589 | redirect: 'manual',
> 590 | })
| ^
591 | const location = res.headers.get('location')
592 | expect(res.status).toBe(307)
593 | expect(location).toBe('https://google.com/')
at Object.<anonymous> (integration/custom-routes/test/index.test.js:590:26)
at runMicrotasks (<anonymous>)
● Custom routes › serverless mode › should match has hostname redirect with encoded query value
expect(received).toBe(expected) // Object.is equality
Expected: "https://xn--bck9bsh7a3b.example.com/"
Received: "xn--bck9bsh7a3b.example.com"
847 | headers: {
848 | host: 'example.com',
> 849 | },
| ^
850 | })
851 |
852 | expect(res.status).toBe(200)
at Object.<anonymous> (integration/custom-routes/test/index.test.js:849:33)
at runMicrotasks (<anonymous>)
test/integration/export-serverless/test/index.test.js
- Static Export > Render in development mode > should render pages only existent in exportPathMap page
Expand output
● Static Export › Render in development mode › should render pages only existent in exportPathMap page
page.waitForSelector: Timeout 30000ms exceeded.
=========================== logs ===========================
waiting for selector "#dynamic-page p"
============================================================
229 |
230 | async hasElementByCssSelector(selector: string) {
> 231 | return this.eval(`!!document.querySelector('${selector}')`) as any
| ^
232 | }
233 |
234 | click() {
at lib/browsers/playwright.ts:231:25
test/integration/export/test/index.test.js
- Static Export > Render in development mode > should render pages only existent in exportPathMap page
Expand output
● Static Export › Render in development mode › should render pages only existent in exportPathMap page
page.waitForSelector: Timeout 30000ms exceeded.
=========================== logs ===========================
waiting for selector "#dynamic-page p"
============================================================
229 |
230 | async hasElementByCssSelector(selector: string) {
> 231 | return this.eval(`!!document.querySelector('${selector}')`) as any
| ^
232 | }
233 |
234 | click() {
at lib/browsers/playwright.ts:231:25
test/integration/middleware/with-base-path/test/index.test.js
- Middleware base tests > dev mode > should execute from absolute paths
- Middleware base tests > production mode > should execute from absolute paths
- Middleware base tests > production mode > should redirect via preflight middleware request
Expand output
● Middleware base tests › dev mode › should execute from absolute paths
expect(received).toBe(expected) // Object.is equality
Expected: "/root/redirect-with-basepath"
Received: "/redirect-with-basepath"
39 | })
40 | })
> 41 |
| ^
42 | function runTests() {
43 | it('should execute from absolute paths', async () => {
44 | const browser = await webdriver(context.appPort, '/redirect-with-basepath')
at Object.<anonymous> (integration/middleware/with-base-path/test/index.test.js:41:68)
● Middleware base tests › production mode › should execute from absolute paths
expect(received).toBe(expected) // Object.is equality
Expected: "/root/redirect-with-basepath"
Received: "/redirect-with-basepath"
39 | })
40 | })
> 41 |
| ^
42 | function runTests() {
43 | it('should execute from absolute paths', async () => {
44 | const browser = await webdriver(context.appPort, '/redirect-with-basepath')
at Object.<anonymous> (integration/middleware/with-base-path/test/index.test.js:41:68)
● Middleware base tests › production mode › should redirect via preflight middleware request
expect(received).toBe(expected) // Object.is equality
Expected: "/root/about"
Received: null
55 | '/root/redirect-with-basepath'
56 | )
> 57 | const html = await res.text()
| ^
58 | const $ = cheerio.load(html)
59 | expect($('.title').text()).toBe('About Page')
60 | })
at Object.<anonymous> (integration/middleware/with-base-path/test/index.test.js:57:30)
Failing test suites
Commit: a9c8dddbda2cdd0854dea4358d91535b97dfb15d
test/production/required-server-files-i18n.test.ts
- should set-up next > should handle bad request correctly with rewrite
Expand output
● should set-up next › should handle bad request correctly with rewrite
expect(received).toBe(expected) // Object.is equality
Expected: 400
Received: 200
400 | )
401 | const $2 = cheerio.load(html2)
> 402 | const data2 = JSON.parse($2('#props').text())
| ^
403 |
404 | expect($2('#catch-all').text()).toBe('optional catch-all page')
405 | expect(data2.params).toEqual({ rest: ['hello'] })
at Object.<anonymous> (production/required-server-files-i18n.test.ts:402:28)
test/development/basic-basepath/misc.test.ts
- misc basic dev tests > With Security Related Issues > should handle encoded / value for trailing slash correctly
Expand output
● misc basic dev tests › With Security Related Issues › should handle encoded / value for trailing slash correctly
expect(received).toBe(expected) // Object.is equality
Expected: "/docs/%2fexample.com"
Received: "/docs/%252fexample.com"
60 | '/docs/%2fexample.com/',
61 | undefined,
> 62 | { redirect: 'manual' }
| ^
63 | )
64 |
65 | const { pathname, hostname } = url.parse(
at Object.<anonymous> (development/basic-basepath/misc.test.ts:62:30)
test/integration/export/test/index.test.js
- Static Export > Render in development mode > should render pages only existent in exportPathMap page
Expand output
● Static Export › Render in development mode › should render pages only existent in exportPathMap page
page.waitForSelector: Timeout 30000ms exceeded.
=========================== logs ===========================
waiting for selector "#dynamic-page p"
============================================================
229 |
230 | async hasElementByCssSelector(selector: string) {
> 231 | return this.eval(`!!document.querySelector('${selector}')`) as any
| ^
232 | }
233 |
234 | click() {
at lib/browsers/playwright.ts:231:25
test/integration/export-serverless/test/index.test.js
- Static Export > Render in development mode > should render pages only existent in exportPathMap page
Expand output
● Static Export › Render in development mode › should render pages only existent in exportPathMap page
page.waitForSelector: Timeout 30000ms exceeded.
=========================== logs ===========================
waiting for selector "#dynamic-page p"
============================================================
229 |
230 | async hasElementByCssSelector(selector: string) {
> 231 | return this.eval(`!!document.querySelector('${selector}')`) as any
| ^
232 | }
233 |
234 | click() {
at lib/browsers/playwright.ts:231:25
test/integration/middleware/with-base-path/test/index.test.js
- Middleware base tests > dev mode > should execute from absolute paths
- Middleware base tests > production mode > should execute from absolute paths
- Middleware base tests > production mode > should redirect via preflight middleware request
Expand output
● Middleware base tests › dev mode › should execute from absolute paths
expect(received).toBe(expected) // Object.is equality
Expected: "/root/redirect-with-basepath"
Received: "/redirect-with-basepath"
39 | })
40 | })
> 41 |
| ^
42 | function runTests() {
43 | it('should execute from absolute paths', async () => {
44 | const browser = await webdriver(context.appPort, '/redirect-with-basepath')
at Object.<anonymous> (integration/middleware/with-base-path/test/index.test.js:41:68)
● Middleware base tests › production mode › should execute from absolute paths
expect(received).toBe(expected) // Object.is equality
Expected: "/root/redirect-with-basepath"
Received: "/redirect-with-basepath"
39 | })
40 | })
> 41 |
| ^
42 | function runTests() {
43 | it('should execute from absolute paths', async () => {
44 | const browser = await webdriver(context.appPort, '/redirect-with-basepath')
at Object.<anonymous> (integration/middleware/with-base-path/test/index.test.js:41:68)
● Middleware base tests › production mode › should redirect via preflight middleware request
expect(received).toBe(expected) // Object.is equality
Expected: "/root/about"
Received: null
55 | '/root/redirect-with-basepath'
56 | )
> 57 | const html = await res.text()
| ^
58 | const $ = cheerio.load(html)
59 | expect($('.title').text()).toBe('About Page')
60 | })
at Object.<anonymous> (integration/middleware/with-base-path/test/index.test.js:57:30)
Stats from current PR
Default Build (Increase detected ⚠️)
General Overall increase ⚠️
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| buildDuration | 18.5s | 18.7s | ⚠️ +214ms |
| buildDurationCached | 4.1s | 4.1s | -29ms |
| nodeModulesSize | 348 MB | 348 MB | ⚠️ +242 B |
Page Load Tests Overall increase ✓
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| / failed reqs | 0 | 0 | ✓ |
| / total time (seconds) | 3.951 | 3.97 | ⚠️ +0.02 |
| / avg req/sec | 632.71 | 629.72 | ⚠️ -2.99 |
| /error-in-render failed reqs | 0 | 0 | ✓ |
| /error-in-render total time (seconds) | 2.128 | 2.08 | -0.05 |
| /error-in-render avg req/sec | 1174.69 | 1201.99 | +27.3 |
Client Bundles (main, webpack, commons)
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| 450.HASH.js gzip | 179 B | 179 B | ✓ |
| framework-HASH.js gzip | 42.2 kB | 42.2 kB | ✓ |
| main-HASH.js gzip | 27.1 kB | 27.1 kB | ✓ |
| webpack-HASH.js gzip | 1.45 kB | 1.45 kB | ✓ |
| Overall change | 70.9 kB | 70.9 kB | ✓ |
Legacy Client Bundles (polyfills)
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| polyfills-HASH.js gzip | 31 kB | 31 kB | ✓ |
| Overall change | 31 kB | 31 kB | ✓ |
Client Pages
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| _app-HASH.js gzip | 1.37 kB | 1.37 kB | ✓ |
| _error-HASH.js gzip | 194 B | 194 B | ✓ |
| amp-HASH.js gzip | 312 B | 312 B | ✓ |
| css-HASH.js gzip | 326 B | 326 B | ✓ |
| dynamic-HASH.js gzip | 2.37 kB | 2.37 kB | ✓ |
| head-HASH.js gzip | 350 B | 350 B | ✓ |
| hooks-HASH.js gzip | 919 B | 919 B | ✓ |
| image-HASH.js gzip | 4.74 kB | 4.74 kB | ✓ |
| index-HASH.js gzip | 263 B | 263 B | ✓ |
| link-HASH.js gzip | 2.13 kB | 2.13 kB | ✓ |
| routerDirect..HASH.js gzip | 321 B | 321 B | ✓ |
| script-HASH.js gzip | 383 B | 383 B | ✓ |
| withRouter-HASH.js gzip | 318 B | 318 B | ✓ |
| 85e02e95b279..7e3.css gzip | 107 B | 107 B | ✓ |
| Overall change | 14.1 kB | 14.1 kB | ✓ |
Client Build Manifests
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| _buildManifest.js gzip | 459 B | 459 B | ✓ |
| Overall change | 459 B | 459 B | ✓ |
Rendered Page Sizes
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| index.html gzip | 532 B | 532 B | ✓ |
| link.html gzip | 546 B | 546 B | ✓ |
| withRouter.html gzip | 527 B | 527 B | ✓ |
| Overall change | 1.6 kB | 1.6 kB | ✓ |
Default Build with SWC (Increase detected ⚠️)
General Overall increase ⚠️
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| buildDuration | 20.5s | 21s | ⚠️ +551ms |
| buildDurationCached | 4.2s | 4.2s | ⚠️ +13ms |
| nodeModulesSize | 348 MB | 348 MB | ⚠️ +242 B |
Page Load Tests Overall increase ✓
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| / failed reqs | 0 | 0 | ✓ |
| / total time (seconds) | 4.039 | 3.946 | -0.09 |
| / avg req/sec | 618.89 | 633.59 | +14.7 |
| /error-in-render failed reqs | 0 | 0 | ✓ |
| /error-in-render total time (seconds) | 2.246 | 2.136 | -0.11 |
| /error-in-render avg req/sec | 1113.04 | 1170.6 | +57.56 |
Client Bundles (main, webpack, commons)
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| 450.HASH.js gzip | 179 B | 179 B | ✓ |
| framework-HASH.js gzip | 42.3 kB | 42.3 kB | ✓ |
| main-HASH.js gzip | 27.2 kB | 27.2 kB | ✓ |
| webpack-HASH.js gzip | 1.44 kB | 1.44 kB | ✓ |
| Overall change | 71.1 kB | 71.1 kB | ✓ |
Legacy Client Bundles (polyfills)
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| polyfills-HASH.js gzip | 31 kB | 31 kB | ✓ |
| Overall change | 31 kB | 31 kB | ✓ |
Client Pages
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| _app-HASH.js gzip | 1.35 kB | 1.35 kB | ✓ |
| _error-HASH.js gzip | 180 B | 180 B | ✓ |
| amp-HASH.js gzip | 305 B | 305 B | ✓ |
| css-HASH.js gzip | 321 B | 321 B | ✓ |
| dynamic-HASH.js gzip | 2.36 kB | 2.36 kB | ✓ |
| head-HASH.js gzip | 342 B | 342 B | ✓ |
| hooks-HASH.js gzip | 906 B | 906 B | ✓ |
| image-HASH.js gzip | 4.76 kB | 4.76 kB | ✓ |
| index-HASH.js gzip | 256 B | 256 B | ✓ |
| link-HASH.js gzip | 2.19 kB | 2.19 kB | ✓ |
| routerDirect..HASH.js gzip | 314 B | 314 B | ✓ |
| script-HASH.js gzip | 375 B | 375 B | ✓ |
| withRouter-HASH.js gzip | 309 B | 309 B | ✓ |
| 85e02e95b279..7e3.css gzip | 107 B | 107 B | ✓ |
| Overall change | 14.1 kB | 14.1 kB | ✓ |
Client Build Manifests
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| _buildManifest.js gzip | 459 B | 459 B | ✓ |
| Overall change | 459 B | 459 B | ✓ |
Rendered Page Sizes
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| index.html gzip | 531 B | 531 B | ✓ |
| link.html gzip | 543 B | 543 B | ✓ |
| withRouter.html gzip | 525 B | 525 B | ✓ |
| Overall change | 1.6 kB | 1.6 kB | ✓ |
Stats from current PR
Default Build (Increase detected ⚠️)
General Overall increase ⚠️
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| buildDuration | 16.8s | 16.7s | -51ms |
| buildDurationCached | 3.7s | 3.8s | ⚠️ +65ms |
| nodeModulesSize | 348 MB | 348 MB | ⚠️ +229 B |
Page Load Tests Overall increase ✓
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| / failed reqs | 0 | 0 | ✓ |
| / total time (seconds) | 3.319 | 3.389 | ⚠️ +0.07 |
| / avg req/sec | 753.15 | 737.75 | ⚠️ -15.4 |
| /error-in-render failed reqs | 0 | 0 | ✓ |
| /error-in-render total time (seconds) | 1.637 | 1.614 | -0.02 |
| /error-in-render avg req/sec | 1527.29 | 1548.87 | +21.58 |
Client Bundles (main, webpack, commons)
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| 450.HASH.js gzip | 179 B | 179 B | ✓ |
| framework-HASH.js gzip | 42.2 kB | 42.2 kB | ✓ |
| main-HASH.js gzip | 27.1 kB | 27.1 kB | ✓ |
| webpack-HASH.js gzip | 1.45 kB | 1.45 kB | ✓ |
| Overall change | 70.9 kB | 70.9 kB | ✓ |
Legacy Client Bundles (polyfills)
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| polyfills-HASH.js gzip | 31 kB | 31 kB | ✓ |
| Overall change | 31 kB | 31 kB | ✓ |
Client Pages
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| _app-HASH.js gzip | 1.37 kB | 1.37 kB | ✓ |
| _error-HASH.js gzip | 194 B | 194 B | ✓ |
| amp-HASH.js gzip | 312 B | 312 B | ✓ |
| css-HASH.js gzip | 326 B | 326 B | ✓ |
| dynamic-HASH.js gzip | 2.37 kB | 2.37 kB | ✓ |
| head-HASH.js gzip | 350 B | 350 B | ✓ |
| hooks-HASH.js gzip | 919 B | 919 B | ✓ |
| image-HASH.js gzip | 4.74 kB | 4.74 kB | ✓ |
| index-HASH.js gzip | 263 B | 263 B | ✓ |
| link-HASH.js gzip | 2.13 kB | 2.13 kB | ✓ |
| routerDirect..HASH.js gzip | 321 B | 321 B | ✓ |
| script-HASH.js gzip | 383 B | 383 B | ✓ |
| withRouter-HASH.js gzip | 318 B | 318 B | ✓ |
| 85e02e95b279..7e3.css gzip | 107 B | 107 B | ✓ |
| Overall change | 14.1 kB | 14.1 kB | ✓ |
Client Build Manifests
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| _buildManifest.js gzip | 459 B | 459 B | ✓ |
| Overall change | 459 B | 459 B | ✓ |
Rendered Page Sizes
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| index.html gzip | 532 B | 532 B | ✓ |
| link.html gzip | 546 B | 546 B | ✓ |
| withRouter.html gzip | 527 B | 527 B | ✓ |
| Overall change | 1.6 kB | 1.6 kB | ✓ |
Default Build with SWC (Increase detected ⚠️)
General Overall increase ⚠️
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| buildDuration | 18s | 18.2s | ⚠️ +225ms |
| buildDurationCached | 3.5s | 4s | ⚠️ +432ms |
| nodeModulesSize | 348 MB | 348 MB | ⚠️ +229 B |
Page Load Tests Overall increase ✓
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| / failed reqs | 0 | 0 | ✓ |
| / total time (seconds) | 3.435 | 3.451 | ⚠️ +0.02 |
| / avg req/sec | 727.76 | 724.42 | ⚠️ -3.34 |
| /error-in-render failed reqs | 0 | 0 | ✓ |
| /error-in-render total time (seconds) | 1.561 | 1.511 | -0.05 |
| /error-in-render avg req/sec | 1601.46 | 1654.8 | +53.34 |
Client Bundles (main, webpack, commons)
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| 450.HASH.js gzip | 179 B | 179 B | ✓ |
| framework-HASH.js gzip | 42.3 kB | 42.3 kB | ✓ |
| main-HASH.js gzip | 27.2 kB | 27.2 kB | ✓ |
| webpack-HASH.js gzip | 1.44 kB | 1.44 kB | ✓ |
| Overall change | 71.1 kB | 71.1 kB | ✓ |
Legacy Client Bundles (polyfills)
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| polyfills-HASH.js gzip | 31 kB | 31 kB | ✓ |
| Overall change | 31 kB | 31 kB | ✓ |
Client Pages
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| _app-HASH.js gzip | 1.35 kB | 1.35 kB | ✓ |
| _error-HASH.js gzip | 180 B | 180 B | ✓ |
| amp-HASH.js gzip | 305 B | 305 B | ✓ |
| css-HASH.js gzip | 321 B | 321 B | ✓ |
| dynamic-HASH.js gzip | 2.36 kB | 2.36 kB | ✓ |
| head-HASH.js gzip | 342 B | 342 B | ✓ |
| hooks-HASH.js gzip | 906 B | 906 B | ✓ |
| image-HASH.js gzip | 4.76 kB | 4.76 kB | ✓ |
| index-HASH.js gzip | 256 B | 256 B | ✓ |
| link-HASH.js gzip | 2.19 kB | 2.19 kB | ✓ |
| routerDirect..HASH.js gzip | 314 B | 314 B | ✓ |
| script-HASH.js gzip | 375 B | 375 B | ✓ |
| withRouter-HASH.js gzip | 309 B | 309 B | ✓ |
| 85e02e95b279..7e3.css gzip | 107 B | 107 B | ✓ |
| Overall change | 14.1 kB | 14.1 kB | ✓ |
Client Build Manifests
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| _buildManifest.js gzip | 459 B | 459 B | ✓ |
| Overall change | 459 B | 459 B | ✓ |
Rendered Page Sizes
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| index.html gzip | 531 B | 531 B | ✓ |
| link.html gzip | 543 B | 543 B | ✓ |
| withRouter.html gzip | 525 B | 525 B | ✓ |
| Overall change | 1.6 kB | 1.6 kB | ✓ |
Failing test suites
Commit: 263ff6101eef48eafa7693b89816b37067156b36
test/production/required-server-files-i18n.test.ts
- should set-up next > should handle bad request correctly with rewrite
Expand output
● should set-up next › should handle bad request correctly with rewrite
expect(received).toBe(expected) // Object.is equality
Expected: 400
Received: 200
400 | )
401 | const $2 = cheerio.load(html2)
> 402 | const data2 = JSON.parse($2('#props').text())
| ^
403 |
404 | expect($2('#catch-all').text()).toBe('optional catch-all page')
405 | expect(data2.params).toEqual({ rest: ['hello'] })
at Object.<anonymous> (production/required-server-files-i18n.test.ts:402:28)
test/development/basic-basepath/misc.test.ts
- misc basic dev tests > With Security Related Issues > should handle encoded / value for trailing slash correctly
Expand output
● misc basic dev tests › With Security Related Issues › should handle encoded / value for trailing slash correctly
expect(received).toBe(expected) // Object.is equality
Expected: "/docs/%2fexample.com"
Received: "/docs/%252fexample.com"
60 | '/docs/%2fexample.com/',
61 | undefined,
> 62 | { redirect: 'manual' }
| ^
63 | )
64 |
65 | const { pathname, hostname } = url.parse(
at Object.<anonymous> (development/basic-basepath/misc.test.ts:62:30)
test/integration/export/test/index.test.js
- Static Export > Render in development mode > should render pages only existent in exportPathMap page
Expand output
● Static Export › Render in development mode › should render pages only existent in exportPathMap page
page.waitForSelector: Timeout 30000ms exceeded.
=========================== logs ===========================
waiting for selector "#dynamic-page p"
============================================================
229 |
230 | async hasElementByCssSelector(selector: string) {
> 231 | return this.eval(`!!document.querySelector('${selector}')`) as any
| ^
232 | }
233 |
234 | click() {
at lib/browsers/playwright.ts:231:25
test/integration/export-serverless/test/index.test.js
- Static Export > Render in development mode > should render pages only existent in exportPathMap page
Expand output
● Static Export › Render in development mode › should render pages only existent in exportPathMap page
page.waitForSelector: Timeout 30000ms exceeded.
=========================== logs ===========================
waiting for selector "#dynamic-page p"
============================================================
229 |
230 | async hasElementByCssSelector(selector: string) {
> 231 | return this.eval(`!!document.querySelector('${selector}')`) as any
| ^
232 | }
233 |
234 | click() {
at lib/browsers/playwright.ts:231:25
test/integration/middleware/hmr/test/index.test.js
- HMR with middleware > works for pages when middleware is compiled
- HMR with middleware > refreshes the page when middleware changes
Expand output
● HMR with middleware › works for pages when middleware is compiled
expect(received).toEqual(expected) // deep equality
Expected: true
Received: false
34 | it('works for pages when middleware is compiled', async () => {
35 | const browser = await webdriver(context.appPort, `/`)
> 36 |
| ^
37 | try {
38 | await browser.eval('window.itdidnotrefresh = "hello"')
39 | await fetchViaHTTP(context.appPort, `/about`)
at Object.<anonymous> (integration/middleware/hmr/test/index.test.js:36:58)
● HMR with middleware › refreshes the page when middleware changes
expect(received).toEqual(expected) // deep equality
Expected: "AboutA"
Received: "Unhandled Runtime Error"
44 | } finally {
45 | await browser.close()
> 46 | }
| ^
47 | })
48 |
49 | it('refreshes the page when middleware changes ', async () => {
at Object.<anonymous> (integration/middleware/hmr/test/index.test.js:46:22)
test/integration/middleware/with-base-path/test/index.test.js
- Middleware base tests > dev mode > should execute from absolute paths
- Middleware base tests > production mode > should execute from absolute paths
- Middleware base tests > production mode > should redirect via preflight middleware request
Expand output
● Middleware base tests › dev mode › should execute from absolute paths
expect(received).toBe(expected) // Object.is equality
Expected: "/root/redirect-with-basepath"
Received: "/redirect-with-basepath"
39 | })
40 | })
> 41 |
| ^
42 | function runTests() {
43 | it('should execute from absolute paths', async () => {
44 | const browser = await webdriver(context.appPort, '/redirect-with-basepath')
at Object.<anonymous> (integration/middleware/with-base-path/test/index.test.js:41:68)
● Middleware base tests › production mode › should execute from absolute paths
expect(received).toBe(expected) // Object.is equality
Expected: "/root/redirect-with-basepath"
Received: "/redirect-with-basepath"
39 | })
40 | })
> 41 |
| ^
42 | function runTests() {
43 | it('should execute from absolute paths', async () => {
44 | const browser = await webdriver(context.appPort, '/redirect-with-basepath')
at Object.<anonymous> (integration/middleware/with-base-path/test/index.test.js:41:68)
● Middleware base tests › production mode › should redirect via preflight middleware request
expect(received).toBe(expected) // Object.is equality
Expected: "/root/about"
Received: null
55 | '/root/redirect-with-basepath'
56 | )
> 57 | const html = await res.text()
| ^
58 | const $ = cheerio.load(html)
59 | expect($('.title').text()).toBe('About Page')
60 | })
at Object.<anonymous> (integration/middleware/with-base-path/test/index.test.js:57:30)
test/integration/middleware/with-eval/test/index.test.js
- Middleware usage of dynamic code evaluation > dev mode > shows a warning when running code with eval
- Middleware usage of dynamic code evaluation > dev mode > does not show warning when no code uses eval
- Middleware usage of dynamic code evaluation > dev mode > does not has problems with eval in page or server code
Expand output
● Middleware usage of dynamic code evaluation › dev mode › shows a warning when running code with eval
FetchError: invalid json response body at http://localhost:34593/using-eval reason: Unexpected token < in JSON at position 0
36 | })
37 |
> 38 | beforeEach(() => (output = ''))
| ^
39 | afterAll(() => killApp(context.app))
40 |
41 | it('shows a warning when running code with eval', async () => {
at ../node_modules/node-fetch/lib/index.js:272:32
at Object.<anonymous> (integration/middleware/with-eval/test/index.test.js:38:26)
● Middleware usage of dynamic code evaluation › dev mode › does not show warning when no code uses eval
FetchError: invalid json response body at http://localhost:34593/not-using-eval reason: Unexpected token < in JSON at position 0
49 | // TODO check why that has a backslash on windows
50 | expect(output).toMatch(/lib[\\/]utils\.js/)
> 51 | expect(output).toContain('usingEval')
| ^
52 | expect(stripAnsi(output)).toContain("value: eval('100')")
53 | })
54 |
at ../node_modules/node-fetch/lib/index.js:272:32
at Object.<anonymous> (integration/middleware/with-eval/test/index.test.js:51:26)
● Middleware usage of dynamic code evaluation › dev mode › does not has problems with eval in page or server code
expect(received).toMatch(expected)
Expected pattern: />100<!-- --> and <!-- -->100<\//
Received string: "<!DOCTYPE html><html><head><style data-next-hide-fouc=\"true\">body{display:none}</style><noscript data-next-hide-fouc=\"true\"><style>body{display:block}</style></noscript><meta charSet=\"utf-8\"/><meta name=\"viewport\" content=\"width=device-width\"/><meta name=\"next-head-count\" content=\"2\"/><noscript data-n-css=\"\"></noscript><script defer=\"\" nomodule=\"\" src=\"/_next/static/chunks/polyfills.js?ts=1641381550716\"></script><script src=\"/_next/static/chunks/webpack.js?ts=1641381550716\" defer=\"\"></script><script src=\"/_next/static/chunks/main.js?ts=1641381550716\" defer=\"\"></script><script src=\"/_next/static/chunks/pages/_app.js?ts=1641381550716\" defer=\"\"></script><script src=\"/_next/static/chunks/pages/_error.js?ts=1641381550716\" defer=\"\"></script><script src=\"/_next/static/development/_buildManifest.js?ts=1641381550716\" defer=\"\"></script><script src=\"/_next/static/development/_ssgManifest.js?ts=1641381550716\" defer=\"\"></script><script src=\"/_next/static/development/_middlewareManifest.js?ts=1641381550716\" defer=\"\"></script><noscript id=\"__next_css__DO_NOT_USE__\"></noscript></head><body><div id=\"__next\" data-reactroot=\"\"></div><script src=\"/_next/static/chunks/react-refresh.js?ts=1641381550716\"></script><script id=\"__NEXT_DATA__\" type=\"application/json\">{\"props\":{\"pageProps\":{\"statusCode\":200}},\"page\":\"/_error\",\"query\":{},\"buildId\":\"development\",\"isFallback\":false,\"err\":{\"name\":\"Error\",\"message\":\"ENOENT: no such file or directory, open 'url'\",\"stack\":\"Error: ENOENT: no such file or directory, open 'url'\\n at Object.openSync (fs.js:497:3)\\n at Object.readFileSync (fs.js:393:35)\\n at requireFn (/home/runner/work/next.js/next.js/packages/next/dist/server/web/sandbox/require.js:37:110)\\n at evalmachine.\\u003canonymous\\u003e:8:12\\n at requireFn (/home/runner/work/next.js/next.js/packages/next/dist/server/web/sandbox/require.js:39:13)\\n at evalmachine.\\u003canonymous\\u003e:11:27\\n at requireFn (/home/runner/work/next.js/next.js/packages/next/dist/server/web/sandbox/require.js:39:13)\\n at evalmachine.\\u003canonymous\\u003e:6:15\\n at requireFn (/home/runner/work/next.js/next.js/packages/next/dist/server/web/sandbox/require.js:39:13)\\n at evalmachine.\\u003canonymous\\u003e:7:16\",\"middleware\":true},\"gip\":true,\"scriptLoader\":[]}</script></body></html>"
56 | const res = await fetchViaHTTP(context.appPort, `/not-using-eval`)
57 | const json = await res.json()
> 58 | await waitFor(500)
| ^
59 | expect(json.value).toEqual(100)
60 | expect(output).not.toContain(DYNAMIC_CODE_ERROR)
61 | })
at Object.<anonymous> (integration/middleware/with-eval/test/index.test.js:58:26)
Stats from current PR
Default Build (Decrease detected ✓)
General Overall increase ⚠️
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| buildDuration | 20.1s | 20s | -69ms |
| buildDurationCached | 4.3s | 4.3s | ⚠️ +16ms |
| nodeModulesSize | 348 MB | 348 MB | ⚠️ +244 B |
Page Load Tests Overall decrease ⚠️
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| / failed reqs | 0 | 0 | ✓ |
| / total time (seconds) | 4.108 | 4.21 | ⚠️ +0.1 |
| / avg req/sec | 608.58 | 593.89 | ⚠️ -14.69 |
| /error-in-render failed reqs | 0 | 0 | ✓ |
| /error-in-render total time (seconds) | 2.11 | 2.086 | -0.02 |
| /error-in-render avg req/sec | 1184.99 | 1198.24 | +13.25 |
Client Bundles (main, webpack, commons)
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| 450.HASH.js gzip | 179 B | 179 B | ✓ |
| framework-HASH.js gzip | 42.2 kB | 42.2 kB | ✓ |
| main-HASH.js gzip | 27.1 kB | 27.1 kB | ✓ |
| webpack-HASH.js gzip | 1.45 kB | 1.45 kB | ✓ |
| Overall change | 70.9 kB | 70.9 kB | ✓ |
Legacy Client Bundles (polyfills)
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| polyfills-HASH.js gzip | 31 kB | 31 kB | ✓ |
| Overall change | 31 kB | 31 kB | ✓ |
Client Pages
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| _app-HASH.js gzip | 1.37 kB | 1.37 kB | ✓ |
| _error-HASH.js gzip | 194 B | 194 B | ✓ |
| amp-HASH.js gzip | 312 B | 312 B | ✓ |
| css-HASH.js gzip | 326 B | 326 B | ✓ |
| dynamic-HASH.js gzip | 2.37 kB | 2.37 kB | ✓ |
| head-HASH.js gzip | 350 B | 350 B | ✓ |
| hooks-HASH.js gzip | 919 B | 919 B | ✓ |
| image-HASH.js gzip | 4.74 kB | 4.74 kB | ✓ |
| index-HASH.js gzip | 263 B | 263 B | ✓ |
| link-HASH.js gzip | 2.13 kB | 2.13 kB | ✓ |
| routerDirect..HASH.js gzip | 321 B | 321 B | ✓ |
| script-HASH.js gzip | 383 B | 383 B | ✓ |
| withRouter-HASH.js gzip | 318 B | 318 B | ✓ |
| 85e02e95b279..7e3.css gzip | 107 B | 107 B | ✓ |
| Overall change | 14.1 kB | 14.1 kB | ✓ |
Client Build Manifests
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| _buildManifest.js gzip | 459 B | 459 B | ✓ |
| Overall change | 459 B | 459 B | ✓ |
Rendered Page Sizes
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| index.html gzip | 532 B | 532 B | ✓ |
| link.html gzip | 546 B | 546 B | ✓ |
| withRouter.html gzip | 527 B | 527 B | ✓ |
| Overall change | 1.6 kB | 1.6 kB | ✓ |
Default Build with SWC (Decrease detected ✓)
General Overall increase ⚠️
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| buildDuration | 21.8s | 21.5s | -279ms |
| buildDurationCached | 4.3s | 4.3s | ⚠️ +2ms |
| nodeModulesSize | 348 MB | 348 MB | ⚠️ +244 B |
Page Load Tests Overall decrease ⚠️
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| / failed reqs | 0 | 0 | ✓ |
| / total time (seconds) | 4.146 | 4.217 | ⚠️ +0.07 |
| / avg req/sec | 603.05 | 592.9 | ⚠️ -10.15 |
| /error-in-render failed reqs | 0 | 0 | ✓ |
| /error-in-render total time (seconds) | 2.129 | 2.14 | ⚠️ +0.01 |
| /error-in-render avg req/sec | 1174.11 | 1168.38 | ⚠️ -5.73 |
Client Bundles (main, webpack, commons)
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| 450.HASH.js gzip | 179 B | 179 B | ✓ |
| framework-HASH.js gzip | 42.3 kB | 42.3 kB | ✓ |
| main-HASH.js gzip | 27.2 kB | 27.2 kB | ✓ |
| webpack-HASH.js gzip | 1.44 kB | 1.44 kB | ✓ |
| Overall change | 71.1 kB | 71.1 kB | ✓ |
Legacy Client Bundles (polyfills)
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| polyfills-HASH.js gzip | 31 kB | 31 kB | ✓ |
| Overall change | 31 kB | 31 kB | ✓ |
Client Pages
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| _app-HASH.js gzip | 1.35 kB | 1.35 kB | ✓ |
| _error-HASH.js gzip | 180 B | 180 B | ✓ |
| amp-HASH.js gzip | 305 B | 305 B | ✓ |
| css-HASH.js gzip | 321 B | 321 B | ✓ |
| dynamic-HASH.js gzip | 2.36 kB | 2.36 kB | ✓ |
| head-HASH.js gzip | 342 B | 342 B | ✓ |
| hooks-HASH.js gzip | 906 B | 906 B | ✓ |
| image-HASH.js gzip | 4.76 kB | 4.76 kB | ✓ |
| index-HASH.js gzip | 256 B | 256 B | ✓ |
| link-HASH.js gzip | 2.19 kB | 2.19 kB | ✓ |
| routerDirect..HASH.js gzip | 314 B | 314 B | ✓ |
| script-HASH.js gzip | 375 B | 375 B | ✓ |
| withRouter-HASH.js gzip | 309 B | 309 B | ✓ |
| 85e02e95b279..7e3.css gzip | 107 B | 107 B | ✓ |
| Overall change | 14.1 kB | 14.1 kB | ✓ |
Client Build Manifests
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| _buildManifest.js gzip | 459 B | 459 B | ✓ |
| Overall change | 459 B | 459 B | ✓ |
Rendered Page Sizes
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| index.html gzip | 531 B | 531 B | ✓ |
| link.html gzip | 544 B | 544 B | ✓ |
| withRouter.html gzip | 525 B | 525 B | ✓ |
| Overall change | 1.6 kB | 1.6 kB | ✓ |
Failing test suites
Commit: d80db50eaef45e5fe2671fc49387d58baaad54b3
test/production/dependencies-can-use-env-vars-in-middlewares/index.test.ts
- dependencies can use env vars in middlewares > uses the environment variables
Expand output
● dependencies can use env vars in middlewares › uses the environment variables
expect(received).toContain(expected) // indexOf
Expected substring: "{\"string\":\"a constant string\",\"hello\":\"env-var-used-in-middleware\",\"customPackage\":\"my-custom-package-env-var\"}"
Received string: "<!DOCTYPE html><html><head><meta name=\"viewport\" content=\"width=device-width\"/><meta charSet=\"utf-8\"/><title>404: This page could not be found</title><meta name=\"next-head-count\" content=\"3\"/><noscript data-n-css=\"\"></noscript><script defer=\"\" nomodule=\"\" src=\"/_next/static/chunks/polyfills-5cd94c89d3acac5f.js\"></script><script src=\"/_next/static/chunks/webpack-7d0ef319438b7284.js\" defer=\"\"></script><script src=\"/_next/static/chunks/framework-e020fd95cfb4ceb0.js\" defer=\"\"></script><script src=\"/_next/static/chunks/main-3680c800bf170827.js\" defer=\"\"></script><script src=\"/_next/static/chunks/pages/_app-ba0d1cdf43a37972.js\" defer=\"\"></script><script src=\"/_next/static/chunks/pages/_error-6679c1efb053c50e.js\" defer=\"\"></script><script src=\"/_next/static/3WDqANFsaMkHTXCYiOunm/_buildManifest.js\" defer=\"\"></script><script src=\"/_next/static/3WDqANFsaMkHTXCYiOunm/_ssgManifest.js\" defer=\"\"></script><script src=\"/_next/static/3WDqANFsaMkHTXCYiOunm/_middlewareManifest.js\" defer=\"\"></script></head><body><div id=\"__next\" data-reactroot=\"\"><div style=\"color:#000;background:#fff;font-family:-apple-system, BlinkMacSystemFont, Roboto, "Segoe UI", "Fira Sans", Avenir, "Helvetica Neue", "Lucida Grande", sans-serif;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center\"><div><style>body { margin: 0 }</style><h1 style=\"display:inline-block;border-right:1px solid rgba(0, 0, 0,.3);margin:0;margin-right:20px;padding:10px 23px 10px 0;font-size:24px;font-weight:500;vertical-align:top\">404</h1><div style=\"display:inline-block;text-align:left;line-height:49px;height:49px;vertical-align:middle\"><h2 style=\"font-size:14px;font-weight:normal;line-height:inherit;margin:0;padding:0\">This page could not be found<!-- -->.</h2></div></div></div></div><script id=\"__NEXT_DATA__\" type=\"application/json\">{\"props\":{\"pageProps\":{\"statusCode\":404}},\"page\":\"/_error\",\"query\":{},\"buildId\":\"3WDqANFsaMkHTXCYiOunm\",\"nextExport\":true,\"isFallback\":false,\"gip\":true,\"scriptLoader\":[]}</script></body></html>"
60 | expect(envVars).toContain('MY_CUSTOM_PACKAGE_ENV_VAR')
61 | })
> 62 |
| ^
63 | it('uses the environment variables', async () => {
64 | const html = await renderViaHTTP(next.url, '/api')
65 | expect(html).toContain(
at Object.<anonymous> (production/dependencies-can-use-env-vars-in-middlewares/index.test.ts:62:22)
test/development/basic-basepath/misc.test.ts
- misc basic dev tests > With Security Related Issues > should handle encoded / value for trailing slash correctly
Expand output
● misc basic dev tests › With Security Related Issues › should handle encoded / value for trailing slash correctly
expect(received).toBe(expected) // Object.is equality
Expected: "/docs/%2fexample.com"
Received: "/docs/%252fexample.com"
60 | '/docs/%2fexample.com/',
61 | undefined,
> 62 | { redirect: 'manual' }
| ^
63 | )
64 |
65 | const { pathname, hostname } = url.parse(
at Object.<anonymous> (development/basic-basepath/misc.test.ts:62:30)
test/integration/export-serverless/test/index.test.js
- Static Export > Render in development mode > should render pages only existent in exportPathMap page
Expand output
● Static Export › Render in development mode › should render pages only existent in exportPathMap page
page.waitForSelector: Timeout 30000ms exceeded.
=========================== logs ===========================
waiting for selector "#dynamic-page p"
============================================================
226 | async getAttribute(attr) {
227 | return this.chain((el) => el.getAttribute(attr))
> 228 | }
| ^
229 |
230 | async hasElementByCssSelector(selector: string) {
231 | return this.eval(`!!document.querySelector('${selector}')`) as any
at lib/browsers/playwright.ts:228:25
test/integration/export/test/index.test.js
- Static Export > Render in development mode > should render pages only existent in exportPathMap page
Expand output
● Static Export › Render in development mode › should render pages only existent in exportPathMap page
page.waitForSelector: Timeout 30000ms exceeded.
=========================== logs ===========================
waiting for selector "#dynamic-page p"
============================================================
226 | async getAttribute(attr) {
227 | return this.chain((el) => el.getAttribute(attr))
> 228 | }
| ^
229 |
230 | async hasElementByCssSelector(selector: string) {
231 | return this.eval(`!!document.querySelector('${selector}')`) as any
at lib/browsers/playwright.ts:228:25
test/integration/middleware/with-i18n/test/index.test.js
- Middleware i18n tests > dev mode > reads the locale from the pathname
- Middleware i18n tests > dev mode > rewrites from a locale correctly
- Middleware i18n tests > production mode > reads the locale from the pathname
- Middleware i18n tests > production mode > rewrites from a locale correctly
Expand output
● Middleware i18n tests › dev mode › reads the locale from the pathname
expect(received).toBe(expected) // Object.is equality
Expected: "fr"
Received: ""
42 | runTests()
43 | })
> 44 | })
| ^
45 |
46 | function runTests() {
47 | it(`reads the locale from the pathname`, async () => {
at Object.<anonymous> (integration/middleware/with-i18n/test/index.test.js:44:37)
● Middleware i18n tests › dev mode › rewrites from a locale correctly
expect(received).toBe(expected) // Object.is equality
Expected: "es"
Received: ""
51 | const $ = cheerio.load(html)
52 | expect($('#locale').text()).toBe('fr')
> 53 | expect($('#country').text()).toBe('spain')
| ^
54 | })
55 |
56 | it(`rewrites from a locale correctly`, async () => {
at Object.<anonymous> (integration/middleware/with-i18n/test/index.test.js:53:37)
● Middleware i18n tests › production mode › reads the locale from the pathname
expect(received).toBe(expected) // Object.is equality
Expected: "fr"
Received: ""
42 | runTests()
43 | })
> 44 | })
| ^
45 |
46 | function runTests() {
47 | it(`reads the locale from the pathname`, async () => {
at Object.<anonymous> (integration/middleware/with-i18n/test/index.test.js:44:37)
● Middleware i18n tests › production mode › rewrites from a locale correctly
expect(received).toBe(expected) // Object.is equality
Expected: "es"
Received: ""
51 | const $ = cheerio.load(html)
52 | expect($('#locale').text()).toBe('fr')
> 53 | expect($('#country').text()).toBe('spain')
| ^
54 | })
55 |
56 | it(`rewrites from a locale correctly`, async () => {
at Object.<anonymous> (integration/middleware/with-i18n/test/index.test.js:53:37)
test/integration/middleware/with-base-path/test/index.test.js
- Middleware base tests > dev mode > should execute from absolute paths
- Middleware base tests > production mode > should execute from absolute paths
- Middleware base tests > production mode > should redirect via preflight middleware request
Expand output
● Middleware base tests › dev mode › should execute from absolute paths
expect(received).toBe(expected) // Object.is equality
Expected: "/root/redirect-with-basepath"
Received: "/redirect-with-basepath"
38 | runPreflightTests()
39 | })
> 40 | })
| ^
41 |
42 | function runTests() {
43 | it('should execute from absolute paths', async () => {
at Object.<anonymous> (integration/middleware/with-base-path/test/index.test.js:40:68)
● Middleware base tests › production mode › should execute from absolute paths
expect(received).toBe(expected) // Object.is equality
Expected: "/root/redirect-with-basepath"
Received: "/redirect-with-basepath"
38 | runPreflightTests()
39 | })
> 40 | })
| ^
41 |
42 | function runTests() {
43 | it('should execute from absolute paths', async () => {
at Object.<anonymous> (integration/middleware/with-base-path/test/index.test.js:40:68)
● Middleware base tests › production mode › should redirect via preflight middleware request
expect(received).toBe(expected) // Object.is equality
Expected: "/root/about"
Received: null
54 | context.appPort,
55 | '/root/redirect-with-basepath'
> 56 | )
| ^
57 | const html = await res.text()
58 | const $ = cheerio.load(html)
59 | expect($('.title').text()).toBe('About Page')
at Object.<anonymous> (integration/middleware/with-base-path/test/index.test.js:56:30)
Stats from current PR
Default Build (Decrease detected ✓)
General Overall increase ⚠️
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| buildDuration | 16.2s | 16.2s | -85ms |
| buildDurationCached | 3.3s | 3.2s | -53ms |
| nodeModulesSize | 355 MB | 355 MB | ⚠️ +244 B |
Page Load Tests Overall decrease ⚠️
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| / failed reqs | 0 | 0 | ✓ |
| / total time (seconds) | 2.99 | 3.037 | ⚠️ +0.05 |
| / avg req/sec | 836.13 | 823.21 | ⚠️ -12.92 |
| /error-in-render failed reqs | 0 | 0 | ✓ |
| /error-in-render total time (seconds) | 1.387 | 1.39 | 0 |
| /error-in-render avg req/sec | 1802.75 | 1798.04 | ⚠️ -4.71 |
Client Bundles (main, webpack, commons)
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| 450.HASH.js gzip | 179 B | 179 B | ✓ |
| framework-HASH.js gzip | 42.2 kB | 42.2 kB | ✓ |
| main-HASH.js gzip | 27.2 kB | 27.2 kB | ✓ |
| webpack-HASH.js gzip | 1.44 kB | 1.44 kB | ✓ |
| Overall change | 71 kB | 71 kB | ✓ |
Legacy Client Bundles (polyfills)
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| polyfills-HASH.js gzip | 31 kB | 31 kB | ✓ |
| Overall change | 31 kB | 31 kB | ✓ |
Client Pages
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| _app-HASH.js gzip | 1.37 kB | 1.37 kB | ✓ |
| _error-HASH.js gzip | 194 B | 194 B | ✓ |
| amp-HASH.js gzip | 312 B | 312 B | ✓ |
| css-HASH.js gzip | 326 B | 326 B | ✓ |
| dynamic-HASH.js gzip | 2.37 kB | 2.37 kB | ✓ |
| head-HASH.js gzip | 350 B | 350 B | ✓ |
| hooks-HASH.js gzip | 919 B | 919 B | ✓ |
| image-HASH.js gzip | 4.7 kB | 4.7 kB | ✓ |
| index-HASH.js gzip | 263 B | 263 B | ✓ |
| link-HASH.js gzip | 2.13 kB | 2.13 kB | ✓ |
| routerDirect..HASH.js gzip | 321 B | 321 B | ✓ |
| script-HASH.js gzip | 383 B | 383 B | ✓ |
| withRouter-HASH.js gzip | 318 B | 318 B | ✓ |
| 85e02e95b279..7e3.css gzip | 107 B | 107 B | ✓ |
| Overall change | 14.1 kB | 14.1 kB | ✓ |
Client Build Manifests
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| _buildManifest.js gzip | 459 B | 459 B | ✓ |
| Overall change | 459 B | 459 B | ✓ |
Rendered Page Sizes
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| index.html gzip | 531 B | 531 B | ✓ |
| link.html gzip | 545 B | 545 B | ✓ |
| withRouter.html gzip | 526 B | 526 B | ✓ |
| Overall change | 1.6 kB | 1.6 kB | ✓ |
Default Build with SWC (Increase detected ⚠️)
General Overall increase ⚠️
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| buildDuration | 16.1s | 16s | -71ms |
| buildDurationCached | 3.2s | 3.2s | -22ms |
| nodeModulesSize | 355 MB | 355 MB | ⚠️ +244 B |
Page Load Tests Overall increase ✓
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| / failed reqs | 0 | 0 | ✓ |
| / total time (seconds) | 3.039 | 2.989 | -0.05 |
| / avg req/sec | 822.75 | 836.27 | +13.52 |
| /error-in-render failed reqs | 0 | 0 | ✓ |
| /error-in-render total time (seconds) | 1.35 | 1.305 | -0.05 |
| /error-in-render avg req/sec | 1852.22 | 1915.65 | +63.43 |
Client Bundles (main, webpack, commons)
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| 450.HASH.js gzip | 179 B | 179 B | ✓ |
| framework-HASH.js gzip | 42.3 kB | 42.3 kB | ✓ |
| main-HASH.js gzip | 27.3 kB | 27.3 kB | ✓ |
| webpack-HASH.js gzip | 1.44 kB | 1.44 kB | ✓ |
| Overall change | 71.3 kB | 71.3 kB | ✓ |
Legacy Client Bundles (polyfills)
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| polyfills-HASH.js gzip | 31 kB | 31 kB | ✓ |
| Overall change | 31 kB | 31 kB | ✓ |
Client Pages
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| _app-HASH.js gzip | 1.35 kB | 1.35 kB | ✓ |
| _error-HASH.js gzip | 180 B | 180 B | ✓ |
| amp-HASH.js gzip | 305 B | 305 B | ✓ |
| css-HASH.js gzip | 321 B | 321 B | ✓ |
| dynamic-HASH.js gzip | 2.36 kB | 2.36 kB | ✓ |
| head-HASH.js gzip | 342 B | 342 B | ✓ |
| hooks-HASH.js gzip | 911 B | 911 B | ✓ |
| image-HASH.js gzip | 4.73 kB | 4.73 kB | ✓ |
| index-HASH.js gzip | 256 B | 256 B | ✓ |
| link-HASH.js gzip | 2.19 kB | 2.19 kB | ✓ |
| routerDirect..HASH.js gzip | 314 B | 314 B | ✓ |
| script-HASH.js gzip | 375 B | 375 B | ✓ |
| withRouter-HASH.js gzip | 309 B | 309 B | ✓ |
| 85e02e95b279..7e3.css gzip | 107 B | 107 B | ✓ |
| Overall change | 14.1 kB | 14.1 kB | ✓ |
Client Build Manifests
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| _buildManifest.js gzip | 459 B | 459 B | ✓ |
| Overall change | 459 B | 459 B | ✓ |
Rendered Page Sizes
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| index.html gzip | 531 B | 531 B | ✓ |
| link.html gzip | 545 B | 545 B | ✓ |
| withRouter.html gzip | 526 B | 526 B | ✓ |
| Overall change | 1.6 kB | 1.6 kB | ✓ |
Failing test suites
Commit: 688e577234edf18fb54d43283da4f03bae457a0a
test/production/dependencies-can-use-env-vars-in-middlewares/index.test.ts
- dependencies can use env vars in middlewares > uses the environment variables
Expand output
● dependencies can use env vars in middlewares › uses the environment variables
expect(received).toContain(expected) // indexOf
Expected substring: "{\"string\":\"a constant string\",\"hello\":\"env-var-used-in-middleware\",\"customPackage\":\"my-custom-package-env-var\"}"
Received string: "<!DOCTYPE html><html><head><meta name=\"viewport\" content=\"width=device-width\"/><meta charSet=\"utf-8\"/><title>404: This page could not be found</title><meta name=\"next-head-count\" content=\"3\"/><noscript data-n-css=\"\"></noscript><script defer=\"\" nomodule=\"\" src=\"/_next/static/chunks/polyfills-5cd94c89d3acac5f.js\"></script><script src=\"/_next/static/chunks/webpack-7d0ef319438b7284.js\" defer=\"\"></script><script src=\"/_next/static/chunks/framework-e020fd95cfb4ceb0.js\" defer=\"\"></script><script src=\"/_next/static/chunks/main-7678192bf75f2d7f.js\" defer=\"\"></script><script src=\"/_next/static/chunks/pages/_app-ba0d1cdf43a37972.js\" defer=\"\"></script><script src=\"/_next/static/chunks/pages/_error-6679c1efb053c50e.js\" defer=\"\"></script><script src=\"/_next/static/YrRq76N4sXs4LLsc8kmA2/_buildManifest.js\" defer=\"\"></script><script src=\"/_next/static/YrRq76N4sXs4LLsc8kmA2/_ssgManifest.js\" defer=\"\"></script><script src=\"/_next/static/YrRq76N4sXs4LLsc8kmA2/_middlewareManifest.js\" defer=\"\"></script></head><body><div id=\"__next\" data-reactroot=\"\"><div style=\"color:#000;background:#fff;font-family:-apple-system, BlinkMacSystemFont, Roboto, "Segoe UI", "Fira Sans", Avenir, "Helvetica Neue", "Lucida Grande", sans-serif;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center\"><div><style>body { margin: 0 }</style><h1 style=\"display:inline-block;border-right:1px solid rgba(0, 0, 0,.3);margin:0;margin-right:20px;padding:10px 23px 10px 0;font-size:24px;font-weight:500;vertical-align:top\">404</h1><div style=\"display:inline-block;text-align:left;line-height:49px;height:49px;vertical-align:middle\"><h2 style=\"font-size:14px;font-weight:normal;line-height:inherit;margin:0;padding:0\">This page could not be found<!-- -->.</h2></div></div></div></div><script id=\"__NEXT_DATA__\" type=\"application/json\">{\"props\":{\"pageProps\":{\"statusCode\":404}},\"page\":\"/_error\",\"query\":{},\"buildId\":\"YrRq76N4sXs4LLsc8kmA2\",\"nextExport\":true,\"isFallback\":false,\"gip\":true,\"scriptLoader\":[]}</script></body></html>"
60 | expect(envVars).toContain('MY_CUSTOM_PACKAGE_ENV_VAR')
61 | })
> 62 |
| ^
63 | it('uses the environment variables', async () => {
64 | const html = await renderViaHTTP(next.url, '/api')
65 | expect(html).toContain(
at Object.<anonymous> (production/dependencies-can-use-env-vars-in-middlewares/index.test.ts:62:22)
test/development/basic-basepath/misc.test.ts
- misc basic dev tests > With Security Related Issues > should handle encoded / value for trailing slash correctly
Expand output
● misc basic dev tests › With Security Related Issues › should handle encoded / value for trailing slash correctly
expect(received).toBe(expected) // Object.is equality
Expected: "/docs/%2fexample.com"
Received: "/docs/%252fexample.com"
60 | '/docs/%2fexample.com/',
61 | undefined,
> 62 | { redirect: 'manual' }
| ^
63 | )
64 |
65 | const { pathname, hostname } = url.parse(
at Object.<anonymous> (development/basic-basepath/misc.test.ts:62:30)
test/integration/export-serverless/test/index.test.js
- Static Export > Render in development mode > should render pages only existent in exportPathMap page
Expand output
● Static Export › Render in development mode › should render pages only existent in exportPathMap page
page.waitForSelector: Timeout 30000ms exceeded.
=========================== logs ===========================
waiting for selector "#dynamic-page p"
============================================================
226 | async getAttribute(attr) {
227 | return this.chain((el) => el.getAttribute(attr))
> 228 | }
| ^
229 |
230 | async hasElementByCssSelector(selector: string) {
231 | return this.eval(`!!document.querySelector('${selector}')`) as any
at lib/browsers/playwright.ts:228:25
test/integration/export/test/index.test.js
- Static Export > Render in development mode > should render pages only existent in exportPathMap page
Expand output
● Static Export › Render in development mode › should render pages only existent in exportPathMap page
page.waitForSelector: Timeout 30000ms exceeded.
=========================== logs ===========================
waiting for selector "#dynamic-page p"
============================================================
226 | async getAttribute(attr) {
227 | return this.chain((el) => el.getAttribute(attr))
> 228 | }
| ^
229 |
230 | async hasElementByCssSelector(selector: string) {
231 | return this.eval(`!!document.querySelector('${selector}')`) as any
at lib/browsers/playwright.ts:228:25
test/integration/middleware/with-eval/test/index.test.js
- Middleware usage of dynamic code evaluation > dev mode > shows a warning when running code with eval
- Middleware usage of dynamic code evaluation > dev mode > does not show warning when no code uses eval
- Middleware usage of dynamic code evaluation > dev mode > does not has problems with eval in page or server code
Expand output
● Middleware usage of dynamic code evaluation › dev mode › shows a warning when running code with eval
FetchError: invalid json response body at http://localhost:38405/using-eval reason: Unexpected token < in JSON at position 0
35 | })
36 | })
> 37 |
| ^
38 | beforeEach(() => (output = ''))
39 | afterAll(() => killApp(context.app))
40 |
at ../node_modules/node-fetch/lib/index.js:273:32
at Object.<anonymous> (integration/middleware/with-eval/test/index.test.js:37:26)
● Middleware usage of dynamic code evaluation › dev mode › does not show warning when no code uses eval
FetchError: invalid json response body at http://localhost:38405/not-using-eval reason: Unexpected token < in JSON at position 0
48 | expect(output).toContain('pages/_middleware')
49 | // TODO check why that has a backslash on windows
> 50 | expect(output).toMatch(/lib[\\/]utils\.js/)
| ^
51 | expect(output).toContain('usingEval')
52 | expect(stripAnsi(output)).toContain("value: eval('100')")
53 | })
at ../node_modules/node-fetch/lib/index.js:273:32
at Object.<anonymous> (integration/middleware/with-eval/test/index.test.js:50:26)
● Middleware usage of dynamic code evaluation › dev mode › does not has problems with eval in page or server code
expect(received).toMatch(expected)
Expected pattern: />100<!-- --> and <!-- -->100<\//
Received string: "<!DOCTYPE html><html><head><style data-next-hide-fouc=\"true\">body{display:none}</style><noscript data-next-hide-fouc=\"true\"><style>body{display:block}</style></noscript><meta charSet=\"utf-8\"/><meta name=\"viewport\" content=\"width=device-width\"/><meta name=\"next-head-count\" content=\"2\"/><noscript data-n-css=\"\"></noscript><script defer=\"\" nomodule=\"\" src=\"/_next/static/chunks/polyfills.js?ts=1643087820333\"></script><script src=\"/_next/static/chunks/webpack.js?ts=1643087820333\" defer=\"\"></script><script src=\"/_next/static/chunks/main.js?ts=1643087820333\" defer=\"\"></script><script src=\"/_next/static/chunks/pages/_app.js?ts=1643087820333\" defer=\"\"></script><script src=\"/_next/static/chunks/pages/_error.js?ts=1643087820333\" defer=\"\"></script><script src=\"/_next/static/development/_buildManifest.js?ts=1643087820333\" defer=\"\"></script><script src=\"/_next/static/development/_ssgManifest.js?ts=1643087820333\" defer=\"\"></script><script src=\"/_next/static/development/_middlewareManifest.js?ts=1643087820333\" defer=\"\"></script><noscript id=\"__next_css__DO_NOT_USE__\"></noscript></head><body><div id=\"__next\" data-reactroot=\"\"></div><script src=\"/_next/static/chunks/react-refresh.js?ts=1643087820333\"></script><script id=\"__NEXT_DATA__\" type=\"application/json\">{\"props\":{\"pageProps\":{\"statusCode\":200}},\"page\":\"/_error\",\"query\":{},\"buildId\":\"development\",\"isFallback\":false,\"err\":{\"name\":\"Error\",\"message\":\"ENOENT: no such file or directory, open 'url'\",\"stack\":\"Error: ENOENT: no such file or directory, open 'url'\\n at Object.openSync (fs.js:497:3)\\n at Object.readFileSync (fs.js:393:35)\\n at requireFn (/home/runner/work/next.js/next.js/packages/next/dist/server/web/sandbox/require.js:37:110)\\n at evalmachine.\\u003canonymous\\u003e:8:12\\n at requireFn (/home/runner/work/next.js/next.js/packages/next/dist/server/web/sandbox/require.js:39:13)\\n at evalmachine.\\u003canonymous\\u003e:11:27\\n at requireFn (/home/runner/work/next.js/next.js/packages/next/dist/server/web/sandbox/require.js:39:13)\\n at evalmachine.\\u003canonymous\\u003e:6:15\\n at requireFn (/home/runner/work/next.js/next.js/packages/next/dist/server/web/sandbox/require.js:39:13)\\n at evalmachine.\\u003canonymous\\u003e:7:16\",\"middleware\":true},\"gip\":true,\"scriptLoader\":[]}</script></body></html>"
55 | it('does not show warning when no code uses eval', async () => {
56 | const res = await fetchViaHTTP(context.appPort, `/not-using-eval`)
> 57 | const json = await res.json()
| ^
58 | await waitFor(500)
59 | expect(json.value).toEqual(100)
60 | expect(output).not.toContain(DYNAMIC_CODE_ERROR)
at Object.<anonymous> (integration/middleware/with-eval/test/index.test.js:57:26)
test/integration/middleware/with-base-path/test/index.test.js
- Middleware base tests > dev mode > should execute from absolute paths
- Middleware base tests > production mode > should execute from absolute paths
- Middleware base tests > production mode > should redirect via preflight middleware request
Expand output
● Middleware base tests › dev mode › should execute from absolute paths
expect(received).toBe(expected) // Object.is equality
Expected: "/root/redirect-with-basepath"
Received: "/redirect-with-basepath"
38 | runPreflightTests()
39 | })
> 40 | })
| ^
41 |
42 | function runTests() {
43 | it('should execute from absolute paths', async () => {
at Object.<anonymous> (integration/middleware/with-base-path/test/index.test.js:40:68)
● Middleware base tests › production mode › should execute from absolute paths
expect(received).toBe(expected) // Object.is equality
Expected: "/root/redirect-with-basepath"
Received: "/redirect-with-basepath"
38 | runPreflightTests()
39 | })
> 40 | })
| ^
41 |
42 | function runTests() {
43 | it('should execute from absolute paths', async () => {
at Object.<anonymous> (integration/middleware/with-base-path/test/index.test.js:40:68)
● Middleware base tests › production mode › should redirect via preflight middleware request
expect(received).toBe(expected) // Object.is equality
Expected: "/root/about"
Received: null
54 | context.appPort,
55 | '/root/redirect-with-basepath'
> 56 | )
| ^
57 | const html = await res.text()
58 | const $ = cheerio.load(html)
59 | expect($('.title').text()).toBe('About Page')
at Object.<anonymous> (integration/middleware/with-base-path/test/index.test.js:56:30)
Stats from current PR
Default Build (Decrease detected ✓)
General Overall increase ⚠️
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| buildDuration | 14.8s | 14.7s | -162ms |
| buildDurationCached | 3.8s | 3.9s | ⚠️ +12ms |
| nodeModulesSize | 356 MB | 356 MB | ⚠️ +236 B |
Page Load Tests Overall decrease ⚠️
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| / failed reqs | 0 | 0 | ✓ |
| / total time (seconds) | 3.411 | 3.462 | ⚠️ +0.05 |
| / avg req/sec | 732.99 | 722.04 | ⚠️ -10.95 |
| /error-in-render failed reqs | 0 | 0 | ✓ |
| /error-in-render total time (seconds) | 1.591 | 1.664 | ⚠️ +0.07 |
| /error-in-render avg req/sec | 1571.52 | 1502.09 | ⚠️ -69.43 |
Client Bundles (main, webpack, commons)
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| 450.HASH.js gzip | 179 B | 179 B | ✓ |
| framework-HASH.js gzip | 42.2 kB | 42.2 kB | ✓ |
| main-HASH.js gzip | 27.2 kB | 27.2 kB | ✓ |
| webpack-HASH.js gzip | 1.44 kB | 1.44 kB | ✓ |
| Overall change | 71 kB | 71 kB | ✓ |
Legacy Client Bundles (polyfills)
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| polyfills-HASH.js gzip | 31 kB | 31 kB | ✓ |
| Overall change | 31 kB | 31 kB | ✓ |
Client Pages
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| _app-HASH.js gzip | 1.37 kB | 1.37 kB | ✓ |
| _error-HASH.js gzip | 194 B | 194 B | ✓ |
| amp-HASH.js gzip | 312 B | 312 B | ✓ |
| css-HASH.js gzip | 326 B | 326 B | ✓ |
| dynamic-HASH.js gzip | 2.37 kB | 2.37 kB | ✓ |
| head-HASH.js gzip | 350 B | 350 B | ✓ |
| hooks-HASH.js gzip | 919 B | 919 B | ✓ |
| image-HASH.js gzip | 4.87 kB | 4.87 kB | ✓ |
| index-HASH.js gzip | 263 B | 263 B | ✓ |
| link-HASH.js gzip | 2.13 kB | 2.13 kB | ✓ |
| routerDirect..HASH.js gzip | 321 B | 321 B | ✓ |
| script-HASH.js gzip | 383 B | 383 B | ✓ |
| withRouter-HASH.js gzip | 318 B | 318 B | ✓ |
| 85e02e95b279..7e3.css gzip | 107 B | 107 B | ✓ |
| Overall change | 14.2 kB | 14.2 kB | ✓ |
Client Build Manifests
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| _buildManifest.js gzip | 459 B | 459 B | ✓ |
| Overall change | 459 B | 459 B | ✓ |
Rendered Page Sizes
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| index.html gzip | 531 B | 531 B | ✓ |
| link.html gzip | 544 B | 544 B | ✓ |
| withRouter.html gzip | 526 B | 526 B | ✓ |
| Overall change | 1.6 kB | 1.6 kB | ✓ |
Default Build with SWC (Increase detected ⚠️)
General Overall increase ⚠️
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| buildDuration | 18.7s | 19s | ⚠️ +310ms |
| buildDurationCached | 3.8s | 3.7s | -32ms |
| nodeModulesSize | 356 MB | 356 MB | ⚠️ +236 B |
Page Load Tests Overall increase ✓
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| / failed reqs | 0 | 0 | ✓ |
| / total time (seconds) | 3.456 | 3.42 | -0.04 |
| / avg req/sec | 723.43 | 730.96 | +7.53 |
| /error-in-render failed reqs | 0 | 0 | ✓ |
| /error-in-render total time (seconds) | 1.593 | 1.546 | -0.05 |
| /error-in-render avg req/sec | 1569.02 | 1617.36 | +48.34 |
Client Bundles (main, webpack, commons)
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| 450.HASH.js gzip | 179 B | 179 B | ✓ |
| framework-HASH.js gzip | 42.3 kB | 42.3 kB | ✓ |
| main-HASH.js gzip | 27.3 kB | 27.3 kB | ✓ |
| webpack-HASH.js gzip | 1.44 kB | 1.44 kB | ✓ |
| Overall change | 71.3 kB | 71.3 kB | ✓ |
Legacy Client Bundles (polyfills)
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| polyfills-HASH.js gzip | 31 kB | 31 kB | ✓ |
| Overall change | 31 kB | 31 kB | ✓ |
Client Pages
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| _app-HASH.js gzip | 1.35 kB | 1.35 kB | ✓ |
| _error-HASH.js gzip | 180 B | 180 B | ✓ |
| amp-HASH.js gzip | 305 B | 305 B | ✓ |
| css-HASH.js gzip | 321 B | 321 B | ✓ |
| dynamic-HASH.js gzip | 2.36 kB | 2.36 kB | ✓ |
| head-HASH.js gzip | 342 B | 342 B | ✓ |
| hooks-HASH.js gzip | 911 B | 911 B | ✓ |
| image-HASH.js gzip | 4.89 kB | 4.89 kB | ✓ |
| index-HASH.js gzip | 256 B | 256 B | ✓ |
| link-HASH.js gzip | 2.19 kB | 2.19 kB | ✓ |
| routerDirect..HASH.js gzip | 314 B | 314 B | ✓ |
| script-HASH.js gzip | 375 B | 375 B | ✓ |
| withRouter-HASH.js gzip | 309 B | 309 B | ✓ |
| 85e02e95b279..7e3.css gzip | 107 B | 107 B | ✓ |
| Overall change | 14.2 kB | 14.2 kB | ✓ |
Client Build Manifests
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| _buildManifest.js gzip | 459 B | 459 B | ✓ |
| Overall change | 459 B | 459 B | ✓ |
Rendered Page Sizes
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| index.html gzip | 530 B | 530 B | ✓ |
| link.html gzip | 544 B | 544 B | ✓ |
| withRouter.html gzip | 524 B | 524 B | ✓ |
| Overall change | 1.6 kB | 1.6 kB | ✓ |
Failing test suites
Commit: 3b0fb9675aad45709e11653fc4d3b0bbd7659e83
yarn testheadless test/production/dependencies-can-use-env-vars-in-middlewares/index.test.ts
- dependencies can use env vars in middlewares > uses the environment variables
Expand output
● dependencies can use env vars in middlewares › uses the environment variables
expect(received).toContain(expected) // indexOf
Expected substring: "{\"string\":\"a constant string\",\"hello\":\"env-var-used-in-middleware\",\"customPackage\":\"my-custom-package-env-var\"}"
Received string: "<!DOCTYPE html><html><head><meta name=\"viewport\" content=\"width=device-width\"/><meta charSet=\"utf-8\"/><title>404: This page could not be found</title><meta name=\"next-head-count\" content=\"3\"/><noscript data-n-css=\"\"></noscript><script defer=\"\" nomodule=\"\" src=\"/_next/static/chunks/polyfills-5cd94c89d3acac5f.js\"></script><script src=\"/_next/static/chunks/webpack-7d0ef319438b7284.js\" defer=\"\"></script><script src=\"/_next/static/chunks/framework-e4a67534aaf451e8.js\" defer=\"\"></script><script src=\"/_next/static/chunks/main-5fecebef91d288c0.js\" defer=\"\"></script><script src=\"/_next/static/chunks/pages/_app-0065203e2706de25.js\" defer=\"\"></script><script src=\"/_next/static/chunks/pages/_error-6679c1efb053c50e.js\" defer=\"\"></script><script src=\"/_next/static/Jsx20v63rofS7TUjsdkg6/_buildManifest.js\" defer=\"\"></script><script src=\"/_next/static/Jsx20v63rofS7TUjsdkg6/_ssgManifest.js\" defer=\"\"></script><script src=\"/_next/static/Jsx20v63rofS7TUjsdkg6/_middlewareManifest.js\" defer=\"\"></script></head><body><div id=\"__next\" data-reactroot=\"\"><div style=\"color:#000;background:#fff;font-family:-apple-system, BlinkMacSystemFont, Roboto, "Segoe UI", "Fira Sans", Avenir, "Helvetica Neue", "Lucida Grande", sans-serif;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center\"><div><style>body { margin: 0 }</style><h1 style=\"display:inline-block;border-right:1px solid rgba(0, 0, 0,.3);margin:0;margin-right:20px;padding:10px 23px 10px 0;font-size:24px;font-weight:500;vertical-align:top\">404</h1><div style=\"display:inline-block;text-align:left;line-height:49px;height:49px;vertical-align:middle\"><h2 style=\"font-size:14px;font-weight:normal;line-height:inherit;margin:0;padding:0\">This page could not be found<!-- -->.</h2></div></div></div></div><script id=\"__NEXT_DATA__\" type=\"application/json\">{\"props\":{\"pageProps\":{\"statusCode\":404}},\"page\":\"/_error\",\"query\":{},\"buildId\":\"Jsx20v63rofS7TUjsdkg6\",\"nextExport\":true,\"isFallback\":false,\"gip\":true,\"scriptLoader\":[]}</script></body></html>"
63 | it('uses the environment variables', async () => {
64 | const html = await renderViaHTTP(next.url, '/api')
> 65 | expect(html).toContain(
| ^
66 | JSON.stringify({
67 | string: 'a constant string',
68 | hello: 'env-var-used-in-middleware',
at Object.<anonymous> (production/dependencies-can-use-env-vars-in-middlewares/index.test.ts:65:18)
Read more about building and testing Next.js in contributing.md.
yarn testheadless test/development/basic-basepath/misc.test.ts
- misc basic dev tests > With Security Related Issues > should handle encoded / value for trailing slash correctly
Expand output
● misc basic dev tests › With Security Related Issues › should handle encoded / value for trailing slash correctly
expect(received).toBe(expected) // Object.is equality
Expected: "/docs/%2fexample.com"
Received: "/docs/%252fexample.com"
67 | )
68 | expect(res.status).toBe(308)
> 69 | expect(pathname).toBe('/docs/%2fexample.com')
| ^
70 | expect(hostname).not.toBe('example.com')
71 | const text = await res.text()
72 | expect(text).toEqual('/docs/%2fexample.com')
at Object.<anonymous> (development/basic-basepath/misc.test.ts:69:24)
Read more about building and testing Next.js in contributing.md.
yarn testheadless test/integration/custom-routes/test/index.test.js
- Custom routes > dev mode > should handle has query encoding correctly
- Custom routes > dev mode > should handle encoded value in the pathname correctly
- Custom routes > dev mode > should handle named regex parameters with multi-match successfully
- Custom routes > dev mode > should match has hostname redirect with encoded query value
- Custom routes > server mode > should handle has query encoding correctly
- Custom routes > server mode > should handle encoded value in the pathname correctly
- Custom routes > server mode > should handle named regex parameters with multi-match successfully
- Custom routes > server mode > should match has hostname redirect with encoded query value
- Custom routes > serverless mode > should handle has query encoding correctly
- Custom routes > serverless mode > should handle encoded value in the pathname correctly
- Custom routes > serverless mode > should handle named regex parameters with multi-match successfully
- Custom routes > serverless mode > should match has hostname redirect with encoded query value
Expand output
● Custom routes › dev mode › should handle has query encoding correctly
expect(received).toEqual(expected) // deep equality
- Expected - 2
+ Received + 1
Object {
"params": Object {
"slug": Array [
- "hello",
- "world",
+ "hello/world",
],
},
}
73 | if (status === 200) {
74 | const $ = cheerio.load(await res.text())
> 75 | expect(JSON.parse($('#props').text())).toEqual({
| ^
76 | params: {
77 | slug: expected.slug,
78 | },
at Object.<anonymous> (integration/custom-routes/test/index.test.js:75:48)
● Custom routes › dev mode › should handle encoded value in the pathname correctly
expect(received).toBe(expected) // Object.is equality
Expected: "/%5Cgoogle.com/about"
Received: "/%255Cgoogle.com/about"
763 | )
764 | expect(res.status).toBe(307)
> 765 | expect(pathname).toBe(encodeURI('/\\google.com/about'))
| ^
766 | expect(hostname).not.toBe('google.com')
767 | expect(query).toEqual({})
768 | })
at Object.<anonymous> (integration/custom-routes/test/index.test.js:765:22)
at runMicrotasks (<anonymous>)
● Custom routes › dev mode › should handle named regex parameters with multi-match successfully
expect(received).toBe(expected) // Object.is equality
Expected: "/integrations/-some/thing"
Received: "/integrations/-some%2Fthing"
788 | const { pathname } = url.parse(res.headers.get('location') || '')
789 | expect(res.status).toBe(307)
> 790 | expect(pathname).toBe('/integrations/-some/thing')
| ^
791 | })
792 |
793 | it('should redirect with URL in query correctly', async () => {
at Object.<anonymous> (integration/custom-routes/test/index.test.js:790:22)
at runMicrotasks (<anonymous>)
● Custom routes › dev mode › should match has hostname redirect with encoded query value
expect(received).toBe(expected) // Object.is equality
Expected: "https://xn--bck9bsh7a3b.example.com/"
Received: "xn--bck9bsh7a3b.example.com"
1142 | const parsed = url.parse(res.headers.get('location'), true)
1143 |
> 1144 | expect(parsed.hostname).toBe('https://xn--bck9bsh7a3b.example.com/')
| ^
1145 | })
1146 |
1147 | it('should match has header for header correctly', async () => {
at Object.<anonymous> (integration/custom-routes/test/index.test.js:1144:29)
at runMicrotasks (<anonymous>)
● Custom routes › server mode › should handle has query encoding correctly
expect(received).toEqual(expected) // deep equality
- Expected - 2
+ Received + 1
Object {
"params": Object {
"slug": Array [
- "hello",
- "world",
+ "hello/world",
],
},
}
73 | if (status === 200) {
74 | const $ = cheerio.load(await res.text())
> 75 | expect(JSON.parse($('#props').text())).toEqual({
| ^
76 | params: {
77 | slug: expected.slug,
78 | },
at Object.<anonymous> (integration/custom-routes/test/index.test.js:75:48)
at runMicrotasks (<anonymous>)
● Custom routes › server mode › should handle encoded value in the pathname correctly
expect(received).toBe(expected) // Object.is equality
Expected: "/%5Cgoogle.com/about"
Received: "/%255Cgoogle.com/about"
763 | )
764 | expect(res.status).toBe(307)
> 765 | expect(pathname).toBe(encodeURI('/\\google.com/about'))
| ^
766 | expect(hostname).not.toBe('google.com')
767 | expect(query).toEqual({})
768 | })
at Object.<anonymous> (integration/custom-routes/test/index.test.js:765:22)
at runMicrotasks (<anonymous>)
● Custom routes › server mode › should handle named regex parameters with multi-match successfully
expect(received).toBe(expected) // Object.is equality
Expected: "/integrations/-some/thing"
Received: "/integrations/-some%2Fthing"
788 | const { pathname } = url.parse(res.headers.get('location') || '')
789 | expect(res.status).toBe(307)
> 790 | expect(pathname).toBe('/integrations/-some/thing')
| ^
791 | })
792 |
793 | it('should redirect with URL in query correctly', async () => {
at Object.<anonymous> (integration/custom-routes/test/index.test.js:790:22)
at runMicrotasks (<anonymous>)
● Custom routes › server mode › should match has hostname redirect with encoded query value
expect(received).toBe(expected) // Object.is equality
Expected: "https://xn--bck9bsh7a3b.example.com/"
Received: "xn--bck9bsh7a3b.example.com"
1142 | const parsed = url.parse(res.headers.get('location'), true)
1143 |
> 1144 | expect(parsed.hostname).toBe('https://xn--bck9bsh7a3b.example.com/')
| ^
1145 | })
1146 |
1147 | it('should match has header for header correctly', async () => {
at Object.<anonymous> (integration/custom-routes/test/index.test.js:1144:29)
at runMicrotasks (<anonymous>)
● Custom routes › serverless mode › should handle has query encoding correctly
expect(received).toEqual(expected) // deep equality
- Expected - 2
+ Received + 1
Object {
"params": Object {
"slug": Array [
- "hello",
- "world",
+ "hello/world",
],
},
}
73 | if (status === 200) {
74 | const $ = cheerio.load(await res.text())
> 75 | expect(JSON.parse($('#props').text())).toEqual({
| ^
76 | params: {
77 | slug: expected.slug,
78 | },
at Object.<anonymous> (integration/custom-routes/test/index.test.js:75:48)
● Custom routes › serverless mode › should handle encoded value in the pathname correctly
expect(received).toBe(expected) // Object.is equality
Expected: "/%5Cgoogle.com/about"
Received: "/%255Cgoogle.com/about"
763 | )
764 | expect(res.status).toBe(307)
> 765 | expect(pathname).toBe(encodeURI('/\\google.com/about'))
| ^
766 | expect(hostname).not.toBe('google.com')
767 | expect(query).toEqual({})
768 | })
at Object.<anonymous> (integration/custom-routes/test/index.test.js:765:22)
at runMicrotasks (<anonymous>)
● Custom routes › serverless mode › should handle named regex parameters with multi-match successfully
expect(received).toBe(expected) // Object.is equality
Expected: "/integrations/-some/thing"
Received: "/integrations/-some%2Fthing"
788 | const { pathname } = url.parse(res.headers.get('location') || '')
789 | expect(res.status).toBe(307)
> 790 | expect(pathname).toBe('/integrations/-some/thing')
| ^
791 | })
792 |
793 | it('should redirect with URL in query correctly', async () => {
at Object.<anonymous> (integration/custom-routes/test/index.test.js:790:22)
at runMicrotasks (<anonymous>)
● Custom routes › serverless mode › should match has hostname redirect with encoded query value
expect(received).toBe(expected) // Object.is equality
Expected: "https://xn--bck9bsh7a3b.example.com/"
Received: "xn--bck9bsh7a3b.example.com"
1142 | const parsed = url.parse(res.headers.get('location'), true)
1143 |
> 1144 | expect(parsed.hostname).toBe('https://xn--bck9bsh7a3b.example.com/')
| ^
1145 | })
1146 |
1147 | it('should match has header for header correctly', async () => {
at Object.<anonymous> (integration/custom-routes/test/index.test.js:1144:29)
at runMicrotasks (<anonymous>)
Read more about building and testing Next.js in contributing.md.
yarn testheadless test/integration/middleware/with-base-path/test/index.test.js
- Middleware base tests > dev mode > should execute from absolute paths
- Middleware base tests > production mode > should execute from absolute paths
- Middleware base tests > production mode > should redirect via preflight middleware request
Expand output
● Middleware base tests › dev mode › should execute from absolute paths
expect(received).toBe(expected) // Object.is equality
Expected: "/root/redirect-with-basepath"
Received: "/redirect-with-basepath"
44 | const browser = await webdriver(context.appPort, '/redirect-with-basepath')
45 | try {
> 46 | expect(await browser.eval(`window.location.pathname`)).toBe(
| ^
47 | '/root/redirect-with-basepath'
48 | )
49 | } finally {
at Object.<anonymous> (integration/middleware/with-base-path/test/index.test.js:46:62)
● Middleware base tests › production mode › should execute from absolute paths
expect(received).toBe(expected) // Object.is equality
Expected: "/root/redirect-with-basepath"
Received: "/redirect-with-basepath"
44 | const browser = await webdriver(context.appPort, '/redirect-with-basepath')
45 | try {
> 46 | expect(await browser.eval(`window.location.pathname`)).toBe(
| ^
47 | '/root/redirect-with-basepath'
48 | )
49 | } finally {
at Object.<anonymous> (integration/middleware/with-base-path/test/index.test.js:46:62)
● Middleware base tests › production mode › should redirect via preflight middleware request
expect(received).toBe(expected) // Object.is equality
Expected: "/root/about"
Received: null
72 | `next.router.sde["http://localhost:${context.appPort}/root/redirect-me-to-about"].redirect`
73 | )
> 74 | expect(redirect).toBe('/root/about')
| ^
75 | } finally {
76 | await browser.close()
77 | }
at Object.<anonymous> (integration/middleware/with-base-path/test/index.test.js:74:24)
Read more about building and testing Next.js in contributing.md.
yarn testheadless test/integration/middleware/with-i18n/test/index.test.js
- Middleware i18n tests > dev mode > reads the locale from the pathname
- Middleware i18n tests > dev mode > rewrites from a locale correctly
- Middleware i18n tests > production mode > reads the locale from the pathname
- Middleware i18n tests > production mode > rewrites from a locale correctly
Expand output
● Middleware i18n tests › dev mode › reads the locale from the pathname
expect(received).toBe(expected) // Object.is equality
Expected: "fr"
Received: ""
50 | const html = await res.text()
51 | const $ = cheerio.load(html)
> 52 | expect($('#locale').text()).toBe('fr')
| ^
53 | expect($('#country').text()).toBe('spain')
54 | })
55 |
at Object.<anonymous> (integration/middleware/with-i18n/test/index.test.js:52:33)
● Middleware i18n tests › dev mode › rewrites from a locale correctly
expect(received).toBe(expected) // Object.is equality
Expected: "es"
Received: ""
59 | const html = await res.text()
60 | const $ = cheerio.load(html)
> 61 | expect($('#locale').text()).toBe('es')
| ^
62 | expect($('#country').text()).toBe('us')
63 | })
64 | }
at Object.<anonymous> (integration/middleware/with-i18n/test/index.test.js:61:33)
● Middleware i18n tests › production mode › reads the locale from the pathname
expect(received).toBe(expected) // Object.is equality
Expected: "fr"
Received: ""
50 | const html = await res.text()
51 | const $ = cheerio.load(html)
> 52 | expect($('#locale').text()).toBe('fr')
| ^
53 | expect($('#country').text()).toBe('spain')
54 | })
55 |
at Object.<anonymous> (integration/middleware/with-i18n/test/index.test.js:52:33)
● Middleware i18n tests › production mode › rewrites from a locale correctly
expect(received).toBe(expected) // Object.is equality
Expected: "es"
Received: ""
59 | const html = await res.text()
60 | const $ = cheerio.load(html)
> 61 | expect($('#locale').text()).toBe('es')
| ^
62 | expect($('#country').text()).toBe('us')
63 | })
64 | }
at Object.<anonymous> (integration/middleware/with-i18n/test/index.test.js:61:33)
Read more about building and testing Next.js in contributing.md.
yarn testheadless test/integration/export/test/index.test.js
- Static Export > Render in development mode > should render pages only existent in exportPathMap page
Expand output
● Static Export › Render in development mode › should render pages only existent in exportPathMap page
page.waitForSelector: Timeout 30000ms exceeded.
=========================== logs ===========================
waiting for selector "#dynamic-page p"
============================================================
299 | return this.chain(() => {
300 | return page
> 301 | .waitForSelector(selector, { timeout, state: 'attached' })
| ^
302 | .then(async (el) => {
303 | // it seems selenium waits longer and tests rely on this behavior
304 | // so we wait for the load event fire before returning
at lib/browsers/playwright.ts:301:10
Read more about building and testing Next.js in contributing.md.
yarn testheadless test/integration/export-serverless/test/index.test.js
- Static Export > Render in development mode > should render pages only existent in exportPathMap page
Expand output
● Static Export › Render in development mode › should render pages only existent in exportPathMap page
page.waitForSelector: Timeout 30000ms exceeded.
=========================== logs ===========================
waiting for selector "#dynamic-page p"
============================================================
299 | return this.chain(() => {
300 | return page
> 301 | .waitForSelector(selector, { timeout, state: 'attached' })
| ^
302 | .then(async (el) => {
303 | // it seems selenium waits longer and tests rely on this behavior
304 | // so we wait for the load event fire before returning
at lib/browsers/playwright.ts:301:10
Read more about building and testing Next.js in contributing.md.
Stats from current PR
Default Build (Decrease detected ✓)
General Overall increase ⚠️
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| buildDuration | 19s | 19.1s | ⚠️ +67ms |
| buildDurationCached | 7.3s | 7.4s | ⚠️ +58ms |
| nodeModulesSize | 359 MB | 359 MB | ⚠️ +228 B |
Page Load Tests Overall decrease ⚠️
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| / failed reqs | 0 | 0 | ✓ |
| / total time (seconds) | 3.895 | 3.901 | ⚠️ +0.01 |
| / avg req/sec | 641.78 | 640.91 | ⚠️ -0.87 |
| /error-in-render failed reqs | 0 | 0 | ✓ |
| /error-in-render total time (seconds) | 1.695 | 1.748 | ⚠️ +0.05 |
| /error-in-render avg req/sec | 1475.26 | 1429.98 | ⚠️ -45.28 |
Client Bundles (main, webpack, commons)
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| 450.HASH.js gzip | 179 B | 179 B | ✓ |
| framework-HASH.js gzip | 42 kB | 42 kB | ✓ |
| main-HASH.js gzip | 27.9 kB | 27.9 kB | ✓ |
| webpack-HASH.js gzip | 1.44 kB | 1.44 kB | ✓ |
| Overall change | 71.5 kB | 71.5 kB | ✓ |
Legacy Client Bundles (polyfills)
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| polyfills-HASH.js gzip | 31 kB | 31 kB | ✓ |
| Overall change | 31 kB | 31 kB | ✓ |
Client Pages
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| _app-HASH.js gzip | 1.36 kB | 1.36 kB | ✓ |
| _error-HASH.js gzip | 194 B | 194 B | ✓ |
| amp-HASH.js gzip | 312 B | 312 B | ✓ |
| css-HASH.js gzip | 326 B | 326 B | ✓ |
| dynamic-HASH.js gzip | 2.57 kB | 2.57 kB | ✓ |
| head-HASH.js gzip | 350 B | 350 B | ✓ |
| hooks-HASH.js gzip | 919 B | 919 B | ✓ |
| image-HASH.js gzip | 5.01 kB | 5.01 kB | ✓ |
| index-HASH.js gzip | 263 B | 263 B | ✓ |
| link-HASH.js gzip | 2.26 kB | 2.26 kB | ✓ |
| routerDirect..HASH.js gzip | 321 B | 321 B | ✓ |
| script-HASH.js gzip | 383 B | 383 B | ✓ |
| withRouter-HASH.js gzip | 318 B | 318 B | ✓ |
| 85e02e95b279..7e3.css gzip | 107 B | 107 B | ✓ |
| Overall change | 14.7 kB | 14.7 kB | ✓ |
Client Build Manifests
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| _buildManifest.js gzip | 459 B | 459 B | ✓ |
| Overall change | 459 B | 459 B | ✓ |
Rendered Page Sizes
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| index.html gzip | 532 B | 532 B | ✓ |
| link.html gzip | 545 B | 545 B | ✓ |
| withRouter.html gzip | 527 B | 527 B | ✓ |
| Overall change | 1.6 kB | 1.6 kB | ✓ |
Default Build with SWC (Decrease detected ✓)
General Overall increase ⚠️
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| buildDuration | 22.4s | 22.7s | ⚠️ +251ms |
| buildDurationCached | 7.2s | 7.3s | ⚠️ +115ms |
| nodeModulesSize | 359 MB | 359 MB | ⚠️ +228 B |
Page Load Tests Overall decrease ⚠️
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| / failed reqs | 0 | 0 | ✓ |
| / total time (seconds) | 3.878 | 3.913 | ⚠️ +0.03 |
| / avg req/sec | 644.59 | 638.97 | ⚠️ -5.62 |
| /error-in-render failed reqs | 0 | 0 | ✓ |
| /error-in-render total time (seconds) | 1.644 | 1.688 | ⚠️ +0.04 |
| /error-in-render avg req/sec | 1520.32 | 1480.65 | ⚠️ -39.67 |
Client Bundles (main, webpack, commons)
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| 450.HASH.js gzip | 179 B | 179 B | ✓ |
| framework-HASH.js gzip | 42.1 kB | 42.1 kB | ✓ |
| main-HASH.js gzip | 27.9 kB | 27.9 kB | ✓ |
| webpack-HASH.js gzip | 1.44 kB | 1.44 kB | ✓ |
| Overall change | 71.7 kB | 71.7 kB | ✓ |
Legacy Client Bundles (polyfills)
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| polyfills-HASH.js gzip | 31 kB | 31 kB | ✓ |
| Overall change | 31 kB | 31 kB | ✓ |
Client Pages
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| _app-HASH.js gzip | 1.35 kB | 1.35 kB | ✓ |
| _error-HASH.js gzip | 180 B | 180 B | ✓ |
| amp-HASH.js gzip | 305 B | 305 B | ✓ |
| css-HASH.js gzip | 321 B | 321 B | ✓ |
| dynamic-HASH.js gzip | 2.56 kB | 2.56 kB | ✓ |
| head-HASH.js gzip | 342 B | 342 B | ✓ |
| hooks-HASH.js gzip | 911 B | 911 B | ✓ |
| image-HASH.js gzip | 5.05 kB | 5.05 kB | ✓ |
| index-HASH.js gzip | 256 B | 256 B | ✓ |
| link-HASH.js gzip | 2.28 kB | 2.28 kB | ✓ |
| routerDirect..HASH.js gzip | 314 B | 314 B | ✓ |
| script-HASH.js gzip | 375 B | 375 B | ✓ |
| withRouter-HASH.js gzip | 309 B | 309 B | ✓ |
| 85e02e95b279..7e3.css gzip | 107 B | 107 B | ✓ |
| Overall change | 14.7 kB | 14.7 kB | ✓ |
Client Build Manifests
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| _buildManifest.js gzip | 458 B | 458 B | ✓ |
| Overall change | 458 B | 458 B | ✓ |
Rendered Page Sizes
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| index.html gzip | 533 B | 533 B | ✓ |
| link.html gzip | 546 B | 546 B | ✓ |
| withRouter.html gzip | 526 B | 526 B | ✓ |
| Overall change | 1.6 kB | 1.6 kB | ✓ |
Failing test suites
Commit: 47b6e35de2e894209fccb5dc3fdc88b383b3b6da
yarn testheadless test/production/dependencies-can-use-env-vars-in-middlewares/index.test.ts
- dependencies can use env vars in middlewares > uses the environment variables
Expand output
● dependencies can use env vars in middlewares › uses the environment variables
expect(received).toContain(expected) // indexOf
Expected substring: "{\"string\":\"a constant string\",\"hello\":\"env-var-used-in-middleware\",\"customPackage\":\"my-custom-package-env-var\"}"
Received string: "<!DOCTYPE html><html><head><meta name=\"viewport\" content=\"width=device-width\"/><meta charSet=\"utf-8\"/><title>404: This page could not be found</title><meta name=\"next-head-count\" content=\"3\"/><noscript data-n-css=\"\"></noscript><script defer=\"\" nomodule=\"\" src=\"/_next/static/chunks/polyfills-5cd94c89d3acac5f.js\"></script><script src=\"/_next/static/chunks/webpack-7d0ef319438b7284.js\" defer=\"\"></script><script src=\"/_next/static/chunks/framework-e4a67534aaf451e8.js\" defer=\"\"></script><script src=\"/_next/static/chunks/main-32fc8f9cce6e7273.js\" defer=\"\"></script><script src=\"/_next/static/chunks/pages/_app-9a4e0bcfd9f9bf48.js\" defer=\"\"></script><script src=\"/_next/static/chunks/pages/_error-e526a695839b5a36.js\" defer=\"\"></script><script src=\"/_next/static/TKVpZPk1wiv5Z95XdQGFd/_buildManifest.js\" defer=\"\"></script><script src=\"/_next/static/TKVpZPk1wiv5Z95XdQGFd/_ssgManifest.js\" defer=\"\"></script><script src=\"/_next/static/TKVpZPk1wiv5Z95XdQGFd/_middlewareManifest.js\" defer=\"\"></script></head><body><div id=\"__next\" data-reactroot=\"\"><div style=\"color:#000;background:#fff;font-family:-apple-system, BlinkMacSystemFont, Roboto, "Segoe UI", "Fira Sans", Avenir, "Helvetica Neue", "Lucida Grande", sans-serif;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center\"><div><style>body { margin: 0 }</style><h1 style=\"display:inline-block;border-right:1px solid rgba(0, 0, 0,.3);margin:0;margin-right:20px;padding:10px 23px 10px 0;font-size:24px;font-weight:500;vertical-align:top\">404</h1><div style=\"display:inline-block;text-align:left;line-height:49px;height:49px;vertical-align:middle\"><h2 style=\"font-size:14px;font-weight:normal;line-height:inherit;margin:0;padding:0\">This page could not be found<!-- -->.</h2></div></div></div></div><script id=\"__NEXT_DATA__\" type=\"application/json\">{\"props\":{\"pageProps\":{\"statusCode\":404}},\"page\":\"/_error\",\"query\":{},\"buildId\":\"TKVpZPk1wiv5Z95XdQGFd\",\"nextExport\":true,\"isFallback\":false,\"gip\":true,\"scriptLoader\":[]}</script></body></html>"
63 | it('uses the environment variables', async () => {
64 | const html = await renderViaHTTP(next.url, '/api')
> 65 | expect(html).toContain(
| ^
66 | JSON.stringify({
67 | string: 'a constant string',
68 | hello: 'env-var-used-in-middleware',
at Object.<anonymous> (production/dependencies-can-use-env-vars-in-middlewares/index.test.ts:65:18)
Read more about building and testing Next.js in contributing.md.
yarn testheadless test/e2e/middleware-can-use-wasm-files/index.test.ts
- middleware can use wasm files > uses the wasm file
- middleware can use wasm files > can be called twice
- middleware can use wasm files with the experimental modes on > uses the wasm file
Expand output
● middleware can use wasm files › uses the wasm file
FetchError: invalid json response body at http://localhost:39315/ reason: Unexpected token < in JSON at position 0
41 | it('uses the wasm file', async () => {
42 | const response = await fetchViaHTTP(next.url, '/')
> 43 | expect(await response.json()).toEqual({
| ^
44 | input: 1,
45 | value: 2,
46 | })
at ../node_modules/node-fetch/lib/index.js:273:32
at Object.<anonymous> (e2e/middleware-can-use-wasm-files/index.test.ts:43:12)
● middleware can use wasm files › can be called twice
FetchError: invalid json response body at http://localhost:39315/?input=2 reason: Unexpected token < in JSON at position 0
49 | it('can be called twice', async () => {
50 | const response = await fetchViaHTTP(next.url, '/', { input: 2 })
> 51 | expect(await response.json()).toEqual({
| ^
52 | input: 2,
53 | value: 3,
54 | })
at ../node_modules/node-fetch/lib/index.js:273:32
at Object.<anonymous> (e2e/middleware-can-use-wasm-files/index.test.ts:51:12)
● middleware can use wasm files with the experimental modes on › uses the wasm file
FetchError: invalid json response body at http://localhost:44753/ reason: Unexpected token < in JSON at position 0
96 | it('uses the wasm file', async () => {
97 | const response = await fetchViaHTTP(next.url, '/')
> 98 | expect(await response.json()).toEqual({
| ^
99 | input: 1,
100 | value: 2,
101 | })
at ../node_modules/node-fetch/lib/index.js:273:32
at runMicrotasks (<anonymous>)
at Object.<anonymous> (e2e/middleware-can-use-wasm-files/index.test.ts:98:12)
Read more about building and testing Next.js in contributing.md.
yarn testheadless test/integration/middleware/hmr/test/index.test.js
- HMR with middleware > works for pages when middleware is compiled
- HMR with middleware > refreshes the page when middleware changes
Expand output
● HMR with middleware › works for pages when middleware is compiled
expect(received).toEqual(expected) // deep equality
Expected: true
Received: false
40 | await waitFor(1000)
41 |
> 42 | expect(output.includes('about/_middleware')).toEqual(true)
| ^
43 | expect(await browser.eval('window.itdidnotrefresh')).toBe('hello')
44 | } finally {
45 | await browser.close()
at Object.<anonymous> (integration/middleware/hmr/test/index.test.js:42:52)
● HMR with middleware › refreshes the page when middleware changes
expect(received).toEqual(expected) // deep equality
Expected: "AboutA"
Received: "Unhandled Runtime Error"
51 | await browser.eval('window.didrefresh = "hello"')
52 | const text = await browser.elementByCss('h1').text()
> 53 | expect(text).toEqual('AboutA')
| ^
54 |
55 | const middlewarePath = join(context.appDir, '/pages/about/_middleware.js')
56 | const originalContent = fs.readFileSync(middlewarePath, 'utf-8')
at Object.<anonymous> (integration/middleware/hmr/test/index.test.js:53:18)
Read more about building and testing Next.js in contributing.md.
yarn testheadless test/integration/export-serverless/test/index.test.js
- Static Export > Render in development mode > should render pages only existent in exportPathMap page
Expand output
● Static Export › Render in development mode › should render pages only existent in exportPathMap page
page.waitForSelector: Timeout 30000ms exceeded.
=========================== logs ===========================
waiting for selector "#dynamic-page p"
============================================================
304 | return this.chain(() => {
305 | return page
> 306 | .waitForSelector(selector, { timeout, state: 'attached' })
| ^
307 | .then(async (el) => {
308 | // it seems selenium waits longer and tests rely on this behavior
309 | // so we wait for the load event fire before returning
at lib/browsers/playwright.ts:306:10
Read more about building and testing Next.js in contributing.md.
yarn testheadless test/development/basic-basepath/misc.test.ts
- misc basic dev tests > With Security Related Issues > should handle encoded / value for trailing slash correctly
Expand output
● misc basic dev tests › With Security Related Issues › should handle encoded / value for trailing slash correctly
expect(received).toBe(expected) // Object.is equality
Expected: "/docs/%2fexample.com"
Received: "/docs/%252fexample.com"
67 | )
68 | expect(res.status).toBe(308)
> 69 | expect(pathname).toBe('/docs/%2fexample.com')
| ^
70 | expect(hostname).not.toBe('example.com')
71 | const text = await res.text()
72 | expect(text).toEqual('/docs/%2fexample.com')
at Object.<anonymous> (development/basic-basepath/misc.test.ts:69:24)
Read more about building and testing Next.js in contributing.md.
yarn testheadless test/integration/middleware/with-base-path/test/index.test.js
- Middleware base tests > dev mode > should execute from absolute paths
- Middleware base tests > production mode > should execute from absolute paths
- Middleware base tests > production mode > should redirect via preflight middleware request
Expand output
● Middleware base tests › dev mode › should execute from absolute paths
expect(received).toBe(expected) // Object.is equality
Expected: "/root/redirect-with-basepath"
Received: "/redirect-with-basepath"
44 | const browser = await webdriver(context.appPort, '/redirect-with-basepath')
45 | try {
> 46 | expect(await browser.eval(`window.location.pathname`)).toBe(
| ^
47 | '/root/redirect-with-basepath'
48 | )
49 | } finally {
at Object.<anonymous> (integration/middleware/with-base-path/test/index.test.js:46:62)
● Middleware base tests › production mode › should execute from absolute paths
expect(received).toBe(expected) // Object.is equality
Expected: "/root/redirect-with-basepath"
Received: "/redirect-with-basepath"
44 | const browser = await webdriver(context.appPort, '/redirect-with-basepath')
45 | try {
> 46 | expect(await browser.eval(`window.location.pathname`)).toBe(
| ^
47 | '/root/redirect-with-basepath'
48 | )
49 | } finally {
at Object.<anonymous> (integration/middleware/with-base-path/test/index.test.js:46:62)
● Middleware base tests › production mode › should redirect via preflight middleware request
expect(received).toBe(expected) // Object.is equality
Expected: "/root/about"
Received: null
72 | `next.router.sde["http://localhost:${context.appPort}/root/redirect-me-to-about"].redirect`
73 | )
> 74 | expect(redirect).toBe('/root/about')
| ^
75 | } finally {
76 | await browser.close()
77 | }
at Object.<anonymous> (integration/middleware/with-base-path/test/index.test.js:74:24)
Read more about building and testing Next.js in contributing.md.
yarn testheadless test/integration/export/test/index.test.js
- Static Export > Render in development mode > should render pages only existent in exportPathMap page
Expand output
● Static Export › Render in development mode › should render pages only existent in exportPathMap page
page.waitForSelector: Timeout 30000ms exceeded.
=========================== logs ===========================
waiting for selector "#dynamic-page p"
============================================================
304 | return this.chain(() => {
305 | return page
> 306 | .waitForSelector(selector, { timeout, state: 'attached' })
| ^
307 | .then(async (el) => {
308 | // it seems selenium waits longer and tests rely on this behavior
309 | // so we wait for the load event fire before returning
at lib/browsers/playwright.ts:306:10
Read more about building and testing Next.js in contributing.md.
yarn testheadless test/integration/middleware/with-i18n/test/index.test.js
- Middleware i18n tests > dev mode > reads the locale from the pathname
- Middleware i18n tests > dev mode > rewrites from a locale correctly
- Middleware i18n tests > production mode > reads the locale from the pathname
- Middleware i18n tests > production mode > rewrites from a locale correctly
Expand output
● Middleware i18n tests › dev mode › reads the locale from the pathname
expect(received).toBe(expected) // Object.is equality
Expected: "fr"
Received: ""
50 | const html = await res.text()
51 | const $ = cheerio.load(html)
> 52 | expect($('#locale').text()).toBe('fr')
| ^
53 | expect($('#country').text()).toBe('spain')
54 | })
55 |
at Object.<anonymous> (integration/middleware/with-i18n/test/index.test.js:52:33)
● Middleware i18n tests › dev mode › rewrites from a locale correctly
expect(received).toBe(expected) // Object.is equality
Expected: "es"
Received: ""
59 | const html = await res.text()
60 | const $ = cheerio.load(html)
> 61 | expect($('#locale').text()).toBe('es')
| ^
62 | expect($('#country').text()).toBe('us')
63 | })
64 | }
at Object.<anonymous> (integration/middleware/with-i18n/test/index.test.js:61:33)
● Middleware i18n tests › production mode › reads the locale from the pathname
expect(received).toBe(expected) // Object.is equality
Expected: "fr"
Received: ""
50 | const html = await res.text()
51 | const $ = cheerio.load(html)
> 52 | expect($('#locale').text()).toBe('fr')
| ^
53 | expect($('#country').text()).toBe('spain')
54 | })
55 |
at Object.<anonymous> (integration/middleware/with-i18n/test/index.test.js:52:33)
● Middleware i18n tests › production mode › rewrites from a locale correctly
expect(received).toBe(expected) // Object.is equality
Expected: "es"
Received: ""
59 | const html = await res.text()
60 | const $ = cheerio.load(html)
> 61 | expect($('#locale').text()).toBe('es')
| ^
62 | expect($('#country').text()).toBe('us')
63 | })
64 | }
at Object.<anonymous> (integration/middleware/with-i18n/test/index.test.js:61:33)
Read more about building and testing Next.js in contributing.md.
yarn testheadless test/integration/custom-routes/test/index.test.js
- Custom routes > dev mode > should handle has query encoding correctly
- Custom routes > dev mode > should handle encoded value in the pathname correctly
- Custom routes > dev mode > should handle named regex parameters with multi-match successfully
- Custom routes > dev mode > should match has hostname redirect with encoded query value
- Custom routes > server mode > should handle has query encoding correctly
- Custom routes > server mode > should handle encoded value in the pathname correctly
- Custom routes > server mode > should handle named regex parameters with multi-match successfully
- Custom routes > server mode > should match has hostname redirect with encoded query value
- Custom routes > serverless mode > should handle has query encoding correctly
- Custom routes > serverless mode > should handle encoded value in the pathname correctly
- Custom routes > serverless mode > should handle named regex parameters with multi-match successfully
- Custom routes > serverless mode > should match has hostname redirect with encoded query value
Expand output
● Custom routes › dev mode › should handle has query encoding correctly
expect(received).toEqual(expected) // deep equality
- Expected - 2
+ Received + 1
Object {
"params": Object {
"slug": Array [
- "hello",
- "world",
+ "hello/world",
],
},
}
73 | if (status === 200) {
74 | const $ = cheerio.load(await res.text())
> 75 | expect(JSON.parse($('#props').text())).toEqual({
| ^
76 | params: {
77 | slug: expected.slug,
78 | },
at Object.<anonymous> (integration/custom-routes/test/index.test.js:75:48)
● Custom routes › dev mode › should handle encoded value in the pathname correctly
expect(received).toBe(expected) // Object.is equality
Expected: "/%5Cgoogle.com/about"
Received: "/%255Cgoogle.com/about"
763 | )
764 | expect(res.status).toBe(307)
> 765 | expect(pathname).toBe(encodeURI('/\\google.com/about'))
| ^
766 | expect(hostname).not.toBe('google.com')
767 | expect(query).toEqual({})
768 | })
at Object.<anonymous> (integration/custom-routes/test/index.test.js:765:22)
at runMicrotasks (<anonymous>)
● Custom routes › dev mode › should handle named regex parameters with multi-match successfully
expect(received).toBe(expected) // Object.is equality
Expected: "/integrations/-some/thing"
Received: "/integrations/-some%2Fthing"
788 | const { pathname } = url.parse(res.headers.get('location') || '')
789 | expect(res.status).toBe(307)
> 790 | expect(pathname).toBe('/integrations/-some/thing')
| ^
791 | })
792 |
793 | it('should redirect with URL in query correctly', async () => {
at Object.<anonymous> (integration/custom-routes/test/index.test.js:790:22)
at runMicrotasks (<anonymous>)
● Custom routes › dev mode › should match has hostname redirect with encoded query value
expect(received).toBe(expected) // Object.is equality
Expected: "https://xn--bck9bsh7a3b.example.com/"
Received: "xn--bck9bsh7a3b.example.com"
1142 | const parsed = url.parse(res.headers.get('location'), true)
1143 |
> 1144 | expect(parsed.hostname).toBe('https://xn--bck9bsh7a3b.example.com/')
| ^
1145 | })
1146 |
1147 | it('should match has header for header correctly', async () => {
at Object.<anonymous> (integration/custom-routes/test/index.test.js:1144:29)
at runMicrotasks (<anonymous>)
● Custom routes › server mode › should handle has query encoding correctly
expect(received).toEqual(expected) // deep equality
- Expected - 2
+ Received + 1
Object {
"params": Object {
"slug": Array [
- "hello",
- "world",
+ "hello/world",
],
},
}
73 | if (status === 200) {
74 | const $ = cheerio.load(await res.text())
> 75 | expect(JSON.parse($('#props').text())).toEqual({
| ^
76 | params: {
77 | slug: expected.slug,
78 | },
at Object.<anonymous> (integration/custom-routes/test/index.test.js:75:48)
at runMicrotasks (<anonymous>)
● Custom routes › server mode › should handle encoded value in the pathname correctly
expect(received).toBe(expected) // Object.is equality
Expected: "/%5Cgoogle.com/about"
Received: "/%255Cgoogle.com/about"
763 | )
764 | expect(res.status).toBe(307)
> 765 | expect(pathname).toBe(encodeURI('/\\google.com/about'))
| ^
766 | expect(hostname).not.toBe('google.com')
767 | expect(query).toEqual({})
768 | })
at Object.<anonymous> (integration/custom-routes/test/index.test.js:765:22)
at runMicrotasks (<anonymous>)
● Custom routes › server mode › should handle named regex parameters with multi-match successfully
expect(received).toBe(expected) // Object.is equality
Expected: "/integrations/-some/thing"
Received: "/integrations/-some%2Fthing"
788 | const { pathname } = url.parse(res.headers.get('location') || '')
789 | expect(res.status).toBe(307)
> 790 | expect(pathname).toBe('/integrations/-some/thing')
| ^
791 | })
792 |
793 | it('should redirect with URL in query correctly', async () => {
at Object.<anonymous> (integration/custom-routes/test/index.test.js:790:22)
at runMicrotasks (<anonymous>)
● Custom routes › server mode › should match has hostname redirect with encoded query value
expect(received).toBe(expected) // Object.is equality
Expected: "https://xn--bck9bsh7a3b.example.com/"
Received: "xn--bck9bsh7a3b.example.com"
1142 | const parsed = url.parse(res.headers.get('location'), true)
1143 |
> 1144 | expect(parsed.hostname).toBe('https://xn--bck9bsh7a3b.example.com/')
| ^
1145 | })
1146 |
1147 | it('should match has header for header correctly', async () => {
at Object.<anonymous> (integration/custom-routes/test/index.test.js:1144:29)
at runMicrotasks (<anonymous>)
● Custom routes › serverless mode › should handle has query encoding correctly
expect(received).toEqual(expected) // deep equality
- Expected - 2
+ Received + 1
Object {
"params": Object {
"slug": Array [
- "hello",
- "world",
+ "hello/world",
],
},
}
73 | if (status === 200) {
74 | const $ = cheerio.load(await res.text())
> 75 | expect(JSON.parse($('#props').text())).toEqual({
| ^
76 | params: {
77 | slug: expected.slug,
78 | },
at Object.<anonymous> (integration/custom-routes/test/index.test.js:75:48)
● Custom routes › serverless mode › should handle encoded value in the pathname correctly
expect(received).toBe(expected) // Object.is equality
Expected: "/%5Cgoogle.com/about"
Received: "/%255Cgoogle.com/about"
763 | )
764 | expect(res.status).toBe(307)
> 765 | expect(pathname).toBe(encodeURI('/\\google.com/about'))
| ^
766 | expect(hostname).not.toBe('google.com')
767 | expect(query).toEqual({})
768 | })
at Object.<anonymous> (integration/custom-routes/test/index.test.js:765:22)
at runMicrotasks (<anonymous>)
● Custom routes › serverless mode › should handle named regex parameters with multi-match successfully
expect(received).toBe(expected) // Object.is equality
Expected: "/integrations/-some/thing"
Received: "/integrations/-some%2Fthing"
788 | const { pathname } = url.parse(res.headers.get('location') || '')
789 | expect(res.status).toBe(307)
> 790 | expect(pathname).toBe('/integrations/-some/thing')
| ^
791 | })
792 |
793 | it('should redirect with URL in query correctly', async () => {
at Object.<anonymous> (integration/custom-routes/test/index.test.js:790:22)
at runMicrotasks (<anonymous>)
● Custom routes › serverless mode › should match has hostname redirect with encoded query value
expect(received).toBe(expected) // Object.is equality
Expected: "https://xn--bck9bsh7a3b.example.com/"
Received: "xn--bck9bsh7a3b.example.com"
1142 | const parsed = url.parse(res.headers.get('location'), true)
1143 |
> 1144 | expect(parsed.hostname).toBe('https://xn--bck9bsh7a3b.example.com/')
| ^
1145 | })
1146 |
1147 | it('should match has header for header correctly', async () => {
at Object.<anonymous> (integration/custom-routes/test/index.test.js:1144:29)
at runMicrotasks (<anonymous>)
Read more about building and testing Next.js in contributing.md.
yarn testheadless test/integration/trailing-slashes-rewrite/test/index.test.js
- Trailing Slash Rewrite Proxying > dev mode > should resolve a dynamic page correctly
- Trailing Slash Rewrite Proxying > production mode > should resolve a dynamic page correctly
Expand output
● Trailing Slash Rewrite Proxying › production mode › should resolve a dynamic page correctly
expect(received).toContain(expected) // indexOf
Expected substring: "a product"
Received string: "/products%25252Ffirst"
32 | it('should resolve a dynamic page correctly', async () => {
33 | const html = await renderViaHTTP(appPort, '/products/first')
> 34 | expect(html).toContain('a product')
| ^
35 | })
36 |
37 | it('should resolve a catch-all page correctly', async () => {
at Object.<anonymous> (integration/trailing-slashes-rewrite/test/index.test.js:34:18)
● Trailing Slash Rewrite Proxying › dev mode › should resolve a dynamic page correctly
expect(received).toContain(expected) // indexOf
Expected substring: "a product"
Received string: "/products%25252Ffirst"
32 | it('should resolve a dynamic page correctly', async () => {
33 | const html = await renderViaHTTP(appPort, '/products/first')
> 34 | expect(html).toContain('a product')
| ^
35 | })
36 |
37 | it('should resolve a catch-all page correctly', async () => {
at Object.<anonymous> (integration/trailing-slashes-rewrite/test/index.test.js:34:18)
Read more about building and testing Next.js in contributing.md.
yarn testheadless test/integration/react-18/test/index.test.js
- Concurrent mode in the edge runtime (dev) > should resolve suspense modules on server side if suspense
- Concurrent mode in the edge runtime (dev) > should resolve suspense on server side if not suspended on server
- Concurrent mode in the edge runtime (dev) > should resolve suspense on server side if suspended on server
- Concurrent mode in the edge runtime (dev) > should hydrate suspenses on client side if suspended on server
- Concurrent mode in the edge runtime (dev) > should drain the entire response
- Concurrent mode in the edge runtime (dev) > throws if useFlushEffects is used more than once
- Concurrent mode in the edge runtime (dev) > throws if useFlushEffects is called on the client
- Concurrent mode in the edge runtime (dev) > flushes styles as the page renders
- Concurrent mode in the edge runtime (dev) > flushes custom effects
- Concurrent mode in the edge runtime (dev) > should recover after undefined exported as default
- Concurrent mode in the edge runtime (prod) > should resolve suspense modules on server side if suspense
- Concurrent mode in the edge runtime (prod) > should resolve suspense on server side if not suspended on server
- Concurrent mode in the edge runtime (prod) > should resolve suspense on server side if suspended on server
- Concurrent mode in the edge runtime (prod) > should hydrate suspenses on client side if suspended on server
- Concurrent mode in the edge runtime (prod) > should drain the entire response
- Concurrent mode in the edge runtime (prod) > throws if useFlushEffects is used more than once
- Concurrent mode in the edge runtime (prod) > throws if useFlushEffects is called on the client
- Concurrent mode in the edge runtime (prod) > flushes styles as the page renders
- Concurrent mode in the edge runtime (prod) > flushes custom effects
Expand output
● Concurrent mode in the edge runtime (dev) › should resolve suspense modules on server side if suspense
page.goto: Timeout 30000ms exceeded.
=========================== logs ===========================
navigating to "http://localhost:35195/suspense/no-preload", waiting until "load"
============================================================
149 | this.activeTrace = encodeURIComponent(url)
150 | }
> 151 | await page.goto(url, { waitUntil: 'load' })
| ^
152 | }
153 |
154 | back(): BrowserInterface {
at Playwright.loadPage (lib/browsers/playwright.ts:151:16)
at Object.webdriver [as default] (lib/next-webdriver.ts:98:3)
at withBrowser (integration/react-18/test/concurrent.js:10:17)
at Object.<anonymous> (integration/react-18/test/concurrent.js:20:5)
● Concurrent mode in the edge runtime (dev) › should resolve suspense on server side if not suspended on server
page.goto: Timeout 30000ms exceeded.
=========================== logs ===========================
navigating to "http://localhost:35195/suspense/no-thrown", waiting until "load"
============================================================
149 | this.activeTrace = encodeURIComponent(url)
150 | }
> 151 | await page.goto(url, { waitUntil: 'load' })
| ^
152 | }
153 |
154 | back(): BrowserInterface {
at Playwright.loadPage (lib/browsers/playwright.ts:151:16)
at Object.webdriver [as default] (lib/next-webdriver.ts:98:3)
at withBrowser (integration/react-18/test/concurrent.js:10:17)
at Object.<anonymous> (integration/react-18/test/concurrent.js:30:5)
● Concurrent mode in the edge runtime (dev) › should resolve suspense on server side if suspended on server
page.goto: Timeout 30000ms exceeded.
=========================== logs ===========================
navigating to "http://localhost:35195/suspense/thrown", waiting until "load"
============================================================
149 | this.activeTrace = encodeURIComponent(url)
150 | }
> 151 | await page.goto(url, { waitUntil: 'load' })
| ^
152 | }
153 |
154 | back(): BrowserInterface {
at Playwright.loadPage (lib/browsers/playwright.ts:151:16)
at Object.webdriver [as default] (lib/next-webdriver.ts:98:3)
at withBrowser (integration/react-18/test/concurrent.js:10:17)
at Object.<anonymous> (integration/react-18/test/concurrent.js:43:5)
● Concurrent mode in the edge runtime (dev) › should hydrate suspenses on client side if suspended on server
page.goto: Timeout 30000ms exceeded.
=========================== logs ===========================
navigating to "http://localhost:35195/suspense/thrown", waiting until "load"
============================================================
149 | this.activeTrace = encodeURIComponent(url)
150 | }
> 151 | await page.goto(url, { waitUntil: 'load' })
| ^
152 | }
153 |
154 | back(): BrowserInterface {
at Playwright.loadPage (lib/browsers/playwright.ts:151:16)
at Object.webdriver [as default] (lib/next-webdriver.ts:98:3)
at withBrowser (integration/react-18/test/concurrent.js:10:17)
at Object.<anonymous> (integration/react-18/test/concurrent.js:56:5)
● Concurrent mode in the edge runtime (dev) › should drain the entire response
page.goto: Timeout 30000ms exceeded.
=========================== logs ===========================
navigating to "http://localhost:35195/suspense/backpressure", waiting until "load"
============================================================
149 | this.activeTrace = encodeURIComponent(url)
150 | }
> 151 | await page.goto(url, { waitUntil: 'load' })
| ^
152 | }
153 |
154 | back(): BrowserInterface {
at Playwright.loadPage (lib/browsers/playwright.ts:151:16)
at Object.webdriver [as default] (lib/next-webdriver.ts:98:3)
at withBrowser (integration/react-18/test/concurrent.js:10:17)
at Object.<anonymous> (integration/react-18/test/concurrent.js:66:5)
● Concurrent mode in the edge runtime (dev) › throws if useFlushEffects is used more than once
thrown: "Exceeded timeout of 90000 ms for a test.
Use jest.setTimeout(newTimeout) to increase the timeout value, if this is a long-running test."
72 | })
73 |
> 74 | it('throws if useFlushEffects is used more than once', async () => {
| ^
75 | await renderViaHTTP(context.appPort, '/use-flush-effect/multiple-calls')
76 | expect(context.stderr).toContain(
77 | 'Error: The `useFlushEffects` hook cannot be used more than once.'
at Object._default [as default] (integration/react-18/test/concurrent.js:74:3)
at fn (integration/react-18/test/index.test.js:135:17)
at integration/react-18/test/index.test.js:197:5
at runTest (integration/react-18/test/index.test.js:171:3)
at runTests (integration/react-18/test/index.test.js:205:3)
at runTestsAgainstRuntime (integration/react-18/test/index.test.js:132:3)
at Object.<anonymous> (integration/react-18/test/index.test.js:201:1)
● Concurrent mode in the edge runtime (dev) › throws if useFlushEffects is called on the client
page.goto: Timeout 30000ms exceeded.
=========================== logs ===========================
navigating to "http://localhost:35195/use-flush-effect/client", waiting until "load"
============================================================
149 | this.activeTrace = encodeURIComponent(url)
150 | }
> 151 | await page.goto(url, { waitUntil: 'load' })
| ^
152 | }
153 |
154 | back(): BrowserInterface {
at Playwright.loadPage (lib/browsers/playwright.ts:151:16)
at Object.webdriver [as default] (lib/next-webdriver.ts:98:3)
at withBrowser (integration/react-18/test/concurrent.js:10:17)
at Object.<anonymous> (integration/react-18/test/concurrent.js:82:5)
● Concurrent mode in the edge runtime (dev) › flushes styles as the page renders
page.goto: Timeout 30000ms exceeded.
=========================== logs ===========================
navigating to "http://localhost:35195/use-flush-effect/styled-jsx", waiting until "load"
============================================================
149 | this.activeTrace = encodeURIComponent(url)
150 | }
> 151 | await page.goto(url, { waitUntil: 'load' })
| ^
152 | }
153 |
154 | back(): BrowserInterface {
at Playwright.loadPage (lib/browsers/playwright.ts:151:16)
at Object.webdriver [as default] (lib/next-webdriver.ts:98:3)
at withBrowser (integration/react-18/test/concurrent.js:10:17)
at Object.<anonymous> (integration/react-18/test/concurrent.js:91:5)
● Concurrent mode in the edge runtime (dev) › flushes custom effects
page.goto: Timeout 30000ms exceeded.
=========================== logs ===========================
navigating to "http://localhost:35195/use-flush-effect/custom", waiting until "load"
============================================================
149 | this.activeTrace = encodeURIComponent(url)
150 | }
> 151 | await page.goto(url, { waitUntil: 'load' })
| ^
152 | }
153 |
154 | back(): BrowserInterface {
at Playwright.loadPage (lib/browsers/playwright.ts:151:16)
at Object.webdriver [as default] (lib/next-webdriver.ts:98:3)
at withBrowser (integration/react-18/test/concurrent.js:10:17)
at Object.<anonymous> (integration/react-18/test/concurrent.js:104:5)
● Concurrent mode in the edge runtime (dev) › should recover after undefined exported as default
page.goto: Timeout 30000ms exceeded.
=========================== logs ===========================
navigating to "http://localhost:35195/invalid", waiting until "load"
============================================================
149 | this.activeTrace = encodeURIComponent(url)
150 | }
> 151 | await page.goto(url, { waitUntil: 'load' })
| ^
152 | }
153 |
154 | back(): BrowserInterface {
at Playwright.loadPage (lib/browsers/playwright.ts:151:16)
at Object.webdriver [as default] (lib/next-webdriver.ts:98:3)
at Object.<anonymous> (integration/react-18/test/index.test.js:139:27)
● Concurrent mode in the edge runtime (prod) › should resolve suspense modules on server side if suspense
TIMED OUT: /barfoo/
404
This page could not be found.
474 |
475 | if (hardError) {
> 476 | throw new Error('TIMED OUT: ' + regex + '\n\n' + content)
| ^
477 | }
478 | return false
479 | }
at Object.check (lib/next-test-utils.js:476:11)
at integration/react-18/test/concurrent.js:21:7
at withBrowser (integration/react-18/test/concurrent.js:11:7)
at Object.<anonymous> (integration/react-18/test/concurrent.js:20:5)
● Concurrent mode in the edge runtime (prod) › should resolve suspense on server side if not suspended on server
TIMED OUT: /true/
undefined
474 |
475 | if (hardError) {
> 476 | throw new Error('TIMED OUT: ' + regex + '\n\n' + content)
| ^
477 | }
478 | return false
479 | }
at Object.check (lib/next-test-utils.js:476:11)
at integration/react-18/test/concurrent.js:31:7
at withBrowser (integration/react-18/test/concurrent.js:11:7)
at Object.<anonymous> (integration/react-18/test/concurrent.js:30:5)
● Concurrent mode in the edge runtime (prod) › should resolve suspense on server side if suspended on server
TIMED OUT: /true/
undefined
474 |
475 | if (hardError) {
> 476 | throw new Error('TIMED OUT: ' + regex + '\n\n' + content)
| ^
477 | }
478 | return false
479 | }
at Object.check (lib/next-test-utils.js:476:11)
at integration/react-18/test/concurrent.js:44:7
at withBrowser (integration/react-18/test/concurrent.js:11:7)
at Object.<anonymous> (integration/react-18/test/concurrent.js:43:5)
● Concurrent mode in the edge runtime (prod) › should hydrate suspenses on client side if suspended on server
TIMED OUT: /true/
undefined
474 |
475 | if (hardError) {
> 476 | throw new Error('TIMED OUT: ' + regex + '\n\n' + content)
| ^
477 | }
478 | return false
479 | }
at Object.check (lib/next-test-utils.js:476:11)
at integration/react-18/test/concurrent.js:57:7
at withBrowser (integration/react-18/test/concurrent.js:11:7)
at Object.<anonymous> (integration/react-18/test/concurrent.js:56:5)
● Concurrent mode in the edge runtime (prod) › should drain the entire response
TIMED OUT: /2000/
0
474 |
475 | if (hardError) {
> 476 | throw new Error('TIMED OUT: ' + regex + '\n\n' + content)
| ^
477 | }
478 | return false
479 | }
at Object.check (lib/next-test-utils.js:476:11)
at integration/react-18/test/concurrent.js:67:7
at withBrowser (integration/react-18/test/concurrent.js:11:7)
at Object.<anonymous> (integration/react-18/test/concurrent.js:66:5)
● Concurrent mode in the edge runtime (prod) › throws if useFlushEffects is used more than once
expect(received).toContain(expected) // indexOf
Expected substring: "Error: The `useFlushEffects` hook cannot be used more than once."
Received string: "warn - You have enabled experimental feature(s).
warn - Experimental features are not covered by semver, and may cause unexpected or broken application behavior. Use them at your own risk.·
warn - using beta Middleware (not covered by semver) - https://nextjs.org/docs/messages/beta-middleware
"
74 | it('throws if useFlushEffects is used more than once', async () => {
75 | await renderViaHTTP(context.appPort, '/use-flush-effect/multiple-calls')
> 76 | expect(context.stderr).toContain(
| ^
77 | 'Error: The `useFlushEffects` hook cannot be used more than once.'
78 | )
79 | })
at Object.<anonymous> (integration/react-18/test/concurrent.js:76:28)
at runMicrotasks (<anonymous>)
● Concurrent mode in the edge runtime (prod) › throws if useFlushEffects is called on the client
TIMED OUT: /useFlushEffects can not be called on the client/
undefined
474 |
475 | if (hardError) {
> 476 | throw new Error('TIMED OUT: ' + regex + '\n\n' + content)
| ^
477 | }
478 | return false
479 | }
at Object.check (lib/next-test-utils.js:476:11)
at integration/react-18/test/concurrent.js:83:7
at withBrowser (integration/react-18/test/concurrent.js:11:7)
at Object.<anonymous> (integration/react-18/test/concurrent.js:82:5)
● Concurrent mode in the edge runtime (prod) › flushes styles as the page renders
TIMED OUT: /blue/
undefined
474 |
475 | if (hardError) {
> 476 | throw new Error('TIMED OUT: ' + regex + '\n\n' + content)
| ^
477 | }
478 | return false
479 | }
at Object.check (lib/next-test-utils.js:476:11)
at integration/react-18/test/concurrent.js:92:7
at withBrowser (integration/react-18/test/concurrent.js:11:7)
at Object.<anonymous> (integration/react-18/test/concurrent.js:91:5)
● Concurrent mode in the edge runtime (prod) › flushes custom effects
TIMED OUT: /foo/
undefined
474 |
475 | if (hardError) {
> 476 | throw new Error('TIMED OUT: ' + regex + '\n\n' + content)
| ^
477 | }
478 | return false
479 | }
at Object.check (lib/next-test-utils.js:476:11)
at integration/react-18/test/concurrent.js:105:7
at withBrowser (integration/react-18/test/concurrent.js:11:7)
at Object.<anonymous> (integration/react-18/test/concurrent.js:104:5)
Read more about building and testing Next.js in contributing.md.
Stats from current PR
Default Build (Decrease detected ✓)
General Overall increase ⚠️
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| buildDuration | 19.4s | 19.5s | ⚠️ +56ms |
| buildDurationCached | 7.6s | 7.7s | ⚠️ +72ms |
| nodeModulesSize | 456 MB | 456 MB | ⚠️ +239 B |
Page Load Tests Overall decrease ⚠️
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| / failed reqs | 0 | 0 | ✓ |
| / total time (seconds) | 3.802 | 3.951 | ⚠️ +0.15 |
| / avg req/sec | 657.57 | 632.68 | ⚠️ -24.89 |
| /error-in-render failed reqs | 0 | 0 | ✓ |
| /error-in-render total time (seconds) | 1.651 | 1.691 | ⚠️ +0.04 |
| /error-in-render avg req/sec | 1514.07 | 1478.24 | ⚠️ -35.83 |
Client Bundles (main, webpack)
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| 925.HASH.js gzip | 179 B | 179 B | ✓ |
| framework-HASH.js gzip | 42 kB | 42 kB | ✓ |
| main-HASH.js gzip | 28 kB | 28 kB | ✓ |
| webpack-HASH.js gzip | 1.44 kB | 1.44 kB | ✓ |
| Overall change | 71.6 kB | 71.6 kB | ✓ |
Legacy Client Bundles (polyfills)
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| polyfills-HASH.js gzip | 31 kB | 31 kB | ✓ |
| Overall change | 31 kB | 31 kB | ✓ |
Client Pages
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| _app-HASH.js gzip | 1.36 kB | 1.36 kB | ✓ |
| _error-HASH.js gzip | 192 B | 192 B | ✓ |
| amp-HASH.js gzip | 309 B | 309 B | ✓ |
| css-HASH.js gzip | 327 B | 327 B | ✓ |
| dynamic-HASH.js gzip | 2.57 kB | 2.57 kB | ✓ |
| head-HASH.js gzip | 351 B | 351 B | ✓ |
| hooks-HASH.js gzip | 920 B | 920 B | ✓ |
| image-HASH.js gzip | 5.48 kB | 5.48 kB | ✓ |
| index-HASH.js gzip | 263 B | 263 B | ✓ |
| link-HASH.js gzip | 2.26 kB | 2.26 kB | ✓ |
| routerDirect..HASH.js gzip | 320 B | 320 B | ✓ |
| script-HASH.js gzip | 387 B | 387 B | ✓ |
| withRouter-HASH.js gzip | 319 B | 319 B | ✓ |
| 85e02e95b279..7e3.css gzip | 107 B | 107 B | ✓ |
| Overall change | 15.2 kB | 15.2 kB | ✓ |
Client Build Manifests
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| _buildManifest.js gzip | 460 B | 460 B | ✓ |
| Overall change | 460 B | 460 B | ✓ |
Rendered Page Sizes
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| index.html gzip | 531 B | 531 B | ✓ |
| link.html gzip | 545 B | 545 B | ✓ |
| withRouter.html gzip | 525 B | 525 B | ✓ |
| Overall change | 1.6 kB | 1.6 kB | ✓ |
Default Build with SWC (Increase detected ⚠️)
General Overall increase ⚠️
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| buildDuration | 23.1s | 23.1s | ⚠️ +12ms |
| buildDurationCached | 7.8s | 7.8s | -42ms |
| nodeModulesSize | 456 MB | 456 MB | ⚠️ +239 B |
Page Load Tests Overall increase ✓
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| / failed reqs | 0 | 0 | ✓ |
| / total time (seconds) | 3.881 | 3.9 | ⚠️ +0.02 |
| / avg req/sec | 644.08 | 641.01 | ⚠️ -3.07 |
| /error-in-render failed reqs | 0 | 0 | ✓ |
| /error-in-render total time (seconds) | 1.706 | 1.696 | -0.01 |
| /error-in-render avg req/sec | 1465.34 | 1473.89 | +8.55 |
Client Bundles (main, webpack)
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| 925.HASH.js gzip | 178 B | 178 B | ✓ |
| framework-HASH.js gzip | 42.3 kB | 42.3 kB | ✓ |
| main-HASH.js gzip | 28.2 kB | 28.2 kB | ✓ |
| webpack-HASH.js gzip | 1.45 kB | 1.45 kB | ✓ |
| Overall change | 72.1 kB | 72.1 kB | ✓ |
Legacy Client Bundles (polyfills)
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| polyfills-HASH.js gzip | 31 kB | 31 kB | ✓ |
| Overall change | 31 kB | 31 kB | ✓ |
Client Pages
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| _app-HASH.js gzip | 1.35 kB | 1.35 kB | ✓ |
| _error-HASH.js gzip | 179 B | 179 B | ✓ |
| amp-HASH.js gzip | 313 B | 313 B | ✓ |
| css-HASH.js gzip | 324 B | 324 B | ✓ |
| dynamic-HASH.js gzip | 2.56 kB | 2.56 kB | ✓ |
| head-HASH.js gzip | 351 B | 351 B | ✓ |
| hooks-HASH.js gzip | 921 B | 921 B | ✓ |
| image-HASH.js gzip | 5.59 kB | 5.59 kB | ✓ |
| index-HASH.js gzip | 261 B | 261 B | ✓ |
| link-HASH.js gzip | 2.33 kB | 2.33 kB | ✓ |
| routerDirect..HASH.js gzip | 322 B | 322 B | ✓ |
| script-HASH.js gzip | 388 B | 388 B | ✓ |
| withRouter-HASH.js gzip | 317 B | 317 B | ✓ |
| 85e02e95b279..7e3.css gzip | 107 B | 107 B | ✓ |
| Overall change | 15.3 kB | 15.3 kB | ✓ |
Client Build Manifests
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| _buildManifest.js gzip | 458 B | 458 B | ✓ |
| Overall change | 458 B | 458 B | ✓ |
Rendered Page Sizes
| vercel/next.js canary | ykzts/next.js redirect-from-encoded-query | Change | |
|---|---|---|---|
| index.html gzip | 531 B | 531 B | ✓ |
| link.html gzip | 545 B | 545 B | ✓ |
| withRouter.html gzip | 526 B | 526 B | ✓ |
| Overall change | 1.6 kB | 1.6 kB | ✓ |