@envive-ai/react-widgets-v3 0.3.56 → 0.3.58
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.
- package/dist/debug/GenericSelect.cjs +4 -1
- package/dist/debug/GenericSelect.js +3 -1
- package/dist/debug/chatEmbed.cjs +1 -1
- package/dist/debug/chatEmbed.js +1 -1
- package/dist/debug/reportIssue.cjs +7 -4
- package/dist/debug/reportIssue.js +6 -4
- package/dist/hocs/withBaseWidget/withBaseWidget.cjs +46 -4
- package/dist/hocs/withBaseWidget/withBaseWidget.d.cts +2 -2
- package/dist/hocs/withBaseWidget/withBaseWidget.js +45 -4
- package/dist/packages/widgets/dist/SearchResults/SearchResultsWidget.d.ts +2 -2
- package/dist/widgets/ChatPreviewComparisonWidget/ChatPreviewComparisonWidget.cjs +6 -6
- package/dist/widgets/ChatPreviewComparisonWidget/ChatPreviewComparisonWidget.d.cts +3 -3
- package/dist/widgets/ChatPreviewComparisonWidget/ChatPreviewComparisonWidget.d.ts +3 -3
- package/dist/widgets/ChatPreviewComparisonWidget/ChatPreviewComparisonWidget.js +6 -6
- package/dist/widgets/ChatPreviewLoadingWidget/ChatPreviewLoadingWidget.d.cts +3 -3
- package/dist/widgets/ChatPreviewWidget/ChatPreviewWidget.cjs +4 -4
- package/dist/widgets/ChatPreviewWidget/ChatPreviewWidget.d.cts +3 -3
- package/dist/widgets/ChatPreviewWidget/ChatPreviewWidget.d.ts +3 -3
- package/dist/widgets/ChatPreviewWidget/ChatPreviewWidget.js +4 -4
- package/dist/widgets/FloatingChatWidget/FloatingChatWidget.cjs +5 -27
- package/dist/widgets/FloatingChatWidget/FloatingChatWidget.d.cts +2 -2
- package/dist/widgets/FloatingChatWidget/FloatingChatWidget.d.ts +2 -2
- package/dist/widgets/FloatingChatWidget/FloatingChatWidget.js +6 -28
- package/dist/widgets/FloatingChatWidget/hooks/useAutoPopup.cjs +1 -1
- package/dist/widgets/FloatingChatWidget/hooks/useAutoPopup.js +1 -1
- package/dist/widgets/FullPageSalesAgentWidget/FullPageSalesAgentWidget.d.cts +2 -2
- package/dist/widgets/FullPageSalesAgentWidget/FullPageSalesAgentWidget.d.ts +2 -2
- package/dist/widgets/ProductCardWidget/ProductCardWidget.cjs +3 -3
- package/dist/widgets/ProductCardWidget/ProductCardWidget.d.cts +2 -2
- package/dist/widgets/ProductCardWidget/ProductCardWidget.d.ts +2 -2
- package/dist/widgets/ProductCardWidget/ProductCardWidget.js +3 -3
- package/dist/widgets/PromptButtonCarouselWithImageWidget/PromptButtonCarouselWithImageWidget.cjs +4 -4
- package/dist/widgets/PromptButtonCarouselWithImageWidget/PromptButtonCarouselWithImageWidget.d.cts +3 -3
- package/dist/widgets/PromptButtonCarouselWithImageWidget/PromptButtonCarouselWithImageWidget.d.ts +3 -3
- package/dist/widgets/PromptButtonCarouselWithImageWidget/PromptButtonCarouselWithImageWidget.js +4 -4
- package/dist/widgets/PromptCarouselWidget/PromptCarouselWidget.cjs +4 -4
- package/dist/widgets/PromptCarouselWidget/PromptCarouselWidget.d.cts +2 -2
- package/dist/widgets/PromptCarouselWidget/PromptCarouselWidget.d.ts +2 -2
- package/dist/widgets/PromptCarouselWidget/PromptCarouselWidget.js +4 -4
- package/dist/widgets/SocialProofFlowWidget/SocialProofFlowWidget.cjs +1 -1
- package/dist/widgets/SocialProofFlowWidget/SocialProofFlowWidget.d.cts +2 -2
- package/dist/widgets/SocialProofFlowWidget/SocialProofFlowWidget.d.ts +2 -2
- package/dist/widgets/SocialProofFlowWidget/SocialProofFlowWidget.js +1 -1
- package/dist/widgets/SocialProofWidget/SocialProofWidget.cjs +6 -6
- package/dist/widgets/SocialProofWidget/SocialProofWidget.d.cts +3 -3
- package/dist/widgets/SocialProofWidget/SocialProofWidget.d.ts +3 -3
- package/dist/widgets/SocialProofWidget/SocialProofWidget.js +6 -6
- package/dist/widgets/TitledPromptCarouselWidget/TitledPromptCarouselWidget.cjs +2 -2
- package/dist/widgets/TitledPromptCarouselWidget/TitledPromptCarouselWidget.d.cts +2 -2
- package/dist/widgets/TitledPromptCarouselWidget/TitledPromptCarouselWidget.d.ts +2 -2
- package/dist/widgets/TitledPromptCarouselWidget/TitledPromptCarouselWidget.js +2 -2
- package/dist/widgets/TypingAnimationFlowWidget/TypingAnimationFlowWidget.cjs +1 -1
- package/dist/widgets/TypingAnimationFlowWidget/TypingAnimationFlowWidget.d.cts +2 -2
- package/dist/widgets/TypingAnimationFlowWidget/TypingAnimationFlowWidget.d.ts +2 -2
- package/dist/widgets/TypingAnimationFlowWidget/TypingAnimationFlowWidget.js +1 -1
- package/dist/widgets/TypingAnimationWidget/TypingAnimationWidget.cjs +3 -3
- package/dist/widgets/TypingAnimationWidget/TypingAnimationWidget.d.cts +3 -3
- package/dist/widgets/TypingAnimationWidget/TypingAnimationWidget.d.ts +3 -3
- package/dist/widgets/TypingAnimationWidget/TypingAnimationWidget.js +3 -3
- package/dist/widgets/dist/SearchResults/SearchResultsWidget.d.cts +2 -2
- package/dist/widgets/hooks/useGetWidgetStatus.cjs +1 -1
- package/dist/widgets/hooks/useGetWidgetStatus.js +1 -1
- package/dist/widgets/utils/functions.cjs +1 -1
- package/dist/widgets/utils/functions.js +1 -1
- package/package.json +1 -1
- package/src/debug/GenericSelect.tsx +4 -1
- package/src/debug/reportIssue.tsx +6 -3
- package/src/hocs/withBaseWidget/__tests__/withBaseWidget.test.tsx +235 -4
- package/src/hocs/withBaseWidget/withBaseWidget.tsx +71 -1
- package/src/widgets/ChatPreviewWidget/__tests__/ChatPreviewWidget.test.tsx +5 -1
- package/src/widgets/FloatingChatWidget/FloatingChatWidget.tsx +19 -42
- package/src/widgets/FloatingChatWidget/__tests__/FloatingChatWidget.test.tsx +1 -1
- package/src/widgets/ProductCardWidget/__tests__/ProductCardWidget.test.tsx +6 -1
- package/src/widgets/PromptButtonCarouselWithImageWidget/__tests__/PromptButtonCarouselWithImageWidget.test.tsx +5 -1
- package/src/widgets/PromptCarouselWidget/PromptCarouselWidget.tsx +3 -1
- package/src/widgets/PromptCarouselWidget/__tests__/PromptCarouselWidget.test.tsx +1 -1
- package/src/widgets/SocialProofWidget/__tests__/SocialProofWidget.test.tsx +5 -1
- package/src/widgets/TitledPromptCarouselWidget/__tests__/TitledPromptCarouselWidget.test.tsx +1 -1
- package/src/widgets/TypingAnimationWidget/__tests__/TypingAnimationWidget.test.tsx +5 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useEffect, useMemo, useRef, useState } from 'react';
|
|
2
2
|
|
|
3
|
+
import Logger from '@envive-ai/react-hooks/application/logging';
|
|
3
4
|
import { useAmplitude } from '@envive-ai/react-hooks/contexts/amplitudeContext';
|
|
4
5
|
import { useTrackComponentVisibleEvent } from '@envive-ai/react-hooks/hooks/TrackComponentVisibleEvent';
|
|
5
6
|
import { HardcopyResponse, useHardcopy } from '@envive-ai/react-hooks/contexts/hardcopyContext';
|
|
@@ -9,6 +10,12 @@ import { OrgUIConfigV3, WidgetConfigV3 } from '@envive-ai/react-hooks/contexts/t
|
|
|
9
10
|
import { useUiConfig } from '@envive-ai/react-hooks/contexts/uiConfigContext';
|
|
10
11
|
import { BaseWidgetProps, WithBaseWidgetOptions } from './types';
|
|
11
12
|
|
|
13
|
+
const logger = new Logger('withBaseWidget');
|
|
14
|
+
|
|
15
|
+
// How long a widget may stay in its loading state after it starts fetching before we
|
|
16
|
+
// consider it stuck and log an error for external session tools to pick up.
|
|
17
|
+
export const WIDGET_LOADING_WATCHDOG_MS = 5000;
|
|
18
|
+
|
|
12
19
|
export function withBaseWidget<P extends BaseWidgetProps>(
|
|
13
20
|
Widget: React.ComponentType<P>,
|
|
14
21
|
options?: WithBaseWidgetOptions,
|
|
@@ -30,8 +37,23 @@ export function withBaseWidget<P extends BaseWidgetProps>(
|
|
|
30
37
|
const [uiConfig, setUiConfig] = useState<OrgUIConfigV3 | undefined>(undefined);
|
|
31
38
|
const { getUiConfig, isLoading: isUiConfigLoading } = useUiConfig();
|
|
32
39
|
|
|
40
|
+
// The context isLoading flags are provider-level and shared across every widget, so a
|
|
41
|
+
// fetch issued by any widget flips them for all of them. Track when this widget's own
|
|
42
|
+
// requests have settled so a later fetch elsewhere can't knock an already-rendered
|
|
43
|
+
// widget back into its loading state.
|
|
44
|
+
//
|
|
45
|
+
// These latches (and hardcopyFetchedRef above) assume widgetConfigId is stable for the
|
|
46
|
+
// lifetime of the instance — the mounter must key widgets by widgetConfigId so a config
|
|
47
|
+
// swap on the same mount point remounts rather than reusing this state (see Widgets.tsx
|
|
48
|
+
// in injection-bundle).
|
|
49
|
+
const [hardcopySettled, setHardcopySettled] = useState(false);
|
|
50
|
+
const [widgetConfigSettled, setWidgetConfigSettled] = useState(false);
|
|
51
|
+
const [uiConfigSettled, setUiConfigSettled] = useState(false);
|
|
52
|
+
const ownRequestsSettled = hardcopySettled && widgetConfigSettled && uiConfigSettled;
|
|
53
|
+
|
|
33
54
|
const isLoading =
|
|
34
|
-
|
|
55
|
+
!ownRequestsSettled &&
|
|
56
|
+
(isHardcopyLoading || isPageLoading || isWidgetConfigLoading || isUiConfigLoading);
|
|
35
57
|
|
|
36
58
|
const visibilityEventProps = {
|
|
37
59
|
widget_config_id: widgetConfigId,
|
|
@@ -52,15 +74,57 @@ export function withBaseWidget<P extends BaseWidgetProps>(
|
|
|
52
74
|
return isVisible && !!widgetConfigId && !!widgetType;
|
|
53
75
|
}, [isVisible, widgetConfigId, widgetType]);
|
|
54
76
|
|
|
77
|
+
// Watchdog: a widget that is still in its loading state this long after it started
|
|
78
|
+
// fetching is stuck (or on a very slow connection). Log a console error so session
|
|
79
|
+
// tools that capture the console (Quantum Metric, Datadog RUM) can count and segment
|
|
80
|
+
// these sessions. Mirror the settled flags through a ref so mid-flight settles don't
|
|
81
|
+
// restart the timer, while the log still reports which requests were pending.
|
|
82
|
+
const settledStateRef = useRef({ hardcopy: false, widgetConfig: false, uiConfig: false });
|
|
83
|
+
settledStateRef.current = {
|
|
84
|
+
hardcopy: hardcopySettled,
|
|
85
|
+
widgetConfig: widgetConfigSettled,
|
|
86
|
+
uiConfig: uiConfigSettled,
|
|
87
|
+
};
|
|
88
|
+
useEffect(() => {
|
|
89
|
+
if (!startLoading || ownRequestsSettled) {
|
|
90
|
+
return undefined;
|
|
91
|
+
}
|
|
92
|
+
const timer = setTimeout(() => {
|
|
93
|
+
const settled = settledStateRef.current;
|
|
94
|
+
logger.logError(
|
|
95
|
+
`Widget still loading ${WIDGET_LOADING_WATCHDOG_MS}ms after fetches started`,
|
|
96
|
+
undefined,
|
|
97
|
+
{
|
|
98
|
+
widget_type: widgetType,
|
|
99
|
+
widget_config_id: widgetConfigId,
|
|
100
|
+
pending_requests: Object.entries(settled)
|
|
101
|
+
.filter(([, isSettled]) => !isSettled)
|
|
102
|
+
.map(([name]) => name),
|
|
103
|
+
// Network Information API — Chromium/Android only, undefined on Safari
|
|
104
|
+
connection_type: (navigator as Navigator & { connection?: { effectiveType?: string } })
|
|
105
|
+
.connection?.effectiveType,
|
|
106
|
+
},
|
|
107
|
+
);
|
|
108
|
+
}, WIDGET_LOADING_WATCHDOG_MS);
|
|
109
|
+
return () => clearTimeout(timer);
|
|
110
|
+
}, [startLoading, ownRequestsSettled, widgetConfigId, widgetType]);
|
|
111
|
+
|
|
55
112
|
useEffect(() => {
|
|
56
113
|
if (!startLoading || hardcopyFetchedRef.current) {
|
|
57
114
|
return;
|
|
58
115
|
}
|
|
116
|
+
// Hardcopy is fetch-once by design: it is a network request whose deps (userEvent)
|
|
117
|
+
// can churn as the page context updates, and the served copy must not change under
|
|
118
|
+
// the shopper. The uiConfig/widgetConfig effects below need no such guard — they
|
|
119
|
+
// resolve locally from the already-loaded org config, so re-runs are free.
|
|
59
120
|
hardcopyFetchedRef.current = true;
|
|
60
121
|
getHardcopy({ widgetType, userEvent })
|
|
61
122
|
.then(setHardcopyContent)
|
|
62
123
|
.catch(() => {
|
|
63
124
|
// Silently handle errors - widget will render without hardcopy content
|
|
125
|
+
})
|
|
126
|
+
.finally(() => {
|
|
127
|
+
setHardcopySettled(true);
|
|
64
128
|
});
|
|
65
129
|
}, [startLoading, widgetType, getHardcopy, userEvent, widgetConfigId]);
|
|
66
130
|
|
|
@@ -72,6 +136,9 @@ export function withBaseWidget<P extends BaseWidgetProps>(
|
|
|
72
136
|
.then(setUiConfig)
|
|
73
137
|
.catch(() => {
|
|
74
138
|
// Silently handle errors - widget will render without ui config
|
|
139
|
+
})
|
|
140
|
+
.finally(() => {
|
|
141
|
+
setUiConfigSettled(true);
|
|
75
142
|
});
|
|
76
143
|
}, [startLoading, getUiConfig, widgetConfigId, widgetType]);
|
|
77
144
|
|
|
@@ -84,6 +151,9 @@ export function withBaseWidget<P extends BaseWidgetProps>(
|
|
|
84
151
|
.then(setWidgetConfig)
|
|
85
152
|
.catch(() => {
|
|
86
153
|
// Silently handle errors - widget will render without widget config
|
|
154
|
+
})
|
|
155
|
+
.finally(() => {
|
|
156
|
+
setWidgetConfigSettled(true);
|
|
87
157
|
});
|
|
88
158
|
}, [startLoading, widgetConfigId, widgetType, getWidgetConfig]);
|
|
89
159
|
|
|
@@ -5,7 +5,7 @@ import { ChatPreviewWidget } from '../ChatPreviewWidget';
|
|
|
5
5
|
|
|
6
6
|
const mockTrackEvent = vi.fn();
|
|
7
7
|
const mockGetHardcopy = vi.fn();
|
|
8
|
-
const mockUseTrackComponentVisibleEvent = vi.fn();
|
|
8
|
+
const mockUseTrackComponentVisibleEvent = vi.fn(() => ({ isVisible: true }));
|
|
9
9
|
|
|
10
10
|
vi.mock('@envive-ai/react-toolkit-v3/ChatPreview', () => ({
|
|
11
11
|
ChatPreview: () => <div data-testid="chat-preview-mock">Chat Preview</div>,
|
|
@@ -26,6 +26,10 @@ vi.mock('@envive-ai/react-hooks/hooks/TrackComponentVisibleEvent', () => ({
|
|
|
26
26
|
useTrackComponentVisibleEvent: (...args: unknown[]) => mockUseTrackComponentVisibleEvent(...args),
|
|
27
27
|
}));
|
|
28
28
|
|
|
29
|
+
vi.mock('@envive-ai/react-hooks/contexts/featureFlagServiceContext', () => ({
|
|
30
|
+
useFeatureFlagService: () => ({ featureFlagService: undefined }),
|
|
31
|
+
}));
|
|
32
|
+
|
|
29
33
|
vi.mock('@envive-ai/react-hooks/contexts/hardcopyContext', () => ({
|
|
30
34
|
useHardcopy: () => ({
|
|
31
35
|
getHardcopy: mockGetHardcopy,
|
|
@@ -2,10 +2,7 @@ import {
|
|
|
2
2
|
ChatElementDisplayLocationV3,
|
|
3
3
|
FeatureGates,
|
|
4
4
|
} from '@envive-ai/react-hooks/application/models';
|
|
5
|
-
import {
|
|
6
|
-
EnviveMetricsEventName,
|
|
7
|
-
useAmplitude,
|
|
8
|
-
} from '@envive-ai/react-hooks/contexts/amplitudeContext';
|
|
5
|
+
import { useAmplitude } from '@envive-ai/react-hooks/contexts/amplitudeContext';
|
|
9
6
|
import { useSalesAgent } from '@envive-ai/react-hooks/contexts/salesAgentContext';
|
|
10
7
|
import {
|
|
11
8
|
FloatingChatConfig,
|
|
@@ -14,13 +11,7 @@ import {
|
|
|
14
11
|
} from '@envive-ai/react-hooks/contexts/typesV3';
|
|
15
12
|
import { useChatToggle } from '@envive-ai/react-hooks/hooks/ChatToggle';
|
|
16
13
|
import { useTrackComponentVisibleEvent } from '@envive-ai/react-hooks/hooks/TrackComponentVisibleEvent';
|
|
17
|
-
import { useWidgetInteraction } from '@envive-ai/react-hooks/hooks/WidgetInteraction';
|
|
18
14
|
import { useFeatureFlagService } from '@envive-ai/react-hooks/contexts/featureFlagServiceContext';
|
|
19
|
-
import {
|
|
20
|
-
Collapse,
|
|
21
|
-
WidgetInteractionComponent,
|
|
22
|
-
WidgetInteractionType,
|
|
23
|
-
} from '@envive-ai/react-hooks/hooks/WidgetInteraction/types';
|
|
24
15
|
import {
|
|
25
16
|
FloatingButton,
|
|
26
17
|
FloatingButtonBackgroundColor,
|
|
@@ -88,7 +79,6 @@ const FloatingChatWidgetHandler = (props: FloatingChatWidgetHandlerProps) => {
|
|
|
88
79
|
const { previewButtonOnly, previewChatAlwaysOpen, previewCXButtonsEnabled, previewDisclaimer } =
|
|
89
80
|
props;
|
|
90
81
|
const salesAgentData = useSalesAgent();
|
|
91
|
-
const { trackWidgetInteraction } = useWidgetInteraction();
|
|
92
82
|
const { userHasInteractedValue } = useGetWidgetStatus();
|
|
93
83
|
|
|
94
84
|
// TODO: Get hardcopy
|
|
@@ -124,19 +114,6 @@ const FloatingChatWidgetHandler = (props: FloatingChatWidgetHandlerProps) => {
|
|
|
124
114
|
if (isOpen) setIsCXOpen(false);
|
|
125
115
|
}, [isOpen]);
|
|
126
116
|
|
|
127
|
-
const handleClose = (type: Collapse) => {
|
|
128
|
-
trackWidgetInteraction({
|
|
129
|
-
eventName: EnviveMetricsEventName.WidgetInteraction,
|
|
130
|
-
trigger: {
|
|
131
|
-
widget: WidgetInteractionComponent.FLOATING_CHAT,
|
|
132
|
-
widget_interaction: WidgetInteractionType.WIDGET_COLLAPSED,
|
|
133
|
-
widget_interaction_data: {
|
|
134
|
-
widget_collapsed: type,
|
|
135
|
-
},
|
|
136
|
-
},
|
|
137
|
-
});
|
|
138
|
-
};
|
|
139
|
-
|
|
140
117
|
const { shouldShowFloatingButton } = useFloatingButtonVisibility({
|
|
141
118
|
floatingButtonShowConfig: floatingButton?.showOption as FloatingButtonShow,
|
|
142
119
|
isChatOpen: isOpen,
|
|
@@ -191,12 +168,12 @@ const FloatingChatWidgetHandler = (props: FloatingChatWidgetHandlerProps) => {
|
|
|
191
168
|
onClose={
|
|
192
169
|
previewChatAlwaysOpen
|
|
193
170
|
? () => {}
|
|
194
|
-
: () =>
|
|
195
|
-
closeChat(
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
171
|
+
: () =>
|
|
172
|
+
closeChat(
|
|
173
|
+
ChatElementDisplayLocationV3.FLOATING_CHAT_OVERLAY,
|
|
174
|
+
undefined,
|
|
175
|
+
'body_click',
|
|
176
|
+
)
|
|
200
177
|
}
|
|
201
178
|
previewMode={!!previewChatAlwaysOpen}
|
|
202
179
|
>
|
|
@@ -215,22 +192,22 @@ const FloatingChatWidgetHandler = (props: FloatingChatWidgetHandlerProps) => {
|
|
|
215
192
|
onSwipeClose={
|
|
216
193
|
previewChatAlwaysOpen
|
|
217
194
|
? () => {}
|
|
218
|
-
: () =>
|
|
219
|
-
closeChat(
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
195
|
+
: () =>
|
|
196
|
+
closeChat(
|
|
197
|
+
ChatElementDisplayLocationV3.FLOATING_CHAT_CLOSE_BUTTON,
|
|
198
|
+
undefined,
|
|
199
|
+
'swipe',
|
|
200
|
+
)
|
|
224
201
|
}
|
|
225
202
|
onClose={
|
|
226
203
|
previewChatAlwaysOpen
|
|
227
204
|
? () => {}
|
|
228
|
-
: () =>
|
|
229
|
-
closeChat(
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
205
|
+
: () =>
|
|
206
|
+
closeChat(
|
|
207
|
+
ChatElementDisplayLocationV3.FLOATING_CHAT_CLOSE_BUTTON,
|
|
208
|
+
undefined,
|
|
209
|
+
'close_button',
|
|
210
|
+
)
|
|
234
211
|
}
|
|
235
212
|
/>
|
|
236
213
|
</Suspense>
|
|
@@ -5,7 +5,7 @@ import { FloatingChatWidget } from '../FloatingChatWidget';
|
|
|
5
5
|
|
|
6
6
|
const mockTrackEvent = vi.fn();
|
|
7
7
|
const mockGetHardcopy = vi.fn();
|
|
8
|
-
const mockUseTrackComponentVisibleEvent = vi.fn();
|
|
8
|
+
const mockUseTrackComponentVisibleEvent = vi.fn(() => ({ isVisible: true }));
|
|
9
9
|
|
|
10
10
|
vi.mock('@envive-ai/react-toolkit-v3/FloatingButton', () => ({
|
|
11
11
|
FloatingButton: () => <div data-testid="floating-button">Floating Button</div>,
|
|
@@ -6,9 +6,10 @@ import { ProductCardWidget } from '../ProductCardWidget';
|
|
|
6
6
|
|
|
7
7
|
const mockTrackEvent = vi.fn();
|
|
8
8
|
const mockGetHardcopy = vi.fn();
|
|
9
|
-
const mockUseTrackComponentVisibleEvent = vi.fn();
|
|
9
|
+
const mockUseTrackComponentVisibleEvent = vi.fn(() => ({ isVisible: true }));
|
|
10
10
|
|
|
11
11
|
vi.mock('@envive-ai/react-toolkit-v3/ProductCard', () => ({
|
|
12
|
+
ProductCardVariant: { DARK: 'dark', LIGHT: 'light' },
|
|
12
13
|
ProductCard: ({ prompts, onSelect }: { prompts: string[]; onSelect: (text: string) => void }) => (
|
|
13
14
|
<div data-testid="product-card-mock">
|
|
14
15
|
{prompts.map(text => (
|
|
@@ -42,6 +43,10 @@ vi.mock('@envive-ai/react-hooks/hooks/TrackComponentVisibleEvent', () => ({
|
|
|
42
43
|
useTrackComponentVisibleEvent: (...args: unknown[]) => mockUseTrackComponentVisibleEvent(...args),
|
|
43
44
|
}));
|
|
44
45
|
|
|
46
|
+
vi.mock('@envive-ai/react-hooks/contexts/featureFlagServiceContext', () => ({
|
|
47
|
+
useFeatureFlagService: () => ({ featureFlagService: undefined }),
|
|
48
|
+
}));
|
|
49
|
+
|
|
45
50
|
vi.mock('@envive-ai/react-hooks/contexts/hardcopyContext', () => ({
|
|
46
51
|
useHardcopy: () => ({
|
|
47
52
|
getHardcopy: mockGetHardcopy,
|
|
@@ -6,7 +6,7 @@ import { PromptButtonCarouselWithImageWidget } from '../PromptButtonCarouselWith
|
|
|
6
6
|
|
|
7
7
|
const mockTrackEvent = vi.fn();
|
|
8
8
|
const mockGetHardcopy = vi.fn();
|
|
9
|
-
const mockUseTrackComponentVisibleEvent = vi.fn();
|
|
9
|
+
const mockUseTrackComponentVisibleEvent = vi.fn(() => ({ isVisible: true }));
|
|
10
10
|
|
|
11
11
|
vi.mock('@envive-ai/react-toolkit-v3/PromptButtonCarouselWithImage', () => ({
|
|
12
12
|
PromptButtonCarouselWithImage: ({
|
|
@@ -48,6 +48,10 @@ vi.mock('@envive-ai/react-hooks/hooks/TrackComponentVisibleEvent', () => ({
|
|
|
48
48
|
useTrackComponentVisibleEvent: (...args: unknown[]) => mockUseTrackComponentVisibleEvent(...args),
|
|
49
49
|
}));
|
|
50
50
|
|
|
51
|
+
vi.mock('@envive-ai/react-hooks/contexts/featureFlagServiceContext', () => ({
|
|
52
|
+
useFeatureFlagService: () => ({ featureFlagService: undefined }),
|
|
53
|
+
}));
|
|
54
|
+
|
|
51
55
|
vi.mock('@envive-ai/react-hooks/hooks/WidgetInteraction', () => ({
|
|
52
56
|
useWidgetInteraction: () => ({
|
|
53
57
|
trackWidgetInteraction: vi.fn(),
|
|
@@ -74,7 +74,9 @@ const PromptCarouselWidgetHandler = (props: BaseWidgetProps) => {
|
|
|
74
74
|
(text: string) => {
|
|
75
75
|
const rawValues = (hardcopyContent as { rawValues?: RawValues } | undefined)?.rawValues;
|
|
76
76
|
const stringId = getStringIdForText(rawValues, text);
|
|
77
|
-
onSuggestionClick
|
|
77
|
+
// Pass the raw text — onSuggestionClick runs its own idExtractor. Passing stringId here
|
|
78
|
+
// double-extracted it, the lookup missed, and suggestion_id landed empty on the event.
|
|
79
|
+
onSuggestionClick(text);
|
|
78
80
|
trackEvent({
|
|
79
81
|
eventName: EnviveMetricsEventName.WidgetTextClicked,
|
|
80
82
|
eventProps: {
|
|
@@ -6,7 +6,7 @@ import { PromptCarouselWidget } from '../PromptCarouselWidget';
|
|
|
6
6
|
|
|
7
7
|
const mockTrackEvent = vi.fn();
|
|
8
8
|
const mockGetHardcopy = vi.fn();
|
|
9
|
-
const mockUseTrackComponentVisibleEvent = vi.fn();
|
|
9
|
+
const mockUseTrackComponentVisibleEvent = vi.fn(() => ({ isVisible: true }));
|
|
10
10
|
|
|
11
11
|
vi.mock('@envive-ai/react-toolkit-v3/PromptCarousel', () => ({
|
|
12
12
|
PromptCarousel: ({
|
|
@@ -6,7 +6,7 @@ import { SocialProofWidget } from '../SocialProofWidget';
|
|
|
6
6
|
|
|
7
7
|
const mockTrackEvent = vi.fn();
|
|
8
8
|
const mockGetHardcopy = vi.fn();
|
|
9
|
-
const mockUseTrackComponentVisibleEvent = vi.fn();
|
|
9
|
+
const mockUseTrackComponentVisibleEvent = vi.fn(() => ({ isVisible: true }));
|
|
10
10
|
|
|
11
11
|
vi.mock('@envive-ai/react-toolkit-v3/SocialProof', async importOriginal => {
|
|
12
12
|
const actual = await importOriginal();
|
|
@@ -54,6 +54,10 @@ vi.mock('@envive-ai/react-hooks/hooks/TrackComponentVisibleEvent', () => ({
|
|
|
54
54
|
useTrackComponentVisibleEvent: (...args: unknown[]) => mockUseTrackComponentVisibleEvent(...args),
|
|
55
55
|
}));
|
|
56
56
|
|
|
57
|
+
vi.mock('@envive-ai/react-hooks/contexts/featureFlagServiceContext', () => ({
|
|
58
|
+
useFeatureFlagService: () => ({ featureFlagService: undefined }),
|
|
59
|
+
}));
|
|
60
|
+
|
|
57
61
|
vi.mock('@envive-ai/react-hooks/hooks/WidgetInteraction', () => ({
|
|
58
62
|
useWidgetInteraction: () => ({
|
|
59
63
|
trackWidgetInteraction: vi.fn(),
|
package/src/widgets/TitledPromptCarouselWidget/__tests__/TitledPromptCarouselWidget.test.tsx
CHANGED
|
@@ -6,7 +6,7 @@ import { TitledPromptCarouselWidget } from '../TitledPromptCarouselWidget';
|
|
|
6
6
|
|
|
7
7
|
const mockTrackEvent = vi.fn();
|
|
8
8
|
const mockGetHardcopy = vi.fn();
|
|
9
|
-
const mockUseTrackComponentVisibleEvent = vi.fn();
|
|
9
|
+
const mockUseTrackComponentVisibleEvent = vi.fn(() => ({ isVisible: true }));
|
|
10
10
|
|
|
11
11
|
vi.mock('@envive-ai/react-toolkit-v3/TitledPromptCarousel', () => ({
|
|
12
12
|
TitledPromptCarousel: ({
|
|
@@ -6,7 +6,7 @@ import { UserEvent, UserEventCategory } from '@spiffy-ai/commerce-api-client';
|
|
|
6
6
|
import { TypingAnimationWidget } from '../TypingAnimationWidget';
|
|
7
7
|
|
|
8
8
|
const mockTrackEvent = vi.fn();
|
|
9
|
-
const mockUseTrackComponentVisibleEvent = vi.fn();
|
|
9
|
+
const mockUseTrackComponentVisibleEvent = vi.fn(() => ({ isVisible: true }));
|
|
10
10
|
|
|
11
11
|
vi.mock('@envive-ai/react-toolkit-v3/TypingAnimation', () => ({
|
|
12
12
|
TypingAnimation: ({
|
|
@@ -52,6 +52,10 @@ vi.mock('@envive-ai/react-hooks/hooks/TrackComponentVisibleEvent', () => ({
|
|
|
52
52
|
useTrackComponentVisibleEvent: (...args: unknown[]) => mockUseTrackComponentVisibleEvent(...args),
|
|
53
53
|
}));
|
|
54
54
|
|
|
55
|
+
vi.mock('@envive-ai/react-hooks/contexts/featureFlagServiceContext', () => ({
|
|
56
|
+
useFeatureFlagService: () => ({ featureFlagService: undefined }),
|
|
57
|
+
}));
|
|
58
|
+
|
|
55
59
|
vi.mock('@envive-ai/react-hooks/hooks/WidgetInteraction', () => ({
|
|
56
60
|
useWidgetInteraction: () => ({
|
|
57
61
|
trackWidgetInteraction: vi.fn(),
|