@sentry/wizard 3.34.4 → 3.36.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -1
- package/dist/e2e-tests/tests/nuxt-3.test.d.ts +1 -0
- package/dist/e2e-tests/tests/nuxt-3.test.js +257 -0
- package/dist/e2e-tests/tests/nuxt-3.test.js.map +1 -0
- package/dist/e2e-tests/tests/nuxt-4.test.d.ts +1 -0
- package/dist/e2e-tests/tests/nuxt-4.test.js +258 -0
- package/dist/e2e-tests/tests/nuxt-4.test.js.map +1 -0
- package/dist/e2e-tests/tests/remix.test.js +92 -27
- package/dist/e2e-tests/tests/remix.test.js.map +1 -1
- package/dist/e2e-tests/tests/sveltekit.test.js +102 -42
- package/dist/e2e-tests/tests/sveltekit.test.js.map +1 -1
- package/dist/e2e-tests/utils/index.d.ts +18 -1
- package/dist/e2e-tests/utils/index.js +31 -2
- package/dist/e2e-tests/utils/index.js.map +1 -1
- package/dist/lib/Constants.d.ts +1 -0
- package/dist/lib/Constants.js +1 -0
- package/dist/lib/Constants.js.map +1 -1
- package/dist/package.json +1 -1
- package/dist/src/android/templates.js +1 -1
- package/dist/src/android/templates.js.map +1 -1
- package/dist/src/apple/templates.js +2 -2
- package/dist/src/apple/templates.js.map +1 -1
- package/dist/src/nextjs/nextjs-wizard.js +1 -0
- package/dist/src/nextjs/nextjs-wizard.js.map +1 -1
- package/dist/src/nuxt/nuxt-wizard.d.ts +3 -0
- package/dist/src/nuxt/nuxt-wizard.js +227 -0
- package/dist/src/nuxt/nuxt-wizard.js.map +1 -0
- package/dist/src/nuxt/sdk-example.d.ts +8 -0
- package/dist/src/nuxt/sdk-example.js +179 -0
- package/dist/src/nuxt/sdk-example.js.map +1 -0
- package/dist/src/nuxt/sdk-setup.d.ts +11 -0
- package/dist/src/nuxt/sdk-setup.js +326 -0
- package/dist/src/nuxt/sdk-setup.js.map +1 -0
- package/dist/src/nuxt/templates.d.ts +22 -0
- package/dist/src/nuxt/templates.js +84 -0
- package/dist/src/nuxt/templates.js.map +1 -0
- package/dist/src/nuxt/utils.d.ts +1 -0
- package/dist/src/nuxt/utils.js +71 -0
- package/dist/src/nuxt/utils.js.map +1 -0
- package/dist/src/remix/remix-wizard.js +2 -1
- package/dist/src/remix/remix-wizard.js.map +1 -1
- package/dist/src/run.d.ts +1 -1
- package/dist/src/run.js +30 -23
- package/dist/src/run.js.map +1 -1
- package/dist/src/sourcemaps/tools/rollup.js +1 -1
- package/dist/src/sourcemaps/tools/rollup.js.map +1 -1
- package/dist/src/sveltekit/sveltekit-wizard.js +2 -1
- package/dist/src/sveltekit/sveltekit-wizard.js.map +1 -1
- package/dist/src/utils/clack-utils.d.ts +9 -2
- package/dist/src/utils/clack-utils.js +93 -27
- package/dist/src/utils/clack-utils.js.map +1 -1
- package/dist/src/utils/package-json.d.ts +5 -0
- package/dist/src/utils/package-json.js.map +1 -1
- package/dist/src/utils/package-manager.d.ts +1 -0
- package/dist/src/utils/package-manager.js +129 -0
- package/dist/src/utils/package-manager.js.map +1 -1
- package/dist/test/nuxt/templates.test.d.ts +1 -0
- package/dist/test/nuxt/templates.test.js +70 -0
- package/dist/test/nuxt/templates.test.js.map +1 -0
- package/e2e-tests/README.md +59 -0
- package/e2e-tests/test-applications/nuxt-3-test-app/README.md +75 -0
- package/e2e-tests/test-applications/nuxt-3-test-app/nuxt.config.ts +5 -0
- package/e2e-tests/test-applications/nuxt-3-test-app/package.json +18 -0
- package/e2e-tests/test-applications/nuxt-3-test-app/public/favicon.ico +0 -0
- package/e2e-tests/test-applications/nuxt-3-test-app/public/robots.txt +1 -0
- package/e2e-tests/tests/nuxt-3.test.ts +192 -0
- package/e2e-tests/tests/nuxt-4.test.ts +191 -0
- package/e2e-tests/tests/remix.test.ts +163 -50
- package/e2e-tests/tests/sveltekit.test.ts +180 -79
- package/e2e-tests/utils/index.ts +34 -1
- package/lib/Constants.ts +1 -0
- package/package.json +1 -1
- package/src/android/templates.ts +0 -2
- package/src/apple/templates.ts +14 -2
- package/src/nextjs/nextjs-wizard.ts +1 -0
- package/src/nuxt/nuxt-wizard.ts +177 -0
- package/src/nuxt/sdk-example.ts +135 -0
- package/src/nuxt/sdk-setup.ts +248 -0
- package/src/nuxt/templates.ts +296 -0
- package/src/nuxt/utils.ts +32 -0
- package/src/remix/remix-wizard.ts +2 -1
- package/src/run.ts +7 -0
- package/src/sourcemaps/tools/rollup.ts +1 -1
- package/src/sveltekit/sveltekit-wizard.ts +2 -1
- package/src/utils/clack-utils.ts +74 -13
- package/src/utils/package-json.ts +5 -0
- package/src/utils/package-manager.ts +66 -0
- package/test/nuxt/templates.test.ts +228 -0
|
@@ -9,68 +9,122 @@ import {
|
|
|
9
9
|
checkIfRunsOnProdMode,
|
|
10
10
|
checkPackageJson,
|
|
11
11
|
cleanupGit,
|
|
12
|
+
createFile,
|
|
12
13
|
KEYS,
|
|
14
|
+
modifyFile,
|
|
13
15
|
revertLocalChanges,
|
|
14
16
|
startWizardInstance,
|
|
15
17
|
TEST_ARGS,
|
|
16
18
|
} from '../utils';
|
|
17
19
|
import * as path from 'path';
|
|
18
20
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
const SERVER_TEMPLATE = `import { createRequestHandler } from '@remix-run/express';
|
|
22
|
+
import { installGlobals } from '@remix-run/node';
|
|
23
|
+
import compression from 'compression';
|
|
24
|
+
import express from 'express';
|
|
25
|
+
import morgan from 'morgan';
|
|
26
|
+
|
|
27
|
+
installGlobals();
|
|
28
|
+
|
|
29
|
+
const viteDevServer =
|
|
30
|
+
process.env.NODE_ENV === 'production'
|
|
31
|
+
? undefined
|
|
32
|
+
: await import('vite').then(vite =>
|
|
33
|
+
vite.createServer({
|
|
34
|
+
server: { middlewareMode: true },
|
|
35
|
+
}),
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
const app = express();
|
|
39
|
+
|
|
40
|
+
app.use(compression());
|
|
41
|
+
app.disable('x-powered-by');
|
|
42
|
+
|
|
43
|
+
if (viteDevServer) {
|
|
44
|
+
app.use(viteDevServer.middlewares);
|
|
45
|
+
} else {
|
|
46
|
+
app.use('/assets', express.static('build/client/assets', { immutable: true, maxAge: '1y' }));
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
app.use(express.static('build/client', { maxAge: '1h' }));
|
|
50
|
+
app.use(morgan('tiny'));
|
|
51
|
+
|
|
52
|
+
app.all(
|
|
53
|
+
'*',
|
|
54
|
+
createRequestHandler({
|
|
55
|
+
build: viteDevServer
|
|
56
|
+
? () => viteDevServer.ssrLoadModule('virtual:remix/server-build')
|
|
57
|
+
: await import('./build/server/index.js'),
|
|
58
|
+
}),
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
app.listen(0, () => console.log('Express server listening'));
|
|
62
|
+
`;
|
|
25
63
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
64
|
+
|
|
65
|
+
async function runWizardOnRemixProject(projectDir: string, integration: Integration, fileModificationFn?: (projectDir: string, integration: Integration) => unknown) {
|
|
66
|
+
const wizardInstance = startWizardInstance(integration, projectDir);
|
|
67
|
+
let packageManagerPrompted = false;
|
|
68
|
+
|
|
69
|
+
if (fileModificationFn) {
|
|
70
|
+
fileModificationFn(projectDir, integration);
|
|
71
|
+
|
|
72
|
+
await wizardInstance.waitForOutput(
|
|
73
|
+
'Do you want to continue anyway?',
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
packageManagerPrompted = await wizardInstance.sendStdinAndWaitForOutput(
|
|
77
|
+
[KEYS.ENTER],
|
|
29
78
|
'Please select your package manager.',
|
|
30
79
|
);
|
|
80
|
+
} else {
|
|
31
81
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
(await wizardInstance.sendStdinAndWaitForOutput(
|
|
35
|
-
// Selecting `yarn` as the package manager
|
|
36
|
-
[KEYS.DOWN, KEYS.ENTER],
|
|
37
|
-
// "Do you want to enable Tracing", sometimes doesn't work as `Tracing` can be printed in bold.
|
|
38
|
-
'to track the performance of your application?',
|
|
39
|
-
{
|
|
40
|
-
timeout: 240_000,
|
|
41
|
-
},
|
|
42
|
-
));
|
|
43
|
-
|
|
44
|
-
const replayOptionPrompted =
|
|
45
|
-
tracingOptionPrompted &&
|
|
46
|
-
(await wizardInstance.sendStdinAndWaitForOutput(
|
|
47
|
-
[KEYS.ENTER],
|
|
48
|
-
// "Do you want to enable Sentry Session Replay", sometimes doesn't work as `Sentry Session Replay` can be printed in bold.
|
|
49
|
-
'to get a video-like reproduction of errors during a user session?',
|
|
50
|
-
));
|
|
51
|
-
|
|
52
|
-
replayOptionPrompted &&
|
|
53
|
-
(await wizardInstance.sendStdinAndWaitForOutput(
|
|
54
|
-
[KEYS.ENTER],
|
|
55
|
-
'Do you want to create an example page',
|
|
56
|
-
{
|
|
57
|
-
optional: true,
|
|
58
|
-
},
|
|
59
|
-
));
|
|
60
|
-
|
|
61
|
-
await wizardInstance.sendStdinAndWaitForOutput(
|
|
62
|
-
[KEYS.ENTER, KEYS.ENTER],
|
|
63
|
-
'Sentry has been successfully configured for your Remix project',
|
|
82
|
+
packageManagerPrompted = await wizardInstance.waitForOutput(
|
|
83
|
+
'Please select your package manager.',
|
|
64
84
|
);
|
|
85
|
+
}
|
|
65
86
|
|
|
66
|
-
|
|
67
|
-
|
|
87
|
+
const tracingOptionPrompted =
|
|
88
|
+
packageManagerPrompted &&
|
|
89
|
+
(await wizardInstance.sendStdinAndWaitForOutput(
|
|
90
|
+
// Selecting `yarn` as the package manager
|
|
91
|
+
[KEYS.DOWN, KEYS.ENTER],
|
|
92
|
+
// "Do you want to enable Tracing", sometimes doesn't work as `Tracing` can be printed in bold.
|
|
93
|
+
'to track the performance of your application?',
|
|
94
|
+
{
|
|
95
|
+
timeout: 240_000,
|
|
96
|
+
},
|
|
97
|
+
));
|
|
68
98
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
99
|
+
const replayOptionPrompted =
|
|
100
|
+
tracingOptionPrompted &&
|
|
101
|
+
(await wizardInstance.sendStdinAndWaitForOutput(
|
|
102
|
+
[KEYS.ENTER],
|
|
103
|
+
// "Do you want to enable Sentry Session Replay", sometimes doesn't work as `Sentry Session Replay` can be printed in bold.
|
|
104
|
+
'to get a video-like reproduction of errors during a user session?',
|
|
105
|
+
));
|
|
106
|
+
|
|
107
|
+
replayOptionPrompted &&
|
|
108
|
+
(await wizardInstance.sendStdinAndWaitForOutput(
|
|
109
|
+
[KEYS.ENTER],
|
|
110
|
+
'Do you want to create an example page',
|
|
111
|
+
{
|
|
112
|
+
optional: true,
|
|
113
|
+
},
|
|
114
|
+
));
|
|
73
115
|
|
|
116
|
+
await wizardInstance.sendStdinAndWaitForOutput(
|
|
117
|
+
[KEYS.ENTER, KEYS.ENTER],
|
|
118
|
+
'Sentry has been successfully configured for your Remix project',
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
wizardInstance.kill();
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
function checkRemixProject(projectDir: string, integration: Integration, options?: {
|
|
125
|
+
devModeExpectedOutput?: string;
|
|
126
|
+
prodModeExpectedOutput?: string;
|
|
127
|
+
}) {
|
|
74
128
|
test('package.json is updated correctly', () => {
|
|
75
129
|
checkPackageJson(projectDir, integration);
|
|
76
130
|
});
|
|
@@ -140,15 +194,74 @@ describe('Remix', () => {
|
|
|
140
194
|
]);
|
|
141
195
|
});
|
|
142
196
|
|
|
143
|
-
test('builds
|
|
197
|
+
test('builds successfully', async () => {
|
|
144
198
|
await checkIfBuilds(projectDir, 'built');
|
|
145
199
|
});
|
|
146
200
|
|
|
147
201
|
test('runs on dev mode correctly', async () => {
|
|
148
|
-
await checkIfRunsOnDevMode(projectDir, 'to expose');
|
|
202
|
+
await checkIfRunsOnDevMode(projectDir, options?.devModeExpectedOutput || 'to expose');
|
|
149
203
|
});
|
|
150
204
|
|
|
151
205
|
test('runs on prod mode correctly', async () => {
|
|
152
|
-
await checkIfRunsOnProdMode(projectDir, '[remix-serve]');
|
|
206
|
+
await checkIfRunsOnProdMode(projectDir, options?.prodModeExpectedOutput || '[remix-serve]');
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
describe('Remix', () => {
|
|
211
|
+
describe('with empty project', () => {
|
|
212
|
+
const integration = Integration.remix;
|
|
213
|
+
const projectDir = path.resolve(
|
|
214
|
+
__dirname,
|
|
215
|
+
'../test-applications/remix-test-app',
|
|
216
|
+
);
|
|
217
|
+
|
|
218
|
+
beforeAll(async () => {
|
|
219
|
+
await runWizardOnRemixProject(projectDir, integration);
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
afterAll(() => {
|
|
223
|
+
revertLocalChanges(projectDir);
|
|
224
|
+
cleanupGit(projectDir);
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
checkRemixProject(projectDir, integration);
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
describe('with existing custom Express server', () => {
|
|
231
|
+
const integration = Integration.remix;
|
|
232
|
+
const projectDir = path.resolve(
|
|
233
|
+
__dirname,
|
|
234
|
+
'../test-applications/remix-test-app',
|
|
235
|
+
);
|
|
236
|
+
|
|
237
|
+
beforeAll(async () => {
|
|
238
|
+
await runWizardOnRemixProject(projectDir, integration, (projectDir) => {
|
|
239
|
+
createFile(
|
|
240
|
+
`${projectDir}/server.mjs`,
|
|
241
|
+
SERVER_TEMPLATE,
|
|
242
|
+
);
|
|
243
|
+
|
|
244
|
+
modifyFile(`${projectDir}/package.json`, {
|
|
245
|
+
'"start": "remix-serve ./build/server/index.js"': '"start": "node ./server.mjs"',
|
|
246
|
+
'"dev": "remix vite:dev"': '"dev": "node ./server.mjs"',
|
|
247
|
+
});
|
|
248
|
+
});
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
afterAll(() => {
|
|
252
|
+
revertLocalChanges(projectDir);
|
|
253
|
+
cleanupGit(projectDir);
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
checkRemixProject(projectDir, integration, {
|
|
257
|
+
devModeExpectedOutput: 'Express server listening',
|
|
258
|
+
prodModeExpectedOutput: 'Express server listening',
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
test('server.mjs contains instrumentation file import', () => {
|
|
262
|
+
checkFileContents(`${projectDir}/server.mjs`, [
|
|
263
|
+
"import './instrumentation.server.mjs';",
|
|
264
|
+
]);
|
|
265
|
+
});
|
|
153
266
|
});
|
|
154
267
|
});
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
checkIfRunsOnProdMode,
|
|
10
10
|
checkPackageJson,
|
|
11
11
|
cleanupGit,
|
|
12
|
+
createFile,
|
|
12
13
|
KEYS,
|
|
13
14
|
revertLocalChanges,
|
|
14
15
|
startWizardInstance,
|
|
@@ -16,65 +17,93 @@ import {
|
|
|
16
17
|
} from '../utils';
|
|
17
18
|
import * as path from 'path';
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
20
|
+
const SERVER_HOOK_TEMPLATE = `import type { Handle } from '@sveltejs/kit';
|
|
21
|
+
|
|
22
|
+
export const handle: Handle = async ({ event, resolve }) => {
|
|
23
|
+
if (event.url.pathname.startsWith('/custom')) {
|
|
24
|
+
return new Response('custom response');
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const response = await resolve(event);
|
|
28
|
+
return response;
|
|
29
|
+
};
|
|
30
|
+
`;
|
|
31
|
+
const CLIENT_HOOK_TEMPLATE = `
|
|
32
|
+
export async function handleError({ error, event }) {
|
|
33
|
+
// you can capture the \`error\` and \`event\` from the client
|
|
34
|
+
// but it only runs if the unexpected error comes from \`+ page.ts\`
|
|
35
|
+
console.log(error)
|
|
36
|
+
|
|
37
|
+
return {
|
|
38
|
+
// don't show sensitive data to the user
|
|
39
|
+
message: 'Yikes! 💩',
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
`;
|
|
43
|
+
|
|
44
|
+
async function runWizardOnSvelteKitProject(projectDir: string, integration: Integration, fileModificationFn?: (projectDir: string, integration: Integration) => unknown) {
|
|
45
|
+
const wizardInstance = startWizardInstance(integration, projectDir);
|
|
46
|
+
let packageManagerPrompted = false;
|
|
47
|
+
|
|
48
|
+
if (fileModificationFn) {
|
|
49
|
+
fileModificationFn(projectDir, integration);
|
|
50
|
+
|
|
51
|
+
// As we modified project, we have a warning prompt before we get the package manager prompt
|
|
52
|
+
await wizardInstance.waitForOutput(
|
|
53
|
+
'Do you want to continue anyway?',
|
|
54
|
+
);
|
|
28
55
|
|
|
29
|
-
|
|
56
|
+
packageManagerPrompted = await wizardInstance.sendStdinAndWaitForOutput(
|
|
57
|
+
[KEYS.ENTER],
|
|
30
58
|
'Please select your package manager.',
|
|
31
|
-
{
|
|
32
|
-
optional: true,
|
|
33
|
-
}
|
|
34
59
|
);
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
(await wizardInstance.sendStdinAndWaitForOutput(
|
|
39
|
-
// Selecting `yarn` as the package manager
|
|
40
|
-
[KEYS.DOWN, KEYS.ENTER],
|
|
41
|
-
// "Do you want to enable Tracing", sometimes doesn't work as `Tracing` can be printed in bold.
|
|
42
|
-
'to track the performance of your application?',
|
|
43
|
-
{
|
|
44
|
-
timeout: 240_000,
|
|
45
|
-
}
|
|
46
|
-
));
|
|
47
|
-
|
|
48
|
-
const replayOptionPrompted =
|
|
49
|
-
tracingOptionPrompted &&
|
|
50
|
-
(await wizardInstance.sendStdinAndWaitForOutput(
|
|
51
|
-
[KEYS.ENTER],
|
|
52
|
-
// "Do you want to enable Sentry Session Replay", sometimes doesn't work as `Sentry Session Replay` can be printed in bold.
|
|
53
|
-
'to get a video-like reproduction of errors during a user session?',
|
|
54
|
-
));
|
|
55
|
-
|
|
56
|
-
replayOptionPrompted &&
|
|
57
|
-
(await wizardInstance.sendStdinAndWaitForOutput(
|
|
58
|
-
[KEYS.ENTER],
|
|
59
|
-
'Do you want to create an example page',
|
|
60
|
-
{
|
|
61
|
-
optional: true,
|
|
62
|
-
},
|
|
63
|
-
));
|
|
64
|
-
|
|
65
|
-
await wizardInstance.sendStdinAndWaitForOutput(
|
|
66
|
-
[KEYS.ENTER, KEYS.ENTER],
|
|
67
|
-
'Successfully installed the Sentry SvelteKit SDK!',
|
|
60
|
+
} else {
|
|
61
|
+
packageManagerPrompted = await wizardInstance.waitForOutput(
|
|
62
|
+
'Please select your package manager'
|
|
68
63
|
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const tracingOptionPrompted =
|
|
67
|
+
packageManagerPrompted &&
|
|
68
|
+
(await wizardInstance.sendStdinAndWaitForOutput(
|
|
69
|
+
// Selecting `yarn` as the package manager
|
|
70
|
+
[KEYS.DOWN, KEYS.ENTER],
|
|
71
|
+
// "Do you want to enable Tracing", sometimes doesn't work as `Tracing` can be printed in bold.
|
|
72
|
+
'to track the performance of your application?',
|
|
73
|
+
{
|
|
74
|
+
timeout: 240_000,
|
|
75
|
+
}
|
|
76
|
+
));
|
|
77
|
+
|
|
78
|
+
const replayOptionPrompted =
|
|
79
|
+
tracingOptionPrompted &&
|
|
80
|
+
(await wizardInstance.sendStdinAndWaitForOutput(
|
|
81
|
+
[KEYS.ENTER],
|
|
82
|
+
// "Do you want to enable Sentry Session Replay", sometimes doesn't work as `Sentry Session Replay` can be printed in bold.
|
|
83
|
+
'to get a video-like reproduction of errors during a user session?',
|
|
84
|
+
));
|
|
85
|
+
|
|
86
|
+
replayOptionPrompted &&
|
|
87
|
+
(await wizardInstance.sendStdinAndWaitForOutput(
|
|
88
|
+
[KEYS.ENTER],
|
|
89
|
+
'Do you want to create an example page',
|
|
90
|
+
{
|
|
91
|
+
optional: true,
|
|
92
|
+
},
|
|
93
|
+
));
|
|
69
94
|
|
|
70
|
-
|
|
71
|
-
|
|
95
|
+
await wizardInstance.sendStdinAndWaitForOutput(
|
|
96
|
+
[KEYS.ENTER, KEYS.ENTER],
|
|
97
|
+
'Successfully installed the Sentry SvelteKit SDK!',
|
|
98
|
+
);
|
|
72
99
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
cleanupGit(projectDir);
|
|
76
|
-
});
|
|
100
|
+
wizardInstance.kill();
|
|
101
|
+
}
|
|
77
102
|
|
|
103
|
+
function checkSvelteKitProject(projectDir: string, integration: Integration, options?: {
|
|
104
|
+
devModeExpectedOutput: string;
|
|
105
|
+
prodModeExpectedOutput: string;
|
|
106
|
+
}) {
|
|
78
107
|
test('should have the correct package.json', () => {
|
|
79
108
|
checkPackageJson(projectDir, integration);
|
|
80
109
|
});
|
|
@@ -99,11 +128,43 @@ describe('Sveltekit', () => {
|
|
|
99
128
|
checkFileExists(path.resolve(projectDir, 'src/hooks.client.ts'));
|
|
100
129
|
});
|
|
101
130
|
|
|
102
|
-
test('
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
131
|
+
test('builds successfully', async () => {
|
|
132
|
+
await checkIfBuilds(projectDir, 'Successfully uploaded source maps to Sentry');
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
test('runs on dev mode correctly', async () => {
|
|
136
|
+
await checkIfRunsOnDevMode(projectDir, options?.devModeExpectedOutput || 'ready in');
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
test('runs on prod mode correctly', async () => {
|
|
140
|
+
await checkIfRunsOnProdMode(projectDir, options?.prodModeExpectedOutput || 'to expose', 'preview');
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
describe('Sveltekit', () => {
|
|
145
|
+
describe('without existing hooks', () => {
|
|
146
|
+
const integration = Integration.sveltekit;
|
|
147
|
+
const projectDir = path.resolve(
|
|
148
|
+
__dirname,
|
|
149
|
+
'../test-applications/sveltekit-test-app',
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
beforeAll(async () => {
|
|
153
|
+
await runWizardOnSvelteKitProject(projectDir, integration);
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
afterAll(() => {
|
|
157
|
+
revertLocalChanges(projectDir);
|
|
158
|
+
cleanupGit(projectDir);
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
checkSvelteKitProject(projectDir, integration);
|
|
162
|
+
|
|
163
|
+
test('hooks.client.ts contains sentry', () => {
|
|
164
|
+
checkFileContents(
|
|
165
|
+
path.resolve(projectDir, 'src/hooks.client.ts'),
|
|
166
|
+
[`import * as Sentry from '@sentry/sveltekit';`,
|
|
167
|
+
`Sentry.init({
|
|
107
168
|
dsn: '${TEST_ARGS.PROJECT_DSN}',
|
|
108
169
|
|
|
109
170
|
tracesSampleRate: 1.0,
|
|
@@ -118,37 +179,77 @@ describe('Sveltekit', () => {
|
|
|
118
179
|
|
|
119
180
|
// If you don't want to use Session Replay, just remove the line below:
|
|
120
181
|
integrations: [replayIntegration()],
|
|
121
|
-
})
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
`Sentry.init({
|
|
182
|
+
});`, 'export const handleError = handleErrorWithSentry(']);
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
test('hooks.server.ts contains sentry', () => {
|
|
186
|
+
checkFileContents(
|
|
187
|
+
path.resolve(projectDir, 'src/hooks.server.ts'),
|
|
188
|
+
[
|
|
189
|
+
`import * as Sentry from '@sentry/sveltekit';`,
|
|
190
|
+
`Sentry.init({
|
|
131
191
|
dsn: '${TEST_ARGS.PROJECT_DSN}',
|
|
132
192
|
|
|
133
193
|
tracesSampleRate: 1.0,
|
|
134
194
|
|
|
135
195
|
// uncomment the line below to enable Spotlight (https://spotlightjs.com)
|
|
136
196
|
// spotlight: import.meta.env.DEV,
|
|
137
|
-
})
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
test('runs on dev mode correctly', async () => {
|
|
142
|
-
await checkIfRunsOnDevMode(projectDir, 'ready in');
|
|
197
|
+
});`, 'export const handleError = handleErrorWithSentry();']);
|
|
198
|
+
});
|
|
143
199
|
});
|
|
144
200
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
201
|
+
describe('with existing hooks', () => {
|
|
202
|
+
const integration = Integration.sveltekit;
|
|
203
|
+
const projectDir = path.resolve(
|
|
204
|
+
__dirname,
|
|
205
|
+
'../test-applications/sveltekit-test-app',
|
|
206
|
+
);
|
|
148
207
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
208
|
+
beforeAll(async () => {
|
|
209
|
+
await runWizardOnSvelteKitProject(projectDir, integration, (projectDir) => {
|
|
210
|
+
createFile(
|
|
211
|
+
path.resolve(projectDir, 'src/hooks.server.ts'),
|
|
212
|
+
SERVER_HOOK_TEMPLATE,
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
createFile(
|
|
216
|
+
path.resolve(projectDir, 'src/hooks.client.ts'),
|
|
217
|
+
CLIENT_HOOK_TEMPLATE,
|
|
218
|
+
)
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
afterAll(() => {
|
|
223
|
+
revertLocalChanges(projectDir);
|
|
224
|
+
cleanupGit(projectDir);
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
checkSvelteKitProject(projectDir, integration);
|
|
228
|
+
|
|
229
|
+
// These are removed from the common tests as the content is different
|
|
230
|
+
// when the hooks are merged instead of created from the template
|
|
231
|
+
test('hooks.client.ts contains sentry instrumentation', () => {
|
|
232
|
+
checkFileContents(
|
|
233
|
+
path.resolve(projectDir, 'src/hooks.client.ts'),
|
|
234
|
+
[`import * as Sentry from '@sentry/sveltekit';`,
|
|
235
|
+
`Sentry.init({
|
|
236
|
+
dsn: "${TEST_ARGS.PROJECT_DSN}",
|
|
237
|
+
tracesSampleRate: 1,
|
|
238
|
+
replaysSessionSampleRate: 0.1,
|
|
239
|
+
replaysOnErrorSampleRate: 1,
|
|
240
|
+
integrations: [Sentry.replayIntegration()]
|
|
241
|
+
})`, 'export const handleError = Sentry.handleErrorWithSentry(']);
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
test('hooks.server.ts contains sentry init', () => {
|
|
245
|
+
checkFileContents(
|
|
246
|
+
path.resolve(projectDir, 'src/hooks.server.ts'),
|
|
247
|
+
[`import * as Sentry from '@sentry/sveltekit';`,
|
|
248
|
+
`Sentry.init({
|
|
249
|
+
dsn: "${TEST_ARGS.PROJECT_DSN}",
|
|
250
|
+
tracesSampleRate: 1
|
|
251
|
+
})`, 'export const handleError = Sentry.handleErrorWithSentry();']);
|
|
252
|
+
});
|
|
152
253
|
});
|
|
153
254
|
});
|
|
154
255
|
|
package/e2e-tests/utils/index.ts
CHANGED
|
@@ -227,11 +227,42 @@ export function startWizardInstance(
|
|
|
227
227
|
}
|
|
228
228
|
|
|
229
229
|
/**
|
|
230
|
-
*
|
|
230
|
+
* Create a file with the given content
|
|
231
231
|
*
|
|
232
232
|
* @param filePath
|
|
233
233
|
* @param content
|
|
234
234
|
*/
|
|
235
|
+
export function createFile(filePath: string, content?: string) {
|
|
236
|
+
return fs.writeFileSync(filePath, content || '');
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Modify the file with the new content
|
|
241
|
+
*
|
|
242
|
+
* @param filePath
|
|
243
|
+
* @param oldContent
|
|
244
|
+
* @param newContent
|
|
245
|
+
*/
|
|
246
|
+
export function modifyFile(
|
|
247
|
+
filePath: string,
|
|
248
|
+
replaceMap: Record<string, string>,
|
|
249
|
+
) {
|
|
250
|
+
const fileContent = fs.readFileSync(filePath, 'utf-8');
|
|
251
|
+
let newFileContent = fileContent;
|
|
252
|
+
|
|
253
|
+
for (const [oldContent, newContent] of Object.entries(replaceMap)) {
|
|
254
|
+
newFileContent = newFileContent.replace(oldContent, newContent);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
fs.writeFileSync(filePath, newFileContent);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Read the file contents and check if it contains the given content
|
|
262
|
+
*
|
|
263
|
+
* @param {string} filePath
|
|
264
|
+
* @param {(string | string[])} content
|
|
265
|
+
*/
|
|
235
266
|
export function checkFileContents(
|
|
236
267
|
filePath: string,
|
|
237
268
|
content: string | string[],
|
|
@@ -255,6 +286,7 @@ export function checkFileExists(filePath: string) {
|
|
|
255
286
|
|
|
256
287
|
/**
|
|
257
288
|
* Check if the package.json contains the given integration
|
|
289
|
+
*
|
|
258
290
|
* @param projectDir
|
|
259
291
|
* @param integration
|
|
260
292
|
*/
|
|
@@ -264,6 +296,7 @@ export function checkPackageJson(projectDir: string, integration: Integration) {
|
|
|
264
296
|
|
|
265
297
|
/**
|
|
266
298
|
* Check if the .sentryclirc contains the auth token
|
|
299
|
+
*
|
|
267
300
|
* @param projectDir
|
|
268
301
|
*/
|
|
269
302
|
export function checkSentryCliRc(projectDir: string) {
|
package/lib/Constants.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sentry/wizard",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.36.0",
|
|
4
4
|
"homepage": "https://github.com/getsentry/sentry-wizard",
|
|
5
5
|
"repository": "https://github.com/getsentry/sentry-wizard",
|
|
6
6
|
"description": "Sentry wizard helping you to configure your project",
|
package/src/android/templates.ts
CHANGED
|
@@ -33,8 +33,6 @@ export const manifest = (dsn: string) => `
|
|
|
33
33
|
|
|
34
34
|
<!-- enable the performance API by setting a sample-rate, adjust in production env -->
|
|
35
35
|
<meta-data android:name="io.sentry.traces.sample-rate" android:value="1.0" />
|
|
36
|
-
<!-- enable profiling when starting transactions, adjust in production env -->
|
|
37
|
-
<meta-data android:name="io.sentry.traces.profiling.sample-rate" android:value="1.0" />
|
|
38
36
|
`;
|
|
39
37
|
|
|
40
38
|
export const sentryImport = `import io.sentry.Sentry;\n`;
|
package/src/apple/templates.ts
CHANGED
|
@@ -20,7 +20,13 @@ export function getSwiftSnippet(dsn: string): string {
|
|
|
20
20
|
return ` SentrySDK.start { options in
|
|
21
21
|
options.dsn = "${dsn}"
|
|
22
22
|
options.debug = true // Enabled debug when first installing is always helpful
|
|
23
|
-
|
|
23
|
+
// Set tracesSampleRate to 1.0 to capture 100% of transactions for performance monitoring.
|
|
24
|
+
// We recommend adjusting this value in production.
|
|
25
|
+
options.tracesSampleRate = 1.0
|
|
26
|
+
|
|
27
|
+
// Sample rate for profiling, applied on top of TracesSampleRate.
|
|
28
|
+
// We recommend adjusting this value in production.
|
|
29
|
+
options.profilesSampleRate = 1.0
|
|
24
30
|
|
|
25
31
|
// Uncomment the following lines to add more data to your events
|
|
26
32
|
// options.attachScreenshot = true // This adds a screenshot to the error events
|
|
@@ -34,7 +40,13 @@ export function getObjcSnippet(dsn: string): string {
|
|
|
34
40
|
return ` [SentrySDK startWithConfigureOptions:^(SentryOptions * options) {
|
|
35
41
|
options.dsn = @"${dsn}";
|
|
36
42
|
options.debug = YES; // Enabled debug when first installing is always helpful
|
|
37
|
-
|
|
43
|
+
// Set tracesSampleRate to 1.0 to capture 100% of transactions for performance monitoring.
|
|
44
|
+
// We recommend adjusting this value in production.
|
|
45
|
+
options.tracesSampleRate = @1.0;
|
|
46
|
+
|
|
47
|
+
// Sample rate for profiling, applied on top of TracesSampleRate.
|
|
48
|
+
// We recommend adjusting this value in production.
|
|
49
|
+
options.profilesSampleRate = @1.0;
|
|
38
50
|
|
|
39
51
|
//Uncomment the following lines to add more data to your events
|
|
40
52
|
//options.attachScreenshot = YES; //This will add a screenshot to the error events
|
|
@@ -94,6 +94,7 @@ export async function runNextjsWizardWithTelemetry(
|
|
|
94
94
|
const { packageManager: packageManagerFromInstallStep } =
|
|
95
95
|
await installPackage({
|
|
96
96
|
packageName: '@sentry/nextjs@^8',
|
|
97
|
+
packageNameDisplayLabel: '@sentry/nextjs',
|
|
97
98
|
alreadyInstalled: !!packageJson?.dependencies?.['@sentry/nextjs'],
|
|
98
99
|
});
|
|
99
100
|
|