UNPKG

@sentry/wizard

Version:

Sentry wizard helping you to configure your project

206 lines 10.5 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); const Constants_1 = require("../../lib/Constants"); const utils_1 = require("../utils"); const path = __importStar(require("path")); const utils_2 = require("../utils"); const vitest_1 = require("vitest"); vitest_1.describe.sequential('Angular-19', () => { (0, vitest_1.describe)('with empty project', () => { const integration = Constants_1.Integration.angular; const projectDir = path.resolve(__dirname, '../test-applications/angular-19-test-app'); (0, vitest_1.beforeAll)(async () => { (0, utils_1.revertLocalChanges)(projectDir); await runWizardOnAngularProject(projectDir, integration); }); (0, vitest_1.afterAll)(() => { (0, utils_1.revertLocalChanges)(projectDir); (0, utils_1.cleanupGit)(projectDir); }); checkAngularProject(projectDir, integration); }); (0, vitest_1.describe)('with pre-defined ErrorHandler', () => { const integration = Constants_1.Integration.angular; const projectDir = path.resolve(__dirname, '../test-applications/angular-19-test-app'); (0, vitest_1.beforeAll)(async () => { (0, utils_1.revertLocalChanges)(projectDir); await runWizardOnAngularProject(projectDir, integration, (projectDir) => { (0, utils_1.modifyFile)(`${projectDir}/src/app/app.config.ts`, { 'providers: [': `providers: [{ provide: ErrorHandler, useValue: null }, `, }); }); }); (0, vitest_1.afterAll)(() => { (0, utils_1.revertLocalChanges)(projectDir); (0, utils_1.cleanupGit)(projectDir); }); checkAngularProject(projectDir, integration, { preExistingErrorHandler: true, }); }); }); async function runWizardOnAngularProject(projectDir, integration, fileModificationFn) { const wizardInstance = (0, utils_1.startWizardInstance)(integration, projectDir, true); if (fileModificationFn) { fileModificationFn(projectDir); await wizardInstance.waitForOutput('Do you want to continue anyway?'); await wizardInstance.sendStdinAndWaitForOutput([utils_1.KEYS.ENTER], 'Please select your package manager.'); } else { await wizardInstance.waitForOutput('Please select your package manager.'); } await wizardInstance.sendStdinAndWaitForOutput( // Selecting `yarn` as the package manager [utils_1.KEYS.DOWN, utils_1.KEYS.ENTER], // "Do you want to enable Tracing", sometimes doesn't work as `Tracing` can be printed in bold. 'to track the performance of your application?', { timeout: 240000, optional: true, }); await wizardInstance.sendStdinAndWaitForOutput([utils_1.KEYS.ENTER], // "Do you want to enable Sentry Session Replay", sometimes doesn't work as `Sentry Session Replay` can be printed in bold. 'to get a video-like reproduction of errors during a user session?'); await wizardInstance.sendStdinAndWaitForOutput( // select "Yes" for replay [utils_1.KEYS.ENTER], // "Do you want to enable Logs", sometimes doesn't work as `Logs` can be printed in bold. 'to send your application logs to Sentry?'); await wizardInstance.sendStdinAndWaitForOutput( // select "Yes" for logs [utils_1.KEYS.ENTER], 'Where are your build artifacts located?', { optional: true, timeout: 5000, }); const sourcemapsConfiguredPromise = wizardInstance.waitForOutput('Added a sentry:sourcemaps script to your package.json'); const buildScriptPromptedPromise = wizardInstance.waitForOutput('Do you want to automatically run the sentry:sourcemaps script after each production build?'); const optionalArtifactsNotFoundPromise = wizardInstance.waitForOutput("We couldn't find build artifacts at", { optional: true, timeout: 5000, }); // ./dist is the default value, no need to change it wizardInstance.sendStdin(utils_1.KEYS.ENTER); const optionalArtifactsNotFoundPrompted = await optionalArtifactsNotFoundPromise; if (optionalArtifactsNotFoundPrompted) { // The wizard now presents options when artifacts aren't found: // - "Let the wizard run the build command" // - "Enter a different path manually" // - "Proceed anyway — I believe the path is correct" // We want to select "Proceed anyway" (third option) wizardInstance.sendStdin(utils_1.KEYS.DOWN); wizardInstance.sendStdin(utils_1.KEYS.DOWN); wizardInstance.sendStdin(utils_1.KEYS.ENTER); } await sourcemapsConfiguredPromise; await buildScriptPromptedPromise; await wizardInstance.sendStdinAndWaitForOutput([utils_1.KEYS.ENTER], // yes, automatically add sentry:sourcemaps script 'Is yarn build your production build command?'); await wizardInstance.sendStdinAndWaitForOutput([utils_1.KEYS.ENTER], // yes, yarn build is the production build command 'Are you using a CI/CD tool to build and deploy your application?'); await wizardInstance.sendStdinAndWaitForOutput([utils_1.KEYS.DOWN, utils_1.KEYS.ENTER], // no CI/CD tool 'Do you want to create an example component to test your Sentry setup?'); await wizardInstance.sendStdinAndWaitForOutput([utils_1.KEYS.ENTER], // yes, create example component 'Did you apply the snippet above?'); await wizardInstance.sendStdinAndWaitForOutput([utils_1.KEYS.ENTER], // yes, applied the snippet 'Looks like you have Prettier in your project. Do you want to run it on your files?'); await wizardInstance.sendStdinAndWaitForOutput([utils_1.KEYS.ENTER], // yes, run prettier 'Successfully installed the Sentry Angular SDK!'); wizardInstance.kill(); } function checkAngularProject(projectDir, integration, options) { (0, vitest_1.test)('package.json is updated correctly', () => { (0, utils_1.checkPackageJson)(projectDir, integration); const packageJsonFile = path.resolve(projectDir, 'package.json'); (0, utils_1.checkFileContents)(packageJsonFile, [ `"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"`, `"build": "ng build && yarn sentry:sourcemaps"`, ]); }); (0, vitest_1.test)('Sentry is correctly injected into Angular app config', () => { const appConfigFile = path.resolve(projectDir, 'src/main.ts'); (0, utils_1.checkFileExists)(appConfigFile); (0, utils_1.checkFileContents)(appConfigFile, [ `import * as Sentry from '@sentry/angular'`, 'Sentry.init({', utils_2.TEST_ARGS.PROJECT_DSN, 'Sentry.browserTracingIntegration()', 'Sentry.replayIntegration()', 'tracesSampleRate: 1', 'replaysSessionSampleRate: 0.1', 'replaysOnErrorSampleRate: 1', 'enableLogs: true', ]); }); (0, vitest_1.test)('Sentry is correctly injected into Angular app module', () => { const appModuleFile = path.resolve(projectDir, 'src/app/app.config.ts'); (0, utils_1.checkFileExists)(appModuleFile); // Checking if the ErrorHandler is already present in the providers array, // and if it is, we skip adding it if (options?.preExistingErrorHandler) { (0, utils_1.checkFileDoesNotContain)(appModuleFile, 'Sentry.createErrorHandler()'); } (0, utils_1.checkFileContents)(appModuleFile, [ `import * as Sentry from '@sentry/angular'`, options?.preExistingErrorHandler ? `provide: ErrorHandler, useValue: null` : `provide: ErrorHandler, useValue: Sentry.createErrorHandler()`, `provide: Sentry.TraceService, deps: [Router]`, `provideAppInitializer(() => { inject(Sentry.TraceService); })`, ]); }); (0, vitest_1.test)('angular.json is updated correctly', async () => { const angularJsonFile = path.resolve(projectDir, 'angular.json'); (0, utils_1.checkFileExists)(angularJsonFile); // eslint-disable-next-line @typescript-eslint/no-explicit-any const angularJson = (await import(angularJsonFile)); // eslint-disable-next-line @typescript-eslint/no-explicit-any for (const [, project] of Object.entries( // eslint-disable-next-line @typescript-eslint/no-explicit-any angularJson.projects)) { (0, vitest_1.expect)( // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access project?.architect?.build?.configurations?.production?.sourceMap).toBe(true); } }); (0, vitest_1.test)('builds successfully', async () => { await (0, utils_1.checkIfBuilds)(projectDir); }); (0, vitest_1.test)('runs on prod mode correctly', async () => { await (0, utils_1.checkIfRunsOnProdMode)(projectDir, 'Application bundle generation complete.'); }); (0, vitest_1.test)('runs on dev mode correctly', async () => { await (0, utils_1.checkIfRunsOnDevMode)(projectDir, 'Application bundle generation complete.'); }); } //# sourceMappingURL=angular-19.test.js.map