@atlaskit/teams-app-internal-analytics 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/CHANGELOG.md +1 -0
  2. package/LICENSE.md +11 -0
  3. package/README.md +189 -0
  4. package/analytics.spec.yaml +42 -0
  5. package/dist/cjs/common/test-utils/index.js +102 -0
  6. package/dist/cjs/common/utils/constants.js +7 -0
  7. package/dist/cjs/common/utils/generated/analytics.types.js +1 -0
  8. package/dist/cjs/common/utils/generated/create-event-payload.js +45 -0
  9. package/dist/cjs/common/utils/generated/use-analytics-events.js +31 -0
  10. package/dist/cjs/index.js +19 -0
  11. package/dist/cjs/ui/analytics-context/index.js +33 -0
  12. package/dist/es2019/common/test-utils/index.js +89 -0
  13. package/dist/es2019/common/utils/constants.js +1 -0
  14. package/dist/es2019/common/utils/generated/analytics.types.js +0 -0
  15. package/dist/es2019/common/utils/generated/create-event-payload.js +28 -0
  16. package/dist/es2019/common/utils/generated/use-analytics-events.js +24 -0
  17. package/dist/es2019/index.js +2 -0
  18. package/dist/es2019/ui/analytics-context/index.js +23 -0
  19. package/dist/esm/common/test-utils/index.js +93 -0
  20. package/dist/esm/common/utils/constants.js +1 -0
  21. package/dist/esm/common/utils/generated/analytics.types.js +0 -0
  22. package/dist/esm/common/utils/generated/create-event-payload.js +38 -0
  23. package/dist/esm/common/utils/generated/use-analytics-events.js +23 -0
  24. package/dist/esm/index.js +2 -0
  25. package/dist/esm/ui/analytics-context/index.js +23 -0
  26. package/dist/types/common/test-utils/index.d.ts +107 -0
  27. package/dist/types/common/utils/constants.d.ts +1 -0
  28. package/dist/types/common/utils/generated/analytics.types.d.ts +39 -0
  29. package/dist/types/common/utils/generated/create-event-payload.d.ts +27 -0
  30. package/dist/types/common/utils/generated/use-analytics-events.d.ts +4 -0
  31. package/dist/types/index.d.ts +2 -0
  32. package/dist/types/ui/analytics-context/index.d.ts +12 -0
  33. package/dist/types-ts4.5/common/test-utils/index.d.ts +107 -0
  34. package/dist/types-ts4.5/common/utils/constants.d.ts +1 -0
  35. package/dist/types-ts4.5/common/utils/generated/analytics.types.d.ts +39 -0
  36. package/dist/types-ts4.5/common/utils/generated/create-event-payload.d.ts +31 -0
  37. package/dist/types-ts4.5/common/utils/generated/use-analytics-events.d.ts +8 -0
  38. package/dist/types-ts4.5/index.d.ts +2 -0
  39. package/dist/types-ts4.5/ui/analytics-context/index.d.ts +12 -0
  40. package/package.json +102 -0
  41. package/test-utils/package.json +17 -0
