diff --git a/static/app/views/prevent/preventAI/onboarding.spec.tsx b/static/app/views/prevent/preventAI/onboarding.spec.tsx
index af54154a84b7d8..0ef6c8389b8438 100644
--- a/static/app/views/prevent/preventAI/onboarding.spec.tsx
+++ b/static/app/views/prevent/preventAI/onboarding.spec.tsx
@@ -1,11 +1,12 @@
import {ThemeProvider, type Theme} from '@emotion/react';
import {OrganizationFixture} from 'sentry-fixture/organization';
-import {render, screen} from 'sentry-test/reactTestingLibrary';
+import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
import {textWithMarkupMatcher} from 'sentry-test/utils';
import ConfigStore from 'sentry/stores/configStore';
import type {Config} from 'sentry/types/system';
+import {trackAnalytics} from 'sentry/utils/analytics';
import PreventAIOnboarding from './onboarding';
@@ -20,6 +21,7 @@ jest.mock(
() => 'prevent-pr-comments-dark-mock.svg',
{virtual: true}
);
+jest.mock('sentry/utils/analytics');
describe('PreventAIOnboarding', () => {
const organization = OrganizationFixture({
@@ -81,11 +83,16 @@ describe('PreventAIOnboarding', () => {
expect(screen.getByRole('heading', {name: 'Setup Seer'})).toBeInTheDocument();
});
- it('renders external links with correct hrefs', () => {
+ it('renders external links with correct hrefs', async () => {
render(, {organization});
const orgSettingsLink = screen.getByRole('link', {name: 'organization settings'});
expect(orgSettingsLink).toHaveAttribute('href', '/settings/test-org/#hideAiFeatures');
+ await userEvent.click(orgSettingsLink);
+ expect(trackAnalytics).toHaveBeenCalledWith(
+ 'prevent.ai_onboarding.settings_link.clicked',
+ {organization}
+ );
const sentryGitHubAppLink = screen.getByRole('link', {
name: 'Sentry GitHub App',
@@ -94,6 +101,11 @@ describe('PreventAIOnboarding', () => {
'href',
'/settings/test-org/integrations/github/'
);
+ await userEvent.click(sentryGitHubAppLink);
+ expect(trackAnalytics).toHaveBeenCalledWith(
+ 'prevent.ai_onboarding.github_integration_link.clicked',
+ {organization}
+ );
const githubIntegrationLink = screen.getByRole('link', {
name: 'GitHub integration',
@@ -102,15 +114,30 @@ describe('PreventAIOnboarding', () => {
'href',
'https://docs.sentry.io/organization/integrations/source-code-mgmt/github/#installing-github'
);
+ await userEvent.click(githubIntegrationLink);
+ expect(trackAnalytics).toHaveBeenCalledWith(
+ 'prevent.ai_onboarding.github_docs_link.clicked',
+ {organization}
+ );
const seerLink = screen.getByRole('link', {name: 'Seer by Sentry GitHub App'});
expect(seerLink).toHaveAttribute('href', 'https://github.com/apps/seer-by-sentry');
+ await userEvent.click(seerLink);
+ expect(trackAnalytics).toHaveBeenCalledWith(
+ 'prevent.ai_onboarding.seer_app_link.clicked',
+ {organization}
+ );
const learnMoreLink = screen.getByRole('link', {name: 'Learn more'});
expect(learnMoreLink).toHaveAttribute(
'href',
'https://docs.sentry.io/product/ai-in-sentry/ai-code-review/'
);
+ await userEvent.click(learnMoreLink);
+ expect(trackAnalytics).toHaveBeenCalledWith(
+ 'prevent.ai_onboarding.ai_code_review_docs_link.clicked',
+ {organization}
+ );
});
it('renders feature list items', () => {
diff --git a/static/app/views/prevent/preventAI/onboarding.tsx b/static/app/views/prevent/preventAI/onboarding.tsx
index 4f4d03d8749bef..abfb6ae3a2c016 100644
--- a/static/app/views/prevent/preventAI/onboarding.tsx
+++ b/static/app/views/prevent/preventAI/onboarding.tsx
@@ -12,6 +12,7 @@ import {Text} from 'sentry/components/core/text';
import {Heading} from 'sentry/components/core/text/heading';
import {IconInfo} from 'sentry/icons/iconInfo';
import {t, tct} from 'sentry/locale';
+import {trackAnalytics} from 'sentry/utils/analytics';
import {getRegionDataFromOrganization} from 'sentry/utils/regions';
import useOrganization from 'sentry/utils/useOrganization';
@@ -38,6 +39,7 @@ function OnboardingStep({step, title, description}: OnboardingStepProps) {
}
export function FeatureOverview() {
+ const organization = useOrganization();
return (
@@ -92,7 +94,17 @@ export function FeatureOverview() {
'Sentry Error Prediction works better with Sentry Issue Context. [link:Learn more] on how to set this up to get the most accurate error prediction we can offer.',
{
link: (
-
+ {
+ trackAnalytics(
+ 'prevent.ai_onboarding.ai_code_review_docs_link.clicked',
+ {
+ organization,
+ }
+ );
+ }}
+ />
),
}
)}
@@ -193,6 +205,11 @@ export default function PreventAIOnboarding() {
pathname: `/settings/${organization.slug}/`,
hash: 'hideAiFeatures',
}}
+ onClick={() => {
+ trackAnalytics('prevent.ai_onboarding.settings_link.clicked', {
+ organization,
+ });
+ }}
/>
),
}
@@ -205,10 +222,27 @@ export default function PreventAIOnboarding() {
'To grant Seer access to your codebase, install the [sentryGitHubApp:Sentry GitHub App] to connect your GitHub repositories. Learn more about [gitHubIntegration:GitHub integration].',
{
sentryGitHubApp: (
-
+ {
+ trackAnalytics(
+ 'prevent.ai_onboarding.github_integration_link.clicked',
+ {
+ organization,
+ }
+ );
+ }}
+ />
),
gitHubIntegration: (
-
+ {
+ trackAnalytics('prevent.ai_onboarding.github_docs_link.clicked', {
+ organization,
+ });
+ }}
+ />
),
}
)}
@@ -219,7 +253,16 @@ export default function PreventAIOnboarding() {
description={tct(
'AI Code Review uses the Sentry Seer agent to power its core functionalities. Install the [link:Seer by Sentry GitHub App] within the same GitHub organization.',
{
- link: ,
+ link: (
+ {
+ trackAnalytics('prevent.ai_onboarding.seer_app_link.clicked', {
+ organization,
+ });
+ }}
+ />
+ ),
}
)}
/>