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 `