@playpilot/tpi 5.4.0 → 5.5.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.
- package/README.md +10 -4
- package/dist/link-injections.js +9 -9
- package/events.md +6 -0
- package/package.json +1 -1
- package/src/lib/data/translations.ts +5 -0
- package/src/lib/enums/TrackingEvent.ts +3 -0
- package/src/lib/splitTest.ts +40 -0
- package/src/lib/tracking.ts +1 -1
- package/src/lib/types/script.d.ts +1 -0
- package/src/main.ts +5 -0
- package/src/routes/+page.svelte +4 -1
- package/src/routes/components/Playlinks.svelte +99 -47
- package/src/routes/components/Popover.svelte +1 -1
- package/src/routes/components/Title.svelte +1 -1
- package/src/routes/components/TitleModal.svelte +4 -0
- package/src/tests/lib/splitTest.test.js +88 -0
- package/src/tests/routes/+page.test.js +4 -0
- package/src/tests/routes/components/Playlinks.test.js +1 -13
package/events.md
CHANGED
|
@@ -60,3 +60,9 @@ Event | Action | Info | Payload
|
|
|
60
60
|
`ali_manual_report` | _Fires only through manual action when reporting issues with an injection via the Editor._ | | `Title`, `report_reason`, `sid` (of injection), `title` (of injection), `sentence`, `failed` (true or false), `failed_message` (reason for failure as given in the editor), `manual` (true or false)
|
|
61
61
|
`ali_editor_error` | _Fires whenever an error occurs within the Editor._ | | `Title`, `phrase`, `sentence`
|
|
62
62
|
`ali_injection_error` | _Fires whenever an error occurs during injection_ | This includes fetching the injections as well as actually injecting itself. Does not include fetching of the config object. | `message` (error message as given by the browser)
|
|
63
|
+
|
|
64
|
+
### Split Testing
|
|
65
|
+
Event | Action | Info | Payload
|
|
66
|
+
--- | --- | --- | ---
|
|
67
|
+
`ali_split_test_view` | _Should be fired for any active split test_ | | `key`, `variant` (0 or 1)
|
|
68
|
+
`ali_split_test_action` | _Should be fired for any assertion in split tests_ | | `key` (matches the key of `ali_split_test_view`), `variant` (0 or 1), `action`
|
package/package.json
CHANGED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { TrackingEvent } from "./enums/TrackingEvent"
|
|
2
|
+
import { track } from "./tracking"
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Each split test uses a different split test identifier so a user can be part of one, multiple, or none, tests.
|
|
6
|
+
* The identifier is saved on the window object so that it is consistent across this session.
|
|
7
|
+
*/
|
|
8
|
+
export function getSplitTestIdentifier(key: string): number {
|
|
9
|
+
const windowIdentifier = window.PlayPilotLinkInjections?.split_test_identifiers?.[key]
|
|
10
|
+
if (windowIdentifier) return windowIdentifier
|
|
11
|
+
|
|
12
|
+
if (!window.PlayPilotLinkInjections?.split_test_identifiers) window.PlayPilotLinkInjections.split_test_identifiers = {}
|
|
13
|
+
|
|
14
|
+
const randomIdentifier = Math.random()
|
|
15
|
+
window.PlayPilotLinkInjections.split_test_identifiers[key] = randomIdentifier
|
|
16
|
+
|
|
17
|
+
return randomIdentifier
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Split tests are either on or off with a 50/50 split. That's all we need for now.
|
|
22
|
+
*/
|
|
23
|
+
export function isInSplitTest(key: string): boolean {
|
|
24
|
+
const identifier = getSplitTestIdentifier(key)
|
|
25
|
+
const isInSplitTest = identifier > 0.5
|
|
26
|
+
|
|
27
|
+
return isInSplitTest
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function trackSplitTestView(key: string): void {
|
|
31
|
+
const variant = isInSplitTest(key) ? 1 : 0
|
|
32
|
+
|
|
33
|
+
track(TrackingEvent.SplitTestView, null, { key, variant })
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function trackSplitTestAction(key: string, action: string): void {
|
|
37
|
+
const variant = isInSplitTest(key) ? 1 : 0
|
|
38
|
+
|
|
39
|
+
track(TrackingEvent.SplitTestAction, null, { key, variant, action })
|
|
40
|
+
}
|
package/src/lib/tracking.ts
CHANGED
|
@@ -10,7 +10,7 @@ const baseUrl = 'https://insights.playpilot.net'
|
|
|
10
10
|
* @param [title] Title related to the event
|
|
11
11
|
* @param [payload] Any data that will be included with the event
|
|
12
12
|
*/
|
|
13
|
-
export async function track(event: string, title: TitleData | null = null, payload: Record<string, string | string[] | number | null | undefined> = {}): Promise<void> {
|
|
13
|
+
export async function track(event: string, title: TitleData | null = null, payload: Record<string, string | string[] | number | boolean | null | undefined> = {}): Promise<void> {
|
|
14
14
|
const headers = new Headers({ 'Content-Type': 'application/json' })
|
|
15
15
|
|
|
16
16
|
if (title) {
|
package/src/main.ts
CHANGED
|
@@ -14,6 +14,7 @@ window.PlayPilotLinkInjections = {
|
|
|
14
14
|
domain_sid: null,
|
|
15
15
|
last_successful_fetch: null,
|
|
16
16
|
tracked_events: [],
|
|
17
|
+
split_test_identifiers: {},
|
|
17
18
|
app: null,
|
|
18
19
|
|
|
19
20
|
initialize(config = { token: '', selector: '', after_article_selector: '', after_article_insert_position: '', language: null, organization_sid: null, domain_sid: null, editorial_token: '' }): void {
|
|
@@ -81,6 +82,10 @@ window.PlayPilotLinkInjections = {
|
|
|
81
82
|
console.groupCollapsed('Tracked events')
|
|
82
83
|
console.log(this.tracked_events)
|
|
83
84
|
console.groupEnd()
|
|
85
|
+
|
|
86
|
+
console.groupCollapsed('Split tests')
|
|
87
|
+
console.log(this.split_test_identifiers)
|
|
88
|
+
console.groupEnd()
|
|
84
89
|
console.groupEnd()
|
|
85
90
|
}
|
|
86
91
|
}
|
package/src/routes/+page.svelte
CHANGED
|
@@ -7,9 +7,10 @@
|
|
|
7
7
|
import { isCrawler } from '$lib/crawler'
|
|
8
8
|
import { TrackingEvent } from '$lib/enums/TrackingEvent'
|
|
9
9
|
import { authorize, getAuthToken, isEditorialModeEnabled, removeAuthCookie, setEditorialParamInUrl } from '$lib/auth'
|
|
10
|
+
import { trackSplitTestView } from '$lib/splitTest'
|
|
11
|
+
import type { LinkInjectionResponse, LinkInjection, LinkInjectionTypes } from '$lib/types/injection'
|
|
10
12
|
import Editor from './components/Editorial/Editor.svelte'
|
|
11
13
|
import EditorTrigger from './components/Editorial/EditorTrigger.svelte'
|
|
12
|
-
import type { LinkInjectionResponse, LinkInjection, LinkInjectionTypes } from '$lib/types/injection'
|
|
13
14
|
import Alert from './components/Editorial/Alert.svelte'
|
|
14
15
|
import TrackingPixels from './components/TrackingPixels.svelte'
|
|
15
16
|
|
|
@@ -40,6 +41,8 @@
|
|
|
40
41
|
(async () => {
|
|
41
42
|
await initialize()
|
|
42
43
|
track(TrackingEvent.ArticlePageView)
|
|
44
|
+
|
|
45
|
+
trackSplitTestView('initial_test')
|
|
43
46
|
})()
|
|
44
47
|
|
|
45
48
|
return () => clearLinkInjections()
|
|
@@ -6,20 +6,22 @@
|
|
|
6
6
|
import type { PlaylinkData } from '$lib/types/playlink'
|
|
7
7
|
import type { TitleData } from '$lib/types/title'
|
|
8
8
|
import { heading } from '$lib/actions/heading'
|
|
9
|
-
import IconContinue from './Icons/IconContinue.svelte'
|
|
10
9
|
import { getContext } from 'svelte'
|
|
11
10
|
import { removeImageUrlPrefix } from '$lib/image'
|
|
12
11
|
|
|
13
12
|
interface Props {
|
|
14
13
|
playlinks: PlaylinkData[]
|
|
15
14
|
title: TitleData
|
|
16
|
-
list?: boolean
|
|
17
15
|
}
|
|
18
16
|
|
|
19
|
-
const { playlinks, title
|
|
17
|
+
const { playlinks, title }: Props = $props()
|
|
20
18
|
|
|
21
19
|
const isModal = getContext('scope') === 'modal'
|
|
22
20
|
|
|
21
|
+
let outerWidth = $state(0)
|
|
22
|
+
|
|
23
|
+
const list = $derived(outerWidth < 500)
|
|
24
|
+
|
|
23
25
|
// Remove any playlinks without logos, as these are likely sub providers.
|
|
24
26
|
const filteredPlaylinks = $derived(playlinks.filter(playlink => !!playlink.logo_url))
|
|
25
27
|
const mergedPlaylink = $derived(mergePlaylinks(filteredPlaylinks))
|
|
@@ -45,21 +47,23 @@
|
|
|
45
47
|
</div>
|
|
46
48
|
{/if}
|
|
47
49
|
|
|
48
|
-
<div class="playlinks" class:list>
|
|
50
|
+
<div class="playlinks" class:list bind:clientWidth={outerWidth}>
|
|
49
51
|
{#each mergedPlaylink as { name, url, logo_url, highlighted, cta_text, extra_info: { category } }}
|
|
50
52
|
<a href={url} target="_blank" class="playlink" class:highlighted={highlighted && cta_text} onclick={() => onclick(name)} data-playlink={name} rel="sponsored">
|
|
51
|
-
<
|
|
53
|
+
<div class="playlink-content">
|
|
54
|
+
<img src={removeImageUrlPrefix(logo_url)} alt="" height="36" width="36" />
|
|
52
55
|
|
|
53
|
-
<div>
|
|
54
56
|
<span class="name">{name}</span>
|
|
55
|
-
<
|
|
56
|
-
</div>
|
|
57
|
+
<span class="category">{categoryStrings[category] || t('Stream')}</span>
|
|
57
58
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
{#if cta_text}
|
|
60
|
+
<span class="cta">{cta_text}</span>
|
|
61
|
+
{/if}
|
|
62
|
+
|
|
63
|
+
<div class="action">
|
|
64
|
+
{t('Watch')}
|
|
61
65
|
</div>
|
|
62
|
-
|
|
66
|
+
</div>
|
|
63
67
|
</a>
|
|
64
68
|
{/each}
|
|
65
69
|
|
|
@@ -71,16 +75,13 @@
|
|
|
71
75
|
</div>
|
|
72
76
|
|
|
73
77
|
<style lang="scss">
|
|
78
|
+
$image-size: margin(2.25);
|
|
79
|
+
|
|
74
80
|
img {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
width: var(--size);
|
|
81
|
+
height: $image-size;
|
|
82
|
+
width: $image-size;
|
|
78
83
|
border-radius: margin(0.5);
|
|
79
84
|
background: rgba(0, 0, 0, 0.25);
|
|
80
|
-
|
|
81
|
-
@media (min-width: 640px) {
|
|
82
|
-
--size: #{margin(2.5)};
|
|
83
|
-
}
|
|
84
85
|
}
|
|
85
86
|
|
|
86
87
|
.heading {
|
|
@@ -94,40 +95,35 @@
|
|
|
94
95
|
|
|
95
96
|
.playlinks {
|
|
96
97
|
box-sizing: border-box;
|
|
97
|
-
display:
|
|
98
|
+
display: grid;
|
|
99
|
+
grid-template-columns: repeat(auto-fill, minmax(margin(15), 1fr));
|
|
98
100
|
gap: margin(0.5);
|
|
99
101
|
width: calc(100% + margin(2));
|
|
100
102
|
padding: margin(0.5) margin(1);
|
|
101
103
|
margin: 0 margin(-1);
|
|
102
|
-
overflow: auto;
|
|
103
|
-
scrollbar-width: none;
|
|
104
|
-
}
|
|
105
104
|
|
|
106
|
-
|
|
107
|
-
|
|
105
|
+
&.list {
|
|
106
|
+
grid-template-columns: 1fr;
|
|
107
|
+
}
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
.list {
|
|
111
|
-
display: grid;
|
|
112
|
-
grid-template-columns: repeat(auto-fill, minmax(margin(15), 1fr));
|
|
113
110
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
111
|
+
@keyframes sheen {
|
|
112
|
+
0%, 20%, 60%, 80.01%, 100% {
|
|
113
|
+
background-position: -100% 0;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
80% {
|
|
117
|
+
background-position: 100% 0;
|
|
118
118
|
}
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
.playlink {
|
|
122
122
|
position: relative;
|
|
123
|
-
display: flex;
|
|
124
|
-
align-items: center;
|
|
125
|
-
gap: margin(0.75);
|
|
126
|
-
padding: margin(0.75);
|
|
127
123
|
background: var(--playpilot-playlink-background, var(--playpilot-lighter));
|
|
128
124
|
box-shadow: var(--playpilot-playlink-shadow, var(--playpilot-shadow));
|
|
129
125
|
border-radius: var(--playpilot-playlink-border-radius, margin(0.5));
|
|
130
|
-
color: var(--playpilot-playlink-text-color, var(--playpilot-text-color
|
|
126
|
+
color: var(--playpilot-playlink-text-color, var(--playpilot-text-color)) !important;
|
|
131
127
|
font-weight: var(--playpilot-playlink-font-weight, inherit);
|
|
132
128
|
font-style: var(--playpilot-playlink-font-style, normal) !important;
|
|
133
129
|
text-decoration: none !important;
|
|
@@ -143,6 +139,12 @@
|
|
|
143
139
|
}
|
|
144
140
|
|
|
145
141
|
&.highlighted {
|
|
142
|
+
grid-column: span 2;
|
|
143
|
+
|
|
144
|
+
.list & {
|
|
145
|
+
grid-column: 1;
|
|
146
|
+
}
|
|
147
|
+
|
|
146
148
|
&::before {
|
|
147
149
|
content: "";
|
|
148
150
|
z-index: 1;
|
|
@@ -153,35 +155,81 @@
|
|
|
153
155
|
bottom: 0;
|
|
154
156
|
left: 0;
|
|
155
157
|
border-radius: inherit;
|
|
156
|
-
|
|
158
|
+
background: linear-gradient(to left, currentColor 20%, transparent 50%, currentColor 80%);
|
|
159
|
+
background-size: 200% 100%;
|
|
160
|
+
background-position: -100% 0;
|
|
157
161
|
opacity: 0.35;
|
|
158
162
|
pointer-events: none;
|
|
163
|
+
|
|
164
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
165
|
+
animation: sheen 4000ms ease-in-out infinite;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
&::after {
|
|
170
|
+
content: "";
|
|
171
|
+
z-index: 2;
|
|
172
|
+
display: block;
|
|
173
|
+
position: absolute;
|
|
174
|
+
top: 2px;
|
|
175
|
+
right: 2px;
|
|
176
|
+
bottom: 2px;
|
|
177
|
+
left: 2px;
|
|
178
|
+
border-radius: inherit;
|
|
179
|
+
background: var(--playpilot-playlink-background, var(--playpilot-lighter));
|
|
159
180
|
}
|
|
160
181
|
}
|
|
161
182
|
|
|
162
183
|
img {
|
|
184
|
+
grid-area: image;
|
|
163
185
|
margin: 0;
|
|
164
186
|
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
.playlink-content {
|
|
190
|
+
position: relative;
|
|
191
|
+
z-index: 5;
|
|
192
|
+
display: grid;
|
|
193
|
+
grid-template-areas: "image name action" "image category action";
|
|
194
|
+
grid-template-columns: $image-size auto margin(4);
|
|
195
|
+
align-items: center;
|
|
196
|
+
gap: 0 margin(0.75);
|
|
197
|
+
padding: margin(0.75);
|
|
165
198
|
|
|
166
|
-
.
|
|
167
|
-
|
|
168
|
-
gap: margin(0.
|
|
199
|
+
.highlighted & {
|
|
200
|
+
grid-template-areas: "image name action" "image category action" "image cta action";
|
|
201
|
+
gap: margin(0.25) margin(0.75);
|
|
169
202
|
}
|
|
170
203
|
}
|
|
171
204
|
|
|
172
205
|
.name {
|
|
173
|
-
|
|
206
|
+
grid-area: name;
|
|
207
|
+
width: 100%;
|
|
208
|
+
overflow: hidden;
|
|
209
|
+
font-weight: var(--playpilot-playlink-font-weight, 500);
|
|
174
210
|
font-family: var(--playpilot-playlink-font-family, inherit);
|
|
211
|
+
text-overflow: ellipsis;
|
|
212
|
+
white-space: nowrap;
|
|
175
213
|
}
|
|
176
214
|
|
|
177
215
|
.category {
|
|
178
|
-
|
|
216
|
+
grid-area: category;
|
|
217
|
+
width: 100%;
|
|
179
218
|
font-size: var(--playpilot-playlinks-category-font-size, margin(0.625));
|
|
180
|
-
color: var(--playpilot-playlink-category-text-color, var(--playpilot-text-color));
|
|
219
|
+
color: var(--playpilot-playlink-category-text-color, var(--playpilot-text-color-alt));
|
|
181
220
|
font-weight: var(--playpilot-playlink-category-font-weight, inherit);
|
|
182
221
|
font-family: var(--playpilot-playlink-category-font-family, inherit);
|
|
183
222
|
}
|
|
184
223
|
|
|
224
|
+
.cta {
|
|
225
|
+
grid-area: cta;
|
|
226
|
+
width: 100%;
|
|
227
|
+
font-size: var(--playpilot-playlinks-cta-font-size, var(--playpilot-playlinks-category-font-size, margin(0.625)));
|
|
228
|
+
color: var(--playpilot-playlink-cta-text-color, var(--playpilot-playlink-category-text-color, var(--playpilot-text-color)));
|
|
229
|
+
font-weight: var(--playpilot-playlink-cta-font-weight, var(--playpilot-playlink-category-font-weight, inherit));
|
|
230
|
+
font-family: var(--playpilot-playlink-cta-font-family, var(--playpilot-playlink-category-font-family, inherit));
|
|
231
|
+
}
|
|
232
|
+
|
|
185
233
|
.disclaimer {
|
|
186
234
|
margin-top: var(--playpilot-playlinks-disclaimer-margin-top, margin(0.5));
|
|
187
235
|
opacity: var(--playpilot-playlinks-disclaimer-opacity, 0.65);
|
|
@@ -205,9 +253,13 @@
|
|
|
205
253
|
line-height: 1.35;
|
|
206
254
|
}
|
|
207
255
|
|
|
208
|
-
.
|
|
209
|
-
|
|
256
|
+
.action {
|
|
257
|
+
grid-area: action;
|
|
210
258
|
margin-left: auto;
|
|
211
|
-
padding:
|
|
259
|
+
padding: margin(0.5);
|
|
260
|
+
font-weight: var(--playpilot-playlinks-action-font-weight, 500);
|
|
261
|
+
color: var(--playpilot-playlinks-action-text-color, var(--playpilot-text-color));
|
|
262
|
+
border: var(--playpilot-playlinks-action-border, 1px solid currentColor);
|
|
263
|
+
border-radius: var(--playpilot-playlinks-action-border-radius, margin(2));
|
|
212
264
|
}
|
|
213
265
|
</style>
|
|
@@ -91,7 +91,7 @@
|
|
|
91
91
|
border-radius: var(--playpilot-popover-border-radius, margin(1));
|
|
92
92
|
background: var(--playpilot-popover-background, var(--playpilot-light));
|
|
93
93
|
box-shadow: var(--playpilot-popover-shadow, var(--playpilot-shadow-large));
|
|
94
|
-
max-height: min(var(--max-height), margin(
|
|
94
|
+
max-height: min(var(--max-height), margin(36));
|
|
95
95
|
scrollbar-width: thin;
|
|
96
96
|
overflow-y: overlay;
|
|
97
97
|
overflow-x: hidden;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { TrackingEvent } from '$lib/enums/TrackingEvent'
|
|
3
3
|
import { track } from '$lib/tracking'
|
|
4
4
|
import type { TitleData } from '$lib/types/title'
|
|
5
|
+
import { trackSplitTestAction } from '$lib/splitTest'
|
|
5
6
|
import { onMount } from 'svelte'
|
|
6
7
|
import Modal from './Modal.svelte'
|
|
7
8
|
import Title from './Title.svelte'
|
|
@@ -19,6 +20,9 @@
|
|
|
19
20
|
|
|
20
21
|
onMount(() => {
|
|
21
22
|
const openTimestamp = Date.now()
|
|
23
|
+
|
|
24
|
+
trackSplitTestAction('initial_test', 'modal')
|
|
25
|
+
|
|
22
26
|
return () => track(TrackingEvent.TitleModalClose, title, { time_spent: Date.now() - openTimestamp })
|
|
23
27
|
})
|
|
24
28
|
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { describe, it, expect, vi, afterEach } from 'vitest'
|
|
2
|
+
import { getSplitTestIdentifier, isInSplitTest, trackSplitTestAction, trackSplitTestView } from '$lib/splitTest'
|
|
3
|
+
import { track } from '$lib/tracking'
|
|
4
|
+
import { TrackingEvent } from '$lib/enums/TrackingEvent'
|
|
5
|
+
|
|
6
|
+
vi.mock('$lib/tracking', () => ({
|
|
7
|
+
track: vi.fn(),
|
|
8
|
+
}))
|
|
9
|
+
|
|
10
|
+
describe('$lib/splitTest', () => {
|
|
11
|
+
describe('getSplitTestIdentifier', () => {
|
|
12
|
+
afterEach(() => {
|
|
13
|
+
// @ts-ignore
|
|
14
|
+
window.PlayPilotLinkInjections = {}
|
|
15
|
+
|
|
16
|
+
vi.resetAllMocks()
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
it('Should set window object with given key if window object was not set to begin with', () => {
|
|
20
|
+
// @ts-ignore
|
|
21
|
+
window.PlayPilotLinkInjections = {}
|
|
22
|
+
|
|
23
|
+
const value = getSplitTestIdentifier('Some key')
|
|
24
|
+
|
|
25
|
+
expect(window.PlayPilotLinkInjections.split_test_identifiers).toEqual({ 'Some key': value })
|
|
26
|
+
// @ts-ignore
|
|
27
|
+
expect(value).toBe(window.PlayPilotLinkInjections.split_test_identifiers['Some key'])
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
it('Should return value as stored in the window object', () => {
|
|
31
|
+
// @ts-ignore
|
|
32
|
+
window.PlayPilotLinkInjections.split_test_identifiers = {}
|
|
33
|
+
window.PlayPilotLinkInjections.split_test_identifiers['Some key'] = 0.5
|
|
34
|
+
|
|
35
|
+
expect(getSplitTestIdentifier('Some key')).toBe(0.5)
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
it('Should set separate value for different keys', () => {
|
|
39
|
+
// @ts-ignore
|
|
40
|
+
window.PlayPilotLinkInjections.split_test_identifiers = {}
|
|
41
|
+
|
|
42
|
+
getSplitTestIdentifier('Some key')
|
|
43
|
+
getSplitTestIdentifier('Some other key')
|
|
44
|
+
|
|
45
|
+
expect(window.PlayPilotLinkInjections.split_test_identifiers).toEqual({
|
|
46
|
+
'Some key': expect.any(Number),
|
|
47
|
+
'Some other key': expect.any(Number),
|
|
48
|
+
})
|
|
49
|
+
})
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
describe('isInSplitTest', () => {
|
|
53
|
+
it('Should return true if stored value is higher than 0.5', () => {
|
|
54
|
+
// @ts-ignore
|
|
55
|
+
window.PlayPilotLinkInjections.split_test_identifiers = {}
|
|
56
|
+
window.PlayPilotLinkInjections.split_test_identifiers['Some key'] = 0.75
|
|
57
|
+
|
|
58
|
+
expect(isInSplitTest('Some key')).toBe(true)
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
it('Should return false if stored value is lower than 0.5', () => {
|
|
62
|
+
// @ts-ignore
|
|
63
|
+
window.PlayPilotLinkInjections.split_test_identifiers = {}
|
|
64
|
+
window.PlayPilotLinkInjections.split_test_identifiers['Some key'] = 0.25
|
|
65
|
+
|
|
66
|
+
expect(isInSplitTest('Some key')).toBe(false)
|
|
67
|
+
})
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
describe('trackSplitTestView', () => {
|
|
71
|
+
it('Should track view event with the given key', () => {
|
|
72
|
+
trackSplitTestView('Some key')
|
|
73
|
+
|
|
74
|
+
const variant = isInSplitTest('Some key') ? 1 : 0
|
|
75
|
+
|
|
76
|
+
expect(track).toHaveBeenCalledWith(TrackingEvent.SplitTestView, null, { key: 'Some key', variant })
|
|
77
|
+
})
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
describe('trackSplitTestAction', () => {
|
|
81
|
+
it('Should track action event with the given key and action', () => {
|
|
82
|
+
trackSplitTestAction('Some key', 'Some action')
|
|
83
|
+
const variant = isInSplitTest('Some key') ? 1 : 0
|
|
84
|
+
|
|
85
|
+
expect(track).toHaveBeenCalledWith(TrackingEvent.SplitTestAction, null, { key: 'Some key', variant, action: 'Some action' })
|
|
86
|
+
})
|
|
87
|
+
})
|
|
88
|
+
})
|
|
@@ -104,19 +104,7 @@ describe('Playlinks.svelte', () => {
|
|
|
104
104
|
expect(getAllByText('Some playlink')).toHaveLength(1)
|
|
105
105
|
})
|
|
106
106
|
|
|
107
|
-
it('Should
|
|
108
|
-
const { container } = render(Playlinks, { playlinks: [], title })
|
|
109
|
-
|
|
110
|
-
expect(container.querySelector('.list')).not.toBeTruthy()
|
|
111
|
-
})
|
|
112
|
-
|
|
113
|
-
it('Should have list class when prop is given', () => {
|
|
114
|
-
const { container } = render(Playlinks, { playlinks: [], title, list: true })
|
|
115
|
-
|
|
116
|
-
expect(container.querySelector('.list')).toBeTruthy()
|
|
117
|
-
})
|
|
118
|
-
|
|
119
|
-
it('Should highlight and replace category text for playlinks that have highlighted as true', () => {
|
|
107
|
+
it('Should highlight and show category text for playlinks that have highlighted as true', () => {
|
|
120
108
|
const playlinks = [
|
|
121
109
|
{ name: 'Some playlink', logo_url: 'logo', extra_info: { category: 'SVOD' } },
|
|
122
110
|
{ name: 'Some other playlink', logo_url: 'logo', highlighted: true, cta_text: '', extra_info: { category: 'BUY' } },
|