@sentry/wizard 6.10.0 → 6.12.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.
Files changed (203) hide show
  1. package/CHANGELOG.md +69 -0
  2. package/dist/ci-ensure-runtime-loaded.sh +82 -0
  3. package/dist/e2e-tests/tests/angular-17.test.js +72 -82
  4. package/dist/e2e-tests/tests/angular-17.test.js.map +1 -1
  5. package/dist/e2e-tests/tests/angular-19.test.js +71 -80
  6. package/dist/e2e-tests/tests/angular-19.test.js.map +1 -1
  7. package/dist/e2e-tests/tests/cloudflare-worker.test.d.ts +1 -0
  8. package/dist/e2e-tests/tests/cloudflare-worker.test.js +69 -0
  9. package/dist/e2e-tests/tests/cloudflare-worker.test.js.map +1 -0
  10. package/dist/e2e-tests/tests/cloudflare-wrangler-sourcemaps.test.js +2 -5
  11. package/dist/e2e-tests/tests/cloudflare-wrangler-sourcemaps.test.js.map +1 -1
  12. package/dist/e2e-tests/tests/expo.test.js +36 -61
  13. package/dist/e2e-tests/tests/expo.test.js.map +1 -1
  14. package/dist/e2e-tests/tests/flutter.test.js +63 -70
  15. package/dist/e2e-tests/tests/flutter.test.js.map +1 -1
  16. package/dist/e2e-tests/tests/help-message.test.js +2 -2
  17. package/dist/e2e-tests/tests/help-message.test.js.map +1 -1
  18. package/dist/e2e-tests/tests/nextjs-14.test.js +48 -76
  19. package/dist/e2e-tests/tests/nextjs-14.test.js.map +1 -1
  20. package/dist/e2e-tests/tests/nextjs-15.test.js +89 -99
  21. package/dist/e2e-tests/tests/nextjs-15.test.js.map +1 -1
  22. package/dist/e2e-tests/tests/nextjs-16.test.js +48 -45
  23. package/dist/e2e-tests/tests/nextjs-16.test.js.map +1 -1
  24. package/dist/e2e-tests/tests/nuxt-3.test.js +45 -58
  25. package/dist/e2e-tests/tests/nuxt-3.test.js.map +1 -1
  26. package/dist/e2e-tests/tests/nuxt-4.test.js +59 -73
  27. package/dist/e2e-tests/tests/nuxt-4.test.js.map +1 -1
  28. package/dist/e2e-tests/tests/pnpm-workspace.test.js +6 -8
  29. package/dist/e2e-tests/tests/pnpm-workspace.test.js.map +1 -1
  30. package/dist/e2e-tests/tests/react-native.test.js +44 -80
  31. package/dist/e2e-tests/tests/react-native.test.js.map +1 -1
  32. package/dist/e2e-tests/tests/react-router-instrumentation-api.test.d.ts +1 -0
  33. package/dist/e2e-tests/tests/react-router-instrumentation-api.test.js +96 -0
  34. package/dist/e2e-tests/tests/react-router-instrumentation-api.test.js.map +1 -0
  35. package/dist/e2e-tests/tests/react-router.test.js +165 -145
  36. package/dist/e2e-tests/tests/react-router.test.js.map +1 -1
  37. package/dist/e2e-tests/tests/remix.test.js +162 -132
  38. package/dist/e2e-tests/tests/remix.test.js.map +1 -1
  39. package/dist/e2e-tests/tests/sveltekit-hooks.test.js +48 -36
  40. package/dist/e2e-tests/tests/sveltekit-hooks.test.js.map +1 -1
  41. package/dist/e2e-tests/tests/sveltekit-tracing.test.js +5 -7
  42. package/dist/e2e-tests/tests/sveltekit-tracing.test.js.map +1 -1
  43. package/dist/e2e-tests/utils/index.d.ts +15 -43
  44. package/dist/e2e-tests/utils/index.js +95 -185
  45. package/dist/e2e-tests/utils/index.js.map +1 -1
  46. package/dist/get-e2e-test-matrix.mjs +11 -0
  47. package/dist/lib/Constants.d.ts +1 -0
  48. package/dist/lib/Constants.js +5 -0
  49. package/dist/lib/Constants.js.map +1 -1
  50. package/dist/src/android/android-wizard.js +2 -4
  51. package/dist/src/android/android-wizard.js.map +1 -1
  52. package/dist/src/angular/angular-wizard.js +4 -6
  53. package/dist/src/angular/angular-wizard.js.map +1 -1
  54. package/dist/src/angular/sdk-setup.js +1 -1
  55. package/dist/src/angular/sdk-setup.js.map +1 -1
  56. package/dist/src/apple/apple-wizard.js +2 -4
  57. package/dist/src/apple/apple-wizard.js.map +1 -1
  58. package/dist/src/apple/code-tools.js +17 -3
  59. package/dist/src/apple/code-tools.js.map +1 -1
  60. package/dist/src/apple/configure-package-manager.js +18 -5
  61. package/dist/src/apple/configure-package-manager.js.map +1 -1
  62. package/dist/src/cloudflare/cloudflare-wizard.d.ts +3 -0
  63. package/dist/src/cloudflare/cloudflare-wizard.js +104 -0
  64. package/dist/src/cloudflare/cloudflare-wizard.js.map +1 -0
  65. package/dist/src/cloudflare/sdk-setup.d.ts +8 -0
  66. package/dist/src/cloudflare/sdk-setup.js +47 -0
  67. package/dist/src/cloudflare/sdk-setup.js.map +1 -0
  68. package/dist/src/cloudflare/templates.d.ts +5 -0
  69. package/dist/src/cloudflare/templates.js +50 -0
  70. package/dist/src/cloudflare/templates.js.map +1 -0
  71. package/dist/src/cloudflare/wrangler/create-wrangler-config.d.ts +4 -0
  72. package/dist/src/cloudflare/wrangler/create-wrangler-config.js +27 -0
  73. package/dist/src/cloudflare/wrangler/create-wrangler-config.js.map +1 -0
  74. package/dist/src/cloudflare/wrangler/ensure-wrangler-config.d.ts +4 -0
  75. package/dist/src/cloudflare/wrangler/ensure-wrangler-config.js +25 -0
  76. package/dist/src/cloudflare/wrangler/ensure-wrangler-config.js.map +1 -0
  77. package/dist/src/cloudflare/wrangler/find-wrangler-config.d.ts +4 -0
  78. package/dist/src/cloudflare/wrangler/find-wrangler-config.js +23 -0
  79. package/dist/src/cloudflare/wrangler/find-wrangler-config.js.map +1 -0
  80. package/dist/src/cloudflare/wrangler/get-entry-point-from-wrangler-config.d.ts +6 -0
  81. package/dist/src/cloudflare/wrangler/get-entry-point-from-wrangler-config.js +52 -0
  82. package/dist/src/cloudflare/wrangler/get-entry-point-from-wrangler-config.js.map +1 -0
  83. package/dist/src/cloudflare/wrangler/update-wrangler-config.d.ts +17 -0
  84. package/dist/src/cloudflare/wrangler/update-wrangler-config.js +173 -0
  85. package/dist/src/cloudflare/wrangler/update-wrangler-config.js.map +1 -0
  86. package/dist/src/cloudflare/wrap-worker.d.ts +33 -0
  87. package/dist/src/cloudflare/wrap-worker.js +116 -0
  88. package/dist/src/cloudflare/wrap-worker.js.map +1 -0
  89. package/dist/src/flutter/flutter-wizard.js +3 -6
  90. package/dist/src/flutter/flutter-wizard.js.map +1 -1
  91. package/dist/src/nextjs/nextjs-wizard.js +0 -2
  92. package/dist/src/nextjs/nextjs-wizard.js.map +1 -1
  93. package/dist/src/nuxt/nuxt-wizard.js +3 -5
  94. package/dist/src/nuxt/nuxt-wizard.js.map +1 -1
  95. package/dist/src/react-native/expo.d.ts +6 -0
  96. package/dist/src/react-native/expo.js +27 -1
  97. package/dist/src/react-native/expo.js.map +1 -1
  98. package/dist/src/react-native/git.d.ts +5 -0
  99. package/dist/src/react-native/git.js +32 -1
  100. package/dist/src/react-native/git.js.map +1 -1
  101. package/dist/src/react-native/javascript.js +3 -1
  102. package/dist/src/react-native/javascript.js.map +1 -1
  103. package/dist/src/react-native/react-native-wizard.js +14 -10
  104. package/dist/src/react-native/react-native-wizard.js.map +1 -1
  105. package/dist/src/react-router/codemods/client.entry.d.ts +1 -1
  106. package/dist/src/react-router/codemods/client.entry.js +69 -12
  107. package/dist/src/react-router/codemods/client.entry.js.map +1 -1
  108. package/dist/src/react-router/codemods/react-router-config.js +1 -1
  109. package/dist/src/react-router/codemods/react-router-config.js.map +1 -1
  110. package/dist/src/react-router/codemods/root.js +1 -2
  111. package/dist/src/react-router/codemods/root.js.map +1 -1
  112. package/dist/src/react-router/codemods/server-entry.d.ts +1 -1
  113. package/dist/src/react-router/codemods/server-entry.js +39 -4
  114. package/dist/src/react-router/codemods/server-entry.js.map +1 -1
  115. package/dist/src/react-router/codemods/vite.js +46 -1
  116. package/dist/src/react-router/codemods/vite.js.map +1 -1
  117. package/dist/src/react-router/react-router-wizard.js +55 -10
  118. package/dist/src/react-router/react-router-wizard.js.map +1 -1
  119. package/dist/src/react-router/sdk-setup.d.ts +5 -3
  120. package/dist/src/react-router/sdk-setup.js +35 -9
  121. package/dist/src/react-router/sdk-setup.js.map +1 -1
  122. package/dist/src/react-router/templates.d.ts +2 -2
  123. package/dist/src/react-router/templates.js +72 -2
  124. package/dist/src/react-router/templates.js.map +1 -1
  125. package/dist/src/remix/remix-wizard.js +2 -4
  126. package/dist/src/remix/remix-wizard.js.map +1 -1
  127. package/dist/src/run.d.ts +1 -1
  128. package/dist/src/run.js +5 -0
  129. package/dist/src/run.js.map +1 -1
  130. package/dist/src/sourcemaps/tools/vite.js +1 -1
  131. package/dist/src/sourcemaps/tools/vite.js.map +1 -1
  132. package/dist/src/sveltekit/sdk-setup/vite.js +1 -1
  133. package/dist/src/sveltekit/sdk-setup/vite.js.map +1 -1
  134. package/dist/src/sveltekit/sveltekit-wizard.js +2 -4
  135. package/dist/src/sveltekit/sveltekit-wizard.js.map +1 -1
  136. package/dist/src/utils/abort-if-sportlight-not-supported.d.ts +5 -0
  137. package/dist/src/utils/abort-if-sportlight-not-supported.js +40 -0
  138. package/dist/src/utils/abort-if-sportlight-not-supported.js.map +1 -0
  139. package/dist/src/utils/ast-utils.d.ts +11 -1
  140. package/dist/src/utils/ast-utils.js +19 -1
  141. package/dist/src/utils/ast-utils.js.map +1 -1
  142. package/dist/src/utils/clack/index.d.ts +2 -2
  143. package/dist/src/utils/clack/index.js.map +1 -1
  144. package/dist/src/utils/clack/mcp-config.js +117 -59
  145. package/dist/src/utils/clack/mcp-config.js.map +1 -1
  146. package/dist/src/version.d.ts +1 -1
  147. package/dist/src/version.js +1 -1
  148. package/dist/src/version.js.map +1 -1
  149. package/dist/test/angular/angular-wizard.test.js +2 -4
  150. package/dist/test/angular/angular-wizard.test.js.map +1 -1
  151. package/dist/test/apple/code-tools.test.js +78 -0
  152. package/dist/test/apple/code-tools.test.js.map +1 -1
  153. package/dist/test/apple/configure-package-manager.test.d.ts +1 -0
  154. package/dist/test/apple/configure-package-manager.test.js +161 -0
  155. package/dist/test/apple/configure-package-manager.test.js.map +1 -0
  156. package/dist/test/cloudflare/create-wrangler-config.test.d.ts +1 -0
  157. package/dist/test/cloudflare/create-wrangler-config.test.js +48 -0
  158. package/dist/test/cloudflare/create-wrangler-config.test.js.map +1 -0
  159. package/dist/test/cloudflare/ensure-wrangler-config.test.d.ts +1 -0
  160. package/dist/test/cloudflare/ensure-wrangler-config.test.js +61 -0
  161. package/dist/test/cloudflare/ensure-wrangler-config.test.js.map +1 -0
  162. package/dist/test/cloudflare/find-wrangler-config.test.d.ts +1 -0
  163. package/dist/test/cloudflare/find-wrangler-config.test.js +77 -0
  164. package/dist/test/cloudflare/find-wrangler-config.test.js.map +1 -0
  165. package/dist/test/cloudflare/get-entry-point-from-wrangler-config.test.d.ts +1 -0
  166. package/dist/test/cloudflare/get-entry-point-from-wrangler-config.test.js +81 -0
  167. package/dist/test/cloudflare/get-entry-point-from-wrangler-config.test.js.map +1 -0
  168. package/dist/test/cloudflare/sdk-setup.test.d.ts +1 -0
  169. package/dist/test/cloudflare/sdk-setup.test.js +170 -0
  170. package/dist/test/cloudflare/sdk-setup.test.js.map +1 -0
  171. package/dist/test/cloudflare/templates.test.d.ts +1 -0
  172. package/dist/test/cloudflare/templates.test.js +122 -0
  173. package/dist/test/cloudflare/templates.test.js.map +1 -0
  174. package/dist/test/cloudflare/update-wrangler-config.test.d.ts +1 -0
  175. package/dist/test/cloudflare/update-wrangler-config.test.js +216 -0
  176. package/dist/test/cloudflare/update-wrangler-config.test.js.map +1 -0
  177. package/dist/test/cloudflare/wrap-worker.test.d.ts +1 -0
  178. package/dist/test/cloudflare/wrap-worker.test.js +206 -0
  179. package/dist/test/cloudflare/wrap-worker.test.js.map +1 -0
  180. package/dist/test/react-native/expo.test.js +140 -0
  181. package/dist/test/react-native/expo.test.js.map +1 -1
  182. package/dist/test/react-native/git.test.d.ts +1 -0
  183. package/dist/test/react-native/git.test.js +160 -0
  184. package/dist/test/react-native/git.test.js.map +1 -0
  185. package/dist/test/react-router/codemods/client-entry.test.js +29 -0
  186. package/dist/test/react-router/codemods/client-entry.test.js.map +1 -1
  187. package/dist/test/react-router/codemods/root.test.js +4 -0
  188. package/dist/test/react-router/codemods/root.test.js.map +1 -1
  189. package/dist/test/react-router/codemods/server-entry.test.js +70 -0
  190. package/dist/test/react-router/codemods/server-entry.test.js.map +1 -1
  191. package/dist/test/react-router/codemods/vite.test.js +89 -0
  192. package/dist/test/react-router/codemods/vite.test.js.map +1 -1
  193. package/dist/test/react-router/sdk-setup.test.js +64 -8
  194. package/dist/test/react-router/sdk-setup.test.js.map +1 -1
  195. package/dist/test/react-router/templates.test.js +50 -0
  196. package/dist/test/react-router/templates.test.js.map +1 -1
  197. package/dist/test/sourcemaps/tools/vite.test.js +12 -8
  198. package/dist/test/sourcemaps/tools/vite.test.js.map +1 -1
  199. package/dist/test/utils/ast-utils.test.js +22 -0
  200. package/dist/test/utils/ast-utils.test.js.map +1 -1
  201. package/dist/test/utils/clack/mcp-config.test.js +176 -51
  202. package/dist/test/utils/clack/mcp-config.test.js.map +1 -1
  203. package/package.json +6 -5
