Skip to content

Commit 8767da0

Browse files
authored
chore: Add usage tracking for global breadcrumbs feature (#3726)
1 parent b78eee1 commit 8767da0

File tree

2 files changed

+38
-3
lines changed

2 files changed

+38
-3
lines changed

src/app-layout/__tests__/global-breadcrumbs.test.tsx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { getGeneratedAnalyticsMetadata } from '@cloudscape-design/component-tool
99

1010
import AppLayout from '../../../lib/components/app-layout';
1111
import BreadcrumbGroup, { BreadcrumbGroupProps } from '../../../lib/components/breadcrumb-group';
12+
import { metrics } from '../../../lib/components/internal/metrics';
1213
import { awsuiPluginsInternal } from '../../../lib/components/internal/plugins/api';
1314
import createWrapper from '../../../lib/components/test-utils/dom';
1415
import { describeEachAppLayout } from './utils';
@@ -57,6 +58,11 @@ async function renderAsync(jsx: React.ReactElement) {
5758
return result;
5859
}
5960

61+
let sendPanoramaMetricSpy: jest.SpyInstance;
62+
beforeEach(() => {
63+
sendPanoramaMetricSpy = jest.spyOn(metrics, 'sendOpsMetricObject').mockImplementation(() => {});
64+
});
65+
6066
afterEach(() => {
6167
// force unmount for all rendered component to run clean state assertions
6268
cleanup();
@@ -66,6 +72,7 @@ afterEach(() => {
6672
breadcrumbInstances: [],
6773
breadcrumbRegistrations: [],
6874
});
75+
jest.resetAllMocks();
6976
});
7077

7178
describeEachAppLayout({ themes: ['refresh-toolbar'], sizes: ['desktop'] }, () => {
@@ -74,13 +81,15 @@ describeEachAppLayout({ themes: ['refresh-toolbar'], sizes: ['desktop'] }, () =>
7481
await delay();
7582
expect(findAllBreadcrumbsInstances()).toHaveLength(1);
7683
expect(wrapper.findBreadcrumbGroup()!.findBreadcrumbLinks()).toHaveLength(2);
84+
expect(sendPanoramaMetricSpy).not.toHaveBeenCalled();
7785
});
7886

7987
test('renders normal breadcrumbs when placed inside the breadcrumbs slot', async () => {
8088
render(<AppLayout breadcrumbs={<BreadcrumbGroup items={defaultBreadcrumbs} />} />);
8189
await delay();
8290
expect(findDiscoveredBreadcrumbs()).toBeFalsy();
8391
expect(findAppLayoutBreadcrumbItems()).toHaveLength(2);
92+
expect(sendPanoramaMetricSpy).not.toHaveBeenCalled();
8493
});
8594

8695
test('no relocation happens on the initial render', () => {
@@ -106,6 +115,18 @@ describeEachAppLayout({ themes: ['refresh-toolbar'], sizes: ['desktop'] }, () =>
106115
expect(findAppLayoutBreadcrumbItems()).toHaveLength(2);
107116
});
108117

118+
test('reports a single metric when global breadcrumbs used', async () => {
119+
const { rerender } = await renderAsync(<AppLayout content={<BreadcrumbGroup items={defaultBreadcrumbs} />} />);
120+
expect(sendPanoramaMetricSpy).toHaveBeenCalledTimes(1);
121+
expect(sendPanoramaMetricSpy).toHaveBeenCalledWith('awsui-global-breadcrumbs-used', { breadcrumbs: 'Home > Page' });
122+
123+
sendPanoramaMetricSpy.mockClear();
124+
rerender(
125+
<AppLayout content={<BreadcrumbGroup items={[defaultBreadcrumbs[0], { text: 'Another', href: '/another' }]} />} />
126+
);
127+
expect(sendPanoramaMetricSpy).toHaveBeenCalledTimes(0);
128+
});
129+
109130
test('event handlers work for relocated breadcrumbs', async () => {
110131
const onFollow = jest.fn(event => event.preventDefault());
111132
await renderAsync(<AppLayout content={<BreadcrumbGroup items={defaultBreadcrumbs} onFollow={onFollow} />} />);
@@ -334,6 +355,14 @@ describeEachAppLayout({ themes: ['refresh-toolbar'], sizes: ['desktop'] }, () =>
334355
);
335356
expect(findAllBreadcrumbsInstances()).toHaveLength(2);
336357
});
358+
359+
test('does not report metrics if globalization is disabled', async () => {
360+
render(
361+
<AppLayout content={<BreadcrumbGroup items={defaultBreadcrumbs} {...{ __disableGlobalization: true }} />} />
362+
);
363+
await delay();
364+
expect(sendPanoramaMetricSpy).toHaveBeenCalledTimes(0);
365+
});
337366
});
338367

339368
describe('without feature flag', () => {
@@ -343,6 +372,7 @@ describe('without feature flag', () => {
343372
expect(findAllBreadcrumbsInstances()).toHaveLength(1);
344373
expect(wrapper.findAppLayout()!.findBreadcrumbs()).toBeFalsy();
345374
expect(wrapper.findAppLayout()!.findContentRegion().findBreadcrumbGroup()).toBeTruthy();
375+
expect(sendPanoramaMetricSpy).not.toHaveBeenCalled();
346376
});
347377
});
348378

src/internal/plugins/helpers/use-global-breadcrumbs.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
BreadcrumbsSlotContext,
99
} from '../../../app-layout/visual-refresh-toolbar/contexts';
1010
import { BreadcrumbGroupProps } from '../../../breadcrumb-group/interfaces';
11+
import { metrics } from '../../metrics';
1112
import { awsuiPluginsInternal } from '../api';
1213
import { BreadcrumbsGlobalRegistration } from '../controllers/breadcrumbs';
1314

@@ -24,9 +25,13 @@ function useSetGlobalBreadcrumbsImplementation({
2425
if (isInToolbar || __disableGlobalization || !isLayoutVisible) {
2526
return;
2627
}
27-
const registration = awsuiPluginsInternal.breadcrumbs.registerBreadcrumbs(props, isRegistered =>
28-
setRegistered(isRegistered ?? true)
29-
);
28+
const registration = awsuiPluginsInternal.breadcrumbs.registerBreadcrumbs(props, isRegistered => {
29+
setRegistered(isRegistered ?? true);
30+
if (isRegistered) {
31+
const breadcrumbs = props.items.map(item => item.text).join(' > ');
32+
metrics.sendOpsMetricObject('awsui-global-breadcrumbs-used', { breadcrumbs });
33+
}
34+
});
3035
registrationRef.current = registration;
3136

3237
return () => {

0 commit comments

Comments
 (0)