rsnext/test/e2e/module-layer/module-layer.test.ts
Sebastian Silbermann fe8d953e2d
Replace hasRedbox() (#67025)
...with `assertHasRedbox` and `assertNoRedbox`.

`hasRedbox()` has a hardcoded timeout of 5s that is only required for
the negative assertion.
Instead, we now have dedicated assertions for the positive
(`assertHasRedbox`) and negative case (`assertNoRedbox`).
The negative assertion still has the hardcoded timeout.
But the positive assertion just retries until we find the Redbox.

This speeds up tests using the positive assertion.
Removing `hasRedbox` also uncovered some unused expressions e.g. `await
hasRedbox(browser)`.
These expressions probably wanted to use `expect(await
hasRedbox(browser)).toBe(true)
2024-06-20 10:37:32 +02:00

131 lines
4.4 KiB
TypeScript

import { nextTestSetup } from 'e2e-utils'
import { assertHasRedbox, getRedboxSource, retry } from 'next-test-utils'
describe('module layer', () => {
const { next, isNextStart, isNextDev } = nextTestSetup({
files: __dirname,
})
function runTests() {
const routes = [
// app client components pages
'/app/client',
'/app/client-edge',
// app sever components pages
'/app/server',
'/app/server-edge',
// app routes
'/app/route',
'/app/route-edge',
// pages/api
'/api/default',
'/api/default-edge',
'/api/server-only',
'/api/server-only-edge',
'/api/mixed',
]
for (const route of routes) {
it(`should render routes marked with restriction marks without errors ${route}`, async () => {
const { status } = await next.fetch(route)
expect([route, status]).toEqual([route, 200])
})
}
it('should render installed react-server condition for middleware', async () => {
const json = await next.fetch('/middleware').then((res) => res.json())
expect(json.React).toContain('version') // basic react-server export
expect(json.React).not.toContain('useEffect') // no client api export
})
// This is for backward compatibility, don't change react usage in existing pages/api
it('should contain client react exports for pages api', async () => {
async function verifyReactExports(route, isEdge) {
const json = await next.fetch(route).then((res) => res.json())
// contain all react-server and default condition exports
expect(json.React).toContain('version')
expect(json.React).toContain('useEffect')
// contain react-dom-server default condition exports
expect(json.ReactDomServer).toContain('version')
expect(json.ReactDomServer).toContain('renderToString')
expect(json.ReactDomServer).toContain('renderToStaticMarkup')
expect(json.ReactDomServer).toContain(
isEdge ? 'renderToReadableStream' : 'renderToPipeableStream'
)
}
await verifyReactExports('/api/default', false)
await verifyReactExports('/api/default-edge', true)
await verifyReactExports('/api/server-only', false)
await verifyReactExports('/api/server-only-edge', true)
})
if (isNextStart) {
it('should log the build info properly', async () => {
const cliOutput = next.cliOutput
expect(cliOutput).toContain('Middleware')
const functionsManifest = JSON.parse(
await next.readFile('.next/server/functions-config-manifest.json')
)
expect(functionsManifest.functions).toContainKeys([
'/app/route-edge',
'/api/default-edge',
'/api/server-only-edge',
'/app/client-edge',
'/app/server-edge',
])
const pagesManifest = JSON.parse(
await next.readFile('.next/server/pages-manifest.json')
)
const middlewareManifest = JSON.parse(
await next.readFile('.next/server/middleware-manifest.json')
)
expect(middlewareManifest.middleware).toBeTruthy()
expect(pagesManifest).toContainKeys([
'/api/default-edge',
'/pages-ssr',
'/api/default',
'/api/server-only',
])
})
}
}
if (isNextDev) {
describe('client packages in middleware', () => {
const middlewareFile = 'middleware.js'
let middlewareContent = ''
afterAll(async () => {
await next.patchFile(middlewareFile, middlewareContent)
})
it('should error when import server packages in middleware', async () => {
const browser = await next.browser('/')
middlewareContent = await next.readFile(middlewareFile)
await next.patchFile(
middlewareFile,
middlewareContent
.replace("import 'server-only'", "// import 'server-only'")
.replace("// import './lib/mixed-lib'", "import './lib/mixed-lib'")
)
await retry(async () => {
await assertHasRedbox(browser)
const source = await getRedboxSource(browser)
expect(source).toContain(
`You're importing a component that imports client-only. It only works in a Client Component but none of its parents are marked with "use client"`
)
})
})
})
}
describe('with server-only in server targets', () => {
runTests()
})
})