@@ -0,0 +1,93 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
3
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
4
+ import React from 'react';
5
+ import { render } from '@testing-library/react';
6
+ import userEvent from '@testing-library/user-event';
7
+ import FabricAnalyticsListeners, { FabricChannel } from '@atlaskit/analytics-listeners';
8
+ /**
9
+ * Creates a mock analytics client for testing
10
+ */
11
+ export var createMockAnalyticsClient = function createMockAnalyticsClient() {
12
+ return {
13
+ sendUIEvent: jest.fn(),
14
+ sendOperationalEvent: jest.fn(),
15
+ sendTrackEvent: jest.fn(),
16
+ sendScreenEvent: jest.fn()
17
+ };
18
+ };
19
+
20
+ /**
21
+ * Test utility for testing analytics payloads end-to-end.
22
+ * Renders children with analytics listener and provides mock client for event verification.
23
+ *
24
+ * @example
25
+ * ```tsx
26
+ * const { user, mockClient, expectEventToBeFired } = renderWithAnalyticsListener({
27
+ * children: (
28
+ * <PeopleTeamsAnalyticsContext data={{ source: 'teamsApp' }}>
29
+ * <ButtonWithAnalytics eventType="ui" testId="button-with-analytics"/>
30
+ * </PeopleTeamsAnalyticsContext>
31
+ * )
32
+ * });
33
+ *
34
+ * // Test triggers event however it needs to
35
+ * const button = screen.getByTestId('button-with-analytics');
36
+ * await act(() => user.click(button));
37
+ *
38
+ * // Option 1: Use the helper function
39
+ * expectEventToBeFired('ui', {
40
+ * action: 'clicked',
41
+ * source: 'teamsApp',
42
+ * attributes: expect.objectContaining({
43
+ * packageName: expect.any(String)
44
+ * })
45
+ * });
46
+ *
47
+ * // Option 2: Use mockClient directly for more control
48
+ * expect(mockClient.sendUIEvent).toHaveBeenCalledWith(
49
+ * expect.objectContaining({ source: 'teamsApp' })
50
+ * );
51
+ * ```
52
+ */
53
+ export var renderWithAnalyticsListener = function renderWithAnalyticsListener(ui, options) {
54
+ var _ref = options || {},
55
+ setup = _ref.setup,
56
+ providedMockClient = _ref.mockClient;
57
+ if (setup) {
58
+ setup();
59
+ }
60
+ var mockClient = providedMockClient || createMockAnalyticsClient();
61
+ var user = userEvent.setup();
62
+ var renderResult = render( /*#__PURE__*/React.createElement(FabricAnalyticsListeners, {
63
+ excludedChannels: Object.values(FabricChannel).filter(function (channel) {
64
+ return channel !== FabricChannel.peopleTeams;
65
+ }),
66
+ client: mockClient
67
+ }, ui));
68
+ var expectEventToBeFired = function expectEventToBeFired(eventType, expectedPayload) {
69
+ var getMockForEventType = function getMockForEventType(type) {
70
+ switch (type) {
71
+ case 'ui':
72
+ return mockClient.sendUIEvent;
73
+ case 'operational':
74
+ return mockClient.sendOperationalEvent;
75
+ case 'track':
76
+ return mockClient.sendTrackEvent;
77
+ case 'screen':
78
+ return mockClient.sendScreenEvent;
79
+ default:
80
+ throw new Error("Unsupported event type: ".concat(type));
81
+ }
82
+ };
83
+ var targetMock = getMockForEventType(eventType);
84
+ expect(targetMock).toHaveBeenCalledWith(expect.objectContaining(_objectSpread(_objectSpread({}, expectedPayload), {}, {
85
+ attributes: expect.objectContaining(expectedPayload.attributes || {})
86
+ })));
87
+ };
88
+ return _objectSpread(_objectSpread({}, renderResult), {}, {
89
+ user: user,
90
+ mockClient: mockClient,
91
+ expectEventToBeFired: expectEventToBeFired
92
+ });
93
+ };
@@ -0,0 +1 @@
1
+ export var EVENT_CHANNEL = 'peopleTeams';
@@ -0,0 +1,38 @@
1
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
+ /**
3
+ * THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
4
+ *
5
+ * Generates Typescript types for analytics events from analytics.spec.yaml
6
+ *
7
+ * @codegen <<SignedSource::050566410df453c9b1ba071c6805ead2>>
8
+ * @codegenCommand yarn workspace @atlassian/analytics-tooling run analytics:codegen teams-app-internal-analytics
9
+ */
10
+
11
+ var createEventPayload = function createEventPayload(eventKey) {
12
+ for (var _len = arguments.length, _ref = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
13
+ _ref[_key - 1] = arguments[_key];
14
+ }
15
+ var attributes = _ref[0];
16
+ var _eventKey$split = eventKey.split('.'),
17
+ _eventKey$split2 = _slicedToArray(_eventKey$split, 4),
18
+ eventType = _eventKey$split2[0],
19
+ actionSubject = _eventKey$split2[1],
20
+ action = _eventKey$split2[2],
21
+ actionSubjectId = _eventKey$split2[3];
22
+ if (eventType === 'screen') {
23
+ return {
24
+ eventType: eventType,
25
+ name: actionSubject,
26
+ action: 'viewed',
27
+ attributes: attributes
28
+ };
29
+ }
30
+ return {
31
+ eventType: eventType,
32
+ actionSubject: actionSubject,
33
+ action: action,
34
+ actionSubjectId: actionSubjectId,
35
+ attributes: attributes
36
+ };
37
+ };
38
+ export default createEventPayload;
@@ -0,0 +1,23 @@
1
+ /**
2
+ * THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
3
+ *
4
+ * Generates Typescript types for analytics events from analytics.spec.yaml
5
+ *
6
+ * @codegen <<SignedSource::d01fef63886f2825ffbc3a0ec1ca7534>>
7
+ * @codegenCommand yarn workspace @atlassian/analytics-tooling run analytics:codegen teams-app-internal-analytics
8
+ */
9
+ import { useCallback } from 'react';
10
+ import { useAnalyticsEvents as useAnalyticsNextEvents } from '@atlaskit/analytics-next';
11
+ import { EVENT_CHANNEL } from '../constants';
12
+ import createEventPayload from './create-event-payload';
13
+ export var useAnalyticsEvents = function useAnalyticsEvents() {
14
+ var _useAnalyticsNextEven = useAnalyticsNextEvents(),
15
+ createAnalyticsEvent = _useAnalyticsNextEven.createAnalyticsEvent;
16
+ var fireEvent = useCallback(function () {
17
+ var event = createAnalyticsEvent(createEventPayload.apply(void 0, arguments));
18
+ event.fire(EVENT_CHANNEL);
19
+ }, [createAnalyticsEvent]);
20
+ return {
21
+ fireEvent: fireEvent
22
+ };
23
+ };
@@ -0,0 +1,2 @@
1
+ export { TeamsAppAnalyticsContext } from './ui/analytics-context';
2
+ export { useAnalyticsEvents } from './common/utils/generated/use-analytics-events';
@@ -0,0 +1,23 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+ import _typeof from "@babel/runtime/helpers/typeof";
3
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
4
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
5
+ import React, { useMemo } from 'react';
6
+ import { PeopleTeamsAnalyticsContext } from '@atlaskit/analytics-namespaced-context';
7
+ export var defaultAnalyticsContextData = {
8
+ packageName: "@atlaskit/teams-app-internal-analytics",
9
+ packageVersion: "0.0.0"
10
+ };
11
+ export function TeamsAppAnalyticsContext(_ref) {
12
+ var data = _ref.data,
13
+ children = _ref.children;
14
+ var analyticsContextData = useMemo(function () {
15
+ if (_typeof(data) === 'object') {
16
+ return _objectSpread(_objectSpread({}, defaultAnalyticsContextData), data);
17
+ }
18
+ return defaultAnalyticsContextData;
19
+ }, [data]);
20
+ return /*#__PURE__*/React.createElement(PeopleTeamsAnalyticsContext, {
21
+ data: analyticsContextData
22
+ }, children);
23
+ }
@@ -0,0 +1,107 @@
1
+ import React from 'react';
2
+ import type { EventType } from '@atlaskit/analytics-gas-types';
3
+ import { type AnalyticsWebClient } from '@atlaskit/analytics-listeners';
4
+ import type { AnalyticsEventPayload } from '@atlaskit/analytics-next';
5
+ interface AnalyticsTestUtilOptions {
6
+ /** Additional setup before rendering */
7
+ setup?: () => void;
8
+ /** Optional mock client to use instead of creating a new one */
9
+ mockClient?: AnalyticsWebClient;
10
+ }
11
+ /**
12
+ * Creates a mock analytics client for testing
13
+ */
14
+ export declare const createMockAnalyticsClient: () => AnalyticsWebClient;
15
+ /**
16
+ * Test utility for testing analytics payloads end-to-end.
17
+ * Renders children with analytics listener and provides mock client for event verification.
18
+ *
19
+ * @example
20
+ * ```tsx
21
+ * const { user, mockClient, expectEventToBeFired } = renderWithAnalyticsListener({
22
+ * children: (
23
+ * <PeopleTeamsAnalyticsContext data={{ source: 'teamsApp' }}>
24
+ * <ButtonWithAnalytics eventType="ui" testId="button-with-analytics"/>
25
+ * </PeopleTeamsAnalyticsContext>
26
+ * )
27
+ * });
28
+ *
29
+ * // Test triggers event however it needs to
30
+ * const button = screen.getByTestId('button-with-analytics');
31
+ * await act(() => user.click(button));
32
+ *
33
+ * // Option 1: Use the helper function
34
+ * expectEventToBeFired('ui', {
35
+ * action: 'clicked',
36
+ * source: 'teamsApp',
37
+ * attributes: expect.objectContaining({
38
+ * packageName: expect.any(String)
39
+ * })
40
+ * });
41
+ *
42
+ * // Option 2: Use mockClient directly for more control
43
+ * expect(mockClient.sendUIEvent).toHaveBeenCalledWith(
44
+ * expect.objectContaining({ source: 'teamsApp' })
45
+ * );
46
+ * ```
47
+ */
48
+ export declare const renderWithAnalyticsListener: (ui: React.ReactElement, options?: AnalyticsTestUtilOptions) => {
49
+ user: import("@testing-library/user-event").UserEvent;
50
+ mockClient: AnalyticsWebClient;
51
+ expectEventToBeFired: (eventType: EventType, expectedPayload: AnalyticsEventPayload) => void;
52
+ container: HTMLElement;
53
+ baseElement: HTMLElement;
54
+ debug: (baseElement?: Element | DocumentFragment | Array<Element | DocumentFragment>, maxLength?: number, options?: import("pretty-format").OptionsReceived) => void;
55
+ rerender: (ui: React.ReactElement) => void;
56
+ unmount: () => void;
57
+ asFragment: () => DocumentFragment;
58
+ getByLabelText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").SelectorMatcherOptions | undefined) => HTMLElement;
59
+ getAllByLabelText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").SelectorMatcherOptions | undefined) => HTMLElement[];
60
+ queryByLabelText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").SelectorMatcherOptions | undefined) => HTMLElement | null;
61
+ queryAllByLabelText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").SelectorMatcherOptions | undefined) => HTMLElement[];
62
+ findByLabelText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").SelectorMatcherOptions | undefined, waitForElementOptions?: import("@testing-library/react").waitForOptions | undefined) => Promise<HTMLElement>;
63
+ findAllByLabelText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").SelectorMatcherOptions | undefined, waitForElementOptions?: import("@testing-library/react").waitForOptions | undefined) => Promise<HTMLElement[]>;
64
+ getByPlaceholderText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined) => HTMLElement;
65
+ getAllByPlaceholderText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined) => HTMLElement[];
66
+ queryByPlaceholderText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined) => HTMLElement | null;
67
+ queryAllByPlaceholderText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined) => HTMLElement[];
68
+ findByPlaceholderText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined, waitForElementOptions?: import("@testing-library/react").waitForOptions | undefined) => Promise<HTMLElement>;
69
+ findAllByPlaceholderText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined, waitForElementOptions?: import("@testing-library/react").waitForOptions | undefined) => Promise<HTMLElement[]>;
70
+ getByText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").SelectorMatcherOptions | undefined) => HTMLElement;
71
+ getAllByText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").SelectorMatcherOptions | undefined) => HTMLElement[];
72
+ queryByText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").SelectorMatcherOptions | undefined) => HTMLElement | null;
73
+ queryAllByText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").SelectorMatcherOptions | undefined) => HTMLElement[];
74
+ findByText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").SelectorMatcherOptions | undefined, waitForElementOptions?: import("@testing-library/react").waitForOptions | undefined) => Promise<HTMLElement>;
75
+ findAllByText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").SelectorMatcherOptions | undefined, waitForElementOptions?: import("@testing-library/react").waitForOptions | undefined) => Promise<HTMLElement[]>;
76
+ getByAltText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined) => HTMLElement;
77
+ getAllByAltText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined) => HTMLElement[];
78
+ queryByAltText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined) => HTMLElement | null;
79
+ queryAllByAltText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined) => HTMLElement[];
80
+ findByAltText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined, waitForElementOptions?: import("@testing-library/react").waitForOptions | undefined) => Promise<HTMLElement>;
81
+ findAllByAltText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined, waitForElementOptions?: import("@testing-library/react").waitForOptions | undefined) => Promise<HTMLElement[]>;
82
+ getByTitle: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined) => HTMLElement;
83
+ getAllByTitle: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined) => HTMLElement[];
84
+ queryByTitle: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined) => HTMLElement | null;
85
+ queryAllByTitle: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined) => HTMLElement[];
86
+ findByTitle: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined, waitForElementOptions?: import("@testing-library/react").waitForOptions | undefined) => Promise<HTMLElement>;
87
+ findAllByTitle: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined, waitForElementOptions?: import("@testing-library/react").waitForOptions | undefined) => Promise<HTMLElement[]>;
88
+ getByDisplayValue: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined) => HTMLElement;
89
+ getAllByDisplayValue: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined) => HTMLElement[];
90
+ queryByDisplayValue: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined) => HTMLElement | null;
91
+ queryAllByDisplayValue: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined) => HTMLElement[];
92
+ findByDisplayValue: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined, waitForElementOptions?: import("@testing-library/react").waitForOptions | undefined) => Promise<HTMLElement>;
93
+ findAllByDisplayValue: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined, waitForElementOptions?: import("@testing-library/react").waitForOptions | undefined) => Promise<HTMLElement[]>;
94
+ getByRole: (role: import("@testing-library/react").ByRoleMatcher, options?: import("@testing-library/react").ByRoleOptions | undefined) => HTMLElement;
95
+ getAllByRole: (role: import("@testing-library/react").ByRoleMatcher, options?: import("@testing-library/react").ByRoleOptions | undefined) => HTMLElement[];
96
+ queryByRole: (role: import("@testing-library/react").ByRoleMatcher, options?: import("@testing-library/react").ByRoleOptions | undefined) => HTMLElement | null;
97
+ queryAllByRole: (role: import("@testing-library/react").ByRoleMatcher, options?: import("@testing-library/react").ByRoleOptions | undefined) => HTMLElement[];
98
+ findByRole: (role: import("@testing-library/react").ByRoleMatcher, options?: import("@testing-library/react").ByRoleOptions | undefined, waitForElementOptions?: import("@testing-library/react").waitForOptions | undefined) => Promise<HTMLElement>;
99
+ findAllByRole: (role: import("@testing-library/react").ByRoleMatcher, options?: import("@testing-library/react").ByRoleOptions | undefined, waitForElementOptions?: import("@testing-library/react").waitForOptions | undefined) => Promise<HTMLElement[]>;
100
+ getByTestId: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined) => HTMLElement;
101
+ getAllByTestId: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined) => HTMLElement[];
102
+ queryByTestId: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined) => HTMLElement | null;
103
+ queryAllByTestId: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined) => HTMLElement[];
104
+ findByTestId: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined, waitForElementOptions?: import("@testing-library/react").waitForOptions | undefined) => Promise<HTMLElement>;
105
+ findAllByTestId: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined, waitForElementOptions?: import("@testing-library/react").waitForOptions | undefined) => Promise<HTMLElement[]>;
106
+ };
107
+ export {};
@@ -0,0 +1 @@
1
+ export declare const EVENT_CHANNEL = "peopleTeams";
@@ -0,0 +1,39 @@
1
+ /**
2
+ * THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
3
+ *
4
+ * Generates Typescript types for analytics events from analytics.spec.yaml
5
+ *
6
+ * @codegen <<SignedSource::d5728d78d59f2a7bb511dc13bc1e6953>>
7
+ * @codegenCommand yarn workspace @atlassian/analytics-tooling run analytics:codegen teams-app-internal-analytics
8
+ */
9
+ export type PackageMetaDataType = {
10
+ packageName: string;
11
+ packageVersion: string;
12
+ };
13
+ export type ButtonClickedAnalyticsExampleAttributesType = {
14
+ testAttribute: string;
15
+ };
16
+ export type AutomationTriggeredAnalyticsExampleAttributesType = {
17
+ testAttribute: string;
18
+ };
19
+ export type AutomationFiredAnalyticsExampleAttributesType = {
20
+ testAttribute: string;
21
+ };
22
+ export type AnalyticsExampleScreenViewedAttributesType = {
23
+ testAttribute: string;
24
+ };
25
+ export type AnalyticsEventAttributes = {
26
+ /**
27
+ * fired when the teams-app-internal-analytics example button is clicked */
28
+ 'ui.button.clicked.analyticsExample': ButtonClickedAnalyticsExampleAttributesType;
29
+ /**
30
+ * fired when the teams-app-internal-analytics example button is clicked */
31
+ 'track.automation.triggered.analyticsExample': AutomationTriggeredAnalyticsExampleAttributesType;
32
+ /**
33
+ * fired when the teams-app-internal-analytics example button is clicked */
34
+ 'operational.automation.fired.analyticsExample': AutomationFiredAnalyticsExampleAttributesType;
35
+ /**
36
+ * fired when the teams-app-internal-analytics example is viewed */
37
+ 'screen.analyticsExampleScreen.viewed': AnalyticsExampleScreenViewedAttributesType;
38
+ };
39
+ export type EventKey = keyof AnalyticsEventAttributes;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
3
+ *
4
+ * Generates Typescript types for analytics events from analytics.spec.yaml
5
+ *
6
+ * @codegen <<SignedSource::050566410df453c9b1ba071c6805ead2>>
7
+ * @codegenCommand yarn workspace @atlassian/analytics-tooling run analytics:codegen teams-app-internal-analytics
8
+ */
9
+ import type { AnalyticsEventAttributes, EventKey } from './analytics.types';
10
+ type OptionalIfUndefined<T> = undefined extends T ? [param?: T] : [param: T];
11
+ export type EventPayloadAttributes<K extends EventKey> = OptionalIfUndefined<AnalyticsEventAttributes[K]>;
12
+ type EventTypes = 'ui' | 'track' | 'operational' | 'screen';
13
+ type ScreenEventPayload<K extends EventKey> = {
14
+ eventType: 'screen';
15
+ name: string;
16
+ action: 'viewed';
17
+ attributes?: AnalyticsEventAttributes[K];
18
+ };
19
+ type EventPayload<K extends EventKey> = {
20
+ eventType: Omit<EventTypes, 'screen'>;
21
+ actionSubject: string;
22
+ action: string;
23
+ actionSubjectId?: string;
24
+ attributes?: AnalyticsEventAttributes[K];
25
+ };
26
+ declare const createEventPayload: <K extends EventKey>(eventKey: K, ...[attributes]: EventPayloadAttributes<K>) => ScreenEventPayload<K> | EventPayload<K>;
27
+ export default createEventPayload;
@@ -0,0 +1,4 @@
1
+ import type { EventKey } from './analytics.types';
2
+ export declare const useAnalyticsEvents: () => {
3
+ fireEvent: <K extends EventKey>(eventKey: K, ...params: undefined extends import("./analytics.types").AnalyticsEventAttributes[K] ? [param?: import("./analytics.types").AnalyticsEventAttributes[K] | undefined] : [param: import("./analytics.types").AnalyticsEventAttributes[K]]) => void;
4
+ };
@@ -0,0 +1,2 @@
1
+ export { TeamsAppAnalyticsContext } from './ui/analytics-context';
2
+ export { useAnalyticsEvents } from './common/utils/generated/use-analytics-events';
@@ -0,0 +1,12 @@
1
+ import React, { type ReactNode } from 'react';
2
+ import type { PackageMetaDataType } from '../../common/utils/generated/analytics.types';
3
+ export declare const defaultAnalyticsContextData: PackageMetaDataType;
4
+ type TeamsAppAnalyticsContextData = {
5
+ source?: string;
6
+ attributes?: Record<string, any>;
7
+ };
8
+ export declare function TeamsAppAnalyticsContext({ data, children, }: {
9
+ data?: TeamsAppAnalyticsContextData;
10
+ children: ReactNode;
11
+ }): React.JSX.Element;
12
+ export {};
@@ -0,0 +1,107 @@
1
+ import React from 'react';
2
+ import type { EventType } from '@atlaskit/analytics-gas-types';
3
+ import { type AnalyticsWebClient } from '@atlaskit/analytics-listeners';
4
+ import type { AnalyticsEventPayload } from '@atlaskit/analytics-next';
5
+ interface AnalyticsTestUtilOptions {
6
+ /** Additional setup before rendering */
7
+ setup?: () => void;
8
+ /** Optional mock client to use instead of creating a new one */
9
+ mockClient?: AnalyticsWebClient;
10
+ }
11
+ /**
12
+ * Creates a mock analytics client for testing
13
+ */
14
+ export declare const createMockAnalyticsClient: () => AnalyticsWebClient;
15
+ /**
16
+ * Test utility for testing analytics payloads end-to-end.
17
+ * Renders children with analytics listener and provides mock client for event verification.
18
+ *
19
+ * @example
20
+ * ```tsx
21
+ * const { user, mockClient, expectEventToBeFired } = renderWithAnalyticsListener({
22
+ * children: (
23
+ * <PeopleTeamsAnalyticsContext data={{ source: 'teamsApp' }}>
24
+ * <ButtonWithAnalytics eventType="ui" testId="button-with-analytics"/>
25
+ * </PeopleTeamsAnalyticsContext>
26
+ * )
27
+ * });
28
+ *
29
+ * // Test triggers event however it needs to
30
+ * const button = screen.getByTestId('button-with-analytics');
31
+ * await act(() => user.click(button));
32
+ *
33
+ * // Option 1: Use the helper function
34
+ * expectEventToBeFired('ui', {
35
+ * action: 'clicked',
36
+ * source: 'teamsApp',
37
+ * attributes: expect.objectContaining({
38
+ * packageName: expect.any(String)
39
+ * })
40
+ * });
41
+ *
42
+ * // Option 2: Use mockClient directly for more control
43
+ * expect(mockClient.sendUIEvent).toHaveBeenCalledWith(
44
+ * expect.objectContaining({ source: 'teamsApp' })
45
+ * );
46
+ * ```
47
+ */
48
+ export declare const renderWithAnalyticsListener: (ui: React.ReactElement, options?: AnalyticsTestUtilOptions) => {
49
+ user: import("@testing-library/user-event").UserEvent;
50
+ mockClient: AnalyticsWebClient;
51
+ expectEventToBeFired: (eventType: EventType, expectedPayload: AnalyticsEventPayload) => void;
52
+ container: HTMLElement;
53
+ baseElement: HTMLElement;
54
+ debug: (baseElement?: Element | DocumentFragment | Array<Element | DocumentFragment>, maxLength?: number, options?: import("pretty-format").OptionsReceived) => void;
55
+ rerender: (ui: React.ReactElement) => void;
56
+ unmount: () => void;
57
+ asFragment: () => DocumentFragment;
58
+ getByLabelText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").SelectorMatcherOptions | undefined) => HTMLElement;
59
+ getAllByLabelText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").SelectorMatcherOptions | undefined) => HTMLElement[];
60
+ queryByLabelText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").SelectorMatcherOptions | undefined) => HTMLElement | null;
61
+ queryAllByLabelText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").SelectorMatcherOptions | undefined) => HTMLElement[];
62
+ findByLabelText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").SelectorMatcherOptions | undefined, waitForElementOptions?: import("@testing-library/react").waitForOptions | undefined) => Promise<HTMLElement>;
63
+ findAllByLabelText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").SelectorMatcherOptions | undefined, waitForElementOptions?: import("@testing-library/react").waitForOptions | undefined) => Promise<HTMLElement[]>;
64
+ getByPlaceholderText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined) => HTMLElement;
65
+ getAllByPlaceholderText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined) => HTMLElement[];
66
+ queryByPlaceholderText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined) => HTMLElement | null;
67
+ queryAllByPlaceholderText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined) => HTMLElement[];
68
+ findByPlaceholderText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined, waitForElementOptions?: import("@testing-library/react").waitForOptions | undefined) => Promise<HTMLElement>;
69
+ findAllByPlaceholderText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined, waitForElementOptions?: import("@testing-library/react").waitForOptions | undefined) => Promise<HTMLElement[]>;
70
+ getByText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").SelectorMatcherOptions | undefined) => HTMLElement;
71
+ getAllByText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").SelectorMatcherOptions | undefined) => HTMLElement[];
72
+ queryByText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").SelectorMatcherOptions | undefined) => HTMLElement | null;
73
+ queryAllByText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").SelectorMatcherOptions | undefined) => HTMLElement[];
74
+ findByText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").SelectorMatcherOptions | undefined, waitForElementOptions?: import("@testing-library/react").waitForOptions | undefined) => Promise<HTMLElement>;
75
+ findAllByText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").SelectorMatcherOptions | undefined, waitForElementOptions?: import("@testing-library/react").waitForOptions | undefined) => Promise<HTMLElement[]>;
76
+ getByAltText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined) => HTMLElement;
77
+ getAllByAltText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined) => HTMLElement[];
78
+ queryByAltText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined) => HTMLElement | null;
79
+ queryAllByAltText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined) => HTMLElement[];
80
+ findByAltText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined, waitForElementOptions?: import("@testing-library/react").waitForOptions | undefined) => Promise<HTMLElement>;
81
+ findAllByAltText: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined, waitForElementOptions?: import("@testing-library/react").waitForOptions | undefined) => Promise<HTMLElement[]>;
82
+ getByTitle: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined) => HTMLElement;
83
+ getAllByTitle: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined) => HTMLElement[];
84
+ queryByTitle: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined) => HTMLElement | null;
85
+ queryAllByTitle: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined) => HTMLElement[];
86
+ findByTitle: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined, waitForElementOptions?: import("@testing-library/react").waitForOptions | undefined) => Promise<HTMLElement>;
87
+ findAllByTitle: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined, waitForElementOptions?: import("@testing-library/react").waitForOptions | undefined) => Promise<HTMLElement[]>;
88
+ getByDisplayValue: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined) => HTMLElement;
89
+ getAllByDisplayValue: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined) => HTMLElement[];
90
+ queryByDisplayValue: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined) => HTMLElement | null;
91
+ queryAllByDisplayValue: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined) => HTMLElement[];
92
+ findByDisplayValue: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined, waitForElementOptions?: import("@testing-library/react").waitForOptions | undefined) => Promise<HTMLElement>;
93
+ findAllByDisplayValue: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined, waitForElementOptions?: import("@testing-library/react").waitForOptions | undefined) => Promise<HTMLElement[]>;
94
+ getByRole: (role: import("@testing-library/react").ByRoleMatcher, options?: import("@testing-library/react").ByRoleOptions | undefined) => HTMLElement;
95
+ getAllByRole: (role: import("@testing-library/react").ByRoleMatcher, options?: import("@testing-library/react").ByRoleOptions | undefined) => HTMLElement[];
96
+ queryByRole: (role: import("@testing-library/react").ByRoleMatcher, options?: import("@testing-library/react").ByRoleOptions | undefined) => HTMLElement | null;
97
+ queryAllByRole: (role: import("@testing-library/react").ByRoleMatcher, options?: import("@testing-library/react").ByRoleOptions | undefined) => HTMLElement[];
98
+ findByRole: (role: import("@testing-library/react").ByRoleMatcher, options?: import("@testing-library/react").ByRoleOptions | undefined, waitForElementOptions?: import("@testing-library/react").waitForOptions | undefined) => Promise<HTMLElement>;
99
+ findAllByRole: (role: import("@testing-library/react").ByRoleMatcher, options?: import("@testing-library/react").ByRoleOptions | undefined, waitForElementOptions?: import("@testing-library/react").waitForOptions | undefined) => Promise<HTMLElement[]>;
100
+ getByTestId: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined) => HTMLElement;
101
+ getAllByTestId: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined) => HTMLElement[];
102
+ queryByTestId: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined) => HTMLElement | null;
103
+ queryAllByTestId: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined) => HTMLElement[];
104
+ findByTestId: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined, waitForElementOptions?: import("@testing-library/react").waitForOptions | undefined) => Promise<HTMLElement>;
105
+ findAllByTestId: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions | undefined, waitForElementOptions?: import("@testing-library/react").waitForOptions | undefined) => Promise<HTMLElement[]>;
106
+ };
107
+ export {};
@@ -0,0 +1 @@
1
+ export declare const EVENT_CHANNEL = "peopleTeams";
@@ -0,0 +1,39 @@
1
+ /**
2
+ * THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
3
+ *
4
+ * Generates Typescript types for analytics events from analytics.spec.yaml
5
+ *
6
+ * @codegen <<SignedSource::d5728d78d59f2a7bb511dc13bc1e6953>>
7
+ * @codegenCommand yarn workspace @atlassian/analytics-tooling run analytics:codegen teams-app-internal-analytics
8
+ */
9
+ export type PackageMetaDataType = {
10
+ packageName: string;
11
+ packageVersion: string;
12
+ };
13
+ export type ButtonClickedAnalyticsExampleAttributesType = {
14
+ testAttribute: string;
15
+ };
16
+ export type AutomationTriggeredAnalyticsExampleAttributesType = {
17
+ testAttribute: string;
18
+ };
19
+ export type AutomationFiredAnalyticsExampleAttributesType = {
20
+ testAttribute: string;
21
+ };
22
+ export type AnalyticsExampleScreenViewedAttributesType = {
23
+ testAttribute: string;
24
+ };
25
+ export type AnalyticsEventAttributes = {
26
+ /**
27
+ * fired when the teams-app-internal-analytics example button is clicked */
28
+ 'ui.button.clicked.analyticsExample': ButtonClickedAnalyticsExampleAttributesType;
29
+ /**
30
+ * fired when the teams-app-internal-analytics example button is clicked */
31
+ 'track.automation.triggered.analyticsExample': AutomationTriggeredAnalyticsExampleAttributesType;
32
+ /**
33
+ * fired when the teams-app-internal-analytics example button is clicked */
34
+ 'operational.automation.fired.analyticsExample': AutomationFiredAnalyticsExampleAttributesType;
35
+ /**
36
+ * fired when the teams-app-internal-analytics example is viewed */
37
+ 'screen.analyticsExampleScreen.viewed': AnalyticsExampleScreenViewedAttributesType;
38
+ };
39
+ export type EventKey = keyof AnalyticsEventAttributes;
@@ -0,0 +1,31 @@
1
+ /**
2
+ * THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
3
+ *
4
+ * Generates Typescript types for analytics events from analytics.spec.yaml
5
+ *
6
+ * @codegen <<SignedSource::050566410df453c9b1ba071c6805ead2>>
7
+ * @codegenCommand yarn workspace @atlassian/analytics-tooling run analytics:codegen teams-app-internal-analytics
8
+ */
9
+ import type { AnalyticsEventAttributes, EventKey } from './analytics.types';
10
+ type OptionalIfUndefined<T> = undefined extends T ? [
11
+ param?: T
12
+ ] : [
13
+ param: T
14
+ ];
15
+ export type EventPayloadAttributes<K extends EventKey> = OptionalIfUndefined<AnalyticsEventAttributes[K]>;
16
+ type EventTypes = 'ui' | 'track' | 'operational' | 'screen';
17
+ type ScreenEventPayload<K extends EventKey> = {
18
+ eventType: 'screen';
19
+ name: string;
20
+ action: 'viewed';
21
+ attributes?: AnalyticsEventAttributes[K];
22
+ };
23
+ type EventPayload<K extends EventKey> = {
24
+ eventType: Omit<EventTypes, 'screen'>;
25
+ actionSubject: string;
26
+ action: string;
27
+ actionSubjectId?: string;
28
+ attributes?: AnalyticsEventAttributes[K];
29
+ };
30
+ declare const createEventPayload: <K extends EventKey>(eventKey: K, ...[attributes]: EventPayloadAttributes<K>) => ScreenEventPayload<K> | EventPayload<K>;
31
+ export default createEventPayload;
@@ -0,0 +1,8 @@
1
+ import type { EventKey } from './analytics.types';
2
+ export declare const useAnalyticsEvents: () => {
3
+ fireEvent: <K extends EventKey>(eventKey: K, ...params: undefined extends import("./analytics.types").AnalyticsEventAttributes[K] ? [
4
+ param?: import("./analytics.types").AnalyticsEventAttributes[K] | undefined
5
+ ] : [
6
+ param: import("./analytics.types").AnalyticsEventAttributes[K]
7
+ ]) => void;
8
+ };
@@ -0,0 +1,2 @@
1
+ export { TeamsAppAnalyticsContext } from './ui/analytics-context';
2
+ export { useAnalyticsEvents } from './common/utils/generated/use-analytics-events';
@@ -0,0 +1,12 @@
1
+ import React, { type ReactNode } from 'react';
2
+ import type { PackageMetaDataType } from '../../common/utils/generated/analytics.types';
3
+ export declare const defaultAnalyticsContextData: PackageMetaDataType;
4
+ type TeamsAppAnalyticsContextData = {
5
+ source?: string;
6
+ attributes?: Record<string, any>;
7
+ };
8
+ export declare function TeamsAppAnalyticsContext({ data, children, }: {
9
+ data?: TeamsAppAnalyticsContextData;
10
+ children: ReactNode;
11
+ }): React.JSX.Element;
12
+ export {};