@times-components/ts-components 1.146.2-0f9388fe36c532b90db3f35d17847fc17a611f1e.44 → 1.146.2-784617dc4a33959b8795da1d7f425c9929322fae.24

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 (138) hide show
  1. package/dist/components/travel-mini-cta/__tests__/index.test.js +262 -0
  2. package/dist/components/travel-mini-cta/index.d.ts +10 -0
  3. package/dist/components/travel-mini-cta/index.js +93 -0
  4. package/dist/components/travel-mini-cta/styles.d.ts +42 -0
  5. package/dist/components/travel-mini-cta/styles.js +268 -0
  6. package/dist/components/travel-mini-cta/travel-mini-cta.stories.js +8 -0
  7. package/dist/components/travel-mini-cta/types.d.ts +10 -0
  8. package/dist/components/{trip-cards → travel-mini-cta}/types.js +1 -1
  9. package/dist/index.d.ts +1 -1
  10. package/dist/index.js +2 -2
  11. package/dist/utils/applyDarkMode.d.ts +1 -0
  12. package/dist/utils/applyDarkMode.js +12 -0
  13. package/dist/utils/getMediaQuery.d.ts +11 -0
  14. package/dist/utils/getMediaQuery.js +19 -0
  15. package/dist/utils/index.d.ts +2 -0
  16. package/dist/utils/index.js +3 -0
  17. package/package.json +3 -3
  18. package/rnw.js +1 -1
  19. package/src/components/travel-mini-cta/__tests__/__snapshots__/index.test.tsx.snap +211 -0
  20. package/src/components/travel-mini-cta/__tests__/index.test.tsx +330 -0
  21. package/src/components/travel-mini-cta/index.tsx +190 -0
  22. package/src/components/travel-mini-cta/styles.ts +331 -0
  23. package/src/components/travel-mini-cta/travel-mini-cta.stories.tsx +23 -0
  24. package/src/components/travel-mini-cta/types.ts +10 -0
  25. package/src/index.ts +1 -2
  26. package/src/utils/applyDarkMode.ts +12 -0
  27. package/src/utils/getMediaQuery.ts +25 -0
  28. package/src/utils/index.ts +2 -0
  29. package/dist/components/carousel-component/CarouselComponent.stories.js +0 -146
  30. package/dist/components/carousel-component/CarouselItem.d.ts +0 -3
  31. package/dist/components/carousel-component/CarouselItem.js +0 -12
  32. package/dist/components/carousel-component/DefaultNavigationArrow.d.ts +0 -8
  33. package/dist/components/carousel-component/DefaultNavigationArrow.js +0 -6
  34. package/dist/components/carousel-component/DefaultPageDot.d.ts +0 -8
  35. package/dist/components/carousel-component/DefaultPageDot.js +0 -4
  36. package/dist/components/carousel-component/__tests__/CarouselComponent.test.d.ts +0 -1
  37. package/dist/components/carousel-component/__tests__/CarouselComponent.test.js +0 -163
  38. package/dist/components/carousel-component/__tests__/CarouselItem.test.d.ts +0 -1
  39. package/dist/components/carousel-component/__tests__/CarouselItem.test.js +0 -80
  40. package/dist/components/carousel-component/__tests__/DefaultNavigationArrow.test.d.ts +0 -1
  41. package/dist/components/carousel-component/__tests__/DefaultNavigationArrow.test.js +0 -62
  42. package/dist/components/carousel-component/__tests__/DefaultPageDot.test.d.ts +0 -1
  43. package/dist/components/carousel-component/__tests__/DefaultPageDot.test.js +0 -68
  44. package/dist/components/carousel-component/hooks/__tests__/useCarousel.test.d.ts +0 -1
  45. package/dist/components/carousel-component/hooks/__tests__/useCarousel.test.js +0 -459
  46. package/dist/components/carousel-component/hooks/useCarousel.d.ts +0 -2
  47. package/dist/components/carousel-component/hooks/useCarousel.js +0 -167
  48. package/dist/components/carousel-component/index.d.ts +0 -4
  49. package/dist/components/carousel-component/index.js +0 -20
  50. package/dist/components/carousel-component/styles.d.ts +0 -28
  51. package/dist/components/carousel-component/styles.js +0 -172
  52. package/dist/components/carousel-component/types.d.ts +0 -53
  53. package/dist/components/carousel-component/types.js +0 -2
  54. package/dist/components/trip-cards/SkeletonCard.d.ts +0 -7
  55. package/dist/components/trip-cards/SkeletonCard.js +0 -22
  56. package/dist/components/trip-cards/TripCard.d.ts +0 -3
  57. package/dist/components/trip-cards/TripCard.js +0 -49
  58. package/dist/components/trip-cards/TripCards.stories.d.ts +0 -1
  59. package/dist/components/trip-cards/TripCards.stories.js +0 -159
  60. package/dist/components/trip-cards/TripCardsLayout.d.ts +0 -3
  61. package/dist/components/trip-cards/TripCardsLayout.js +0 -56
  62. package/dist/components/trip-cards/__tests__/SkeletonCard.test.d.ts +0 -1
  63. package/dist/components/trip-cards/__tests__/SkeletonCard.test.js +0 -139
  64. package/dist/components/trip-cards/__tests__/TripCard.test.d.ts +0 -1
  65. package/dist/components/trip-cards/__tests__/TripCard.test.js +0 -95
  66. package/dist/components/trip-cards/__tests__/TripCardsLayout.test.d.ts +0 -1
  67. package/dist/components/trip-cards/__tests__/TripCardsLayout.test.js +0 -314
  68. package/dist/components/trip-cards/__tests__/assets.test.d.ts +0 -1
  69. package/dist/components/trip-cards/__tests__/assets.test.js +0 -165
  70. package/dist/components/trip-cards/__tests__/helpers.test.d.ts +0 -1
  71. package/dist/components/trip-cards/__tests__/helpers.test.js +0 -220
  72. package/dist/components/trip-cards/__tests__/index.test.js +0 -478
  73. package/dist/components/trip-cards/__tests__/mockData.test.d.ts +0 -1
  74. package/dist/components/trip-cards/__tests__/mockData.test.js +0 -57
  75. package/dist/components/trip-cards/__tests__/skeletonStyles.test.d.ts +0 -1
  76. package/dist/components/trip-cards/__tests__/skeletonStyles.test.js +0 -194
  77. package/dist/components/trip-cards/assets/BoatIcon.d.ts +0 -1
  78. package/dist/components/trip-cards/assets/BoatIcon.js +0 -4
  79. package/dist/components/trip-cards/assets/CalendarIcon.d.ts +0 -1
  80. package/dist/components/trip-cards/assets/CalendarIcon.js +0 -4
  81. package/dist/components/trip-cards/assets/ChevronRightIcon.d.ts +0 -1
  82. package/dist/components/trip-cards/assets/ChevronRightIcon.js +0 -4
  83. package/dist/components/trip-cards/assets/LocationIcon.d.ts +0 -1
  84. package/dist/components/trip-cards/assets/LocationIcon.js +0 -4
  85. package/dist/components/trip-cards/assets/MoonIcon.d.ts +0 -1
  86. package/dist/components/trip-cards/assets/MoonIcon.js +0 -4
  87. package/dist/components/trip-cards/assets/index.d.ts +0 -6
  88. package/dist/components/trip-cards/assets/index.js +0 -7
  89. package/dist/components/trip-cards/helpers.d.ts +0 -11
  90. package/dist/components/trip-cards/helpers.js +0 -138
  91. package/dist/components/trip-cards/index.d.ts +0 -4
  92. package/dist/components/trip-cards/index.js +0 -68
  93. package/dist/components/trip-cards/mockData.d.ts +0 -3
  94. package/dist/components/trip-cards/mockData.js +0 -317
  95. package/dist/components/trip-cards/skeletonStyles.d.ts +0 -9
  96. package/dist/components/trip-cards/skeletonStyles.js +0 -37
  97. package/dist/components/trip-cards/styles.d.ts +0 -43
  98. package/dist/components/trip-cards/styles.js +0 -404
  99. package/dist/components/trip-cards/types.d.ts +0 -119
  100. package/src/components/carousel-component/CarouselComponent.stories.tsx +0 -220
  101. package/src/components/carousel-component/CarouselItem.tsx +0 -26
  102. package/src/components/carousel-component/DefaultNavigationArrow.tsx +0 -37
  103. package/src/components/carousel-component/DefaultPageDot.tsx +0 -20
  104. package/src/components/carousel-component/__tests__/CarouselComponent.test.tsx +0 -259
  105. package/src/components/carousel-component/__tests__/CarouselItem.test.tsx +0 -140
  106. package/src/components/carousel-component/__tests__/DefaultNavigationArrow.test.tsx +0 -153
  107. package/src/components/carousel-component/__tests__/DefaultPageDot.test.tsx +0 -105
  108. package/src/components/carousel-component/hooks/__tests__/useCarousel.test.ts +0 -625
  109. package/src/components/carousel-component/hooks/useCarousel.ts +0 -229
  110. package/src/components/carousel-component/index.tsx +0 -92
  111. package/src/components/carousel-component/styles.ts +0 -188
  112. package/src/components/carousel-component/types.ts +0 -62
  113. package/src/components/trip-cards/SkeletonCard.tsx +0 -64
  114. package/src/components/trip-cards/TripCard.tsx +0 -140
  115. package/src/components/trip-cards/TripCards.stories.tsx +0 -224
  116. package/src/components/trip-cards/TripCardsLayout.tsx +0 -145
  117. package/src/components/trip-cards/__tests__/SkeletonCard.test.tsx +0 -169
  118. package/src/components/trip-cards/__tests__/TripCard.test.tsx +0 -120
  119. package/src/components/trip-cards/__tests__/TripCardsLayout.test.tsx +0 -583
  120. package/src/components/trip-cards/__tests__/assets.test.tsx +0 -206
  121. package/src/components/trip-cards/__tests__/helpers.test.ts +0 -272
  122. package/src/components/trip-cards/__tests__/index.test.tsx +0 -550
  123. package/src/components/trip-cards/__tests__/mockData.test.ts +0 -67
  124. package/src/components/trip-cards/__tests__/skeletonStyles.test.tsx +0 -256
  125. package/src/components/trip-cards/assets/BoatIcon.tsx +0 -17
  126. package/src/components/trip-cards/assets/CalendarIcon.tsx +0 -17
  127. package/src/components/trip-cards/assets/ChevronRightIcon.tsx +0 -20
  128. package/src/components/trip-cards/assets/LocationIcon.tsx +0 -17
  129. package/src/components/trip-cards/assets/MoonIcon.tsx +0 -17
  130. package/src/components/trip-cards/assets/index.ts +0 -7
  131. package/src/components/trip-cards/helpers.ts +0 -176
  132. package/src/components/trip-cards/index.tsx +0 -119
  133. package/src/components/trip-cards/mockData.ts +0 -345
  134. package/src/components/trip-cards/skeletonStyles.ts +0 -46
  135. package/src/components/trip-cards/styles.ts +0 -450
  136. package/src/components/trip-cards/types.ts +0 -128
  137. /package/dist/components/{trip-cards → travel-mini-cta}/__tests__/index.test.d.ts +0 -0
  138. /package/dist/components/{carousel-component/CarouselComponent.stories.d.ts → travel-mini-cta/travel-mini-cta.stories.d.ts} +0 -0
