diff --git a/src/flashbar/__tests__/analytics-metadata.test.tsx b/src/flashbar/__tests__/analytics-metadata.test.tsx index e995e8def7..16a89453c3 100644 --- a/src/flashbar/__tests__/analytics-metadata.test.tsx +++ b/src/flashbar/__tests__/analytics-metadata.test.tsx @@ -11,6 +11,7 @@ import { getGeneratedAnalyticsMetadata } from '@cloudscape-design/component-tool import Button from '../../../lib/components/button'; import Flashbar, { FlashbarProps } from '../../../lib/components/flashbar'; +import { DATA_ATTR_ANALYTICS_FLASHBAR } from '../../../lib/components/internal/analytics/selectors'; import createWrapper from '../../../lib/components/test-utils/dom'; import { validateComponentNameAndLabels } from '../../internal/__tests__/analytics-metadata-test-utils'; @@ -204,4 +205,16 @@ describe('Flashbar renders correct analytics metadata', () => { ...getMetadata(undefined, true, true), }); }); + + describe('analytics attributes', () => { + test(`adds ${DATA_ATTR_ANALYTICS_FLASHBAR} attribute with the flashbar type`, () => { + const wrapper = renderFlashbar({ items: [{ id: '0', type: 'success' }] }); + expect(wrapper.find(`[${DATA_ATTR_ANALYTICS_FLASHBAR}="success"]`)!.getElement()).toBeInTheDocument(); + }); + + test(`adds ${DATA_ATTR_ANALYTICS_FLASHBAR} attribute with the effective flashbar type when loading`, () => { + const wrapper = renderFlashbar({ items: [{ id: '0', type: 'success', loading: true }] }); + expect(wrapper.find(`[${DATA_ATTR_ANALYTICS_FLASHBAR}="info"]`)!.getElement()).toBeInTheDocument(); + }); + }); }); diff --git a/src/flashbar/__tests__/analytics.test.tsx b/src/flashbar/__tests__/analytics.test.tsx deleted file mode 100644 index b32fdeef7e..0000000000 --- a/src/flashbar/__tests__/analytics.test.tsx +++ /dev/null @@ -1,185 +0,0 @@ -// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -// SPDX-License-Identifier: Apache-2.0 -import React from 'react'; -import { render as reactRender } from '@testing-library/react'; - -import { clearOneTimeMetricsCache } from '@cloudscape-design/component-toolkit/internal/testing'; - -import Flashbar, { FlashbarProps } from '../../../lib/components/flashbar'; -import { DATA_ATTR_ANALYTICS_FLASHBAR } from '../../../lib/components/internal/analytics/selectors'; -import { createFlashbarWrapper } from './common'; - -declare global { - interface Window { - panorama?: any; - } -} - -const toggleButtonSelector = 'button'; - -function findFlashbarMetric() { - return jest.mocked(window.panorama).mock.calls.filter((args: any) => args[1].eventContext === 'csa_flashbar'); -} - -describe('Analytics', () => { - beforeEach(() => { - window.panorama = () => {}; - jest.spyOn(window, 'panorama'); - }); - afterEach(() => { - clearOneTimeMetricsCache(); - }); - - it('does not send a metric when an empty array is provided', () => { - createFlashbarWrapper(); - expect(findFlashbarMetric()).toHaveLength(0); - }); - - it('sends a render metric when items are provided', () => { - createFlashbarWrapper( - - ); - - expect(findFlashbarMetric()).toEqual([ - [ - 'trackCustomEvent', - expect.objectContaining({ - eventContext: 'csa_flashbar', - eventType: 'render', - eventValue: '2', - eventDetail: expect.any(String), - timestamp: expect.any(Number), - }), - ], - ]); - }); - - it('sends a render metric when stacked items are provided', () => { - createFlashbarWrapper( - - ); - - expect(findFlashbarMetric()).toEqual([ - [ - 'trackCustomEvent', - expect.objectContaining({ - eventContext: 'csa_flashbar', - eventType: 'render', - eventValue: '2', - eventDetail: expect.any(String), - timestamp: expect.any(Number), - }), - ], - ]); - }); - - it('does not send duplicate render metrics on multiple renders', () => { - const items: FlashbarProps['items'] = [ - { type: 'error', header: 'Error', content: 'There was an error' }, - { type: 'success', header: 'Success', content: 'Everything went fine' }, - ]; - - const { rerender } = reactRender(); - jest.mocked(window.panorama).mockClear(); - rerender(); - expect(window.panorama).toBeCalledTimes(0); - }); - - it('sends an expand metric when collapsed', () => { - const wrapper = createFlashbarWrapper( - - ); - jest.mocked(window.panorama).mockClear(); - - wrapper.find(toggleButtonSelector)!.click(); - - expect(window.panorama).toBeCalledTimes(1); - expect(window.panorama).toHaveBeenCalledWith( - 'trackCustomEvent', - expect.objectContaining({ - eventContext: 'csa_flashbar', - eventType: 'expand', - eventValue: '2', - timestamp: expect.any(Number), - }) - ); - }); - - it('sends a collapse metric when collapsed', () => { - const wrapper = createFlashbarWrapper( - - ); - wrapper.find(toggleButtonSelector)!.click(); // expand - jest.mocked(window.panorama).mockClear(); // clear previous events - - wrapper.find(toggleButtonSelector)!.click(); // collapse - expect(window.panorama).toBeCalledTimes(1); - expect(window.panorama).toHaveBeenCalledWith( - 'trackCustomEvent', - expect.objectContaining({ - eventContext: 'csa_flashbar', - eventType: 'collapse', - eventValue: '2', - timestamp: expect.any(Number), - }) - ); - }); - - it('sends a dismiss metric when a flash item is dismissed', () => { - const wrapper = createFlashbarWrapper( - {} }, - ]} - /> - ); - jest.mocked(window.panorama).mockClear(); // clear render event - wrapper.findItems()[0].findDismissButton()!.click(); - - expect(window.panorama).toBeCalledTimes(1); - expect(window.panorama).toHaveBeenCalledWith( - 'trackCustomEvent', - expect.objectContaining({ - eventContext: 'csa_flashbar', - eventType: 'dismiss', - eventValue: 'error', - timestamp: expect.any(Number), - }) - ); - }); - - describe('analytics', () => { - test(`adds ${DATA_ATTR_ANALYTICS_FLASHBAR} attribute with the flashbar type`, () => { - const { container } = reactRender(); - expect(container.querySelector(`[${DATA_ATTR_ANALYTICS_FLASHBAR}="success"]`)).toBeInTheDocument(); - }); - - test(`adds ${DATA_ATTR_ANALYTICS_FLASHBAR} attribute with the effective flashbar type when loading`, () => { - const { container } = reactRender(); - expect(container.querySelector(`[${DATA_ATTR_ANALYTICS_FLASHBAR}="info"]`)).toBeInTheDocument(); - }); - }); -}); diff --git a/src/flashbar/collapsible-flashbar.tsx b/src/flashbar/collapsible-flashbar.tsx index b3e749e615..68dc1a18b4 100644 --- a/src/flashbar/collapsible-flashbar.tsx +++ b/src/flashbar/collapsible-flashbar.tsx @@ -23,7 +23,6 @@ import { getComponentsAnalyticsMetadata, getItemAnalyticsMetadata } from './anal import { useFlashbar } from './common'; import { Flash, focusFlashById } from './flash'; import { FlashbarProps } from './interfaces'; -import { sendToggleMetric } from './internal/analytics'; import { counterTypes, getFlashTypeCount, getItemColor, getVisibleCollapsedItems, StackableItem } from './utils'; import styles from './styles.css.js'; @@ -84,7 +83,6 @@ export default function CollapsibleFlashbar({ items, ...restProps }: FlashbarPro const animateFlash = !isReducedMotion; function toggleCollapseExpand() { - sendToggleMetric(items.length, !isFlashbarStackExpanded); if (!isReducedMotion) { prepareAnimations(); } diff --git a/src/flashbar/flash.tsx b/src/flashbar/flash.tsx index 3472714f35..f84d20fa26 100644 --- a/src/flashbar/flash.tsx +++ b/src/flashbar/flash.tsx @@ -7,7 +7,6 @@ import { useComponentMetadata, warnOnce } from '@cloudscape-design/component-too import { getAnalyticsMetadataAttribute } from '@cloudscape-design/component-toolkit/internal/analytics-metadata'; import { ActionsWrapper } from '../alert/actions-wrapper'; -import { ButtonProps } from '../button/interfaces'; import { InternalButton } from '../button/internal'; import InternalIcon from '../icon/internal'; import { DATA_ATTR_ANALYTICS_FLASHBAR } from '../internal/analytics/selectors'; @@ -23,7 +22,6 @@ import InternalLiveRegion from '../live-region/internal'; import InternalSpinner from '../spinner/internal'; import { GeneratedAnalyticsMetadataFlashbarDismiss } from './analytics-metadata/interfaces'; import { FlashbarProps } from './interfaces'; -import { sendDismissMetric } from './internal/analytics'; import { FOCUS_THROTTLE_DELAY } from './utils'; import analyticsSelectors from './analytics-metadata/styles.css.js'; @@ -142,11 +140,6 @@ export const Flash = React.forwardRef( const effectiveType = loading ? 'info' : type; - const handleDismiss: ButtonProps['onClick'] = event => { - sendDismissMetric(effectiveType); - onDismiss && onDismiss(event); - }; - const analyticsAttributes = { [DATA_ATTR_ANALYTICS_FLASHBAR]: effectiveType, }; @@ -230,7 +223,7 @@ export const Flash = React.forwardRef( onButtonClick={onButtonClick} /> - {dismissible && dismissButton(dismissLabel, handleDismiss)} + {dismissible && dismissButton(dismissLabel, onDismiss)} {ariaRole === 'status' && ( )} diff --git a/src/flashbar/index.tsx b/src/flashbar/index.tsx index f3095b3728..3bb9183a7b 100644 --- a/src/flashbar/index.tsx +++ b/src/flashbar/index.tsx @@ -1,22 +1,15 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -import React, { useEffect } from 'react'; +import React from 'react'; import { applyDisplayName } from '../internal/utils/apply-display-name'; import CollapsibleFlashbar from './collapsible-flashbar'; import { FlashbarProps } from './interfaces'; -import { sendRenderMetric } from './internal/analytics'; import NonCollapsibleFlashbar from './non-collapsible-flashbar'; export { FlashbarProps }; export default function Flashbar(props: FlashbarProps) { - useEffect(() => { - if (props.items.length > 0) { - sendRenderMetric(props.items); - } - }, [props.items]); - if (props.stackItems) { return ; } else { diff --git a/src/flashbar/internal/analytics.ts b/src/flashbar/internal/analytics.ts deleted file mode 100644 index 5a50f2297c..0000000000 --- a/src/flashbar/internal/analytics.ts +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -// SPDX-License-Identifier: Apache-2.0 - -import { metrics } from '../../internal/metrics'; -import { FlashbarProps } from '../interfaces'; -import { getFlashTypeCount } from '../utils'; - -const eventContext = 'csa_flashbar'; - -export const sendRenderMetric = (items: FlashbarProps['items']) => { - const countByType = getFlashTypeCount(items); - - metrics.sendPanoramaMetric({ - eventContext, - eventType: 'render', - eventValue: items.length.toString(), - eventDetail: countByType, - }); -}; - -export const sendToggleMetric = (itemsCount: number, expanded: boolean) => { - metrics.sendPanoramaMetric({ - eventContext, - eventType: expanded ? 'expand' : 'collapse', - eventValue: itemsCount.toString(), - }); -}; - -export const sendDismissMetric = (itemType: string) => { - metrics.sendPanoramaMetric({ - eventContext, - eventType: 'dismiss', - eventValue: itemType, - }); -};