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, + }); + }} + /> + ), } )} />