diff --git a/static/app/gettingStartedDocs/javascript-vue/onboarding.spec.tsx b/static/app/gettingStartedDocs/javascript-vue/onboarding.spec.tsx index 902ea118ce14..c18255adbc9f 100644 --- a/static/app/gettingStartedDocs/javascript-vue/onboarding.spec.tsx +++ b/static/app/gettingStartedDocs/javascript-vue/onboarding.spec.tsx @@ -4,6 +4,7 @@ import {textWithMarkupMatcher} from 'sentry-test/utils'; import {ProductSolution} from 'sentry/components/onboarding/gettingStartedDoc/types'; +import {VueVersion} from './utils'; import {docs} from '.'; describe('javascript-vue onboarding docs', () => { @@ -24,6 +25,80 @@ describe('javascript-vue onboarding docs', () => { ).toBeInTheDocument(); }); + it('initializes Vue 3 with the root component and existing router', () => { + renderWithOnboardingLayout(docs); + + const setup = screen.getByText(textWithMarkupMatcher(/Sentry\.init\(/)); + expect(setup).toHaveTextContent('import App from "./App.vue"'); + expect(setup).toHaveTextContent('import router from "./router"'); + expect(setup).toHaveTextContent('const app = createApp(App)'); + expect(setup).toHaveTextContent('app.use(router)'); + expect(setup).not.toHaveTextContent('createRouter'); + }); + + it('keeps Vue 2 setup with its constructor and root component', () => { + renderWithOnboardingLayout(docs, { + selectedOptions: {siblingOption: VueVersion.VUE2}, + }); + + const setup = screen.getByText(textWithMarkupMatcher(/Sentry\.init\(/)); + expect(setup).toHaveTextContent('import Vue from "vue"'); + expect(setup).toHaveTextContent('import App from "./App.vue"'); + expect(setup).toHaveTextContent('Vue.use(Router)'); + expect(setup).toHaveTextContent(/Sentry\.init\(\{\s*Vue,/); + expect(setup).toHaveTextContent('render: (h) => h(App)'); + }); + + it.each([ + {products: [ProductSolution.LOGS]}, + {products: [ProductSolution.METRICS]}, + {products: [ProductSolution.LOGS, ProductSolution.METRICS]}, + ])('verifies selected signals: $products', ({products}) => { + renderWithOnboardingLayout(docs, { + selectedProducts: [ProductSolution.ERROR_MONITORING, ...products], + }); + + const verify = screen.getByText(textWithMarkupMatcher(/throw new Error/)); + expect(verify).toHaveTextContent('import * as Sentry from "@sentry/vue"'); + expect(verify.textContent?.includes('Sentry.logger.info')).toBe( + products.includes(ProductSolution.LOGS) + ); + expect(verify.textContent?.includes('Sentry.metrics.count')).toBe( + products.includes(ProductSolution.METRICS) + ); + + const setup = screen.getByText(textWithMarkupMatcher(/Sentry\.init\(/)); + expect(setup).toHaveTextContent('dataCollection:'); + expect(setup).not.toHaveTextContent(/sendDefaultPii|enableLogs|enableMetrics/); + }); + + it.each([VueVersion.VUE2, VueVersion.VUE3])( + 'shows a clickable verification component for %s', + siblingOption => { + renderWithOnboardingLayout(docs, { + selectedOptions: {siblingOption}, + selectedProducts: [ProductSolution.ERROR_MONITORING], + }); + + const verify = screen.getByText(textWithMarkupMatcher(/throw new Error/)); + expect(verify).toHaveTextContent(' + +`; }; export const onboarding: OnboardingConfig = { @@ -68,16 +93,18 @@ export const onboarding: OnboardingConfig = { content: [ { type: 'text', - text: t( - "This snippet contains an intentional error and can be used as a test to make sure that everything's working as expected." + text: tct( + 'Add this button to a Vue component, such as [code:App.vue], then click "Break the world" to send a test error to Sentry. If you selected Logs or Metrics, clicking the button sends those too.', + {code: } ), }, { type: 'code', tabs: [ { - label: 'JavaScript', - language: 'javascript', + label: 'Vue', + language: 'html', + filename: 'App.vue', code: getVerifySnippet(params), }, ], diff --git a/static/app/gettingStartedDocs/javascript-vue/utils.tsx b/static/app/gettingStartedDocs/javascript-vue/utils.tsx index 8713d25637f2..bcf185c8c8e4 100644 --- a/static/app/gettingStartedDocs/javascript-vue/utils.tsx +++ b/static/app/gettingStartedDocs/javascript-vue/utils.tsx @@ -67,7 +67,7 @@ const getDynamicParts = (params: Params): string[] => { if (params.isPerformanceSelected) { dynamicParts.push(` // Tracing - tracesSampleRate: 1.0, // Capture 100% of the transactions + tracesSampleRate: 1.0, // Capture 100% of the traces // Set 'tracePropagationTargets' to control for which URLs distributed tracing should be enabled tracePropagationTargets: ["localhost", /^https:\\/\\/yourserver\\.io\\/api/]`); } @@ -92,13 +92,14 @@ function getSiblingImportsSetupConfiguration(siblingOption: string): string { switch (siblingOption) { case VueVersion.VUE3: return `import {createApp} from "vue"; - import {createRouter} from "vue-router"; + import App from "./App.vue"; import router from "./router"; `; case VueVersion.VUE2: default: return `import Vue from "vue"; - import Router from "vue-router";`; + import Router from "vue-router"; + import App from "./App.vue";`; } } @@ -120,9 +121,7 @@ function getVueConstSetup(siblingOption: string): string { switch (siblingOption) { case VueVersion.VUE3: return ` - const app = createApp({ - // ... - }); + const app = createApp(App); `; case VueVersion.VUE2: return `