From 34a5a02a810911ca9603f272d310c470528acdfb Mon Sep 17 00:00:00 2001 From: Katie Byers Date: Mon, 15 Nov 2021 06:59:27 -0800 Subject: [PATCH] ref(nextjs): Improve integration test debugging (#4144) This includes two changes I made to help myself while debugging the nextjs integration tests for a recent PR: 1) Add the ability to set `debug: true` in `Sentry.init()` via a command line flag. In order to do this, I changed the `--debug` flag from a boolean to one which can appear multiple times and which accepts an optional string, either `requests` or `logs`, with the following behavior: - `yarn test:integration` -> no debug logging of any kind (matches current behavior) - `yarn test:integration --debug` -> sets `debug: true` in `Sentry.init()` (change in behavior) - `yarn test:integration --debug logs` -> sets `debug: true` in `Sentry.init()` (change in behavior) - `yarn test:integration --debug requests` -> logs intercepted requests (current behavior of `--debug` flag) I chose to make SDK debug logging the default (what you get if you just use `--debug` without an argument) because of the two options, it is significantly more useful in my experience. (Logging intercepted requests gets unwieldy fast, as they are large objects and end up just creating a lot of noise to sift through in order to find the one piece of data you might want.) Since bare `--debug` has up until now logged intercepted requests, this is technically a breaking change, but since these tests have a userbase of under 5 people, all of them on our team, I figured we could probably roll with it. :-) 2) Improve the VSCode debugger setup for the integration tests. This involved: - Adding a bash function to link sentry packages into the test app, so that we can test against any changes we make without having to reinstall all of the test app's dependencies again just to use the updated files. - Creating a task to be executed before each run of the debugger, which uses the above script to link monorepo packages (if not already linked) and then rebuilds the test app. (This happens by calling a new `yarn` script.) - Setting up the debugger's sourcemap config, so we can step through TS files rather than the generated JS files. - Adding more comments to the debug config to explain what each bit does and why. --- .vscode/launch.json | 35 ++++++++++++++----- .vscode/tasks.json | 13 +++++++ packages/nextjs/test/integration/package.json | 1 + .../test/integration/pages/api/http/index.ts | 2 ++ .../nextjs/test/integration/pages/fetch.tsx | 1 + .../test/integration/sentry.client.config.js | 2 ++ .../test/integration/sentry.server.config.js | 1 + .../nextjs/test/integration/test/runner.js | 23 ++++++++++-- .../integration/test/server/tracingHttp.js | 1 + .../test/integration/test/utils/client.js | 6 ++-- .../test/integration/test/utils/server.js | 6 ++-- .../nextjs/test/integration_test_utils.sh | 34 ++++++++++++++++-- 12 files changed, 106 insertions(+), 19 deletions(-) create mode 100644 .vscode/tasks.json diff --git a/.vscode/launch.json b/.vscode/launch.json index a0a7d18de2e2..f1e4a2249a26 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -51,17 +51,17 @@ // @sentry/nextjs - Run a specific integration test file - // Must have file in currently active tab when hitting the play button + // Must have test file in currently active tab when hitting the play button, and must already have run `yarn` in test app directory { "name": "Debug @sentry/nextjs integration tests - just open file", "type": "node", "cwd": "${workspaceFolder}/packages/nextjs", "request": "launch", - // TODO create a build task - // "preLaunchTask": "yarn build", - - // this is going straight to `server.js` (rather than running the tests through yarn) in order to be able to skip - // having to reinstall dependencies on every new test run + // since we're not using the normal test runner, we need to make sure we're using the current version of all local + // SDK packages and then manually rebuild the test app + "preLaunchTask": "Prepare nextjs integration test app for debugging", + // running `server.js` directly (rather than running the tests through yarn) allows us to skip having to reinstall + // dependencies on every new test run "program": "${workspaceFolder}/packages/nextjs/test/integration/test/server.js", "args": [ "--debug", @@ -69,10 +69,29 @@ "--filter", "${fileBasename}" ], - "sourceMaps": true, + "skipFiles": [ - "/**", "**/tslib/**" + "/**", + // this prevents us from landing in a neverending cycle of TS async-polyfill functions as we're stepping through + // our code + "${workspaceFolder}/node_modules/tslib/**/*" ], + "sourceMaps": true, + // this controls which files are sourcemapped + "outFiles": [ + // our SDK code + "${workspaceFolder}/**/dist/**/*.js", + // the built test app + "${workspaceFolder}/packages/nextjs/test/integration/.next/**/*.js", + "!**/node_modules/**" + ], + "resolveSourceMapLocations": [ + "${workspaceFolder}/**/dist/**", + "${workspaceFolder}/packages/nextjs/test/integration/.next/**", + "!**/node_modules/**" + ], + "internalConsoleOptions": "openOnSessionStart" + }, ] } diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 000000000000..6e797a064c61 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,13 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 for documentation about `tasks.json` syntax + "version": "2.0.0", + "tasks": [ + { + "label": "Prepare nextjs integration test app for VSCode debugger", + "type": "npm", + "script": "predebug", + "path": "packages/nextjs/test/integration/", + "detail": "Link the SDK (if not already linked) and build test app" + } + ] +} diff --git a/packages/nextjs/test/integration/package.json b/packages/nextjs/test/integration/package.json index cd117b39ec31..5523ee933d20 100644 --- a/packages/nextjs/test/integration/package.json +++ b/packages/nextjs/test/integration/package.json @@ -4,6 +4,7 @@ "scripts": { "dev": "next", "build": "next build", + "predebug": "source ../integration_test_utils.sh && link_monorepo_packages '../../..' && yarn build", "start": "next start" }, "dependencies": { diff --git a/packages/nextjs/test/integration/pages/api/http/index.ts b/packages/nextjs/test/integration/pages/api/http/index.ts index 5804f79bb085..958dc09ad6f6 100644 --- a/packages/nextjs/test/integration/pages/api/http/index.ts +++ b/packages/nextjs/test/integration/pages/api/http/index.ts @@ -3,7 +3,9 @@ import { get } from 'http'; import { NextApiRequest, NextApiResponse } from 'next'; const handler = async (_req: NextApiRequest, res: NextApiResponse): Promise => { + // make an outgoing request in order to test that the `Http` integration creates a span await new Promise(resolve => get('http://example.com', resolve)); + res.status(200).json({}); }; diff --git a/packages/nextjs/test/integration/pages/fetch.tsx b/packages/nextjs/test/integration/pages/fetch.tsx index 44e0a4ceb68d..1b538c936494 100644 --- a/packages/nextjs/test/integration/pages/fetch.tsx +++ b/packages/nextjs/test/integration/pages/fetch.tsx @@ -1,6 +1,7 @@ const ButtonPage = (): JSX.Element => (