@@ -0,0 +1,211 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`TravelMiniCTA should render with all props 1`] = `
4
+ <div>
5
+ <div
6
+ class="sc-bwzfXH bFraBm"
7
+ data-testid="travel-mini-cta"
8
+ >
9
+ <div
10
+ class="sc-htpNat fDJQmH"
11
+ >
12
+ <div
13
+ class="sc-bxivhb fAMkx"
14
+ >
15
+ <div
16
+ class="sc-ifAKCX gShyuV"
17
+ >
18
+ <div
19
+ class="sc-EHOje bKLali"
20
+ >
21
+ <span
22
+ class="sc-bZQynM liwexI"
23
+ >
24
+ T
25
+ </span>
26
+ </div>
27
+ <div
28
+ class="sc-bdVaJa sc-dnqmqq eRKvHY"
29
+ >
30
+ VISIT TIMES HOLIDAYS
31
+ </div>
32
+ </div>
33
+ <div
34
+ class="sc-gzVnrw VgUMC"
35
+ >
36
+ <div
37
+ class="sc-bdVaJa sc-htoDjs kOOBoa"
38
+ >
39
+ VISIT TIMES HOLIDAYS
40
+ </div>
41
+ <div
42
+ class="sc-iwsKbI kpBVfB"
43
+ >
44
+ Begin your journey to Croatia with a holiday designed around you
45
+ </div>
46
+ </div>
47
+ </div>
48
+ <div
49
+ class="sc-gZMcBi eQUwuL"
50
+ >
51
+ <div
52
+ class="sc-gqjmRU eBVWqY"
53
+ >
54
+ <a
55
+ class="sc-VigVT dOCyED"
56
+ href="tel:08083049757"
57
+ >
58
+ Call us on
59
+
60
+ <span
61
+ class="sc-jTzLTM OZjYU"
62
+ >
63
+ 08083049757
64
+ </span>
65
+ </a>
66
+ <div
67
+ class="sc-fjdhpX KnCtx"
68
+ >
69
+ <div
70
+ class="sc-jzJRlG eEbwcv"
71
+ >
72
+ Mon - Fri: 9am - 6pm
73
+ </div>
74
+ <div
75
+ class="sc-jzJRlG eEbwcv"
76
+ >
77
+ Sat: 10am - 5pm
78
+ </div>
79
+ </div>
80
+ </div>
81
+ <div
82
+ class="sc-cSHVUG dAmHXf"
83
+ >
84
+ <button
85
+ class="sc-kAzzGY sc-chPdSV htelVJ"
86
+ disabled=""
87
+ type="button"
88
+ >
89
+ Loading chat...
90
+ </button>
91
+ <div
92
+ id="LP_DIV_TRAVEL_1239001"
93
+ style="display: none;"
94
+ />
95
+ <a
96
+ class="sc-kAzzGY sc-kgoBCf epsPGX"
97
+ href="/enquire"
98
+ >
99
+ Enquire now
100
+ </a>
101
+ </div>
102
+ </div>
103
+ </div>
104
+ </div>
105
+ </div>
106
+ `;
107
+
108
+ exports[`TravelMiniCTA should render with isApp prop 1`] = `
109
+ <div>
110
+ <div
111
+ class="sc-bwzfXH euaLVT"
112
+ data-testid="travel-mini-cta"
113
+ >
114
+ <div
115
+ class="sc-htpNat fDJQmH"
116
+ >
117
+ <div
118
+ class="sc-bxivhb fAMkx"
119
+ >
120
+ <div
121
+ class="sc-ifAKCX gShyuV"
122
+ >
123
+ <div
124
+ class="sc-EHOje bDGqOa"
125
+ >
126
+ <span
127
+ class="sc-bZQynM hVYjTG"
128
+ >
129
+ T
130
+ </span>
131
+ </div>
132
+ <div
133
+ class="sc-bdVaJa sc-dnqmqq dpftVr"
134
+ >
135
+ VISIT TIMES HOLIDAYS
136
+ </div>
137
+ </div>
138
+ <div
139
+ class="sc-gzVnrw VgUMC"
140
+ >
141
+ <div
142
+ class="sc-bdVaJa sc-htoDjs isYUYH"
143
+ >
144
+ VISIT TIMES HOLIDAYS
145
+ </div>
146
+ <div
147
+ class="sc-iwsKbI bGbdiO"
148
+ >
149
+ Begin your journey to Croatia with a holiday designed around you
150
+ </div>
151
+ </div>
152
+ </div>
153
+ <div
154
+ class="sc-gZMcBi eQUwuL"
155
+ >
156
+ <div
157
+ class="sc-gqjmRU eBVWqY"
158
+ >
159
+ <a
160
+ class="sc-VigVT HFijS"
161
+ href="tel:08083049757"
162
+ >
163
+ Call us on
164
+
165
+ <span
166
+ class="sc-jTzLTM diHDON"
167
+ >
168
+ 08083049757
169
+ </span>
170
+ </a>
171
+ <div
172
+ class="sc-fjdhpX KnCtx"
173
+ >
174
+ <div
175
+ class="sc-jzJRlG csKGWf"
176
+ >
177
+ Mon - Fri: 9am - 6pm
178
+ </div>
179
+ <div
180
+ class="sc-jzJRlG csKGWf"
181
+ >
182
+ Sat: 10am - 5pm
183
+ </div>
184
+ </div>
185
+ </div>
186
+ <div
187
+ class="sc-cSHVUG dAmHXf"
188
+ >
189
+ <button
190
+ class="sc-kAzzGY sc-chPdSV ddVxAZ"
191
+ disabled=""
192
+ type="button"
193
+ >
194
+ Loading chat...
195
+ </button>
196
+ <div
197
+ id="LP_DIV_TRAVEL_1239001"
198
+ style="display: none;"
199
+ />
200
+ <a
201
+ class="sc-kAzzGY sc-kgoBCf lnRSck"
202
+ href="/enquire"
203
+ >
204
+ Enquire now
205
+ </a>
206
+ </div>
207
+ </div>
208
+ </div>
209
+ </div>
210
+ </div>
211
+ `;
@@ -0,0 +1,330 @@
1
+ import React from 'react';
2
+ import '@testing-library/jest-dom';
3
+ import {
4
+ render,
5
+ screen,
6
+ act,
7
+ fireEvent,
8
+ waitFor
9
+ } from '@testing-library/react';
10
+ import { TravelMiniCTA } from '../index';
11
+
12
+ describe('TravelMiniCTA', () => {
13
+ const defaultProps = {
14
+ description:
15
+ 'Begin your journey to Croatia with a holiday designed around you',
16
+ phoneLabel: 'Call us on',
17
+ phoneNumber: '08083049757',
18
+ workingHours: ['Mon - Fri: 9am - 6pm', 'Sat: 10am - 5pm'],
19
+ primaryButtonText: 'Chat with us',
20
+ secondaryButtonText: 'Enquire now',
21
+ secondaryButtonUrl: '/enquire'
22
+ };
23
+
24
+ let mockObserve: jest.Mock;
25
+ let mockDisconnect: jest.Mock;
26
+ let mutationCallback: MutationCallback;
27
+
28
+ beforeEach(() => {
29
+ jest.clearAllMocks();
30
+ jest.useFakeTimers();
31
+
32
+ // Mock MutationObserver
33
+ mockObserve = jest.fn();
34
+ mockDisconnect = jest.fn();
35
+
36
+ const MockMutationObserver: typeof MutationObserver = jest.fn(
37
+ (callback: MutationCallback) => {
38
+ mutationCallback = callback;
39
+
40
+ const observer: MutationObserver = {
41
+ observe: mockObserve,
42
+ disconnect: mockDisconnect,
43
+ takeRecords: jest.fn()
44
+ };
45
+
46
+ return observer;
47
+ }
48
+ );
49
+
50
+ global.MutationObserver = MockMutationObserver;
51
+
52
+ // Mock lpTag
53
+ (global as any).lpTag = {
54
+ newPage: jest.fn()
55
+ };
56
+ });
57
+
58
+ afterEach(() => {
59
+ jest.runOnlyPendingTimers();
60
+ jest.useRealTimers();
61
+ delete (global as any).lpTag;
62
+ });
63
+
64
+ it('should render with all props', () => {
65
+ const { container } = render(<TravelMiniCTA {...defaultProps} />);
66
+ expect(container).toMatchSnapshot();
67
+ });
68
+
69
+ it('should render the logo with "T" text', () => {
70
+ render(<TravelMiniCTA {...defaultProps} />);
71
+ expect(screen.getByText('T')).toBeInTheDocument();
72
+ });
73
+
74
+ it('should render the label "VISIT TIMES HOLIDAYS"', () => {
75
+ render(<TravelMiniCTA {...defaultProps} />);
76
+ const labels = screen.getAllByText('VISIT TIMES HOLIDAYS');
77
+ expect(labels.length).toBe(2); // Desktop and mobile labels
78
+ });
79
+
80
+ it('should render the description', () => {
81
+ render(<TravelMiniCTA {...defaultProps} />);
82
+ expect(screen.getByText(defaultProps.description)).toBeInTheDocument();
83
+ });
84
+
85
+ it('should render phone label and number', () => {
86
+ render(<TravelMiniCTA {...defaultProps} />);
87
+ expect(screen.getByText('Call us on')).toBeInTheDocument();
88
+ expect(screen.getByText('08083049757')).toBeInTheDocument();
89
+ });
90
+
91
+ it('should render phone number as a tel link', () => {
92
+ render(<TravelMiniCTA {...defaultProps} />);
93
+ const phoneLink = screen.getByText('Call us on').closest('a');
94
+ expect(phoneLink).toHaveAttribute('href', 'tel:08083049757');
95
+ });
96
+
97
+ it('should render working hours', () => {
98
+ render(<TravelMiniCTA {...defaultProps} />);
99
+ expect(screen.getByText('Mon - Fri: 9am - 6pm')).toBeInTheDocument();
100
+ expect(screen.getByText('Sat: 10am - 5pm')).toBeInTheDocument();
101
+ });
102
+
103
+ it('should render primary button with loading text initially', () => {
104
+ render(<TravelMiniCTA {...defaultProps} />);
105
+ expect(screen.getByText('Loading chat...')).toBeInTheDocument();
106
+ });
107
+
108
+ it('should render secondary button with correct text and URL', () => {
109
+ render(<TravelMiniCTA {...defaultProps} />);
110
+ const secondaryButton = screen.getByText('Enquire now');
111
+ expect(secondaryButton).toBeInTheDocument();
112
+ });
113
+
114
+ it('should render with minimal props', () => {
115
+ render(<TravelMiniCTA />);
116
+ expect(screen.getByTestId('travel-mini-cta')).toBeInTheDocument();
117
+ });
118
+
119
+ it('should render without working hours if not provided', () => {
120
+ const propsWithoutWorkingHours = {
121
+ ...defaultProps,
122
+ workingHours: undefined
123
+ };
124
+ render(<TravelMiniCTA {...propsWithoutWorkingHours} />);
125
+ expect(screen.queryByText('Mon - Fri: 9am - 6pm')).not.toBeInTheDocument();
126
+ });
127
+
128
+ it('should render empty working hours array', () => {
129
+ const propsWithEmptyWorkingHours = {
130
+ ...defaultProps,
131
+ workingHours: []
132
+ };
133
+ const { container } = render(
134
+ <TravelMiniCTA {...propsWithEmptyWorkingHours} />
135
+ );
136
+ expect(
137
+ container.querySelector('[data-testid="travel-mini-cta"]')
138
+ ).toBeInTheDocument();
139
+ });
140
+
141
+ it('should render with custom description', () => {
142
+ const customDescription = 'Explore the world with our expert guidance';
143
+ render(<TravelMiniCTA {...defaultProps} description={customDescription} />);
144
+ expect(screen.getByText(customDescription)).toBeInTheDocument();
145
+ });
146
+
147
+ it('should render with custom phone details', () => {
148
+ const customProps = {
149
+ ...defaultProps,
150
+ phoneLabel: 'Contact us at',
151
+ phoneNumber: '0123456789'
152
+ };
153
+ render(<TravelMiniCTA {...customProps} />);
154
+ expect(screen.getByText('Contact us at')).toBeInTheDocument();
155
+ expect(screen.getByText('0123456789')).toBeInTheDocument();
156
+ });
157
+
158
+ it('should have correct container test id', () => {
159
+ render(<TravelMiniCTA {...defaultProps} />);
160
+ expect(screen.getByTestId('travel-mini-cta')).toBeInTheDocument();
161
+ });
162
+
163
+ it('should render with isApp prop', () => {
164
+ const { container } = render(
165
+ <TravelMiniCTA {...defaultProps} isApp={true} />
166
+ );
167
+ expect(container).toMatchSnapshot();
168
+ });
169
+
170
+ it('should pass isApp prop to styled components', () => {
171
+ render(<TravelMiniCTA {...defaultProps} isApp={true} />);
172
+ const container = screen.getByTestId('travel-mini-cta');
173
+ expect(container).toBeInTheDocument();
174
+ });
175
+
176
+ describe('LivePerson Chat Integration', () => {
177
+ it('should render LivePerson container div with correct ID', () => {
178
+ render(<TravelMiniCTA {...defaultProps} />);
179
+ const chatDiv = document.getElementById('LP_DIV_TRAVEL_1239001');
180
+ expect(chatDiv).toBeInTheDocument();
181
+ });
182
+
183
+ it('should show loading text initially', () => {
184
+ render(<TravelMiniCTA {...defaultProps} />);
185
+ expect(screen.getByText('Loading chat...')).toBeInTheDocument();
186
+ });
187
+
188
+ it('should setup MutationObserver on mount', () => {
189
+ render(<TravelMiniCTA {...defaultProps} />);
190
+ expect(global.MutationObserver).toHaveBeenCalled();
191
+ expect(mockObserve).toHaveBeenCalledWith(expect.any(HTMLElement), {
192
+ childList: true,
193
+ subtree: true
194
+ });
195
+ });
196
+
197
+ it('should set chat ready when LivePerson element is detected', async () => {
198
+ render(<TravelMiniCTA {...defaultProps} />);
199
+
200
+ // Simulate LivePerson injecting the chat element
201
+ const chatDiv = document.getElementById('LP_DIV_TRAVEL_1239001');
202
+ const lpElement = document.createElement('div');
203
+ lpElement.setAttribute('data-lp-event', 'click');
204
+ lpElement.textContent = 'Chat';
205
+ chatDiv && chatDiv.appendChild(lpElement);
206
+
207
+ // Trigger the mutation observer callback
208
+ const observer: MutationObserver = {
209
+ observe: mockObserve,
210
+ disconnect: mockDisconnect,
211
+ takeRecords: jest.fn()
212
+ };
213
+ act(() => {
214
+ mutationCallback([], observer);
215
+ });
216
+
217
+ await waitFor(() => {
218
+ expect(screen.queryByText('Loading chat...')).not.toBeInTheDocument();
219
+ });
220
+ });
221
+
222
+ it('should clear timeout when chat loads successfully', async () => {
223
+ const clearTimeoutSpy = jest.spyOn(global, 'clearTimeout');
224
+ render(<TravelMiniCTA {...defaultProps} />);
225
+
226
+ const chatDiv = document.getElementById('LP_DIV_TRAVEL_1239001');
227
+ const lpElement = document.createElement('div');
228
+ lpElement.setAttribute('data-lp-event', 'click');
229
+ chatDiv && chatDiv.appendChild(lpElement);
230
+
231
+ const observer: MutationObserver = {
232
+ observe: mockObserve,
233
+ disconnect: mockDisconnect,
234
+ takeRecords: jest.fn()
235
+ };
236
+ act(() => {
237
+ mutationCallback([], observer);
238
+ });
239
+
240
+ await waitFor(() => {
241
+ expect(clearTimeoutSpy).toHaveBeenCalled();
242
+ });
243
+
244
+ // Timeout should not fire
245
+ act(() => {
246
+ jest.advanceTimersByTime(15000);
247
+ });
248
+
249
+ expect(screen.queryByText('Chat unavailable')).not.toBeInTheDocument();
250
+ clearTimeoutSpy.mockRestore();
251
+ });
252
+
253
+ it('should disconnect observer on unmount', () => {
254
+ const { unmount } = render(<TravelMiniCTA {...defaultProps} />);
255
+ unmount();
256
+ expect(mockDisconnect).toHaveBeenCalled();
257
+ });
258
+
259
+ it('should clear timeout on unmount', () => {
260
+ const clearTimeoutSpy = jest.spyOn(global, 'clearTimeout');
261
+ const { unmount } = render(<TravelMiniCTA {...defaultProps} />);
262
+ unmount();
263
+ expect(clearTimeoutSpy).toHaveBeenCalled();
264
+ clearTimeoutSpy.mockRestore();
265
+ });
266
+
267
+ it('should trigger LivePerson element click when primary button is clicked', async () => {
268
+ render(<TravelMiniCTA {...defaultProps} />);
269
+
270
+ // Simulate chat loaded
271
+ const chatDiv = document.getElementById('LP_DIV_TRAVEL_1239001');
272
+ const lpElement = document.createElement('button');
273
+ lpElement.setAttribute('data-lp-event', 'click');
274
+
275
+ // Mock click on the LivePerson element
276
+ const lpClickSpy = jest.fn();
277
+ lpElement.onclick = lpClickSpy;
278
+
279
+ chatDiv && chatDiv.appendChild(lpElement);
280
+
281
+ const observer: MutationObserver = {
282
+ observe: mockObserve,
283
+ disconnect: mockDisconnect,
284
+ takeRecords: jest.fn()
285
+ };
286
+ act(() => {
287
+ mutationCallback([], observer);
288
+ });
289
+
290
+ await waitFor(() => {
291
+ expect(screen.queryByText('Loading chat...')).not.toBeInTheDocument();
292
+ });
293
+
294
+ // Get and click the primary button
295
+ const parentElement = chatDiv ? chatDiv.parentElement : null;
296
+ if (parentElement instanceof HTMLButtonElement) {
297
+ fireEvent.click(parentElement);
298
+ expect(lpClickSpy).toHaveBeenCalled();
299
+ }
300
+ });
301
+
302
+ it('should handle button click without errors when chat is ready', async () => {
303
+ render(<TravelMiniCTA {...defaultProps} />);
304
+
305
+ const chatDiv = document.getElementById('LP_DIV_TRAVEL_1239001');
306
+ const lpElement = document.createElement('button');
307
+ lpElement.setAttribute('data-lp-event', 'click');
308
+ chatDiv && chatDiv.appendChild(lpElement);
309
+
310
+ const observer: MutationObserver = {
311
+ observe: mockObserve,
312
+ disconnect: mockDisconnect,
313
+ takeRecords: jest.fn()
314
+ };
315
+ act(() => {
316
+ mutationCallback([], observer);
317
+ });
318
+
319
+ await waitFor(() => {
320
+ expect(screen.queryByText('Loading chat...')).not.toBeInTheDocument();
321
+ });
322
+
323
+ // Click button should not throw error
324
+ const parentElement = chatDiv ? chatDiv.parentElement : null;
325
+ if (parentElement instanceof HTMLButtonElement) {
326
+ expect(() => fireEvent.click(parentElement)).not.toThrow();
327
+ }
328
+ });
329
+ });
330
+ });