Skip to content

Commit

Permalink
test(nextjs): Add NextJS server-side E2E tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
onurtemizkan committed Jan 17, 2023
1 parent 461afdf commit 5bf058a
Show file tree
Hide file tree
Showing 9 changed files with 103 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"build": "next build",
"start": "next start",
"lint": "next lint",
"test": "TEST_MODE=build playwright test",
"test": "test:prod && test:dev",
"test:prod": "TEST_MODE=prod playwright test",
"test:dev": "TEST_MODE=dev playwright test"
},
"dependencies": {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import * as Sentry from '@sentry/nextjs';
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type { NextApiRequest, NextApiResponse } from 'next';

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const exceptionId = Sentry.captureException(new Error('This is an error'));

await Sentry.flush(2000);

res.status(200).json({ exceptionId });
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type { NextApiRequest, NextApiResponse } from 'next';
import * as Sentry from '@sentry/nextjs';

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
await Sentry.flush(2000);

res.status(200).json({
transactionIds: global.transactionIds,
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ const config: PlaywrightTestConfig = {

/* Run your local dev server before starting the tests */
webServer: {
command: process.env.TEST_MODE === 'build' ? 'yarn start' : 'yarn dev',
command: process.env.TEST_MODE === 'prod' ? 'yarn start' : 'yarn dev',
port: 3000,
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@

import * as Sentry from '@sentry/nextjs';

declare global {
namespace globalThis {
var transactionIds: [string | undefined];
var exceptionId: string | undefined;
}
}

Sentry.init({
dsn: process.env.NEXT_PUBLIC_E2E_TEST_DSN,
// Adjust this value in production, or use tracesSampler for greater control
Expand All @@ -13,3 +20,16 @@ Sentry.init({
// `release` value here - use the environment variable `SENTRY_RELEASE`, so
// that it will also get attached to your source maps
});

Sentry.addGlobalEventProcessor(event => {
global.transactionIds = global.transactionIds || [];

if (event.type === 'transaction') {
const eventId = event.event_id;
if (eventId) {
global.transactionIds.push(eventId);
}
}

return event;
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
"buildCommand": "yarn install --pure-lockfile && npx playwright install && yarn build",
"tests": [
{
"testName": "Playwright tests - Build Mode",
"testCommand": "yarn test"
"testName": "Playwright tests - Prod Mode",
"testCommand": "yarn test:prod"
},
{
"testName": "Playwright tests - Dev Mode",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const sentryTestOrgSlug = process.env.E2E_TEST_SENTRY_ORG_SLUG;
const sentryTestProject = process.env.E2E_TEST_SENTRY_TEST_PROJECT;
const EVENT_POLLING_TIMEOUT = 30_000;

test('Sends an exception to Sentry', async ({ page, baseURL }) => {
test('Sends a client-side exception to Sentry', async ({ page }) => {
await page.goto('/');

const exceptionButton = page.locator('id=exception-button');
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { test, expect } from '@playwright/test';
import axios from 'axios';

const authToken = process.env.E2E_TEST_AUTH_TOKEN;
const sentryTestOrgSlug = process.env.E2E_TEST_SENTRY_ORG_SLUG;
const sentryTestProject = process.env.E2E_TEST_SENTRY_TEST_PROJECT;
const EVENT_POLLING_TIMEOUT = 30_000;

test('Sends a server-side exception to Sentry', async ({ baseURL }) => {
const { data } = await axios.get(`${baseURL}api/error`);
const { exceptionId } = data;

console.log(`Polling for error eventId: ${exceptionId}`);

expect
.poll(
async () => {
const response = await axios.get(
`https://sentry.io/api/0/projects/${sentryTestOrgSlug}/${sentryTestProject}/events/${exceptionId}/`,
{ headers: { Authorization: `Bearer ${authToken}` } },
);
return response.status;
},
{ timeout: EVENT_POLLING_TIMEOUT },
)
.toBe(200);
});

test('Sends server-side transactions to Sentry', async ({ baseURL }) => {
const { data } = await axios.get(`${baseURL}api/success`);
const { transactionIds } = data;

console.log(`Polling for transaction eventIds: ${JSON.stringify(transactionIds)}`);

await Promise.all(
transactionIds.map(async (transactionId: string | undefined) => {
if (!transactionId) {
return;
}

await expect
.poll(
async () => {
const response = await axios.get(
`https://sentry.io/api/0/projects/${sentryTestOrgSlug}/${sentryTestProject}/events/${transactionId}/`,
{ headers: { Authorization: `Bearer ${authToken}` } },
);
return response.status;
},
{ timeout: EVENT_POLLING_TIMEOUT },
)
.toBe(200);
}),
);
});

0 comments on commit 5bf058a

Please sign in to comment.