Skip to content

Commit

Permalink
split e2e tests for unstable_after into app and pages, run app tests …
Browse files Browse the repository at this point in the history
…for both nodejs and edge runtimes
  • Loading branch information
lubieowoce committed May 17, 2024
1 parent 089cb3b commit 3e1aa4f
Show file tree
Hide file tree
Showing 29 changed files with 224 additions and 114 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { unstable_after as after } from 'next/server'
import { cache } from 'react'
import { persistentLog } from '../../../utils/log'
import { cliLog } from '../../../utils/log'
import { headers } from 'next/headers'

const thing = cache(() => Symbol('cache me please'))
Expand All @@ -13,7 +13,7 @@ export default function Index({ params }) {
const hostFromAfter = headers().get('host')
const valueFromAfter = thing()

persistentLog({
cliLog({
source: '[page] /[id]/dynamic',
value: params.id,
assertions: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { unstable_after as after } from 'next/server'
import { persistentLog } from '../../utils/log'
import { cliLog } from '../../utils/log'

export default function Layout({ children }) {
after(async () => {
persistentLog({ source: '[layout] /[id]' })
cliLog({ source: '[layout] /[id]' })
})
return <>{children}</>
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ import { cookies } from 'next/headers'

export default function Index() {
after(() => {
cookies().set('testCookie', 'after-render')
cookies().set('testCookie', 'after-render', { path: '/' })
})

const action = async () => {
'use server'
cookies().set('testCookie', 'action')
cookies().set('testCookie', 'action', { path: '/' })

after(() => {
cookies().set('testCookie', 'after-action')
cookies().set('testCookie', 'after-action', { path: '/' })
})
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { unstable_after as after } from 'next/server'
import { cache } from 'react'
import { persistentLog } from '../../../utils/log'
import { cliLog } from '../../../utils/log'
import { headers } from 'next/headers'

const thing = cache(() => Symbol('cache me please'))
Expand All @@ -16,7 +16,7 @@ export default function Index({ params }) {
const valueFromAfter = thing()
const hostFromAfter = headers().get('host')

persistentLog({
cliLog({
source: '[action] /[id]/with-action',
value: params.id,
assertions: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { unstable_after as after } from 'next/server'
import { persistentLog } from '../../../utils/log'
import { cliLog } from '../../../utils/log'

export function generateMetadata({ params }) {
after(() => {
persistentLog({
cliLog({
source: '[metadata] /[id]/with-metadata',
value: params.id,
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { Suspense } from 'react'
import { unstable_after as after } from 'next/server'
import { persistentLog } from '../../utils/log'
import { cliLog } from '../../utils/log'

export const dynamic = 'force-dynamic'

export default async function Page() {
after(() => {
persistentLog({ source: '[page] /delay (Page)' })
cliLog({ source: '[page] /delay (Page)' })
})
return (
<Suspense fallback={'Loading...'}>
Expand All @@ -17,7 +17,7 @@ export default async function Page() {

async function Inner({ children }) {
after(() => {
persistentLog({ source: '[page] /delay (Inner)' })
cliLog({ source: '[page] /delay (Inner)' })
})

// the test intercepts this to assert on whether the after() callbacks ran
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { notFound } from 'next/navigation'
import { unstable_after as after } from 'next/server'
import { persistentLog } from '../../../utils/log'
import { cliLog } from '../../../utils/log'

export default function Page() {
after(() => {
persistentLog({
cliLog({
source: '[page] /interrupted/calls-not-found',
})
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { redirect } from 'next/navigation'
import { unstable_after as after } from 'next/server'
import { persistentLog } from '../../../utils/log'
import { cliLog } from '../../../utils/log'

export default function Page() {
after(() => {
persistentLog({
cliLog({
source: '[page] /interrupted/calls-redirect',
})
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { unstable_after as after } from 'next/server'
import { persistentLog } from '../../../utils/log'
import { cliLog } from '../../../utils/log'

export default function Page() {
after(() => {
persistentLog({
cliLog({
source: '[page] /interrupted/redirect-target',
})
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { unstable_after as after } from 'next/server'
import { persistentLog } from '../../../utils/log'
import { cliLog } from '../../../utils/log'

export default function Page() {
after(() => {
persistentLog({
cliLog({
source: '[page] /interrupted/throws-error',
})
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// 'use client'

import { unstable_after as after } from 'next/server'
import { cliLog } from '../../utils/log-cli'
import { cliLog } from '../../utils/log'

export const dynamic = 'force-dynamic'

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// (patched in tests)
// export const runtime = 'REPLACE_ME'

export default function AppLayout({ children }) {
return (
<html>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { unstable_after as after } from 'next/server'
import { persistentLog } from '../../utils/log'
import { cliLog } from '../../utils/log'

// (patched in tests)
// export const runtime = 'REPLACE_ME'

export const dynamic = 'force-dynamic'

export async function GET() {
const data = { message: 'Hello, world!' }
after(() => {
persistentLog({ source: '[route handler] /route' })
cliLog({ source: '[route handler] /route' })
})

return Response.json({ data })
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { unstable_after as after } from 'next/server'
import { persistentLog } from '../../utils/log'
import { cliLog } from '../../utils/log'

// (patched in tests)
// export const dynamic = 'REPLACE_ME'

export default function Index() {
after(async () => {
persistentLog({ source: '[page] /static' })
cliLog({ source: '[page] /static' })
})
return <div>Page with after()</div>
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ import * as fs from 'fs'
import * as path from 'path'
import * as os from 'os'
import * as Log from './utils/log'
import * as LogCLI from './utils/log-cli'
import { BrowserInterface } from '../../../lib/next-webdriver'

describe('unstable_after()', () => {
const runtimes = ['nodejs', 'edge']

describe.each(runtimes)('unstable_after() in %s runtime', (runtimeValue) => {
const logFileDir = fs.mkdtempSync(path.join(os.tmpdir(), 'logs-'))
const logFile = path.join(logFileDir, 'logs.jsonl')

Expand All @@ -21,8 +22,44 @@ describe('unstable_after()', () => {
},
})

const getLogs = () => Log.readPersistentLog(logFile)
beforeEach(() => Log.clearPersistentLog(logFile))
{
const originalContents: Record<string, string> = {}

beforeAll(async () => {
const placeholder = `// export const runtime = 'REPLACE_ME'`

const filesToPatch = ['app/layout.js', 'app/route/route.js']

for (const file of filesToPatch) {
await next.patchFile(file, (contents) => {
if (!contents.includes(placeholder)) {
throw new Error(`Placeholder "${placeholder}" not found in ${file}`)
}
originalContents[file] = contents

return contents.replace(
placeholder,
`export const runtime = '${runtimeValue}'`
)
})
}
})

afterAll(async () => {
for (const [file, contents] of Object.entries(originalContents)) {
await next.patchFile(file, contents)
}
})
}

let currentCliOutputIndex = 0
beforeEach(() => {
currentCliOutputIndex = next.cliOutput.length
})

const getLogs = () => {
return Log.readCliLogs(next.cliOutput.slice(currentCliOutputIndex))
}

it('runs in dynamic pages', async () => {
await next.render('/123/dynamic')
Expand Down Expand Up @@ -106,9 +143,8 @@ describe('unstable_after()', () => {
)

expect(res.status).toBe(200)
const cliLogs = LogCLI.readCliLogs(next.cliOutput)
await retry(() => {
expect(cliLogs).toContainEqual({
expect(getLogs()).toContainEqual({
source: '[middleware] /middleware/redirect-source',
requestId,
cookies: { testCookie: 'testValue' },
Expand Down Expand Up @@ -207,15 +243,19 @@ describe('unstable_after()', () => {
const cookie1 = await browser.elementById('cookie').text()
expect(cookie1).toEqual('Cookie: null')

await browser.elementByCss('button[type="submit"]').click()
try {
await browser.elementByCss('button[type="submit"]').click()

await retry(async () => {
const cookie1 = await browser.elementById('cookie').text()
expect(cookie1).toEqual('Cookie: "action"')
// const newLogs = next.cliOutput.slice(cliOutputIndex)
// // after() from action
// expect(newLogs).toContain(EXPECTED_ERROR)
})
await retry(async () => {
const cookie1 = await browser.elementById('cookie').text()
expect(cookie1).toEqual('Cookie: "action"')
// const newLogs = next.cliOutput.slice(cliOutputIndex)
// // after() from action
// expect(newLogs).toContain(EXPECTED_ERROR)
})
} finally {
await browser.eval('document.cookie = "testCookie=;path=/;max-age=-1"')
}
})

if (isNextDev) {
Expand Down Expand Up @@ -275,38 +315,6 @@ describe('unstable_after()', () => {
await cleanup()
}
})

describe('errors at compile time when used in pages dir', () => {
it.each([
{
path: '/pages-dir/invalid-in-gssp',
file: 'pages-dir/invalid-in-gssp.js',
},
{
path: '/pages-dir/123/invalid-in-gsp',
file: 'pages-dir/[id]/invalid-in-gsp.js',
},
{
path: '/pages-dir/invalid-in-page',
file: 'pages-dir/invalid-in-page.js',
},
])('$file', async ({ path, file }) => {
const { session, cleanup } = await sandbox(
next,
new Map([[`pages/${file}`, await next.readFile(`_pages/${file}`)]]),
path
)

try {
expect(await session.getRedboxSource(true)).toMatch(
/You're importing a component that needs "?unstable_after"?\. That only works in a Server Component which is not supported in the pages\/ directory\./
)
expect(getLogs()).toHaveLength(0)
} finally {
await cleanup()
}
})
})
})
}
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { cookies } from 'next/headers'
import { NextResponse, unstable_after as after } from 'next/server'
import { cliLog } from './utils/log-cli'
import { cliLog } from './utils/log'

export function middleware(
/** @type {import ('next/server').NextRequest} */ request
Expand Down
File renamed without changes.

0 comments on commit 3e1aa4f

Please sign in to comment.