@@ -24,117 +24,110 @@ var __importStar = (this && this.__importStar) || function (mod) {
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
26
  const fs = __importStar(require("node:fs"));
27
- const path = __importStar(require("node:path"));
28
27
  const Constants_1 = require("../../lib/Constants");
29
28
  const utils_1 = require("../utils");
30
29
  const utils_2 = require("../utils");
31
- const utils_3 = require("../utils");
32
30
  const vitest_1 = require("vitest");
31
+ //@ts-expect-error - clifty is ESM only
32
+ const clifty_1 = require("clifty");
33
33
  (0, vitest_1.describe)('Flutter', () => {
34
- const integration = Constants_1.Integration.flutter;
35
- const projectDir = path.resolve(__dirname, '../test-applications/flutter-test-app');
36
34
  (0, vitest_1.describe)('with apple platforms', () => {
35
+ let wizardExitCode;
36
+ const { projectDir, cleanup } = (0, utils_1.createIsolatedTestEnv)('flutter-test-app');
37
37
  (0, vitest_1.beforeAll)(async () => {
38
- const wizardInstance = (0, utils_2.startWizardInstance)(integration, projectDir);
39
- const tracingOptionPrompted = await wizardInstance.waitForOutput(
40
- // "Do you want to enable Tracing", sometimes doesn't work as `Tracing` can be printed in bold.
41
- 'to track the performance of your application?');
42
- const profilingOptionPrompted = tracingOptionPrompted &&
43
- (await wizardInstance.sendStdinAndWaitForOutput([utils_1.KEYS.ENTER],
44
- // "Do you want to enable Profiling", sometimes doesn't work as `Profiling` can be printed in bold.
45
- 'to analyze CPU usage and optimize performance-critical code on iOS & macOS?'));
46
- const replayOptionPrompted = profilingOptionPrompted &&
47
- (await wizardInstance.sendStdinAndWaitForOutput([utils_1.KEYS.ENTER],
48
- // "Do you want to enable Session Replay", sometimes doesn't work as `Session Replay` can be printed in bold.
49
- 'to record user interactions and debug issues?'));
50
- const logsOptionPrompted = replayOptionPrompted &&
51
- (await wizardInstance.sendStdinAndWaitForOutput([utils_1.KEYS.ENTER],
52
- // "Do you want to enable Logs", sometimes doesn't work as `Logs` can be printed in bold.
53
- 'to send your application logs to Sentry?'));
54
- // Handle the MCP prompt (default is now Yes, so press DOWN to select No)
55
- const mcpPrompted = logsOptionPrompted &&
56
- (await wizardInstance.sendStdinAndWaitForOutput([utils_1.KEYS.ENTER], 'Optionally add a project-scoped MCP server configuration for the Sentry MCP?', {
57
- optional: true,
58
- }));
59
- mcpPrompted &&
60
- (await wizardInstance.sendStdinAndWaitForOutput(
61
- // Decline MCP config by selecting No
62
- [utils_1.KEYS.DOWN, utils_1.KEYS.ENTER], 'Successfully installed the Sentry Flutter SDK!'));
63
- wizardInstance.kill();
38
+ wizardExitCode = await (0, clifty_1.withEnv)({
39
+ cwd: projectDir,
40
+ debug: true,
41
+ })
42
+ .defineInteraction()
43
+ .expectOutput('The Sentry Flutter Wizard will help you set up Sentry for your application')
44
+ .whenAsked('Do you want to enable Tracing')
45
+ .respondWith(clifty_1.KEYS.ENTER)
46
+ .whenAsked('to analyze CPU usage and optimize performance-critical code on iOS & macOS?')
47
+ .respondWith(clifty_1.KEYS.ENTER)
48
+ .whenAsked('to record user interactions and debug issues?')
49
+ .respondWith(clifty_1.KEYS.ENTER)
50
+ .whenAsked('to send your application logs to Sentry?')
51
+ .respondWith(clifty_1.KEYS.ENTER)
52
+ .whenAsked('Optionally add a project-scoped MCP server configuration for the Sentry MCP?')
53
+ .respondWith(clifty_1.KEYS.DOWN, clifty_1.KEYS.ENTER)
54
+ .expectOutput('Successfully installed the Sentry Flutter SDK!')
55
+ .run((0, utils_1.getWizardCommand)(Constants_1.Integration.flutter));
64
56
  });
65
57
  (0, vitest_1.afterAll)(() => {
66
- (0, utils_1.revertLocalChanges)(projectDir);
67
- (0, utils_1.cleanupGit)(projectDir);
58
+ cleanup();
59
+ });
60
+ (0, vitest_1.test)('exits with exit code 0', () => {
61
+ (0, vitest_1.expect)(wizardExitCode).toBe(0);
68
62
  });
69
63
  (0, vitest_1.test)('pubspec.yaml is updated.', () => {
70
- (0, utils_3.checkFileContents)(`${projectDir}/pubspec.yaml`, `sentry_flutter:`); // dependencies
71
- (0, utils_3.checkFileContents)(`${projectDir}/pubspec.yaml`, `sentry_dart_plugin:`); // dev_dependencies
72
- (0, utils_3.checkFileContents)(`${projectDir}/pubspec.yaml`, `sentry:`); // gradle plugin options
64
+ (0, utils_2.checkFileContents)(`${projectDir}/pubspec.yaml`, `sentry_flutter:`); // dependencies
65
+ (0, utils_2.checkFileContents)(`${projectDir}/pubspec.yaml`, `sentry_dart_plugin:`); // dev_dependencies
66
+ (0, utils_2.checkFileContents)(`${projectDir}/pubspec.yaml`, `sentry:`); // gradle plugin options
73
67
  });
74
68
  (0, vitest_1.test)('sentry.properties exists and has auth token', () => {
75
- (0, utils_3.checkSentryProperties)(projectDir);
69
+ (0, utils_2.checkSentryProperties)(projectDir);
76
70
  });
77
71
  (0, vitest_1.test)('.gitignore has sentry.properties', () => {
78
- (0, utils_3.checkFileContents)(`${projectDir}/.gitignore`, `sentry.properties`);
72
+ (0, utils_2.checkFileContents)(`${projectDir}/.gitignore`, `sentry.properties`);
79
73
  });
80
74
  (0, vitest_1.test)('lib/main.dart calls sentry init', () => {
81
- (0, utils_3.checkFileContents)(`${projectDir}/lib/main.dart`, `import 'package:sentry_flutter/sentry_flutter.dart';`);
82
- (0, utils_3.checkFileContents)(`${projectDir}/lib/main.dart`, `await SentryFlutter.init(`);
75
+ (0, utils_2.checkFileContents)(`${projectDir}/lib/main.dart`, `import 'package:sentry_flutter/sentry_flutter.dart';`);
76
+ (0, utils_2.checkFileContents)(`${projectDir}/lib/main.dart`, `await SentryFlutter.init(`);
83
77
  });
84
78
  (0, vitest_1.test)('lib/main.dart enables tracing and profiling', () => {
85
- (0, utils_3.checkFileContents)(`${projectDir}/lib/main.dart`, `options.tracesSampleRate = 1.0;`);
86
- (0, utils_3.checkFileContents)(`${projectDir}/lib/main.dart`, `options.profilesSampleRate = 1.0;`);
79
+ (0, utils_2.checkFileContents)(`${projectDir}/lib/main.dart`, `options.tracesSampleRate = 1.0;`);
80
+ (0, utils_2.checkFileContents)(`${projectDir}/lib/main.dart`, `options.profilesSampleRate = 1.0;`);
87
81
  });
88
82
  (0, vitest_1.test)('lib/main.dart enables logs', () => {
89
- (0, utils_3.checkFileContents)(`${projectDir}/lib/main.dart`, `options.enableLogs = true;`);
83
+ (0, utils_2.checkFileContents)(`${projectDir}/lib/main.dart`, `options.enableLogs = true;`);
90
84
  });
91
85
  (0, vitest_1.test)('builds correctly', async () => {
92
- await (0, utils_3.checkIfFlutterBuilds)(projectDir, '✓ Built build/web');
86
+ await (0, utils_2.checkIfFlutterBuilds)(projectDir, '✓ Built build/web');
93
87
  });
94
88
  });
95
89
  (0, vitest_1.describe)('without apple platforms', () => {
90
+ let wizardExitCode;
91
+ const { projectDir, cleanup } = (0, utils_1.createIsolatedTestEnv)('flutter-test-app');
96
92
  (0, vitest_1.beforeAll)(async () => {
97
- const wizardInstance = (0, utils_2.startWizardInstance)(integration, projectDir);
93
+ // Remove apple platform directories to simulate non-apple setup
98
94
  if (fs.existsSync(`${projectDir}/ios`)) {
99
95
  fs.renameSync(`${projectDir}/ios`, `${projectDir}/_ios`);
100
96
  }
101
97
  if (fs.existsSync(`${projectDir}/macos`)) {
102
98
  fs.renameSync(`${projectDir}/macos`, `${projectDir}/_macos`);
103
99
  }
104
- const continueOnUncommitedFilesPromted = await wizardInstance.waitForOutput('Do you want to continue anyway?');
105
- const tracingOptionPrompted = continueOnUncommitedFilesPromted &&
106
- (await wizardInstance.sendStdinAndWaitForOutput([utils_1.KEYS.ENTER],
107
- // "Do you want to enable Tracing", sometimes doesn't work as `Tracing` can be printed in bold.
108
- 'to track the performance of your application?'));
109
- const replayOptionPrompted = tracingOptionPrompted &&
110
- (await wizardInstance.sendStdinAndWaitForOutput([utils_1.KEYS.ENTER],
111
- // "Do you want to enable Session Replay", sometimes doesn't work as `Session Replay` can be printed in bold.
112
- 'to record user interactions and debug issues?'));
113
- const logsOptionPrompted = replayOptionPrompted &&
114
- (await wizardInstance.sendStdinAndWaitForOutput([utils_1.KEYS.ENTER],
115
- // "Do you want to enable Logs", sometimes doesn't work as `Logs` can be printed in bold.
116
- 'to send your application logs to Sentry?'));
117
- // Handle the MCP prompt (default is now Yes, so press DOWN to select No)
118
- const mcpPrompted = logsOptionPrompted &&
119
- (await wizardInstance.sendStdinAndWaitForOutput([utils_1.KEYS.ENTER], 'Optionally add a project-scoped MCP server configuration for the Sentry MCP?', {
120
- optional: true,
121
- }));
122
- mcpPrompted &&
123
- (await wizardInstance.sendStdinAndWaitForOutput(
124
- // Decline MCP config by selecting No
125
- [utils_1.KEYS.DOWN, utils_1.KEYS.ENTER], 'Successfully installed the Sentry Flutter SDK!'));
126
- wizardInstance.kill();
100
+ wizardExitCode = await (0, clifty_1.withEnv)({
101
+ cwd: projectDir,
102
+ debug: true,
103
+ })
104
+ .defineInteraction()
105
+ .whenAsked('Do you want to continue anyway?')
106
+ .respondWith(clifty_1.KEYS.ENTER)
107
+ .expectOutput('The Sentry Flutter Wizard will help you set up Sentry for your application')
108
+ .whenAsked('Do you want to enable Tracing')
109
+ .respondWith(clifty_1.KEYS.ENTER)
110
+ .whenAsked('to record user interactions and debug issues?')
111
+ .respondWith(clifty_1.KEYS.ENTER)
112
+ .whenAsked('to send your application logs to Sentry?')
113
+ .respondWith(clifty_1.KEYS.ENTER)
114
+ .whenAsked('Optionally add a project-scoped MCP server configuration for the Sentry MCP?')
115
+ .respondWith(clifty_1.KEYS.DOWN, clifty_1.KEYS.ENTER)
116
+ .expectOutput('Successfully installed the Sentry Flutter SDK!')
117
+ .run((0, utils_1.getWizardCommand)(Constants_1.Integration.flutter));
127
118
  });
128
119
  (0, vitest_1.afterAll)(() => {
129
- (0, utils_1.revertLocalChanges)(projectDir);
130
- (0, utils_1.cleanupGit)(projectDir);
120
+ cleanup();
121
+ });
122
+ (0, vitest_1.test)('exits with exit code 0', () => {
123
+ (0, vitest_1.expect)(wizardExitCode).toBe(0);
131
124
  });
132
125
  (0, vitest_1.test)('lib/main.dart does not add profiling with missing ios and macos folder', () => {
133
126
  const fileContent = fs.readFileSync(`${projectDir}/lib/main.dart`, 'utf-8');
134
127
  (0, vitest_1.expect)(fileContent).not.toContain(`options.profilesSampleRate = 1.0;`);
135
128
  });
136
129
  (0, vitest_1.test)('lib/main.dart enables logs', () => {
137
- (0, utils_3.checkFileContents)(`${projectDir}/lib/main.dart`, `options.enableLogs = true;`);
130
+ (0, utils_2.checkFileContents)(`${projectDir}/lib/main.dart`, `options.enableLogs = true;`);
138
131
  });
139
132
  });
140
133
  });
@@ -1 +1 @@
1
- {"version":3,"file":"flutter.test.js","sourceRoot":"","sources":["../../../e2e-tests/tests/flutter.test.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { Integration } from '../../lib/Constants';\nimport {\n KEYS,\n // checkEnvBuildPlugin,\n cleanupGit,\n revertLocalChanges,\n} from '../utils';\nimport { startWizardInstance } from '../utils';\nimport {\n checkFileContents,\n checkIfFlutterBuilds,\n // checkFileExists,\n checkSentryProperties,\n} from '../utils';\nimport { afterAll, beforeAll, describe, expect, test } from 'vitest';\n\ndescribe('Flutter', () => {\n const integration = Integration.flutter;\n const projectDir = path.resolve(\n __dirname,\n '../test-applications/flutter-test-app',\n );\n\n describe('with apple platforms', () => {\n beforeAll(async () => {\n const wizardInstance = startWizardInstance(integration, projectDir);\n\n const tracingOptionPrompted = await wizardInstance.waitForOutput(\n // \"Do you want to enable Tracing\", sometimes doesn't work as `Tracing` can be printed in bold.\n 'to track the performance of your application?',\n );\n\n const profilingOptionPrompted =\n tracingOptionPrompted &&\n (await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n // \"Do you want to enable Profiling\", sometimes doesn't work as `Profiling` can be printed in bold.\n 'to analyze CPU usage and optimize performance-critical code on iOS & macOS?',\n ));\n\n const replayOptionPrompted =\n profilingOptionPrompted &&\n (await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n // \"Do you want to enable Session Replay\", sometimes doesn't work as `Session Replay` can be printed in bold.\n 'to record user interactions and debug issues?',\n ));\n\n const logsOptionPrompted =\n replayOptionPrompted &&\n (await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n // \"Do you want to enable Logs\", sometimes doesn't work as `Logs` can be printed in bold.\n 'to send your application logs to Sentry?',\n ));\n\n // Handle the MCP prompt (default is now Yes, so press DOWN to select No)\n const mcpPrompted =\n logsOptionPrompted &&\n (await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n 'Optionally add a project-scoped MCP server configuration for the Sentry MCP?',\n {\n optional: true,\n },\n ));\n\n mcpPrompted &&\n (await wizardInstance.sendStdinAndWaitForOutput(\n // Decline MCP config by selecting No\n [KEYS.DOWN, KEYS.ENTER],\n 'Successfully installed the Sentry Flutter SDK!',\n ));\n\n wizardInstance.kill();\n });\n\n afterAll(() => {\n revertLocalChanges(projectDir);\n cleanupGit(projectDir);\n });\n\n test('pubspec.yaml is updated.', () => {\n checkFileContents(`${projectDir}/pubspec.yaml`, `sentry_flutter:`); // dependencies\n checkFileContents(`${projectDir}/pubspec.yaml`, `sentry_dart_plugin:`); // dev_dependencies\n checkFileContents(`${projectDir}/pubspec.yaml`, `sentry:`); // gradle plugin options\n });\n\n test('sentry.properties exists and has auth token', () => {\n checkSentryProperties(projectDir);\n });\n\n test('.gitignore has sentry.properties', () => {\n checkFileContents(`${projectDir}/.gitignore`, `sentry.properties`);\n });\n\n test('lib/main.dart calls sentry init', () => {\n checkFileContents(\n `${projectDir}/lib/main.dart`,\n `import 'package:sentry_flutter/sentry_flutter.dart';`,\n );\n checkFileContents(\n `${projectDir}/lib/main.dart`,\n `await SentryFlutter.init(`,\n );\n });\n\n test('lib/main.dart enables tracing and profiling', () => {\n checkFileContents(\n `${projectDir}/lib/main.dart`,\n `options.tracesSampleRate = 1.0;`,\n );\n checkFileContents(\n `${projectDir}/lib/main.dart`,\n `options.profilesSampleRate = 1.0;`,\n );\n });\n\n test('lib/main.dart enables logs', () => {\n checkFileContents(\n `${projectDir}/lib/main.dart`,\n `options.enableLogs = true;`,\n );\n });\n\n test('builds correctly', async () => {\n await checkIfFlutterBuilds(projectDir, '✓ Built build/web');\n });\n });\n\n describe('without apple platforms', () => {\n beforeAll(async () => {\n const wizardInstance = startWizardInstance(integration, projectDir);\n\n if (fs.existsSync(`${projectDir}/ios`)) {\n fs.renameSync(`${projectDir}/ios`, `${projectDir}/_ios`);\n }\n if (fs.existsSync(`${projectDir}/macos`)) {\n fs.renameSync(`${projectDir}/macos`, `${projectDir}/_macos`);\n }\n\n const continueOnUncommitedFilesPromted =\n await wizardInstance.waitForOutput('Do you want to continue anyway?');\n\n const tracingOptionPrompted =\n continueOnUncommitedFilesPromted &&\n (await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n // \"Do you want to enable Tracing\", sometimes doesn't work as `Tracing` can be printed in bold.\n 'to track the performance of your application?',\n ));\n\n const replayOptionPrompted =\n tracingOptionPrompted &&\n (await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n // \"Do you want to enable Session Replay\", sometimes doesn't work as `Session Replay` can be printed in bold.\n 'to record user interactions and debug issues?',\n ));\n\n const logsOptionPrompted =\n replayOptionPrompted &&\n (await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n // \"Do you want to enable Logs\", sometimes doesn't work as `Logs` can be printed in bold.\n 'to send your application logs to Sentry?',\n ));\n\n // Handle the MCP prompt (default is now Yes, so press DOWN to select No)\n const mcpPrompted =\n logsOptionPrompted &&\n (await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n 'Optionally add a project-scoped MCP server configuration for the Sentry MCP?',\n {\n optional: true,\n },\n ));\n\n mcpPrompted &&\n (await wizardInstance.sendStdinAndWaitForOutput(\n // Decline MCP config by selecting No\n [KEYS.DOWN, KEYS.ENTER],\n 'Successfully installed the Sentry Flutter SDK!',\n ));\n\n wizardInstance.kill();\n });\n\n afterAll(() => {\n revertLocalChanges(projectDir);\n cleanupGit(projectDir);\n });\n\n test('lib/main.dart does not add profiling with missing ios and macos folder', () => {\n const fileContent = fs.readFileSync(\n `${projectDir}/lib/main.dart`,\n 'utf-8',\n );\n expect(fileContent).not.toContain(`options.profilesSampleRate = 1.0;`);\n });\n\n test('lib/main.dart enables logs', () => {\n checkFileContents(\n `${projectDir}/lib/main.dart`,\n `options.enableLogs = true;`,\n );\n });\n });\n});\n"]}
1
+ {"version":3,"file":"flutter.test.js","sourceRoot":"","sources":["../../../e2e-tests/tests/flutter.test.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'node:fs';\nimport { Integration } from '../../lib/Constants';\nimport { createIsolatedTestEnv, getWizardCommand } from '../utils';\nimport {\n checkFileContents,\n checkIfFlutterBuilds,\n checkSentryProperties,\n} from '../utils';\nimport { afterAll, beforeAll, describe, expect, test } from 'vitest';\n\n//@ts-expect-error - clifty is ESM only\nimport { KEYS, withEnv } from 'clifty';\n\ndescribe('Flutter', () => {\n describe('with apple platforms', () => {\n let wizardExitCode: number;\n const { projectDir, cleanup } = createIsolatedTestEnv('flutter-test-app');\n\n beforeAll(async () => {\n wizardExitCode = await withEnv({\n cwd: projectDir,\n debug: true,\n })\n .defineInteraction()\n .expectOutput(\n 'The Sentry Flutter Wizard will help you set up Sentry for your application',\n )\n .whenAsked('Do you want to enable Tracing')\n .respondWith(KEYS.ENTER)\n .whenAsked(\n 'to analyze CPU usage and optimize performance-critical code on iOS & macOS?',\n )\n .respondWith(KEYS.ENTER)\n .whenAsked('to record user interactions and debug issues?')\n .respondWith(KEYS.ENTER)\n .whenAsked('to send your application logs to Sentry?')\n .respondWith(KEYS.ENTER)\n .whenAsked(\n 'Optionally add a project-scoped MCP server configuration for the Sentry MCP?',\n )\n .respondWith(KEYS.DOWN, KEYS.ENTER)\n .expectOutput('Successfully installed the Sentry Flutter SDK!')\n .run(getWizardCommand(Integration.flutter));\n });\n\n afterAll(() => {\n cleanup();\n });\n\n test('exits with exit code 0', () => {\n expect(wizardExitCode).toBe(0);\n });\n\n test('pubspec.yaml is updated.', () => {\n checkFileContents(`${projectDir}/pubspec.yaml`, `sentry_flutter:`); // dependencies\n checkFileContents(`${projectDir}/pubspec.yaml`, `sentry_dart_plugin:`); // dev_dependencies\n checkFileContents(`${projectDir}/pubspec.yaml`, `sentry:`); // gradle plugin options\n });\n\n test('sentry.properties exists and has auth token', () => {\n checkSentryProperties(projectDir);\n });\n\n test('.gitignore has sentry.properties', () => {\n checkFileContents(`${projectDir}/.gitignore`, `sentry.properties`);\n });\n\n test('lib/main.dart calls sentry init', () => {\n checkFileContents(\n `${projectDir}/lib/main.dart`,\n `import 'package:sentry_flutter/sentry_flutter.dart';`,\n );\n checkFileContents(\n `${projectDir}/lib/main.dart`,\n `await SentryFlutter.init(`,\n );\n });\n\n test('lib/main.dart enables tracing and profiling', () => {\n checkFileContents(\n `${projectDir}/lib/main.dart`,\n `options.tracesSampleRate = 1.0;`,\n );\n checkFileContents(\n `${projectDir}/lib/main.dart`,\n `options.profilesSampleRate = 1.0;`,\n );\n });\n\n test('lib/main.dart enables logs', () => {\n checkFileContents(\n `${projectDir}/lib/main.dart`,\n `options.enableLogs = true;`,\n );\n });\n\n test('builds correctly', async () => {\n await checkIfFlutterBuilds(projectDir, '✓ Built build/web');\n });\n });\n\n describe('without apple platforms', () => {\n let wizardExitCode: number;\n const { projectDir, cleanup } = createIsolatedTestEnv('flutter-test-app');\n\n beforeAll(async () => {\n // Remove apple platform directories to simulate non-apple setup\n if (fs.existsSync(`${projectDir}/ios`)) {\n fs.renameSync(`${projectDir}/ios`, `${projectDir}/_ios`);\n }\n if (fs.existsSync(`${projectDir}/macos`)) {\n fs.renameSync(`${projectDir}/macos`, `${projectDir}/_macos`);\n }\n\n wizardExitCode = await withEnv({\n cwd: projectDir,\n debug: true,\n })\n .defineInteraction()\n .whenAsked('Do you want to continue anyway?')\n .respondWith(KEYS.ENTER)\n .expectOutput(\n 'The Sentry Flutter Wizard will help you set up Sentry for your application',\n )\n .whenAsked('Do you want to enable Tracing')\n .respondWith(KEYS.ENTER)\n .whenAsked('to record user interactions and debug issues?')\n .respondWith(KEYS.ENTER)\n .whenAsked('to send your application logs to Sentry?')\n .respondWith(KEYS.ENTER)\n .whenAsked(\n 'Optionally add a project-scoped MCP server configuration for the Sentry MCP?',\n )\n .respondWith(KEYS.DOWN, KEYS.ENTER)\n .expectOutput('Successfully installed the Sentry Flutter SDK!')\n .run(getWizardCommand(Integration.flutter));\n });\n\n afterAll(() => {\n cleanup();\n });\n\n test('exits with exit code 0', () => {\n expect(wizardExitCode).toBe(0);\n });\n\n test('lib/main.dart does not add profiling with missing ios and macos folder', () => {\n const fileContent = fs.readFileSync(\n `${projectDir}/lib/main.dart`,\n 'utf-8',\n );\n expect(fileContent).not.toContain(`options.profilesSampleRate = 1.0;`);\n });\n\n test('lib/main.dart enables logs', () => {\n checkFileContents(\n `${projectDir}/lib/main.dart`,\n `options.enableLogs = true;`,\n );\n });\n });\n});\n"]}
@@ -28,8 +28,8 @@ const vitest_1 = require("vitest");
28
28
  -i, --integration Choose the integration to setup
29
29
  env: SENTRY_WIZARD_INTEGRATION
30
30
  [choices: "reactNative", "flutter", "ios", "android", "cordova", "angular",
31
- "electron", "nextjs", "nuxt", "remix", "reactRouter", "sveltekit",
32
- "sourcemaps"]
31
+ "cloudflare", "electron", "nextjs", "nuxt", "remix", "reactRouter",
32
+ "sveltekit", "sourcemaps"]
33
33
  -p, --platform Choose platform(s)
