Skip to content

Commit

Permalink
test(e2e): Add test for Next.js middleware (#8350)
Browse files Browse the repository at this point in the history
  • Loading branch information
lforst authored Jun 19, 2023
1 parent df4f4ab commit 50ead24
Show file tree
Hide file tree
Showing 6 changed files with 154 additions and 2 deletions.
15 changes: 15 additions & 0 deletions packages/e2e-tests/test-applications/nextjs-app-dir/middleware.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export function middleware(request: NextRequest) {
if (request.headers.has('x-should-throw')) {
throw new Error('Middleware Error');
}

return NextResponse.next();
}

// See "Matching Paths" below to learn more
export const config = {
matcher: ['/api/endpoint-behind-middleware'],
};
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
export const config = { runtime: 'edge' };
export const config = {
runtime: 'edge',
};

export default () => new Response('Hello world!');
export default async function handler() {
return new Response(
JSON.stringify({
name: 'Jim Halpert',
}),
{
status: 200,
headers: {
'content-type': 'application/json',
},
},
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type { NextApiRequest, NextApiResponse } from 'next';

type Data = {
name: string;
};

export default function handler(req: NextApiRequest, res: NextApiResponse<Data>) {
res.status(200).json({ name: 'John Doe' });
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const config = { runtime: 'edge' };

export default () => {
throw new Error('Edge Route Error');
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { test, expect } from '@playwright/test';
import { waitForTransaction, waitForError } from '../../../test-utils/event-proxy-server';

test('Should create a transaction for edge routes', async ({ request }) => {
test.skip(process.env.TEST_ENV === 'development', "Doesn't work in dev mode.");

const edgerouteTransactionPromise = waitForTransaction('nextjs-13-app-dir', async transactionEvent => {
return (
transactionEvent?.transaction === 'GET /api/edge-endpoint' && transactionEvent?.contexts?.trace?.status === 'ok'
);
});

const response = await request.get('/api/edge-endpoint');
expect(await response.json()).toStrictEqual({ name: 'Jim Halpert' });

const edgerouteTransaction = await edgerouteTransactionPromise;

expect(edgerouteTransaction.contexts?.trace?.status).toBe('ok');
expect(edgerouteTransaction.contexts?.trace?.op).toBe('http.server');
expect(edgerouteTransaction.contexts?.runtime?.name).toBe('edge');
});

test('Should create a transaction with error status for faulty edge routes', async ({ request }) => {
test.skip(process.env.TEST_ENV === 'development', "Doesn't work in dev mode.");

const edgerouteTransactionPromise = waitForTransaction('nextjs-13-app-dir', async transactionEvent => {
return (
transactionEvent?.transaction === 'GET /api/error-edge-endpoint' &&
transactionEvent?.contexts?.trace?.status === 'internal_error'
);
});

request.get('/api/error-edge-endpoint').catch(() => {
// Noop
});

const edgerouteTransaction = await edgerouteTransactionPromise;

expect(edgerouteTransaction.contexts?.trace?.status).toBe('internal_error');
expect(edgerouteTransaction.contexts?.trace?.op).toBe('http.server');
expect(edgerouteTransaction.contexts?.runtime?.name).toBe('edge');
});

test('Should record exceptions for faulty edge routes', async ({ request }) => {
test.skip(process.env.TEST_ENV === 'development', "Doesn't work in dev mode.");

const errorEventPromise = waitForError('nextjs-13-app-dir', errorEvent => {
return errorEvent?.exception?.values?.[0]?.value === 'Edge Route Error';
});

request.get('/api/error-edge-endpoint').catch(() => {
// Noop
});

expect(await errorEventPromise).toBeDefined();
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { test, expect } from '@playwright/test';
import { waitForTransaction, waitForError } from '../../../test-utils/event-proxy-server';

test('Should create a transaction for middleware', async ({ request }) => {
test.skip(process.env.TEST_ENV === 'development', "Doesn't work in dev mode.");

const middlewareTransactionPromise = waitForTransaction('nextjs-13-app-dir', async transactionEvent => {
return transactionEvent?.transaction === 'middleware' && transactionEvent?.contexts?.trace?.status === 'ok';
});

const response = await request.get('/api/endpoint-behind-middleware');
expect(await response.json()).toStrictEqual({ name: 'John Doe' });

const middlewareTransaction = await middlewareTransactionPromise;

expect(middlewareTransaction.contexts?.trace?.status).toBe('ok');
expect(middlewareTransaction.contexts?.trace?.op).toBe('middleware.nextjs');
expect(middlewareTransaction.contexts?.runtime?.name).toBe('edge');
});

test('Should create a transaction with error status for faulty middleware', async ({ request }) => {
test.skip(process.env.TEST_ENV === 'development', "Doesn't work in dev mode.");

const middlewareTransactionPromise = waitForTransaction('nextjs-13-app-dir', async transactionEvent => {
return (
transactionEvent?.transaction === 'middleware' && transactionEvent?.contexts?.trace?.status === 'internal_error'
);
});

request.get('/api/endpoint-behind-middleware', { headers: { 'x-should-throw': '1' } }).catch(() => {
// Noop
});

const middlewareTransaction = await middlewareTransactionPromise;

expect(middlewareTransaction.contexts?.trace?.status).toBe('internal_error');
expect(middlewareTransaction.contexts?.trace?.op).toBe('middleware.nextjs');
expect(middlewareTransaction.contexts?.runtime?.name).toBe('edge');
});

test('Records exceptions happening in middleware', async ({ request }) => {
test.skip(process.env.TEST_ENV === 'development', "Doesn't work in dev mode.");

const errorEventPromise = waitForError('nextjs-13-app-dir', errorEvent => {
return errorEvent?.exception?.values?.[0]?.value === 'Middleware Error';
});

request.get('/api/endpoint-behind-middleware', { headers: { 'x-should-throw': '1' } }).catch(() => {
// Noop
});

expect(await errorEventPromise).toBeDefined();
});

0 comments on commit 50ead24

Please sign in to comment.