@sentry/wizard 4.7.0 → 4.8.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 (110) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +19 -19
  3. package/dist/e2e-tests/tests/angular-17.test.d.ts +1 -0
  4. package/dist/e2e-tests/tests/angular-17.test.js +196 -0
  5. package/dist/e2e-tests/tests/angular-17.test.js.map +1 -0
  6. package/dist/e2e-tests/tests/angular-19.test.d.ts +1 -0
  7. package/dist/e2e-tests/tests/angular-19.test.js +194 -0
  8. package/dist/e2e-tests/tests/angular-19.test.js.map +1 -0
  9. package/dist/e2e-tests/tests/expo.test.d.ts +1 -0
  10. package/dist/e2e-tests/tests/expo.test.js +95 -0
  11. package/dist/e2e-tests/tests/expo.test.js.map +1 -0
  12. package/dist/e2e-tests/tests/help-message.test.js +2 -2
  13. package/dist/e2e-tests/tests/help-message.test.js.map +1 -1
  14. package/dist/e2e-tests/tests/react-native.test.d.ts +1 -0
  15. package/dist/e2e-tests/tests/react-native.test.js +97 -0
  16. package/dist/e2e-tests/tests/react-native.test.js.map +1 -0
  17. package/dist/e2e-tests/tests/remix.test.js +4 -4
  18. package/dist/e2e-tests/tests/remix.test.js.map +1 -1
  19. package/dist/e2e-tests/tests/sveltekit.test.js +2 -2
  20. package/dist/e2e-tests/tests/sveltekit.test.js.map +1 -1
  21. package/dist/e2e-tests/utils/index.d.ts +7 -0
  22. package/dist/e2e-tests/utils/index.js +18 -1
  23. package/dist/e2e-tests/utils/index.js.map +1 -1
  24. package/dist/lib/Constants.d.ts +1 -0
  25. package/dist/lib/Constants.js +3 -0
  26. package/dist/lib/Constants.js.map +1 -1
  27. package/dist/src/angular/angular-wizard.d.ts +3 -0
  28. package/dist/src/angular/angular-wizard.js +186 -0
  29. package/dist/src/angular/angular-wizard.js.map +1 -0
  30. package/dist/src/angular/codemods/app-config.d.ts +3 -0
  31. package/dist/src/angular/codemods/app-config.js +211 -0
  32. package/dist/src/angular/codemods/app-config.js.map +1 -0
  33. package/dist/src/angular/codemods/main.d.ts +20 -0
  34. package/dist/src/angular/codemods/main.js +62 -0
  35. package/dist/src/angular/codemods/main.js.map +1 -0
  36. package/dist/src/angular/codemods/sourcemaps.d.ts +21 -0
  37. package/dist/src/angular/codemods/sourcemaps.js +94 -0
  38. package/dist/src/angular/codemods/sourcemaps.js.map +1 -0
  39. package/dist/src/angular/example-component.d.ts +8 -0
  40. package/dist/src/angular/example-component.js +286 -0
  41. package/dist/src/angular/example-component.js.map +1 -0
  42. package/dist/src/angular/sdk-setup.d.ts +6 -0
  43. package/dist/src/angular/sdk-setup.js +99 -0
  44. package/dist/src/angular/sdk-setup.js.map +1 -0
  45. package/dist/src/flutter/flutter-wizard.js +10 -2
  46. package/dist/src/flutter/flutter-wizard.js.map +1 -1
  47. package/dist/src/nextjs/nextjs-wizard.js +26 -12
  48. package/dist/src/nextjs/nextjs-wizard.js.map +1 -1
  49. package/dist/src/nextjs/templates.js +56 -7
  50. package/dist/src/nextjs/templates.js.map +1 -1
  51. package/dist/src/nuxt/templates.js +30 -0
  52. package/dist/src/nuxt/templates.js.map +1 -1
  53. package/dist/src/react-native/expo-metro.js +4 -1
  54. package/dist/src/react-native/expo-metro.js.map +1 -1
  55. package/dist/src/react-native/expo.js +5 -1
  56. package/dist/src/react-native/expo.js.map +1 -1
  57. package/dist/src/react-native/javascript.js +9 -2
  58. package/dist/src/react-native/javascript.js.map +1 -1
  59. package/dist/src/react-native/metro.js +8 -2
  60. package/dist/src/react-native/metro.js.map +1 -1
  61. package/dist/src/react-native/xcode.js +5 -1
  62. package/dist/src/react-native/xcode.js.map +1 -1
  63. package/dist/src/remix/sdk-example.js +30 -1
  64. package/dist/src/remix/sdk-example.js.map +1 -1
  65. package/dist/src/remix/sdk-setup.js +11 -5
  66. package/dist/src/remix/sdk-setup.js.map +1 -1
  67. package/dist/src/run.d.ts +1 -1
  68. package/dist/src/run.js +5 -0
  69. package/dist/src/run.js.map +1 -1
  70. package/dist/src/sourcemaps/sourcemaps-wizard.d.ts +1 -1
  71. package/dist/src/sourcemaps/sourcemaps-wizard.js +35 -20
  72. package/dist/src/sourcemaps/sourcemaps-wizard.js.map +1 -1
  73. package/dist/src/sourcemaps/tools/angular.d.ts +1 -0
  74. package/dist/src/sourcemaps/tools/angular.js +7 -7
  75. package/dist/src/sourcemaps/tools/angular.js.map +1 -1
  76. package/dist/src/sourcemaps/tools/sentry-cli.d.ts +5 -1
  77. package/dist/src/sourcemaps/tools/sentry-cli.js +6 -3
  78. package/dist/src/sourcemaps/tools/sentry-cli.js.map +1 -1
  79. package/dist/src/sourcemaps/tools/tsc.js +5 -1
  80. package/dist/src/sourcemaps/tools/tsc.js.map +1 -1
  81. package/dist/src/sourcemaps/tools/vite.js +4 -1
  82. package/dist/src/sourcemaps/tools/vite.js.map +1 -1
  83. package/dist/src/sourcemaps/tools/webpack.js +4 -1
  84. package/dist/src/sourcemaps/tools/webpack.js.map +1 -1
  85. package/dist/src/sveltekit/sdk-example.js +1 -1
  86. package/dist/src/sveltekit/sdk-example.js.map +1 -1
  87. package/dist/src/sveltekit/sveltekit-wizard.js +2 -2
  88. package/dist/src/sveltekit/sveltekit-wizard.js.map +1 -1
  89. package/dist/src/sveltekit/templates.js +28 -1
  90. package/dist/src/sveltekit/templates.js.map +1 -1
  91. package/dist/src/utils/clack/index.d.ts +11 -3
  92. package/dist/src/utils/clack/index.js +9 -3
  93. package/dist/src/utils/clack/index.js.map +1 -1
  94. package/dist/src/version.d.ts +1 -1
  95. package/dist/src/version.js +1 -1
  96. package/dist/src/version.js.map +1 -1
  97. package/dist/test/angular/angular-wizard.test.d.ts +1 -0
  98. package/dist/test/angular/angular-wizard.test.js +27 -0
  99. package/dist/test/angular/angular-wizard.test.js.map +1 -0
  100. package/dist/test/angular/codemods/sourcemaps.test.d.ts +1 -0
  101. package/dist/test/angular/codemods/sourcemaps.test.js +237 -0
  102. package/dist/test/angular/codemods/sourcemaps.test.js.map +1 -0
  103. package/dist/test/angular/example-component.test.d.ts +1 -0
  104. package/dist/test/angular/example-component.test.js +105 -0
  105. package/dist/test/angular/example-component.test.js.map +1 -0
  106. package/dist/test/react-native/metro.test.js +113 -0
  107. package/dist/test/react-native/metro.test.js.map +1 -1
  108. package/dist/test/remix/client-entry.test.js +10 -10
  109. package/dist/test/remix/client-entry.test.js.map +1 -1
  110. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # Changelog
