@times-components/ts-components 1.145.1-777882a8b99dc7733f00b94202a91fa8b7dc2a7e.1 → 1.145.1-7822206a549cb799b9eb65f35228b22be1db32a1.5
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/components/opta/football/opta-match-stats/shared/styles.js +1 -8
- package/dist/components/{opta/football/opta-match-stats/matchday-live/__tests__/OptaMatchStatsMatchdayLive.test.d.ts → travel-mini-cta/__tests__/index.test.d.ts} +0 -1
- package/dist/components/travel-mini-cta/__tests__/index.test.js +346 -0
- package/dist/components/travel-mini-cta/index.d.ts +3 -0
- package/dist/components/travel-mini-cta/index.js +86 -0
- package/dist/components/travel-mini-cta/styles.d.ts +42 -0
- package/dist/components/travel-mini-cta/styles.js +268 -0
- package/dist/components/travel-mini-cta/travel-mini-cta.stories.js +8 -0
- package/dist/components/travel-mini-cta/types.d.ts +10 -0
- package/dist/components/travel-mini-cta/types.js +2 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -2
- package/dist/utils/applyDarkMode.d.ts +1 -0
- package/dist/utils/applyDarkMode.js +12 -0
- package/dist/utils/getMediaQuery.d.ts +11 -0
- package/dist/utils/getMediaQuery.js +19 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.js +3 -0
- package/package.json +3 -3
- package/rnw.js +1 -1
- package/src/components/opta/football/opta-match-stats/commentary/__tests__/__snapshots__/OptaMatchStatsCommentary.test.tsx.snap +1 -1
- package/src/components/opta/football/opta-match-stats/shared/styles.ts +0 -8
- package/src/components/opta/football/opta-match-stats/stats-graphs/__tests__/__snapshots__/OptaMatchStatsGraphs.test.tsx.snap +1 -1
- package/src/components/travel-mini-cta/__tests__/__snapshots__/index.test.tsx.snap +209 -0
- package/src/components/travel-mini-cta/__tests__/index.test.tsx +435 -0
- package/src/components/travel-mini-cta/index.tsx +164 -0
- package/src/components/travel-mini-cta/styles.ts +331 -0
- package/src/components/travel-mini-cta/travel-mini-cta.stories.tsx +23 -0
- package/src/components/travel-mini-cta/types.ts +10 -0
- package/src/index.ts +1 -3
- package/src/utils/applyDarkMode.ts +12 -0
- package/src/utils/getMediaQuery.ts +25 -0
- package/src/utils/index.ts +2 -0
- package/dist/components/opta/football/opta-match-stats/matchday-live/DesktopWidget.d.ts +0 -10
- package/dist/components/opta/football/opta-match-stats/matchday-live/DesktopWidget.js +0 -69
- package/dist/components/opta/football/opta-match-stats/matchday-live/MobileWidget.d.ts +0 -12
- package/dist/components/opta/football/opta-match-stats/matchday-live/MobileWidget.js +0 -90
- package/dist/components/opta/football/opta-match-stats/matchday-live/OptaMatchStatsMatchdayLive.d.ts +0 -12
- package/dist/components/opta/football/opta-match-stats/matchday-live/OptaMatchStatsMatchdayLive.js +0 -10
- package/dist/components/opta/football/opta-match-stats/matchday-live/OptaMatchStatsMatchdayLive.stories.js +0 -24
- package/dist/components/opta/football/opta-match-stats/matchday-live/__tests__/OptaMatchStatsMatchdayLive.test.js +0 -48
- package/dist/components/opta/football/opta-match-stats/matchday-live/styles/MatchdayLiveController.d.ts +0 -1
- package/dist/components/opta/football/opta-match-stats/matchday-live/styles/MatchdayLiveController.js +0 -19
- package/dist/components/opta/football/opta-match-stats/matchday-live/styles/NavigationWrapper.d.ts +0 -12
- package/dist/components/opta/football/opta-match-stats/matchday-live/styles/NavigationWrapper.js +0 -67
- package/dist/components/opta/football/opta-match-stats/matchday-live/styles/WidgetContainer.d.ts +0 -6
- package/dist/components/opta/football/opta-match-stats/matchday-live/styles/WidgetContainer.js +0 -714
- package/src/components/opta/football/opta-match-stats/matchday-live/DesktopWidget.tsx +0 -108
- package/src/components/opta/football/opta-match-stats/matchday-live/MobileWidget.tsx +0 -158
- package/src/components/opta/football/opta-match-stats/matchday-live/OptaMatchStatsMatchdayLive.stories.tsx +0 -38
- package/src/components/opta/football/opta-match-stats/matchday-live/OptaMatchStatsMatchdayLive.tsx +0 -23
- package/src/components/opta/football/opta-match-stats/matchday-live/__tests__/OptaMatchStatsMatchdayLive.test.tsx +0 -61
- package/src/components/opta/football/opta-match-stats/matchday-live/__tests__/__snapshots__/OptaMatchStatsMatchdayLive.test.tsx.snap +0 -61
- package/src/components/opta/football/opta-match-stats/matchday-live/styles/MatchdayLiveController.tsx +0 -19
- package/src/components/opta/football/opta-match-stats/matchday-live/styles/NavigationWrapper.tsx +0 -81
- package/src/components/opta/football/opta-match-stats/matchday-live/styles/WidgetContainer.tsx +0 -745
- /package/dist/components/{opta/football/opta-match-stats/matchday-live/OptaMatchStatsMatchdayLive.stories.d.ts → travel-mini-cta/travel-mini-cta.stories.d.ts} +0 -0
|
@@ -54,13 +54,5 @@ export const WidgetWrapper = styled.div<{
|
|
|
54
54
|
@media (max-width: ${maxMDBreakpoint}px) {
|
|
55
55
|
display: none;
|
|
56
56
|
}
|
|
57
|
-
|
|
58
|
-
${props =>
|
|
59
|
-
props.isApp &&
|
|
60
|
-
`
|
|
61
|
-
@media(prefers-color-scheme: dark) {
|
|
62
|
-
color: ${darkTextColor} !important;
|
|
63
|
-
}
|
|
64
|
-
`}
|
|
65
57
|
}
|
|
66
58
|
`;
|
|
@@ -0,0 +1,209 @@
|
|
|
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
|
+
<div
|
|
91
|
+
id="LP_DIV_TRAVEL_1239001"
|
|
92
|
+
/>
|
|
93
|
+
</button>
|
|
94
|
+
<a
|
|
95
|
+
class="sc-kAzzGY sc-kgoBCf epsPGX"
|
|
96
|
+
href="/enquire"
|
|
97
|
+
>
|
|
98
|
+
Enquire now
|
|
99
|
+
</a>
|
|
100
|
+
</div>
|
|
101
|
+
</div>
|
|
102
|
+
</div>
|
|
103
|
+
</div>
|
|
104
|
+
</div>
|
|
105
|
+
`;
|
|
106
|
+
|
|
107
|
+
exports[`TravelMiniCTA should render with isApp prop 1`] = `
|
|
108
|
+
<div>
|
|
109
|
+
<div
|
|
110
|
+
class="sc-bwzfXH euaLVT"
|
|
111
|
+
data-testid="travel-mini-cta"
|
|
112
|
+
>
|
|
113
|
+
<div
|
|
114
|
+
class="sc-htpNat fDJQmH"
|
|
115
|
+
>
|
|
116
|
+
<div
|
|
117
|
+
class="sc-bxivhb fAMkx"
|
|
118
|
+
>
|
|
119
|
+
<div
|
|
120
|
+
class="sc-ifAKCX gShyuV"
|
|
121
|
+
>
|
|
122
|
+
<div
|
|
123
|
+
class="sc-EHOje bDGqOa"
|
|
124
|
+
>
|
|
125
|
+
<span
|
|
126
|
+
class="sc-bZQynM hVYjTG"
|
|
127
|
+
>
|
|
128
|
+
T
|
|
129
|
+
</span>
|
|
130
|
+
</div>
|
|
131
|
+
<div
|
|
132
|
+
class="sc-bdVaJa sc-dnqmqq dpftVr"
|
|
133
|
+
>
|
|
134
|
+
VISIT TIMES HOLIDAYS
|
|
135
|
+
</div>
|
|
136
|
+
</div>
|
|
137
|
+
<div
|
|
138
|
+
class="sc-gzVnrw VgUMC"
|
|
139
|
+
>
|
|
140
|
+
<div
|
|
141
|
+
class="sc-bdVaJa sc-htoDjs isYUYH"
|
|
142
|
+
>
|
|
143
|
+
VISIT TIMES HOLIDAYS
|
|
144
|
+
</div>
|
|
145
|
+
<div
|
|
146
|
+
class="sc-iwsKbI bGbdiO"
|
|
147
|
+
>
|
|
148
|
+
Begin your journey to Croatia with a holiday designed around you
|
|
149
|
+
</div>
|
|
150
|
+
</div>
|
|
151
|
+
</div>
|
|
152
|
+
<div
|
|
153
|
+
class="sc-gZMcBi eQUwuL"
|
|
154
|
+
>
|
|
155
|
+
<div
|
|
156
|
+
class="sc-gqjmRU eBVWqY"
|
|
157
|
+
>
|
|
158
|
+
<a
|
|
159
|
+
class="sc-VigVT HFijS"
|
|
160
|
+
href="tel:08083049757"
|
|
161
|
+
>
|
|
162
|
+
Call us on
|
|
163
|
+
|
|
164
|
+
<span
|
|
165
|
+
class="sc-jTzLTM diHDON"
|
|
166
|
+
>
|
|
167
|
+
08083049757
|
|
168
|
+
</span>
|
|
169
|
+
</a>
|
|
170
|
+
<div
|
|
171
|
+
class="sc-fjdhpX KnCtx"
|
|
172
|
+
>
|
|
173
|
+
<div
|
|
174
|
+
class="sc-jzJRlG csKGWf"
|
|
175
|
+
>
|
|
176
|
+
Mon - Fri: 9am - 6pm
|
|
177
|
+
</div>
|
|
178
|
+
<div
|
|
179
|
+
class="sc-jzJRlG csKGWf"
|
|
180
|
+
>
|
|
181
|
+
Sat: 10am - 5pm
|
|
182
|
+
</div>
|
|
183
|
+
</div>
|
|
184
|
+
</div>
|
|
185
|
+
<div
|
|
186
|
+
class="sc-cSHVUG dAmHXf"
|
|
187
|
+
>
|
|
188
|
+
<button
|
|
189
|
+
class="sc-kAzzGY sc-chPdSV ddVxAZ"
|
|
190
|
+
disabled=""
|
|
191
|
+
type="button"
|
|
192
|
+
>
|
|
193
|
+
Loading chat...
|
|
194
|
+
<div
|
|
195
|
+
id="LP_DIV_TRAVEL_1239001"
|
|
196
|
+
/>
|
|
197
|
+
</button>
|
|
198
|
+
<a
|
|
199
|
+
class="sc-kAzzGY sc-kgoBCf lnRSck"
|
|
200
|
+
href="/enquire"
|
|
201
|
+
>
|
|
202
|
+
Enquire now
|
|
203
|
+
</a>
|
|
204
|
+
</div>
|
|
205
|
+
</div>
|
|
206
|
+
</div>
|
|
207
|
+
</div>
|
|
208
|
+
</div>
|
|
209
|
+
`;
|
|
@@ -0,0 +1,435 @@
|
|
|
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 render with custom button texts', async () => {
|
|
159
|
+
const customProps = {
|
|
160
|
+
...defaultProps,
|
|
161
|
+
primaryButtonText: 'Start chatting',
|
|
162
|
+
secondaryButtonText: 'Learn more'
|
|
163
|
+
};
|
|
164
|
+
render(<TravelMiniCTA {...customProps} />);
|
|
165
|
+
|
|
166
|
+
// Initially shows loading
|
|
167
|
+
expect(screen.getByText('Loading chat...')).toBeInTheDocument();
|
|
168
|
+
expect(screen.getByText('Learn more')).toBeInTheDocument();
|
|
169
|
+
|
|
170
|
+
// Simulate LivePerson loading with custom text
|
|
171
|
+
const chatDiv = document.getElementById('LP_DIV_TRAVEL_1239001');
|
|
172
|
+
const lpElement = document.createElement('div');
|
|
173
|
+
lpElement.setAttribute('data-lp-event', 'click');
|
|
174
|
+
chatDiv && chatDiv.appendChild(lpElement);
|
|
175
|
+
|
|
176
|
+
const observer: MutationObserver = {
|
|
177
|
+
observe: mockObserve,
|
|
178
|
+
disconnect: mockDisconnect,
|
|
179
|
+
takeRecords: jest.fn()
|
|
180
|
+
};
|
|
181
|
+
act(() => {
|
|
182
|
+
mutationCallback([], observer);
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
await waitFor(() => {
|
|
186
|
+
expect(lpElement.textContent).toBe('Start chatting');
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
it('should have correct container test id', () => {
|
|
191
|
+
render(<TravelMiniCTA {...defaultProps} />);
|
|
192
|
+
expect(screen.getByTestId('travel-mini-cta')).toBeInTheDocument();
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
it('should render with isApp prop', () => {
|
|
196
|
+
const { container } = render(
|
|
197
|
+
<TravelMiniCTA {...defaultProps} isApp={true} />
|
|
198
|
+
);
|
|
199
|
+
expect(container).toMatchSnapshot();
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
it('should pass isApp prop to styled components', () => {
|
|
203
|
+
render(<TravelMiniCTA {...defaultProps} isApp={true} />);
|
|
204
|
+
const container = screen.getByTestId('travel-mini-cta');
|
|
205
|
+
expect(container).toBeInTheDocument();
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
describe('LivePerson Chat Integration', () => {
|
|
209
|
+
it('should render LivePerson container div with correct ID', () => {
|
|
210
|
+
render(<TravelMiniCTA {...defaultProps} />);
|
|
211
|
+
const chatDiv = document.getElementById('LP_DIV_TRAVEL_1239001');
|
|
212
|
+
expect(chatDiv).toBeInTheDocument();
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
it('should show loading text initially', () => {
|
|
216
|
+
render(<TravelMiniCTA {...defaultProps} />);
|
|
217
|
+
expect(screen.getByText('Loading chat...')).toBeInTheDocument();
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
it('should setup MutationObserver on mount', () => {
|
|
221
|
+
render(<TravelMiniCTA {...defaultProps} />);
|
|
222
|
+
expect(global.MutationObserver).toHaveBeenCalled();
|
|
223
|
+
expect(mockObserve).toHaveBeenCalledWith(expect.any(HTMLElement), {
|
|
224
|
+
childList: true,
|
|
225
|
+
subtree: true
|
|
226
|
+
});
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
it('should set chat ready when LivePerson element is detected', async () => {
|
|
230
|
+
render(<TravelMiniCTA {...defaultProps} />);
|
|
231
|
+
|
|
232
|
+
// Simulate LivePerson injecting the chat element
|
|
233
|
+
const chatDiv = document.getElementById('LP_DIV_TRAVEL_1239001');
|
|
234
|
+
const lpElement = document.createElement('div');
|
|
235
|
+
lpElement.setAttribute('data-lp-event', 'click');
|
|
236
|
+
lpElement.textContent = 'Chat';
|
|
237
|
+
chatDiv && chatDiv.appendChild(lpElement);
|
|
238
|
+
|
|
239
|
+
// Trigger the mutation observer callback
|
|
240
|
+
const observer: MutationObserver = {
|
|
241
|
+
observe: mockObserve,
|
|
242
|
+
disconnect: mockDisconnect,
|
|
243
|
+
takeRecords: jest.fn()
|
|
244
|
+
};
|
|
245
|
+
act(() => {
|
|
246
|
+
mutationCallback([], observer);
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
await waitFor(() => {
|
|
250
|
+
expect(screen.queryByText('Loading chat...')).not.toBeInTheDocument();
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
it('should replace button text when primaryButtonText is provided', async () => {
|
|
255
|
+
render(
|
|
256
|
+
<TravelMiniCTA {...defaultProps} primaryButtonText="Custom Chat Text" />
|
|
257
|
+
);
|
|
258
|
+
|
|
259
|
+
const chatDiv = document.getElementById('LP_DIV_TRAVEL_1239001');
|
|
260
|
+
const lpElement = document.createElement('div');
|
|
261
|
+
lpElement.setAttribute('data-lp-event', 'click');
|
|
262
|
+
lpElement.textContent = 'Original Text';
|
|
263
|
+
chatDiv && chatDiv.appendChild(lpElement);
|
|
264
|
+
|
|
265
|
+
const observer: MutationObserver = {
|
|
266
|
+
observe: mockObserve,
|
|
267
|
+
disconnect: mockDisconnect,
|
|
268
|
+
takeRecords: jest.fn()
|
|
269
|
+
};
|
|
270
|
+
act(() => {
|
|
271
|
+
mutationCallback([], observer);
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
await waitFor(() => {
|
|
275
|
+
expect(lpElement.textContent).toBe('Custom Chat Text');
|
|
276
|
+
});
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
it('should show chat unavailable message after timeout', async () => {
|
|
280
|
+
render(<TravelMiniCTA {...defaultProps} />);
|
|
281
|
+
|
|
282
|
+
expect(screen.getByText('Loading chat...')).toBeInTheDocument();
|
|
283
|
+
|
|
284
|
+
// Fast-forward time by 15 seconds
|
|
285
|
+
act(() => {
|
|
286
|
+
jest.advanceTimersByTime(15000);
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
await waitFor(() => {
|
|
290
|
+
expect(screen.getByText('Chat unavailable')).toBeInTheDocument();
|
|
291
|
+
expect(screen.queryByText('Loading chat...')).not.toBeInTheDocument();
|
|
292
|
+
});
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
it('should clear timeout when chat loads successfully', async () => {
|
|
296
|
+
const clearTimeoutSpy = jest.spyOn(global, 'clearTimeout');
|
|
297
|
+
render(<TravelMiniCTA {...defaultProps} />);
|
|
298
|
+
|
|
299
|
+
const chatDiv = document.getElementById('LP_DIV_TRAVEL_1239001');
|
|
300
|
+
const lpElement = document.createElement('div');
|
|
301
|
+
lpElement.setAttribute('data-lp-event', 'click');
|
|
302
|
+
chatDiv && chatDiv.appendChild(lpElement);
|
|
303
|
+
|
|
304
|
+
const observer: MutationObserver = {
|
|
305
|
+
observe: mockObserve,
|
|
306
|
+
disconnect: mockDisconnect,
|
|
307
|
+
takeRecords: jest.fn()
|
|
308
|
+
};
|
|
309
|
+
act(() => {
|
|
310
|
+
mutationCallback([], observer);
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
await waitFor(() => {
|
|
314
|
+
expect(clearTimeoutSpy).toHaveBeenCalled();
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
// Timeout should not fire
|
|
318
|
+
act(() => {
|
|
319
|
+
jest.advanceTimersByTime(15000);
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
expect(screen.queryByText('Chat unavailable')).not.toBeInTheDocument();
|
|
323
|
+
clearTimeoutSpy.mockRestore();
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
it('should disconnect observer on unmount', () => {
|
|
327
|
+
const { unmount } = render(<TravelMiniCTA {...defaultProps} />);
|
|
328
|
+
unmount();
|
|
329
|
+
expect(mockDisconnect).toHaveBeenCalled();
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
it('should clear timeout on unmount', () => {
|
|
333
|
+
const clearTimeoutSpy = jest.spyOn(global, 'clearTimeout');
|
|
334
|
+
const { unmount } = render(<TravelMiniCTA {...defaultProps} />);
|
|
335
|
+
unmount();
|
|
336
|
+
expect(clearTimeoutSpy).toHaveBeenCalled();
|
|
337
|
+
clearTimeoutSpy.mockRestore();
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
it('should trigger LivePerson element click when primary button is clicked', async () => {
|
|
341
|
+
render(<TravelMiniCTA {...defaultProps} />);
|
|
342
|
+
|
|
343
|
+
// Simulate chat loaded
|
|
344
|
+
const chatDiv = document.getElementById('LP_DIV_TRAVEL_1239001');
|
|
345
|
+
const lpElement = document.createElement('button');
|
|
346
|
+
lpElement.setAttribute('data-lp-event', 'click');
|
|
347
|
+
|
|
348
|
+
// Mock click on the LivePerson element
|
|
349
|
+
const lpClickSpy = jest.fn();
|
|
350
|
+
lpElement.onclick = lpClickSpy;
|
|
351
|
+
|
|
352
|
+
chatDiv && chatDiv.appendChild(lpElement);
|
|
353
|
+
|
|
354
|
+
const observer: MutationObserver = {
|
|
355
|
+
observe: mockObserve,
|
|
356
|
+
disconnect: mockDisconnect,
|
|
357
|
+
takeRecords: jest.fn()
|
|
358
|
+
};
|
|
359
|
+
act(() => {
|
|
360
|
+
mutationCallback([], observer);
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
await waitFor(() => {
|
|
364
|
+
expect(screen.queryByText('Loading chat...')).not.toBeInTheDocument();
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
// Get and click the primary button
|
|
368
|
+
const parentElement = chatDiv ? chatDiv.parentElement : null;
|
|
369
|
+
if (parentElement instanceof HTMLButtonElement) {
|
|
370
|
+
fireEvent.click(parentElement);
|
|
371
|
+
expect(lpClickSpy).toHaveBeenCalled();
|
|
372
|
+
}
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
it('should handle button click without errors when chat is ready', async () => {
|
|
376
|
+
render(<TravelMiniCTA {...defaultProps} />);
|
|
377
|
+
|
|
378
|
+
const chatDiv = document.getElementById('LP_DIV_TRAVEL_1239001');
|
|
379
|
+
const lpElement = document.createElement('button');
|
|
380
|
+
lpElement.setAttribute('data-lp-event', 'click');
|
|
381
|
+
chatDiv && chatDiv.appendChild(lpElement);
|
|
382
|
+
|
|
383
|
+
const observer: MutationObserver = {
|
|
384
|
+
observe: mockObserve,
|
|
385
|
+
disconnect: mockDisconnect,
|
|
386
|
+
takeRecords: jest.fn()
|
|
387
|
+
};
|
|
388
|
+
act(() => {
|
|
389
|
+
mutationCallback([], observer);
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
await waitFor(() => {
|
|
393
|
+
expect(screen.queryByText('Loading chat...')).not.toBeInTheDocument();
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
// Click button should not throw error
|
|
397
|
+
const parentElement = chatDiv ? chatDiv.parentElement : null;
|
|
398
|
+
if (parentElement instanceof HTMLButtonElement) {
|
|
399
|
+
expect(() => fireEvent.click(parentElement)).not.toThrow();
|
|
400
|
+
}
|
|
401
|
+
});
|
|
402
|
+
|
|
403
|
+
it('should not disconnect observer or set failed if chat loads before timeout', async () => {
|
|
404
|
+
render(<TravelMiniCTA {...defaultProps} />);
|
|
405
|
+
|
|
406
|
+
const chatDiv = document.getElementById('LP_DIV_TRAVEL_1239001');
|
|
407
|
+
const lpElement = document.createElement('div');
|
|
408
|
+
lpElement.setAttribute('data-lp-event', 'click');
|
|
409
|
+
chatDiv && chatDiv.appendChild(lpElement);
|
|
410
|
+
|
|
411
|
+
// Trigger observer before timeout
|
|
412
|
+
const observer: MutationObserver = {
|
|
413
|
+
observe: mockObserve,
|
|
414
|
+
disconnect: mockDisconnect,
|
|
415
|
+
takeRecords: jest.fn()
|
|
416
|
+
};
|
|
417
|
+
act(() => {
|
|
418
|
+
mutationCallback([], observer);
|
|
419
|
+
});
|
|
420
|
+
|
|
421
|
+
await waitFor(() => {
|
|
422
|
+
expect(screen.queryByText('Loading chat...')).not.toBeInTheDocument();
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
// Fast-forward past the timeout
|
|
426
|
+
act(() => {
|
|
427
|
+
jest.advanceTimersByTime(15000);
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
// Should still not show failed state since chat loaded
|
|
431
|
+
expect(screen.queryByText('Chat unavailable')).not.toBeInTheDocument();
|
|
432
|
+
expect(mockDisconnect).not.toHaveBeenCalled();
|
|
433
|
+
});
|
|
434
|
+
});
|
|
435
|
+
});
|