Skip to content

Commit ba72a54

Browse files
authored
dev: Add amplitude events for links on prevent onboarding page (#102361)
This PR adds some simple track analytic events to the sentry prevent onboarding page to see what aspects of the page are getting engagement vs. not <!-- Sentry employees and contractors can delete or ignore the following. --> ### Legal Boilerplate Look, I get it. The entity doing business as "Sentry" was incorporated in the State of Delaware in 2015 as Functional Software, Inc. and is gonna need some rights from me in order to utilize my contributions in this here PR. So here's the deal: I retain all rights, title and interest in and to my contributions, and by keeping this boilerplate intact I confirm that Sentry can use, modify, copy, and redistribute my contributions, under Sentry's choice of terms.
1 parent bdbcfeb commit ba72a54

File tree

2 files changed

+76
-6
lines changed

2 files changed

+76
-6
lines changed

static/app/views/prevent/preventAI/onboarding.spec.tsx

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import {ThemeProvider, type Theme} from '@emotion/react';
22
import {OrganizationFixture} from 'sentry-fixture/organization';
33

4-
import {render, screen} from 'sentry-test/reactTestingLibrary';
4+
import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
55
import {textWithMarkupMatcher} from 'sentry-test/utils';
66

77
import ConfigStore from 'sentry/stores/configStore';
88
import type {Config} from 'sentry/types/system';
9+
import {trackAnalytics} from 'sentry/utils/analytics';
910

1011
import PreventAIOnboarding from './onboarding';
1112

@@ -20,6 +21,7 @@ jest.mock(
2021
() => 'prevent-pr-comments-dark-mock.svg',
2122
{virtual: true}
2223
);
24+
jest.mock('sentry/utils/analytics');
2325

2426
describe('PreventAIOnboarding', () => {
2527
const organization = OrganizationFixture({
@@ -81,11 +83,16 @@ describe('PreventAIOnboarding', () => {
8183
expect(screen.getByRole('heading', {name: 'Setup Seer'})).toBeInTheDocument();
8284
});
8385

84-
it('renders external links with correct hrefs', () => {
86+
it('renders external links with correct hrefs', async () => {
8587
render(<PreventAIOnboarding />, {organization});
8688

8789
const orgSettingsLink = screen.getByRole('link', {name: 'organization settings'});
8890
expect(orgSettingsLink).toHaveAttribute('href', '/settings/test-org/#hideAiFeatures');
91+
await userEvent.click(orgSettingsLink);
92+
expect(trackAnalytics).toHaveBeenCalledWith(
93+
'prevent.ai_onboarding.settings_link.clicked',
94+
{organization}
95+
);
8996

9097
const sentryGitHubAppLink = screen.getByRole('link', {
9198
name: 'Sentry GitHub App',
@@ -94,6 +101,11 @@ describe('PreventAIOnboarding', () => {
94101
'href',
95102
'/settings/test-org/integrations/github/'
96103
);
104+
await userEvent.click(sentryGitHubAppLink);
105+
expect(trackAnalytics).toHaveBeenCalledWith(
106+
'prevent.ai_onboarding.github_integration_link.clicked',
107+
{organization}
108+
);
97109

98110
const githubIntegrationLink = screen.getByRole('link', {
99111
name: 'GitHub integration',
@@ -102,15 +114,30 @@ describe('PreventAIOnboarding', () => {
102114
'href',
103115
'https://docs.sentry.io/organization/integrations/source-code-mgmt/github/#installing-github'
104116
);
117+
await userEvent.click(githubIntegrationLink);
118+
expect(trackAnalytics).toHaveBeenCalledWith(
119+
'prevent.ai_onboarding.github_docs_link.clicked',
120+
{organization}
121+
);
105122

106123
const seerLink = screen.getByRole('link', {name: 'Seer by Sentry GitHub App'});
107124
expect(seerLink).toHaveAttribute('href', 'https://github.com/apps/seer-by-sentry');
125+
await userEvent.click(seerLink);
126+
expect(trackAnalytics).toHaveBeenCalledWith(
127+
'prevent.ai_onboarding.seer_app_link.clicked',
128+
{organization}
129+
);
108130

109131
const learnMoreLink = screen.getByRole('link', {name: 'Learn more'});
110132
expect(learnMoreLink).toHaveAttribute(
111133
'href',
112134
'https://docs.sentry.io/product/ai-in-sentry/ai-code-review/'
113135
);
136+
await userEvent.click(learnMoreLink);
137+
expect(trackAnalytics).toHaveBeenCalledWith(
138+
'prevent.ai_onboarding.ai_code_review_docs_link.clicked',
139+
{organization}
140+
);
114141
});
115142

116143
it('renders feature list items', () => {

static/app/views/prevent/preventAI/onboarding.tsx

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {Text} from 'sentry/components/core/text';
1212
import {Heading} from 'sentry/components/core/text/heading';
1313
import {IconInfo} from 'sentry/icons/iconInfo';
1414
import {t, tct} from 'sentry/locale';
15+
import {trackAnalytics} from 'sentry/utils/analytics';
1516
import {getRegionDataFromOrganization} from 'sentry/utils/regions';
1617
import useOrganization from 'sentry/utils/useOrganization';
1718

@@ -38,6 +39,7 @@ function OnboardingStep({step, title, description}: OnboardingStepProps) {
3839
}
3940

4041
export function FeatureOverview() {
42+
const organization = useOrganization();
4143
return (
4244
<Flex direction="column" gap="md" padding="xl" background="secondary" radius="md">
4345
<Text variant="primary" size="md" bold>
@@ -92,7 +94,17 @@ export function FeatureOverview() {
9294
'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.',
9395
{
9496
link: (
95-
<ExternalLink href="https://docs.sentry.io/product/ai-in-sentry/ai-code-review/" />
97+
<ExternalLink
98+
href="https://docs.sentry.io/product/ai-in-sentry/ai-code-review/"
99+
onClick={() => {
100+
trackAnalytics(
101+
'prevent.ai_onboarding.ai_code_review_docs_link.clicked',
102+
{
103+
organization,
104+
}
105+
);
106+
}}
107+
/>
96108
),
97109
}
98110
)}
@@ -193,6 +205,11 @@ export default function PreventAIOnboarding() {
193205
pathname: `/settings/${organization.slug}/`,
194206
hash: 'hideAiFeatures',
195207
}}
208+
onClick={() => {
209+
trackAnalytics('prevent.ai_onboarding.settings_link.clicked', {
210+
organization,
211+
});
212+
}}
196213
/>
197214
),
198215
}
@@ -205,10 +222,27 @@ export default function PreventAIOnboarding() {
205222
'To grant Seer access to your codebase, install the [sentryGitHubApp:Sentry GitHub App] to connect your GitHub repositories. Learn more about [gitHubIntegration:GitHub integration].',
206223
{
207224
sentryGitHubApp: (
208-
<Link to={`/settings/${organization.slug}/integrations/github/`} />
225+
<Link
226+
to={`/settings/${organization.slug}/integrations/github/`}
227+
onClick={() => {
228+
trackAnalytics(
229+
'prevent.ai_onboarding.github_integration_link.clicked',
230+
{
231+
organization,
232+
}
233+
);
234+
}}
235+
/>
209236
),
210237
gitHubIntegration: (
211-
<ExternalLink href="https://docs.sentry.io/organization/integrations/source-code-mgmt/github/#installing-github" />
238+
<ExternalLink
239+
href="https://docs.sentry.io/organization/integrations/source-code-mgmt/github/#installing-github"
240+
onClick={() => {
241+
trackAnalytics('prevent.ai_onboarding.github_docs_link.clicked', {
242+
organization,
243+
});
244+
}}
245+
/>
212246
),
213247
}
214248
)}
@@ -219,7 +253,16 @@ export default function PreventAIOnboarding() {
219253
description={tct(
220254
'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.',
221255
{
222-
link: <ExternalLink href="https://github.com/apps/seer-by-sentry" />,
256+
link: (
257+
<ExternalLink
258+
href="https://github.com/apps/seer-by-sentry"
259+
onClick={() => {
260+
trackAnalytics('prevent.ai_onboarding.seer_app_link.clicked', {
261+
organization,
262+
});
263+
}}
264+
/>
265+
),
223266
}
224267
)}
225268
/>

0 commit comments

Comments
 (0)