34
34
  env: SENTRY_WIZARD_PLATFORM
35
35
  [array] [choices: "ios", "android"]
@@ -1 +1 @@
1
- {"version":3,"file":"help-message.test.js","sourceRoot":"","sources":["../../../e2e-tests/tests/help-message.test.ts"],"names":[],"mappings":";;AAAA,2DAA8C;AAC9C,yCAAiC;AACjC,mCAA8C;AAE9C,IAAA,iBAAQ,EAAC,gBAAgB,EAAE,GAAG,EAAE;IAC9B,IAAA,WAAE,EAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,0BAA0B;YACpD,CAAC,CAAC,CAAC,UAAU,EAAE,iBAAiB,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACnE,CAAC,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAEvB,MAAM,OAAO,GAAG,IAAA,gBAAI,EAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,CAAC;QAExD,MAAM,MAAM,GAAG,IAAA,6BAAQ,EAAC,GAAG,OAAO,SAAS,EAAE;YAC3C,KAAK,EAAE,MAAM;SACd,CAAC,CAAC;QAEH,IAAA,eAAM,EAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA0C/C,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { execSync } from 'node:child_process';\nimport { join } from 'node:path';\nimport { describe, expect, it } from 'vitest';\n\ndescribe('--help command', () => {\n it('prints the up to date help command', () => {\n const binName = process.env.SENTRY_WIZARD_E2E_TEST_BIN\n ? ['dist-bin', `sentry-wizard-${process.platform}-${process.arch}`]\n : ['dist', 'bin.js'];\n\n const binPath = join(__dirname, '..', '..', ...binName);\n\n const output = execSync(`${binPath} --help`, {\n stdio: 'pipe',\n });\n\n expect(output.toString()).toMatchInlineSnapshot(`\n \"Options:\n --help Show help [boolean]\n --debug Enable verbose logging\n env: SENTRY_WIZARD_DEBUG [boolean] [default: false]\n --uninstall Revert project setup process\n env: SENTRY_WIZARD_UNINSTALL\n [boolean] [default: false]\n --skip-connect Skips the connection to the server\n env: SENTRY_WIZARD_SKIP_CONNECT\n [boolean] [default: false]\n --quiet Do not fallback to prompting user asking questions\n env: SENTRY_WIZARD_QUIET [boolean] [default: false]\n -i, --integration Choose the integration to setup\n env: SENTRY_WIZARD_INTEGRATION\n [choices: \"reactNative\", \"flutter\", \"ios\", \"android\", \"cordova\", \"angular\",\n \"electron\", \"nextjs\", \"nuxt\", \"remix\", \"reactRouter\", \"sveltekit\",\n \"sourcemaps\"]\n -p, --platform Choose platform(s)\n env: SENTRY_WIZARD_PLATFORM\n [array] [choices: \"ios\", \"android\"]\n -u, --url The url to your Sentry installation\n env: SENTRY_WIZARD_URL\n --project The Sentry project slug to use\n [string] [default: Select project during setup]\n --org The Sentry org slug to use\n [string] [default: Select org during setup]\n --saas Skip the self-hosted or SaaS URL selection process\n [boolean] [default: Select self-hosted or SaaS during setup]\n -s, --signup Redirect to signup page if not logged in\n [boolean] [default: false]\n --disable-telemetry Don't send telemetry data to Sentry\n [boolean] [default: false]\n --force-install Force install the SDK NPM package\n [boolean] [default: false]\n --ignore-git-changes Ignore git changes in the project\n [boolean] [default: false]\n --spotlight Enable Spotlight for local development. This does\n not require a Sentry account or project.\n [boolean] [default: false]\n --version Show version number [boolean]\n \"\n `);\n });\n});\n"]}
1
+ {"version":3,"file":"help-message.test.js","sourceRoot":"","sources":["../../../e2e-tests/tests/help-message.test.ts"],"names":[],"mappings":";;AAAA,2DAA8C;AAC9C,yCAAiC;AACjC,mCAA8C;AAE9C,IAAA,iBAAQ,EAAC,gBAAgB,EAAE,GAAG,EAAE;IAC9B,IAAA,WAAE,EAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,0BAA0B;YACpD,CAAC,CAAC,CAAC,UAAU,EAAE,iBAAiB,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACnE,CAAC,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAEvB,MAAM,OAAO,GAAG,IAAA,gBAAI,EAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,CAAC;QAExD,MAAM,MAAM,GAAG,IAAA,6BAAQ,EAAC,GAAG,OAAO,SAAS,EAAE;YAC3C,KAAK,EAAE,MAAM;SACd,CAAC,CAAC;QAEH,IAAA,eAAM,EAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA0C/C,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { execSync } from 'node:child_process';\nimport { join } from 'node:path';\nimport { describe, expect, it } from 'vitest';\n\ndescribe('--help command', () => {\n it('prints the up to date help command', () => {\n const binName = process.env.SENTRY_WIZARD_E2E_TEST_BIN\n ? ['dist-bin', `sentry-wizard-${process.platform}-${process.arch}`]\n : ['dist', 'bin.js'];\n\n const binPath = join(__dirname, '..', '..', ...binName);\n\n const output = execSync(`${binPath} --help`, {\n stdio: 'pipe',\n });\n\n expect(output.toString()).toMatchInlineSnapshot(`\n \"Options:\n --help Show help [boolean]\n --debug Enable verbose logging\n env: SENTRY_WIZARD_DEBUG [boolean] [default: false]\n --uninstall Revert project setup process\n env: SENTRY_WIZARD_UNINSTALL\n [boolean] [default: false]\n --skip-connect Skips the connection to the server\n env: SENTRY_WIZARD_SKIP_CONNECT\n [boolean] [default: false]\n --quiet Do not fallback to prompting user asking questions\n env: SENTRY_WIZARD_QUIET [boolean] [default: false]\n -i, --integration Choose the integration to setup\n env: SENTRY_WIZARD_INTEGRATION\n [choices: \"reactNative\", \"flutter\", \"ios\", \"android\", \"cordova\", \"angular\",\n \"cloudflare\", \"electron\", \"nextjs\", \"nuxt\", \"remix\", \"reactRouter\",\n \"sveltekit\", \"sourcemaps\"]\n -p, --platform Choose platform(s)\n env: SENTRY_WIZARD_PLATFORM\n [array] [choices: \"ios\", \"android\"]\n -u, --url The url to your Sentry installation\n env: SENTRY_WIZARD_URL\n --project The Sentry project slug to use\n [string] [default: Select project during setup]\n --org The Sentry org slug to use\n [string] [default: Select org during setup]\n --saas Skip the self-hosted or SaaS URL selection process\n [boolean] [default: Select self-hosted or SaaS during setup]\n -s, --signup Redirect to signup page if not logged in\n [boolean] [default: false]\n --disable-telemetry Don't send telemetry data to Sentry\n [boolean] [default: false]\n --force-install Force install the SDK NPM package\n [boolean] [default: false]\n --ignore-git-changes Ignore git changes in the project\n [boolean] [default: false]\n --spotlight Enable Spotlight for local development. This does\n not require a Sentry account or project.\n [boolean] [default: false]\n --version Show version number [boolean]\n \"\n `);\n });\n});\n"]}
@@ -1,99 +1,71 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
2
  Object.defineProperty(exports, "__esModule", { value: true });