2
2
 
3
+ ## 4.8.0
4
+
5
+ - feat: Add Angular Wizard ([#767](https://github.com/getsentry/sentry-wizard/pull/767))
6
+ - feat(nextjs): Add connectivity check to example page([#951](https://github.com/getsentry/sentry-wizard/pull/951))
7
+ - feat(nextjs): Improve error names in example page to better differentiate between frontend and API errors ([#944](https://github.com/getsentry/sentry-wizard/pull/944))
8
+ - feat(nuxt): Add connectivity check to example page ([#966](https://github.com/getsentry/sentry-wizard/pull/966))
9
+ - feat(remix): Add connectivity check to example page([#967](https://github.com/getsentry/sentry-wizard/pull/967))
10
+ - feat(sveltekit): Add connectivity check to example page ([#972](https://github.com/getsentry/sentry-wizard/pull/972))
11
+ - fix(remix): Linting issues in generated client init code ([#949](https://github.com/getsentry/sentry-wizard/pull/949))
12
+ - fix(sveltekit): Move example page from sentry-example to sentry-example-page( [#973](https://github.com/getsentry/sentry-wizard/pull/973))
13
+
3
14
  ## 4.7.0
4
15
 
5
16
  - feat: Add `deno` as a package manager ([#905](https://github.com/getsentry/sentry-wizard/pull/905))
package/README.md CHANGED
@@ -57,25 +57,25 @@ open a [GitHub issue](https://github.com/getsentry/sentry-wizard/issues)!
57
57
 
58
58
  The following CLI arguments are available:
59
59
 
60
- | Option | Description | Type | Default | Choices | Environment Variable |
61
- | ---------------------- | ----------------------------------------------------------------- | ------- | --------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | ---------------------------- |
62
- | `--help` | Show help | boolean | | | |
63
- | `--version` | Show version number | boolean | | | |
64
- | `--debug` | Enable verbose logging | boolean | `false` | | `SENTRY_WIZARD_DEBUG` |
65
- | `--uninstall` | Revert project setup process. Not available for all integrations. | boolean | `false` | | `SENTRY_WIZARD_UNINSTALL` |
66
- | `--skip-connect` | Skips the connection to the server | boolean | `false` | | `SENTRY_WIZARD_SKIP_CONNECT` |
67
- | `--quiet` | Do not fallback to prompting user asking questions | boolean | `false` | | `SENTRY_WIZARD_QUIET` |
68
- | `-i, --integration` | Choose the integration to setup | choices | Select integration during setup | "reactNative", "flutter", ios", "android", "cordova", "electron", "nextjs", "nuxt", "remix", "sveltekit", "sourcemaps" | `SENTRY_WIZARD_INTEGRATION` |
69
- | `-p, --platform` | Choose platform(s) | array | Select platform(s) during setup | "ios", "android" | `SENTRY_WIZARD_PLATFORM` |
70
- | `-u, --url` | The URL to your Sentry installation | string | `https://sentry.io` | | `SENTRY_WIZARD_URL` |
71
- | `--project` | The Sentry project slug to use | string | Select project during setup | | |
72
- | `--org` | The Sentry org slug to use | string | Select org during setup | | |
73
- | `--saas` | Skip the self-hosted or SaaS URL selection process | boolean | Select self-hosted or SaaS during setup | | |
74
- | `-s, --signup` | Redirect to signup page if not logged in | boolean | `false` | | |
75
- | `--disable-telemetry` | Don't send telemetry data to Sentry | boolean | `false` | | |
76
- | `--force-install` | Force install the SDK NPM package (use with caution!) | boolean | `false` | | |
77
- | `--coming-from` | Specify the partner organization initiating this command. | string | | | |
78
- | `--ignore-git-changes` | Ignore git changes in the project and not prompt for confirmation | boolean | `false` | | |
60
+ | Option | Description | Type | Default | Choices | Environment Variable |
61
+ | ---------------------- | ----------------------------------------------------------------- | ------- | --------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- |
62
+ | `--help` | Show help | boolean | | | |
63
+ | `--version` | Show version number | boolean | | | |
64
+ | `--debug` | Enable verbose logging | boolean | `false` | | `SENTRY_WIZARD_DEBUG` |
65
+ | `--uninstall` | Revert project setup process. Not available for all integrations. | boolean | `false` | | `SENTRY_WIZARD_UNINSTALL` |
66
+ | `--skip-connect` | Skips the connection to the server | boolean | `false` | | `SENTRY_WIZARD_SKIP_CONNECT` |
67
+ | `--quiet` | Do not fallback to prompting user asking questions | boolean | `false` | | `SENTRY_WIZARD_QUIET` |
68
+ | `-i, --integration` | Choose the integration to setup | choices | Select integration during setup | "reactNative", "flutter", ios", "android", "cordova", "angular", "electron", "nextjs", "nuxt", "remix", "sveltekit", "sourcemaps" | `SENTRY_WIZARD_INTEGRATION` |
69
+ | `-p, --platform` | Choose platform(s) | array | Select platform(s) during setup | "ios", "android" | `SENTRY_WIZARD_PLATFORM` |
70
+ | `-u, --url` | The URL to your Sentry installation | string | `https://sentry.io` | | `SENTRY_WIZARD_URL` |
71
+ | `--project` | The Sentry project slug to use | string | Select project during setup | | |
72
+ | `--org` | The Sentry org slug to use | string | Select org during setup | | |
73
+ | `--saas` | Skip the self-hosted or SaaS URL selection process | boolean | Select self-hosted or SaaS during setup | | |
74
+ | `-s, --signup` | Redirect to signup page if not logged in | boolean | `false` | | |
75
+ | `--disable-telemetry` | Don't send telemetry data to Sentry | boolean | `false` | | |
76
+ | `--force-install` | Force install the SDK NPM package (use with caution!) | boolean | `false` | | |
77
+ | `--coming-from` | Specify the partner organization initiating this command. | string | | | |
78
+ | `--ignore-git-changes` | Ignore git changes in the project and not prompt for confirmation | boolean | `false` | | |
79
79
 
80
80
  ## Resources
81
81
 
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,196 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ const Constants_1 = require("../../lib/Constants");
27
+ const utils_1 = require("../utils");
28
+ const path = __importStar(require("path"));
29
+ const utils_2 = require("../utils");
30
+ const vitest_1 = require("vitest");
31
+ async function runWizardOnAngularProject(projectDir, integration, fileModificationFn) {
32
+ const wizardInstance = (0, utils_1.startWizardInstance)(integration, projectDir);
33
+ if (fileModificationFn) {
34
+ fileModificationFn(projectDir);
35
+ await wizardInstance.waitForOutput('Do you want to continue anyway?');
36
+ await wizardInstance.sendStdinAndWaitForOutput([utils_1.KEYS.ENTER], 'Please select your package manager.');
37
+ }
38
+ else {
39
+ await wizardInstance.waitForOutput('Please select your package manager.');
40
+ }
41
+ await wizardInstance.sendStdinAndWaitForOutput(
42
+ // Selecting `yarn` as the package manager
43
+ [utils_1.KEYS.DOWN, utils_1.KEYS.ENTER],
44
+ // "Do you want to enable Tracing", sometimes doesn't work as `Tracing` can be printed in bold.
45
+ 'to track the performance of your application?', {
46
+ timeout: 240000,
47
+ optional: true,
48
+ });
49
+ await wizardInstance.sendStdinAndWaitForOutput(
50
+ // select "Yes" for tracing
51
+ [utils_1.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
+ await wizardInstance.sendStdinAndWaitForOutput(
55
+ // select "Yes" for replay
56
+ [utils_1.KEYS.ENTER], 'Where are your build artifacts located?', {
57
+ timeout: 5000,
58
+ });
59
+ const sourcemapsConfiguredPromise = wizardInstance.waitForOutput('Added a sentry:sourcemaps script to your package.json');
60
+ const buildScriptPromptedPromise = wizardInstance.waitForOutput('Do you want to automatically run the sentry:sourcemaps script after each production build?');
61
+ const optionalArtifactsNotFoundPromise = wizardInstance.waitForOutput("We couldn't find artifacts", {
62
+ optional: true,
63
+ timeout: 5000,
64
+ });
65
+ // ./dist is the default value, no need to change it
66
+ wizardInstance.sendStdin(utils_1.KEYS.ENTER);
67
+ const optionalArtifactsNotFoundPrompted = await optionalArtifactsNotFoundPromise;
68
+ if (optionalArtifactsNotFoundPrompted) {
69
+ wizardInstance.sendStdin(utils_1.KEYS.DOWN);
70
+ wizardInstance.sendStdin(utils_1.KEYS.ENTER);
71
+ }
72
+ await sourcemapsConfiguredPromise;
73
+ await buildScriptPromptedPromise;
74
+ await wizardInstance.sendStdinAndWaitForOutput([utils_1.KEYS.ENTER], // yes, automatically add sentry:sourcemaps script
75
+ 'Is yarn build your production build command?');
76
+ await wizardInstance.sendStdinAndWaitForOutput([utils_1.KEYS.ENTER], // yes, yarn build is the production build command
77
+ 'Are you using a CI/CD tool to build and deploy your application?');
78
+ await wizardInstance.sendStdinAndWaitForOutput([utils_1.KEYS.DOWN, utils_1.KEYS.ENTER], // no CI/CD tool
79
+ 'Do you want to create an example component to test your Sentry setup?');
80
+ await wizardInstance.sendStdinAndWaitForOutput([utils_1.KEYS.ENTER], // yes, create example component
81
+ 'Did you apply the snippet above?');
82
+ await wizardInstance.sendStdinAndWaitForOutput([utils_1.KEYS.ENTER], // yes, applied the snippet
83
+ 'Looks like you have Prettier in your project. Do you want to run it on your files?');
84
+ await wizardInstance.sendStdinAndWaitForOutput([utils_1.KEYS.ENTER], // yes, run prettier
85
+ 'Successfully installed the Sentry Angular SDK!');
86
+ wizardInstance.kill();
87
+ }
88
+ function checkAngularProject(projectDir, integration, options) {
89
+ (0, vitest_1.test)('package.json is updated correctly', () => {
90
+ (0, utils_1.checkPackageJson)(projectDir, integration);
91
+ const packageJsonFile = path.resolve(projectDir, 'package.json');
92
+ (0, utils_1.checkFileContents)(packageJsonFile, [
93
+ `"sentry:sourcemaps": "sentry-cli sourcemaps inject --org ${utils_2.TEST_ARGS.ORG_SLUG} --project ${utils_2.TEST_ARGS.PROJECT_SLUG} ./dist && sentry-cli sourcemaps upload --org ${utils_2.TEST_ARGS.ORG_SLUG} --project ${utils_2.TEST_ARGS.PROJECT_SLUG} ./dist"`,
94
+ `"build": "ng build && yarn sentry:sourcemaps"`,
95
+ ]);
96
+ });
97
+ (0, vitest_1.test)('Sentry is correctly injected into Angular app config', () => {
98
+ const appConfigFile = path.resolve(projectDir, 'src/main.ts');
99
+ (0, utils_1.checkFileExists)(appConfigFile);
100
+ (0, utils_1.checkFileContents)(appConfigFile, [
101
+ `import * as Sentry from '@sentry/angular'`,
102
+ 'Sentry.init({',
103
+ utils_2.TEST_ARGS.PROJECT_DSN,
104
+ 'Sentry.browserTracingIntegration()',
105
+ 'Sentry.replayIntegration()',
106
+ 'tracesSampleRate: 1',
107
+ 'replaysSessionSampleRate: 0.1',
108
+ 'replaysOnErrorSampleRate: 1',
109
+ ]);
110
+ });
111
+ (0, vitest_1.test)('Sentry is correctly injected into Angular app module', () => {
112
+ const appModuleFile = path.resolve(projectDir, 'src/app/app.config.ts');
113
+ (0, utils_1.checkFileExists)(appModuleFile);
114
+ // Checking if the ErrorHandler is already present in the providers array,
115
+ // and if it is, we skip adding it
116
+ if (options?.preExistingErrorHandler) {
117
+ (0, utils_1.checkFileDoesNotContain)(appModuleFile, 'Sentry.createErrorHandler()');
118
+ }
119
+ (0, utils_1.checkFileContents)(appModuleFile, [
120
+ `import * as Sentry from '@sentry/angular'`,
121
+ options?.preExistingErrorHandler
122
+ ? `provide: ErrorHandler,
123
+ useValue: null`
124
+ : `provide: ErrorHandler,
125
+ useValue: Sentry.createErrorHandler()`,
126
+ `provide: Sentry.TraceService,
127
+ deps: [Router]`,
128
+ `provide: APP_INITIALIZER,
129
+ useFactory: () => () => {},
130
+ deps: [Sentry.TraceService],
131
+ multi: true`,
132
+ ]);
133
+ });
134
+ (0, vitest_1.test)('angular.json is updated correctly', async () => {
135
+ const angularJsonFile = path.resolve(projectDir, 'angular.json');
136
+ (0, utils_1.checkFileExists)(angularJsonFile);
137
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
138
+ const angularJson = (await import(angularJsonFile));
139
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
140
+ for (const [, project] of Object.entries(
141
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
142
+ angularJson.projects)) {
143
+ (0, vitest_1.expect)(
144
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
145
+ project?.architect?.build?.configurations?.production?.sourceMap).toBe(true);
146
+ }
147
+ });
148
+ (0, vitest_1.test)('builds successfully', async () => {
149
+ await (0, utils_1.checkIfBuilds)(projectDir);
150
+ });
151
+ (0, vitest_1.test)('runs on prod mode correctly', async () => {
152
+ await (0, utils_1.checkIfRunsOnProdMode)(projectDir, 'Application bundle generation complete.');
153
+ });
154
+ (0, vitest_1.test)('runs on dev mode correctly', async () => {
155
+ await (0, utils_1.checkIfRunsOnDevMode)(projectDir, 'Application bundle generation complete.');
156
+ });
157
+ }
158
+ (0, vitest_1.describe)('Angular-17', () => {
159
+ (0, vitest_1.describe)('with empty project', () => {
160
+ const integration = Constants_1.Integration.angular;
161
+ const projectDir = path.resolve(__dirname, '../test-applications/angular-17-test-app');
162
+ (0, vitest_1.beforeAll)(async () => {
163
+ (0, utils_1.revertLocalChanges)(projectDir);
164
+ await runWizardOnAngularProject(projectDir, integration);
165
+ });
166
+ (0, vitest_1.afterAll)(() => {
167
+ (0, utils_1.revertLocalChanges)(projectDir);
168
+ (0, utils_1.cleanupGit)(projectDir);
169
+ });
170
+ checkAngularProject(projectDir, integration);
171
+ });
172
+ vitest_1.describe.skip('with pre-defined ErrorHandler', () => {
173
+ const integration = Constants_1.Integration.angular;
174
+ const projectDir = path.resolve(__dirname, '../test-applications/angular-17-test-app');
175
+ (0, vitest_1.beforeAll)(async () => {
176
+ (0, utils_1.revertLocalChanges)(projectDir);
177
+ await runWizardOnAngularProject(projectDir, integration, (projectDir) => {
178
+ (0, utils_1.modifyFile)(`${projectDir}/src/app/app.config.ts`, {
179
+ 'providers: [': `providers: [{
180
+ provide: ErrorHandler,
181
+ useValue: null
182
+ },
183
+ `,
184
+ });
185
+ });
186
+ });
187
+ (0, vitest_1.afterAll)(() => {
188
+ (0, utils_1.revertLocalChanges)(projectDir);
189
+ (0, utils_1.cleanupGit)(projectDir);
190
+ });
191
+ checkAngularProject(projectDir, integration, {
192
+ preExistingErrorHandler: true,
193
+ });
194
+ });
195
+ });
196
+ //# sourceMappingURL=angular-17.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"angular-17.test.js","sourceRoot":"","sources":["../../../e2e-tests/tests/angular-17.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { Integration } from '../../lib/Constants';\nimport {\n checkFileContents,\n checkFileDoesNotContain,\n checkFileExists,\n checkIfBuilds,\n checkIfRunsOnDevMode,\n checkIfRunsOnProdMode,\n checkPackageJson,\n cleanupGit,\n KEYS,\n modifyFile,\n revertLocalChanges,\n startWizardInstance,\n} from '../utils';\nimport * as path from 'path';\nimport { TEST_ARGS } from '../utils';\nimport { test, expect, describe, beforeAll, afterAll } from 'vitest';\n\nasync function runWizardOnAngularProject(\n projectDir: string,\n integration: Integration,\n fileModificationFn?: (projectDir: string) => unknown,\n) {\n const wizardInstance = startWizardInstance(integration, projectDir);\n\n if (fileModificationFn) {\n fileModificationFn(projectDir);\n\n await wizardInstance.waitForOutput('Do you want to continue anyway?');\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n 'Please select your package manager.',\n );\n } else {\n await wizardInstance.waitForOutput('Please select your package manager.');\n }\n\n await wizardInstance.sendStdinAndWaitForOutput(\n // Selecting `yarn` as the package manager\n [KEYS.DOWN, 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 timeout: 240_000, // installing the sdk can take a while\n optional: true,\n },\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n // select \"Yes\" for tracing\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 await wizardInstance.sendStdinAndWaitForOutput(\n // select \"Yes\" for replay\n [KEYS.ENTER],\n 'Where are your build artifacts located?',\n {\n timeout: 5000,\n },\n );\n\n const sourcemapsConfiguredPromise = wizardInstance.waitForOutput(\n 'Added a sentry:sourcemaps script to your package.json',\n );\n\n const buildScriptPromptedPromise = wizardInstance.waitForOutput(\n 'Do you want to automatically run the sentry:sourcemaps script after each production build?',\n );\n\n const optionalArtifactsNotFoundPromise = wizardInstance.waitForOutput(\n \"We couldn't find artifacts\",\n {\n optional: true,\n timeout: 5000,\n },\n );\n\n // ./dist is the default value, no need to change it\n wizardInstance.sendStdin(KEYS.ENTER);\n\n const optionalArtifactsNotFoundPrompted =\n await optionalArtifactsNotFoundPromise;\n\n if (optionalArtifactsNotFoundPrompted) {\n wizardInstance.sendStdin(KEYS.DOWN);\n wizardInstance.sendStdin(KEYS.ENTER);\n }\n\n await sourcemapsConfiguredPromise;\n\n await buildScriptPromptedPromise;\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, automatically add sentry:sourcemaps script\n 'Is yarn build your production build command?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, yarn build is the production build command\n 'Are you using a CI/CD tool to build and deploy your application?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.DOWN, KEYS.ENTER], // no CI/CD tool\n 'Do you want to create an example component to test your Sentry setup?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, create example component\n 'Did you apply the snippet above?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, applied the snippet\n 'Looks like you have Prettier in your project. Do you want to run it on your files?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, run prettier\n 'Successfully installed the Sentry Angular SDK!',\n );\n\n wizardInstance.kill();\n}\n\nfunction checkAngularProject(\n projectDir: string,\n integration: Integration,\n options?: {\n preExistingErrorHandler?: boolean;\n },\n) {\n test('package.json is updated correctly', () => {\n checkPackageJson(projectDir, integration);\n\n const packageJsonFile = path.resolve(projectDir, 'package.json');\n checkFileContents(packageJsonFile, [\n `\"sentry:sourcemaps\": \"sentry-cli sourcemaps inject --org ${TEST_ARGS.ORG_SLUG} --project ${TEST_ARGS.PROJECT_SLUG} ./dist && sentry-cli sourcemaps upload --org ${TEST_ARGS.ORG_SLUG} --project ${TEST_ARGS.PROJECT_SLUG} ./dist\"`,\n `\"build\": \"ng build && yarn sentry:sourcemaps\"`,\n ]);\n });\n\n test('Sentry is correctly injected into Angular app config', () => {\n const appConfigFile = path.resolve(projectDir, 'src/main.ts');\n checkFileExists(appConfigFile);\n\n checkFileContents(appConfigFile, [\n `import * as Sentry from '@sentry/angular'`,\n 'Sentry.init({',\n TEST_ARGS.PROJECT_DSN,\n 'Sentry.browserTracingIntegration()',\n 'Sentry.replayIntegration()',\n 'tracesSampleRate: 1',\n 'replaysSessionSampleRate: 0.1',\n 'replaysOnErrorSampleRate: 1',\n ]);\n });\n\n test('Sentry is correctly injected into Angular app module', () => {\n const appModuleFile = path.resolve(projectDir, 'src/app/app.config.ts');\n checkFileExists(appModuleFile);\n\n // Checking if the ErrorHandler is already present in the providers array,\n // and if it is, we skip adding it\n if (options?.preExistingErrorHandler) {\n checkFileDoesNotContain(appModuleFile, 'Sentry.createErrorHandler()');\n }\n\n checkFileContents(appModuleFile, [\n `import * as Sentry from '@sentry/angular'`,\n options?.preExistingErrorHandler\n ? `provide: ErrorHandler,\n useValue: null`\n : `provide: ErrorHandler,\n useValue: Sentry.createErrorHandler()`,\n `provide: Sentry.TraceService,\n deps: [Router]`,\n `provide: APP_INITIALIZER,\n useFactory: () => () => {},\n deps: [Sentry.TraceService],\n multi: true`,\n ]);\n });\n\n test('angular.json is updated correctly', async () => {\n const angularJsonFile = path.resolve(projectDir, 'angular.json');\n checkFileExists(angularJsonFile);\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const angularJson = (await import(angularJsonFile)) as Record<string, any>;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n for (const [, project] of Object.entries(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n angularJson.projects as Record<string, any>,\n )) {\n expect(\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n project?.architect?.build?.configurations?.production?.sourceMap,\n ).toBe(true);\n }\n });\n\n test('builds successfully', async () => {\n await checkIfBuilds(projectDir);\n });\n\n test('runs on prod mode correctly', async () => {\n await checkIfRunsOnProdMode(\n projectDir,\n 'Application bundle generation complete.',\n );\n });\n\n test('runs on dev mode correctly', async () => {\n await checkIfRunsOnDevMode(\n projectDir,\n 'Application bundle generation complete.',\n );\n });\n}\n\ndescribe('Angular-17', () => {\n describe('with empty project', () => {\n const integration = Integration.angular;\n const projectDir = path.resolve(\n __dirname,\n '../test-applications/angular-17-test-app',\n );\n\n beforeAll(async () => {\n revertLocalChanges(projectDir);\n await runWizardOnAngularProject(projectDir, integration);\n });\n\n afterAll(() => {\n revertLocalChanges(projectDir);\n cleanupGit(projectDir);\n });\n\n checkAngularProject(projectDir, integration);\n });\n\n describe.skip('with pre-defined ErrorHandler', () => {\n const integration = Integration.angular;\n const projectDir = path.resolve(\n __dirname,\n '../test-applications/angular-17-test-app',\n );\n\n beforeAll(async () => {\n revertLocalChanges(projectDir);\n await runWizardOnAngularProject(projectDir, integration, (projectDir) => {\n modifyFile(`${projectDir}/src/app/app.config.ts`, {\n 'providers: [': `providers: [{\n provide: ErrorHandler,\n useValue: null\n },\n `,\n });\n });\n });\n\n afterAll(() => {\n revertLocalChanges(projectDir);\n cleanupGit(projectDir);\n });\n\n checkAngularProject(projectDir, integration, {\n preExistingErrorHandler: true,\n });\n });\n});\n"]}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,194 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ const Constants_1 = require("../../lib/Constants");
27
+ const utils_1 = require("../utils");
28
+ const path = __importStar(require("path"));
29
+ const utils_2 = require("../utils");
30
+ const vitest_1 = require("vitest");
31
+ async function runWizardOnAngularProject(projectDir, integration, fileModificationFn) {
32
+ const wizardInstance = (0, utils_1.startWizardInstance)(integration, projectDir);
33
+ if (fileModificationFn) {
34
+ fileModificationFn(projectDir);
35
+ await wizardInstance.waitForOutput('Do you want to continue anyway?');
36
+ await wizardInstance.sendStdinAndWaitForOutput([utils_1.KEYS.ENTER], 'Please select your package manager.');
37
+ }
38
+ else {
39
+ await wizardInstance.waitForOutput('Please select your package manager.');
40
+ }
41
+ await wizardInstance.sendStdinAndWaitForOutput(
42
+ // Selecting `yarn` as the package manager
43
+ [utils_1.KEYS.DOWN, utils_1.KEYS.ENTER],
44
+ // "Do you want to enable Tracing", sometimes doesn't work as `Tracing` can be printed in bold.
45
+ 'to track the performance of your application?', {
46
+ timeout: 240000,
47
+ optional: true,
48
+ });
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
+ await wizardInstance.sendStdinAndWaitForOutput(
53
+ // The first choice here is Angular
54
+ [utils_1.KEYS.ENTER], 'Where are your build artifacts located?', {
55
+ optional: true,
56
+ timeout: 5000,
57
+ });
58
+ const sourcemapsConfiguredPromise = wizardInstance.waitForOutput('Added a sentry:sourcemaps script to your package.json');
59
+ const buildScriptPromptedPromise = wizardInstance.waitForOutput('Do you want to automatically run the sentry:sourcemaps script after each production build?');
60
+ const optionalArtifactsNotFoundPromise = wizardInstance.waitForOutput("We couldn't find artifacts", {
61
+ optional: true,
62
+ timeout: 5000,
63
+ });
64
+ // ./dist is the default value, no need to change it
65
+ wizardInstance.sendStdin(utils_1.KEYS.ENTER);
66
+ const optionalArtifactsNotFoundPrompted = await optionalArtifactsNotFoundPromise;
67
+ if (optionalArtifactsNotFoundPrompted) {
68
+ wizardInstance.sendStdin(utils_1.KEYS.DOWN);
69
+ wizardInstance.sendStdin(utils_1.KEYS.ENTER);
70
+ }
71
+ await sourcemapsConfiguredPromise;
72
+ await buildScriptPromptedPromise;
73
+ await wizardInstance.sendStdinAndWaitForOutput([utils_1.KEYS.ENTER], // yes, automatically add sentry:sourcemaps script
74
+ 'Is yarn build your production build command?');
75
+ await wizardInstance.sendStdinAndWaitForOutput([utils_1.KEYS.ENTER], // yes, yarn build is the production build command
76
+ 'Are you using a CI/CD tool to build and deploy your application?');
77
+ await wizardInstance.sendStdinAndWaitForOutput([utils_1.KEYS.DOWN, utils_1.KEYS.ENTER], // no CI/CD tool
78
+ 'Do you want to create an example component to test your Sentry setup?');
79
+ await wizardInstance.sendStdinAndWaitForOutput([utils_1.KEYS.ENTER], // yes, create example component
80
+ 'Did you apply the snippet above?');
81
+ await wizardInstance.sendStdinAndWaitForOutput([utils_1.KEYS.ENTER], // yes, applied the snippet
82
+ 'Looks like you have Prettier in your project. Do you want to run it on your files?');
83
+ await wizardInstance.sendStdinAndWaitForOutput([utils_1.KEYS.ENTER], // yes, run prettier
84
+ 'Successfully installed the Sentry Angular SDK!');
85
+ wizardInstance.kill();
86
+ }
87
+ function checkAngularProject(projectDir, integration, options) {
88
+ (0, vitest_1.test)('package.json is updated correctly', () => {
89
+ (0, utils_1.checkPackageJson)(projectDir, integration);
90
+ const packageJsonFile = path.resolve(projectDir, 'package.json');
91
+ (0, utils_1.checkFileContents)(packageJsonFile, [
92
+ `"sentry:sourcemaps": "sentry-cli sourcemaps inject --org ${utils_2.TEST_ARGS.ORG_SLUG} --project ${utils_2.TEST_ARGS.PROJECT_SLUG} ./dist && sentry-cli sourcemaps upload --org ${utils_2.TEST_ARGS.ORG_SLUG} --project ${utils_2.TEST_ARGS.PROJECT_SLUG} ./dist"`,
93
+ `"build": "ng build && yarn sentry:sourcemaps"`,
94
+ ]);
95
+ });
96
+ (0, vitest_1.test)('Sentry is correctly injected into Angular app config', () => {
97
+ const appConfigFile = path.resolve(projectDir, 'src/main.ts');
98
+ (0, utils_1.checkFileExists)(appConfigFile);
99
+ (0, utils_1.checkFileContents)(appConfigFile, [
100
+ `import * as Sentry from '@sentry/angular'`,
101
+ 'Sentry.init({',
102
+ utils_2.TEST_ARGS.PROJECT_DSN,
103
+ 'Sentry.browserTracingIntegration()',
104
+ 'Sentry.replayIntegration()',
105
+ 'tracesSampleRate: 1',
106
+ 'replaysSessionSampleRate: 0.1',
107
+ 'replaysOnErrorSampleRate: 1',
108
+ ]);
109
+ });
110
+ (0, vitest_1.test)('Sentry is correctly injected into Angular app module', () => {
111
+ const appModuleFile = path.resolve(projectDir, 'src/app/app.config.ts');
112
+ (0, utils_1.checkFileExists)(appModuleFile);
113
+ // Checking if the ErrorHandler is already present in the providers array,
114
+ // and if it is, we skip adding it
115
+ if (options?.preExistingErrorHandler) {
116
+ (0, utils_1.checkFileDoesNotContain)(appModuleFile, 'Sentry.createErrorHandler()');
117
+ }
118
+ (0, utils_1.checkFileContents)(appModuleFile, [
119
+ `import * as Sentry from '@sentry/angular'`,
120
+ options?.preExistingErrorHandler
121
+ ? `provide: ErrorHandler,
122
+ useValue: null`
123
+ : `provide: ErrorHandler,
124
+ useValue: Sentry.createErrorHandler()`,
125
+ `provide: Sentry.TraceService,
126
+ deps: [Router]`,
127
+ `provideAppInitializer(() => {
128
+ inject(Sentry.TraceService);
129
+ })`,
130
+ ]);
131
+ });
132
+ (0, vitest_1.test)('angular.json is updated correctly', async () => {
133
+ const angularJsonFile = path.resolve(projectDir, 'angular.json');
134
+ (0, utils_1.checkFileExists)(angularJsonFile);
135
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
136
+ const angularJson = (await import(angularJsonFile));
137
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
138
+ for (const [, project] of Object.entries(
139
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
140
+ angularJson.projects)) {
141
+ (0, vitest_1.expect)(
142
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
143
+ project?.architect?.build?.configurations?.production?.sourceMap).toBe(true);
144
+ }
145
+ });
146
+ (0, vitest_1.test)('builds successfully', async () => {
147
+ await (0, utils_1.checkIfBuilds)(projectDir);
148
+ });
149
+ (0, vitest_1.test)('runs on prod mode correctly', async () => {
150
+ await (0, utils_1.checkIfRunsOnProdMode)(projectDir, 'Application bundle generation complete.');
151
+ });
152
+ (0, vitest_1.test)('runs on dev mode correctly', async () => {
153
+ await (0, utils_1.checkIfRunsOnDevMode)(projectDir, 'Application bundle generation complete.');
154
+ });
155
+ }
156
+ (0, vitest_1.describe)('Angular-19', () => {
157
+ (0, vitest_1.describe)('with empty project', () => {
158
+ const integration = Constants_1.Integration.angular;
159
+ const projectDir = path.resolve(__dirname, '../test-applications/angular-19-test-app');
160
+ (0, vitest_1.beforeAll)(async () => {
161
+ (0, utils_1.revertLocalChanges)(projectDir);
162
+ await runWizardOnAngularProject(projectDir, integration);
163
+ });
164
+ (0, vitest_1.afterAll)(() => {
165
+ (0, utils_1.revertLocalChanges)(projectDir);
166
+ (0, utils_1.cleanupGit)(projectDir);
167
+ });
168
+ checkAngularProject(projectDir, integration);
169
+ });
170
+ (0, vitest_1.describe)('with pre-defined ErrorHandler', () => {
171
+ const integration = Constants_1.Integration.angular;
172
+ const projectDir = path.resolve(__dirname, '../test-applications/angular-19-test-app');
173
+ (0, vitest_1.beforeAll)(async () => {
174
+ (0, utils_1.revertLocalChanges)(projectDir);
175
+ await runWizardOnAngularProject(projectDir, integration, (projectDir) => {
176
+ (0, utils_1.modifyFile)(`${projectDir}/src/app/app.config.ts`, {
177
+ 'providers: [': `providers: [{
178
+ provide: ErrorHandler,
179
+ useValue: null
180
+ },
181
+ `,
182
+ });
183
+ });
184
+ });
185
+ (0, vitest_1.afterAll)(() => {
186
+ (0, utils_1.revertLocalChanges)(projectDir);
187
+ (0, utils_1.cleanupGit)(projectDir);
188
+ });
189
+ checkAngularProject(projectDir, integration, {
190
+ preExistingErrorHandler: true,
191
+ });
192
+ });
193
+ });
194
+ //# sourceMappingURL=angular-19.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"angular-19.test.js","sourceRoot":"","sources":["../../../e2e-tests/tests/angular-19.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { Integration } from '../../lib/Constants';\nimport {\n checkFileContents,\n checkFileDoesNotContain,\n checkFileExists,\n checkIfBuilds,\n checkIfRunsOnDevMode,\n checkIfRunsOnProdMode,\n checkPackageJson,\n cleanupGit,\n KEYS,\n modifyFile,\n revertLocalChanges,\n startWizardInstance,\n} from '../utils';\nimport * as path from 'path';\nimport { TEST_ARGS } from '../utils';\nimport { test, expect, describe, beforeAll, afterAll } from 'vitest';\n\nasync function runWizardOnAngularProject(\n projectDir: string,\n integration: Integration,\n fileModificationFn?: (projectDir: string) => unknown,\n) {\n const wizardInstance = startWizardInstance(integration, projectDir);\n\n if (fileModificationFn) {\n fileModificationFn(projectDir);\n\n await wizardInstance.waitForOutput('Do you want to continue anyway?');\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n 'Please select your package manager.',\n );\n } else {\n await wizardInstance.waitForOutput('Please select your package manager.');\n }\n\n await wizardInstance.sendStdinAndWaitForOutput(\n // Selecting `yarn` as the package manager\n [KEYS.DOWN, 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 timeout: 240_000,\n optional: true,\n },\n );\n\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 await wizardInstance.sendStdinAndWaitForOutput(\n // The first choice here is Angular\n [KEYS.ENTER],\n 'Where are your build artifacts located?',\n {\n optional: true,\n timeout: 5000,\n },\n );\n\n const sourcemapsConfiguredPromise = wizardInstance.waitForOutput(\n 'Added a sentry:sourcemaps script to your package.json',\n );\n\n const buildScriptPromptedPromise = wizardInstance.waitForOutput(\n 'Do you want to automatically run the sentry:sourcemaps script after each production build?',\n );\n\n const optionalArtifactsNotFoundPromise = wizardInstance.waitForOutput(\n \"We couldn't find artifacts\",\n {\n optional: true,\n timeout: 5000,\n },\n );\n\n // ./dist is the default value, no need to change it\n wizardInstance.sendStdin(KEYS.ENTER);\n\n const optionalArtifactsNotFoundPrompted =\n await optionalArtifactsNotFoundPromise;\n\n if (optionalArtifactsNotFoundPrompted) {\n wizardInstance.sendStdin(KEYS.DOWN);\n wizardInstance.sendStdin(KEYS.ENTER);\n }\n\n await sourcemapsConfiguredPromise;\n await buildScriptPromptedPromise;\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, automatically add sentry:sourcemaps script\n 'Is yarn build your production build command?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, yarn build is the production build command\n 'Are you using a CI/CD tool to build and deploy your application?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.DOWN, KEYS.ENTER], // no CI/CD tool\n 'Do you want to create an example component to test your Sentry setup?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, create example component\n 'Did you apply the snippet above?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, applied the snippet\n 'Looks like you have Prettier in your project. Do you want to run it on your files?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, run prettier\n 'Successfully installed the Sentry Angular SDK!',\n );\n\n wizardInstance.kill();\n}\n\nfunction checkAngularProject(\n projectDir: string,\n integration: Integration,\n options?: {\n preExistingErrorHandler?: boolean;\n },\n) {\n test('package.json is updated correctly', () => {\n checkPackageJson(projectDir, integration);\n\n const packageJsonFile = path.resolve(projectDir, 'package.json');\n checkFileContents(packageJsonFile, [\n `\"sentry:sourcemaps\": \"sentry-cli sourcemaps inject --org ${TEST_ARGS.ORG_SLUG} --project ${TEST_ARGS.PROJECT_SLUG} ./dist && sentry-cli sourcemaps upload --org ${TEST_ARGS.ORG_SLUG} --project ${TEST_ARGS.PROJECT_SLUG} ./dist\"`,\n `\"build\": \"ng build && yarn sentry:sourcemaps\"`,\n ]);\n });\n\n test('Sentry is correctly injected into Angular app config', () => {\n const appConfigFile = path.resolve(projectDir, 'src/main.ts');\n checkFileExists(appConfigFile);\n\n checkFileContents(appConfigFile, [\n `import * as Sentry from '@sentry/angular'`,\n 'Sentry.init({',\n TEST_ARGS.PROJECT_DSN,\n 'Sentry.browserTracingIntegration()',\n 'Sentry.replayIntegration()',\n 'tracesSampleRate: 1',\n 'replaysSessionSampleRate: 0.1',\n 'replaysOnErrorSampleRate: 1',\n ]);\n });\n\n test('Sentry is correctly injected into Angular app module', () => {\n const appModuleFile = path.resolve(projectDir, 'src/app/app.config.ts');\n checkFileExists(appModuleFile);\n\n // Checking if the ErrorHandler is already present in the providers array,\n // and if it is, we skip adding it\n if (options?.preExistingErrorHandler) {\n checkFileDoesNotContain(appModuleFile, 'Sentry.createErrorHandler()');\n }\n\n checkFileContents(appModuleFile, [\n `import * as Sentry from '@sentry/angular'`,\n options?.preExistingErrorHandler\n ? `provide: ErrorHandler,\n useValue: null`\n : `provide: ErrorHandler,\n useValue: Sentry.createErrorHandler()`,\n `provide: Sentry.TraceService,\n deps: [Router]`,\n `provideAppInitializer(() => {\n inject(Sentry.TraceService);\n })`,\n ]);\n });\n\n test('angular.json is updated correctly', async () => {\n const angularJsonFile = path.resolve(projectDir, 'angular.json');\n checkFileExists(angularJsonFile);\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const angularJson = (await import(angularJsonFile)) as Record<string, any>;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n for (const [, project] of Object.entries(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n angularJson.projects as Record<string, any>,\n )) {\n expect(\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n project?.architect?.build?.configurations?.production?.sourceMap,\n ).toBe(true);\n }\n });\n\n test('builds successfully', async () => {\n await checkIfBuilds(projectDir);\n });\n\n test('runs on prod mode correctly', async () => {\n await checkIfRunsOnProdMode(\n projectDir,\n 'Application bundle generation complete.',\n );\n });\n\n test('runs on dev mode correctly', async () => {\n await checkIfRunsOnDevMode(\n projectDir,\n 'Application bundle generation complete.',\n );\n });\n}\n\ndescribe('Angular-19', () => {\n describe('with empty project', () => {\n const integration = Integration.angular;\n const projectDir = path.resolve(\n __dirname,\n '../test-applications/angular-19-test-app',\n );\n\n beforeAll(async () => {\n revertLocalChanges(projectDir);\n await runWizardOnAngularProject(projectDir, integration);\n });\n\n afterAll(() => {\n revertLocalChanges(projectDir);\n cleanupGit(projectDir);\n });\n\n checkAngularProject(projectDir, integration);\n });\n describe('with pre-defined ErrorHandler', () => {\n const integration = Integration.angular;\n const projectDir = path.resolve(\n __dirname,\n '../test-applications/angular-19-test-app',\n );\n\n beforeAll(async () => {\n revertLocalChanges(projectDir);\n await runWizardOnAngularProject(projectDir, integration, (projectDir) => {\n modifyFile(`${projectDir}/src/app/app.config.ts`, {\n 'providers: [': `providers: [{\n provide: ErrorHandler,\n useValue: null\n },\n `,\n });\n });\n });\n\n afterAll(() => {\n revertLocalChanges(projectDir);\n cleanupGit(projectDir);\n });\n\n checkAngularProject(projectDir, integration, {\n preExistingErrorHandler: true,\n });\n });\n});\n"]}
@@ -0,0 +1 @@
1
+ export {};