26
- const path = __importStar(require("node:path"));
27
3
  const Constants_1 = require("../../lib/Constants");
28
4
  const utils_1 = require("../utils");
29
- const utils_2 = require("../utils");
30
- const utils_3 = require("../utils");
31
5
  const vitest_1 = require("vitest");
6
+ //@ts-expect-error - clifty is ESM only
7
+ const clifty_1 = require("clifty");
32
8
  (0, vitest_1.describe)('NextJS-14', () => {
33
9
  const integration = Constants_1.Integration.nextjs;
34
- const projectDir = path.resolve(__dirname, '../test-applications/nextjs-14-test-app');
10
+ let wizardExitCode;
11
+ const { projectDir, cleanup } = (0, utils_1.createIsolatedTestEnv)('nextjs-14-test-app');
35
12
  (0, vitest_1.beforeAll)(async () => {
36
- const wizardInstance = (0, utils_2.startWizardInstance)(integration, projectDir);
37
- const packageManagerPrompted = await wizardInstance.waitForOutput('Please select your package manager.');
38
- const routeThroughNextJsPrompted = packageManagerPrompted &&
39
- (await wizardInstance.sendStdinAndWaitForOutput(
40
- // Selecting `yarn` as the package manager
41
- [utils_1.KEYS.DOWN, utils_1.KEYS.ENTER], 'Do you want to route Sentry requests in the browser through your Next.js server', {
42
- timeout: 240000,
43
- }));
44
- const tracingOptionPrompted = routeThroughNextJsPrompted &&
45
- (await wizardInstance.sendStdinAndWaitForOutput([utils_1.KEYS.ENTER],
46
- // "Do you want to enable Tracing", sometimes doesn't work as `Tracing` can be printed in bold.
47
- 'to track the performance of your application?'));
48
- const replayOptionPrompted = tracingOptionPrompted &&
49
- (await wizardInstance.sendStdinAndWaitForOutput([utils_1.KEYS.ENTER],
50
- // "Do you want to enable Sentry Session Replay", sometimes doesn't work as `Sentry Session Replay` can be printed in bold.
51
- 'to get a video-like reproduction of errors during a user session?'));
52
- const logOptionPrompted = replayOptionPrompted &&
53
- (await wizardInstance.sendStdinAndWaitForOutput([utils_1.KEYS.ENTER],
54
- // "Do you want to enable Logs", sometimes doesn't work as `Logs` can be printed in bold.
55
- 'to send your application logs to Sentry?'));
56
- const examplePagePrompted = logOptionPrompted &&
57
- (await wizardInstance.sendStdinAndWaitForOutput([utils_1.KEYS.ENTER], 'Do you want to create an example page', {
58
- optional: true,
59
- }));
60
- const ciCdPrompted = examplePagePrompted &&
61
- (await wizardInstance.sendStdinAndWaitForOutput([utils_1.KEYS.ENTER], 'Are you using a CI/CD tool'));
62
- // Selecting `No` for CI/CD tool
63
- ciCdPrompted &&
64
- (await wizardInstance.sendStdinAndWaitForOutput([utils_1.KEYS.DOWN, utils_1.KEYS.ENTER], 'Optionally add a project-scoped MCP server configuration for the Sentry MCP?', { optional: true }));
65
- // Decline optional MCP config (default is now Yes, so press DOWN to select No)
66
- await wizardInstance.sendStdinAndWaitForOutput([utils_1.KEYS.DOWN, utils_1.KEYS.ENTER], 'Successfully installed the Sentry Next.js SDK!');
67
- wizardInstance.kill();
13
+ wizardExitCode = await (0, clifty_1.withEnv)({
14
+ cwd: projectDir,
15
+ })
16
+ .defineInteraction()
17
+ .whenAsked('Please select your package manager.')
18
+ .respondWith(clifty_1.KEYS.DOWN, clifty_1.KEYS.ENTER) // Select yarn
19
+ .expectOutput('Installing @sentry/nextjs')
20
+ .whenAsked('Do you want to route Sentry requests in the browser through your Next.js server', {
21
+ timeout: 240000, // package installation can take a while in CI
22
+ })
23
+ .respondWith(clifty_1.KEYS.ENTER)
24
+ .whenAsked('to track the performance of your application?')
25
+ .respondWith(clifty_1.KEYS.ENTER)
26
+ .whenAsked('to get a video-like reproduction of errors during a user session?')
27
+ .respondWith(clifty_1.KEYS.ENTER)
28
+ .whenAsked('to send your application logs to Sentry?')
29
+ .respondWith(clifty_1.KEYS.ENTER)
30
+ .whenAsked('Do you want to create an example page')
31
+ .respondWith(clifty_1.KEYS.ENTER)
32
+ .whenAsked('Are you using a CI/CD tool')
33
+ .respondWith(clifty_1.KEYS.DOWN, clifty_1.KEYS.ENTER) // Select No
34
+ .whenAsked('Optionally add a project-scoped MCP server configuration for the Sentry MCP?')
35
+ .respondWith(clifty_1.KEYS.DOWN, clifty_1.KEYS.ENTER) // Decline MCP config
36
+ .expectOutput('Successfully installed the Sentry Next.js SDK!')
37
+ .run((0, utils_1.getWizardCommand)(integration));
68
38
  });
69
39
  (0, vitest_1.afterAll)(() => {
70
- (0, utils_1.revertLocalChanges)(projectDir);
71
- (0, utils_1.cleanupGit)(projectDir);
40
+ cleanup();
41
+ });
42
+ (0, vitest_1.test)('exits with exit code 0', () => {
43
+ (0, vitest_1.expect)(wizardExitCode).toBe(0);
72
44
  });
73
45
  (0, vitest_1.test)('package.json is updated correctly', () => {
74
- (0, utils_3.checkPackageJson)(projectDir, integration);
46
+ (0, utils_1.checkPackageJson)(projectDir, '@sentry/nextjs');
75
47
  });
76
48
  (0, vitest_1.test)('.env-sentry-build-plugin is created and contains the auth token', () => {
77
49
  (0, utils_1.checkEnvBuildPlugin)(projectDir);
78
50
  });
79
51
  (0, vitest_1.test)('example page exists', () => {
80
- (0, utils_3.checkFileExists)(`${projectDir}/src/app/layout.tsx`);
81
- (0, utils_3.checkFileExists)(`${projectDir}/src/app/sentry-example-page/page.tsx`);
82
- (0, utils_3.checkFileExists)(`${projectDir}/src/app/api/sentry-example-api/route.ts`);
52
+ (0, utils_1.checkFileExists)(`${projectDir}/src/app/layout.tsx`);
53
+ (0, utils_1.checkFileExists)(`${projectDir}/src/app/sentry-example-page/page.tsx`);
54
+ (0, utils_1.checkFileExists)(`${projectDir}/src/app/api/sentry-example-api/route.ts`);
83
55
  });
84
56
  (0, vitest_1.test)('config files created', () => {
85
- (0, utils_3.checkFileExists)(`${projectDir}/sentry.server.config.ts`);
86
- (0, utils_3.checkFileExists)(`${projectDir}/sentry.edge.config.ts`);
57
+ (0, utils_1.checkFileExists)(`${projectDir}/sentry.server.config.ts`);
58
+ (0, utils_1.checkFileExists)(`${projectDir}/sentry.edge.config.ts`);
87
59
  });
88
60
  (0, vitest_1.test)('global error file exists', () => {
89
- (0, utils_3.checkFileExists)(`${projectDir}/src/app/global-error.tsx`);
61
+ (0, utils_1.checkFileExists)(`${projectDir}/src/app/global-error.tsx`);
90
62
  });
91
63
  (0, vitest_1.test)('instrumentation files exists', () => {
92
- (0, utils_3.checkFileExists)(`${projectDir}/src/instrumentation.ts`);
93
- (0, utils_3.checkFileExists)(`${projectDir}/src/instrumentation-client.ts`);
64
+ (0, utils_1.checkFileExists)(`${projectDir}/src/instrumentation.ts`);
65
+ (0, utils_1.checkFileExists)(`${projectDir}/src/instrumentation-client.ts`);
94
66
  });
95
67
  (0, vitest_1.test)('instrumentation file contains Sentry initialization', () => {
96
- (0, utils_3.checkFileContents)(`${projectDir}/src/instrumentation.ts`, [
68
+ (0, utils_1.checkFileContents)(`${projectDir}/src/instrumentation.ts`, [
97
69
  'import * as Sentry from "@sentry/nextjs";',
98
70
  `export async function register() {
99
71
  if (process.env.NEXT_RUNTIME === "nodejs") {
@@ -109,22 +81,22 @@ export const onRequestError = Sentry.captureRequestError;`,
109
81
  ]);
110
82
  });
111
83
  (0, vitest_1.test)('next.config file contains Sentry wrapper', () => {
112
- (0, utils_3.checkFileContents)(`${projectDir}/next.config.mjs`, [
84
+ (0, utils_1.checkFileContents)(`${projectDir}/next.config.mjs`, [
113
85
  "import { withSentryConfig } from '@sentry/nextjs'",
114
86
  'export default withSentryConfig(nextConfig, {',
115
87
  ]);
116
88
  });
117
89
  (0, vitest_1.test)('runs on dev mode correctly', async () => {
118
- await (0, utils_3.checkIfRunsOnDevMode)(projectDir, 'Ready in');
90
+ await (0, utils_1.checkIfRunsOnDevMode)(projectDir, 'Ready in');
119
91
  });
120
92
  (0, vitest_1.test)('builds correctly', async () => {
121
- await (0, utils_3.checkIfBuilds)(projectDir);
93
+ await (0, utils_1.checkIfBuilds)(projectDir);
122
94
  });
123
95
  (0, vitest_1.test)('runs on prod mode correctly', async () => {
124
- await (0, utils_3.checkIfRunsOnProdMode)(projectDir, 'Ready in');
96
+ await (0, utils_1.checkIfRunsOnProdMode)(projectDir, 'Ready in');
125
97
  });
126
98
  (0, vitest_1.test)('root layout contains generateMetadata function', () => {
127
- (0, utils_3.checkFileContents)(`${projectDir}/src/app/layout.tsx`, [
99
+ (0, utils_1.checkFileContents)(`${projectDir}/src/app/layout.tsx`, [
128
100
  "// This file was generated by the Sentry wizard because we couldn't find a root layout file.",
129
101
  "import * as Sentry from '@sentry/nextjs';",
130
102
  "import type { Metadata } from 'next';",
@@ -1 +1 @@
1
- {"version":3,"file":"nextjs-14.test.js","sourceRoot":"","sources":["../../../e2e-tests/tests/nextjs-14.test.ts"],"names":[],"mappings":"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","sourcesContent":["import * as path from 'node:path';\nimport { Integration } from '../../lib/Constants';\nimport {\n KEYS,\n checkEnvBuildPlugin,\n cleanupGit,\n revertLocalChanges,\n} from '../utils';\nimport { startWizardInstance } from '../utils';\nimport {\n checkFileContents,\n checkFileExists,\n checkIfBuilds,\n checkIfRunsOnDevMode,\n checkIfRunsOnProdMode,\n checkPackageJson,\n} from '../utils';\nimport { afterAll, beforeAll, describe, test } from 'vitest';\n\ndescribe('NextJS-14', () => {\n const integration = Integration.nextjs;\n const projectDir = path.resolve(\n __dirname,\n '../test-applications/nextjs-14-test-app',\n );\n\n beforeAll(async () => {\n const wizardInstance = startWizardInstance(integration, projectDir);\n const packageManagerPrompted = await wizardInstance.waitForOutput(\n 'Please select your package manager.',\n );\n\n const routeThroughNextJsPrompted =\n packageManagerPrompted &&\n (await wizardInstance.sendStdinAndWaitForOutput(\n // Selecting `yarn` as the package manager\n [KEYS.DOWN, KEYS.ENTER],\n 'Do you want to route Sentry requests in the browser through your Next.js server',\n {\n timeout: 240_000,\n },\n ));\n\n const tracingOptionPrompted =\n routeThroughNextJsPrompted &&\n (await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n // \"Do you want to enable Tracing\", sometimes doesn't work as `Tracing` can be printed in bold.\n 'to track the performance of your application?',\n ));\n\n const replayOptionPrompted =\n tracingOptionPrompted &&\n (await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n // \"Do you want to enable Sentry Session Replay\", sometimes doesn't work as `Sentry Session Replay` can be printed in bold.\n 'to get a video-like reproduction of errors during a user session?',\n ));\n\n const logOptionPrompted =\n replayOptionPrompted &&\n (await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n // \"Do you want to enable Logs\", sometimes doesn't work as `Logs` can be printed in bold.\n 'to send your application logs to Sentry?',\n ));\n\n const examplePagePrompted =\n logOptionPrompted &&\n (await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n 'Do you want to create an example page',\n {\n optional: true,\n },\n ));\n\n const ciCdPrompted =\n examplePagePrompted &&\n (await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n 'Are you using a CI/CD tool',\n ));\n\n // Selecting `No` for CI/CD tool\n ciCdPrompted &&\n (await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.DOWN, KEYS.ENTER],\n 'Optionally add a project-scoped MCP server configuration for the Sentry MCP?',\n { optional: true },\n ));\n\n // Decline optional MCP config (default is now Yes, so press DOWN to select No)\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.DOWN, KEYS.ENTER],\n 'Successfully installed the Sentry Next.js SDK!',\n );\n\n wizardInstance.kill();\n });\n\n afterAll(() => {\n revertLocalChanges(projectDir);\n cleanupGit(projectDir);\n });\n\n test('package.json is updated correctly', () => {\n checkPackageJson(projectDir, integration);\n });\n\n test('.env-sentry-build-plugin is created and contains the auth token', () => {\n checkEnvBuildPlugin(projectDir);\n });\n\n test('example page exists', () => {\n checkFileExists(`${projectDir}/src/app/layout.tsx`);\n checkFileExists(`${projectDir}/src/app/sentry-example-page/page.tsx`);\n checkFileExists(`${projectDir}/src/app/api/sentry-example-api/route.ts`);\n });\n\n test('config files created', () => {\n checkFileExists(`${projectDir}/sentry.server.config.ts`);\n checkFileExists(`${projectDir}/sentry.edge.config.ts`);\n });\n\n test('global error file exists', () => {\n checkFileExists(`${projectDir}/src/app/global-error.tsx`);\n });\n\n test('instrumentation files exists', () => {\n checkFileExists(`${projectDir}/src/instrumentation.ts`);\n checkFileExists(`${projectDir}/src/instrumentation-client.ts`);\n });\n\n test('instrumentation file contains Sentry initialization', () => {\n checkFileContents(`${projectDir}/src/instrumentation.ts`, [\n 'import * as Sentry from \"@sentry/nextjs\";',\n `export async function register() {\n if (process.env.NEXT_RUNTIME === \"nodejs\") {\n await import(\"../sentry.server.config\");\n }\n\n if (process.env.NEXT_RUNTIME === \"edge\") {\n await import(\"../sentry.edge.config\");\n }\n}\n\nexport const onRequestError = Sentry.captureRequestError;`,\n ]);\n });\n\n test('next.config file contains Sentry wrapper', () => {\n checkFileContents(`${projectDir}/next.config.mjs`, [\n \"import { withSentryConfig } from '@sentry/nextjs'\",\n 'export default withSentryConfig(nextConfig, {',\n ]);\n });\n\n test('runs on dev mode correctly', async () => {\n await checkIfRunsOnDevMode(projectDir, 'Ready in');\n });\n\n test('builds correctly', async () => {\n await checkIfBuilds(projectDir);\n });\n\n test('runs on prod mode correctly', async () => {\n await checkIfRunsOnProdMode(projectDir, 'Ready in');\n });\n\n test('root layout contains generateMetadata function', () => {\n checkFileContents(`${projectDir}/src/app/layout.tsx`, [\n \"// This file was generated by the Sentry wizard because we couldn't find a root layout file.\",\n \"import * as Sentry from '@sentry/nextjs';\",\n \"import type { Metadata } from 'next';\",\n '',\n 'export function generateMetadata(): Metadata {',\n ' return {',\n ' other: {',\n ' ...Sentry.getTraceData(),',\n ' }',\n ' }',\n '};',\n '',\n 'export default function RootLayout({',\n ' children,',\n '}: {',\n ' children: React.ReactNode',\n '}) {',\n ' return (',\n ' <html lang=\"en\">',\n ' <body>{children}</body>',\n ' </html>',\n ' )',\n '}',\n ]);\n });\n});\n"]}
1
+ {"version":3,"file":"nextjs-14.test.js","sourceRoot":"","sources":["../../../e2e-tests/tests/nextjs-14.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { Integration } from '../../lib/Constants';\nimport {\n checkEnvBuildPlugin,\n createIsolatedTestEnv,\n checkFileContents,\n checkFileExists,\n checkIfBuilds,\n checkIfRunsOnDevMode,\n checkIfRunsOnProdMode,\n checkPackageJson,\n getWizardCommand,\n} from '../utils';\nimport { afterAll, beforeAll, describe, expect, test } from 'vitest';\n\n//@ts-expect-error - clifty is ESM only\nimport { KEYS, withEnv } from 'clifty';\n\ndescribe('NextJS-14', () => {\n const integration = Integration.nextjs;\n let wizardExitCode: number;\n\n const { projectDir, cleanup } = createIsolatedTestEnv('nextjs-14-test-app');\n\n beforeAll(async () => {\n wizardExitCode = await withEnv({\n cwd: projectDir,\n })\n .defineInteraction()\n .whenAsked('Please select your package manager.')\n .respondWith(KEYS.DOWN, KEYS.ENTER) // Select yarn\n .expectOutput('Installing @sentry/nextjs')\n .whenAsked(\n 'Do you want to route Sentry requests in the browser through your Next.js server',\n {\n timeout: 240_000, // package installation can take a while in CI\n },\n )\n .respondWith(KEYS.ENTER)\n .whenAsked('to track the performance of your application?')\n .respondWith(KEYS.ENTER)\n .whenAsked(\n 'to get a video-like reproduction of errors during a user session?',\n )\n .respondWith(KEYS.ENTER)\n .whenAsked('to send your application logs to Sentry?')\n .respondWith(KEYS.ENTER)\n .whenAsked('Do you want to create an example page')\n .respondWith(KEYS.ENTER)\n .whenAsked('Are you using a CI/CD tool')\n .respondWith(KEYS.DOWN, KEYS.ENTER) // Select No\n .whenAsked(\n 'Optionally add a project-scoped MCP server configuration for the Sentry MCP?',\n )\n .respondWith(KEYS.DOWN, KEYS.ENTER) // Decline MCP config\n .expectOutput('Successfully installed the Sentry Next.js SDK!')\n .run(getWizardCommand(integration));\n });\n\n afterAll(() => {\n cleanup();\n });\n\n test('exits with exit code 0', () => {\n expect(wizardExitCode).toBe(0);\n });\n\n test('package.json is updated correctly', () => {\n checkPackageJson(projectDir, '@sentry/nextjs');\n });\n\n test('.env-sentry-build-plugin is created and contains the auth token', () => {\n checkEnvBuildPlugin(projectDir);\n });\n\n test('example page exists', () => {\n checkFileExists(`${projectDir}/src/app/layout.tsx`);\n checkFileExists(`${projectDir}/src/app/sentry-example-page/page.tsx`);\n checkFileExists(`${projectDir}/src/app/api/sentry-example-api/route.ts`);\n });\n\n test('config files created', () => {\n checkFileExists(`${projectDir}/sentry.server.config.ts`);\n checkFileExists(`${projectDir}/sentry.edge.config.ts`);\n });\n\n test('global error file exists', () => {\n checkFileExists(`${projectDir}/src/app/global-error.tsx`);\n });\n\n test('instrumentation files exists', () => {\n checkFileExists(`${projectDir}/src/instrumentation.ts`);\n checkFileExists(`${projectDir}/src/instrumentation-client.ts`);\n });\n\n test('instrumentation file contains Sentry initialization', () => {\n checkFileContents(`${projectDir}/src/instrumentation.ts`, [\n 'import * as Sentry from \"@sentry/nextjs\";',\n `export async function register() {\n if (process.env.NEXT_RUNTIME === \"nodejs\") {\n await import(\"../sentry.server.config\");\n }\n\n if (process.env.NEXT_RUNTIME === \"edge\") {\n await import(\"../sentry.edge.config\");\n }\n}\n\nexport const onRequestError = Sentry.captureRequestError;`,\n ]);\n });\n\n test('next.config file contains Sentry wrapper', () => {\n checkFileContents(`${projectDir}/next.config.mjs`, [\n \"import { withSentryConfig } from '@sentry/nextjs'\",\n 'export default withSentryConfig(nextConfig, {',\n ]);\n });\n\n test('runs on dev mode correctly', async () => {\n await checkIfRunsOnDevMode(projectDir, 'Ready in');\n });\n\n test('builds correctly', async () => {\n await checkIfBuilds(projectDir);\n });\n\n test('runs on prod mode correctly', async () => {\n await checkIfRunsOnProdMode(projectDir, 'Ready in');\n });\n\n test('root layout contains generateMetadata function', () => {\n checkFileContents(`${projectDir}/src/app/layout.tsx`, [\n \"// This file was generated by the Sentry wizard because we couldn't find a root layout file.\",\n \"import * as Sentry from '@sentry/nextjs';\",\n \"import type { Metadata } from 'next';\",\n '',\n 'export function generateMetadata(): Metadata {',\n ' return {',\n ' other: {',\n ' ...Sentry.getTraceData(),',\n ' }',\n ' }',\n '};',\n '',\n 'export default function RootLayout({',\n ' children,',\n '}: {',\n ' children: React.ReactNode',\n '}) {',\n ' return (',\n ' <html lang=\"en\">',\n ' <body>{children}</body>',\n ' </html>',\n ' )',\n '}',\n ]);\n });\n});\n"]}