@playpilot/tpi 5.6.0-beta.video.7 → 5.7.0-beta.display-2
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/link-injections.js +9 -9
- package/events.md +8 -2
- package/package.json +1 -1
- package/src/lib/ads.ts +38 -0
- package/src/lib/constants.ts +2 -1
- package/src/lib/enums/ImageDimensions.ts +7 -0
- package/src/lib/enums/SplitTest.ts +23 -0
- package/src/lib/enums/TrackingEvent.ts +3 -0
- package/src/lib/image.ts +12 -0
- package/src/lib/linkInjection.ts +36 -2
- package/src/lib/splitTest.ts +19 -14
- package/src/lib/types/campaign.d.ts +45 -0
- package/src/lib/types/playlink.d.ts +2 -0
- package/src/lib/types/script.d.ts +5 -0
- package/src/main.ts +6 -0
- package/src/routes/+layout.svelte +4 -0
- package/src/routes/+page.svelte +13 -2
- package/src/routes/components/Ads/Display.svelte +140 -0
- package/src/routes/components/Ads/TopScroll.svelte +240 -0
- package/src/routes/components/DragHandle.svelte +105 -0
- package/src/routes/components/Modal.svelte +125 -30
- package/src/routes/components/Playlink.svelte +185 -0
- package/src/routes/components/Playlinks.svelte +34 -168
- package/src/routes/components/Popover.svelte +30 -2
- package/src/routes/components/Title.svelte +13 -43
- package/src/routes/components/TitleModal.svelte +24 -10
- package/src/routes/components/TitlePopover.svelte +12 -6
- package/src/tests/lib/ads.test.js +55 -0
- package/src/tests/lib/splitTest.test.js +97 -18
- package/src/tests/routes/+page.test.js +33 -0
- package/src/tests/routes/components/Ads/Display.test.js +109 -0
- package/src/tests/routes/components/Ads/TopScroll.test.js +104 -0
- package/src/tests/routes/components/Playlink.test.js +95 -0
- package/src/tests/routes/components/Playlinks.test.js +0 -30
- package/src/tests/routes/components/TitleModal.test.js +36 -0
- package/src/tests/routes/components/TitlePopover.test.js +20 -0
- package/src/routes/components/Ads/FloatingPlaylink.svelte +0 -62
- package/src/routes/components/Ads/VideoBackground.svelte +0 -28
|
@@ -49,21 +49,6 @@ describe('Playlinks.svelte', () => {
|
|
|
49
49
|
expect(queryByTestId('commission-disclaimer')).not.toBeTruthy()
|
|
50
50
|
})
|
|
51
51
|
|
|
52
|
-
it('Should render category as words', () => {
|
|
53
|
-
const playlinks = [
|
|
54
|
-
{ name: 'Some playlink', logo_url: 'logo', extra_info: { category: 'SVOD' } },
|
|
55
|
-
{ name: 'Some buy playlink', logo_url: 'logo', extra_info: { category: 'BUY' } },
|
|
56
|
-
{ name: 'Some rent playlink', logo_url: 'logo', extra_info: { category: 'RENT' } },
|
|
57
|
-
{ name: 'Some other playlink', logo_url: 'logo', extra_info: { category: 'other' } },
|
|
58
|
-
]
|
|
59
|
-
// @ts-ignore
|
|
60
|
-
const { getByText, getAllByText } = render(Playlinks, { playlinks, title })
|
|
61
|
-
|
|
62
|
-
expect(getAllByText('Stream')).toHaveLength(2)
|
|
63
|
-
expect(getByText('Buy')).toBeTruthy()
|
|
64
|
-
expect(getByText('Rent')).toBeTruthy()
|
|
65
|
-
})
|
|
66
|
-
|
|
67
52
|
it('Should call track function when clicked', async () => {
|
|
68
53
|
const playlinks = [
|
|
69
54
|
{ name: 'Some playlink', logo_url: 'logo', extra_info: { category: 'SVOD' } },
|
|
@@ -103,19 +88,4 @@ describe('Playlinks.svelte', () => {
|
|
|
103
88
|
|
|
104
89
|
expect(getAllByText('Some playlink')).toHaveLength(1)
|
|
105
90
|
})
|
|
106
|
-
|
|
107
|
-
it('Should highlight and show category text for playlinks that have highlighted as true', () => {
|
|
108
|
-
const playlinks = [
|
|
109
|
-
{ name: 'Some playlink', logo_url: 'logo', extra_info: { category: 'SVOD' } },
|
|
110
|
-
{ name: 'Some other playlink', logo_url: 'logo', highlighted: true, cta_text: '', extra_info: { category: 'BUY' } },
|
|
111
|
-
{ name: 'Some highlighted playlink', logo_url: 'logo', highlighted: true, cta_text: 'Some CTA', extra_info: { category: 'BUY' } },
|
|
112
|
-
]
|
|
113
|
-
// @ts-ignore
|
|
114
|
-
const { getByText } = render(Playlinks, { playlinks, title })
|
|
115
|
-
|
|
116
|
-
expect(getByText('Some playlink').closest('.playlink')?.classList).not.toContain('highlighted')
|
|
117
|
-
expect(getByText('Some other playlink').closest('.playlink')?.classList).not.toContain('highlighted')
|
|
118
|
-
expect(getByText('Some highlighted playlink').closest('.playlink')?.classList).toContain('highlighted')
|
|
119
|
-
expect(getByText('Some CTA')).toBeTruthy()
|
|
120
|
-
})
|
|
121
91
|
})
|
|
@@ -45,4 +45,40 @@ describe('TitleModal.svelte', () => {
|
|
|
45
45
|
|
|
46
46
|
expect(track).toHaveBeenCalledWith(TrackingEvent.TitleModalClose, title, { time_spent: 200 })
|
|
47
47
|
})
|
|
48
|
+
|
|
49
|
+
it('Should render top scroll ad when given', () => {
|
|
50
|
+
// @ts-ignore
|
|
51
|
+
window.PlayPilotLinkInjections = { ads: [{ campaign_format: 'top_scroll', content: {}, cta: {} }] }
|
|
52
|
+
|
|
53
|
+
const { container } = render(TitleModal, { onclose, title })
|
|
54
|
+
|
|
55
|
+
expect(container.querySelector('.top-scroll')).toBeTruthy()
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
it('Should not render top scroll ad when not given', () => {
|
|
59
|
+
// @ts-ignore
|
|
60
|
+
window.PlayPilotLinkInjections = { ads: null }
|
|
61
|
+
|
|
62
|
+
const { container } = render(TitleModal, { onclose, title })
|
|
63
|
+
|
|
64
|
+
expect(container.querySelector('.top-scroll')).not.toBeTruthy()
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
it('Should render display ad when given', () => {
|
|
68
|
+
// @ts-ignore
|
|
69
|
+
window.PlayPilotLinkInjections = { ads: [{ campaign_format: 'card', content: {}, cta: {} }] }
|
|
70
|
+
|
|
71
|
+
const { container } = render(TitleModal, { onclose, title })
|
|
72
|
+
|
|
73
|
+
expect(container.querySelector('.display')).toBeTruthy()
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
it('Should not render top scroll ad when not given', () => {
|
|
77
|
+
// @ts-ignore
|
|
78
|
+
window.PlayPilotLinkInjections = { ads: null }
|
|
79
|
+
|
|
80
|
+
const { container } = render(TitleModal, { onclose, title })
|
|
81
|
+
|
|
82
|
+
expect(container.querySelector('.display')).not.toBeTruthy()
|
|
83
|
+
})
|
|
48
84
|
})
|
|
@@ -37,4 +37,24 @@ describe('TitlePopover.svelte', () => {
|
|
|
37
37
|
|
|
38
38
|
expect(track).toHaveBeenCalledWith(TrackingEvent.TitlePopoverClose, title, { time_spent: 200 })
|
|
39
39
|
})
|
|
40
|
+
|
|
41
|
+
it('Should render top scroll ad when given', () => {
|
|
42
|
+
// @ts-ignore
|
|
43
|
+
window.PlayPilotLinkInjections = { ads: [{ campaign_format: 'top_scroll', content: {}, cta: {} }] }
|
|
44
|
+
|
|
45
|
+
const event = new MouseEvent('mouseenter')
|
|
46
|
+
const { container } = render(TitlePopover, { event, title })
|
|
47
|
+
|
|
48
|
+
expect(container.querySelector('.top-scroll')).toBeTruthy()
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
it('Should not render top scroll ad when not given', () => {
|
|
52
|
+
// @ts-ignore
|
|
53
|
+
window.PlayPilotLinkInjections = { ads: null }
|
|
54
|
+
|
|
55
|
+
const event = new MouseEvent('mouseenter')
|
|
56
|
+
const { container } = render(TitlePopover, { event, title })
|
|
57
|
+
|
|
58
|
+
expect(container.querySelector('.top-scroll')).not.toBeTruthy()
|
|
59
|
+
})
|
|
40
60
|
})
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import { removeImageUrlPrefix } from '$lib/image'
|
|
3
|
-
import type { PlaylinkData } from '$lib/types/playlink'
|
|
4
|
-
import { prefersReducedMotion } from 'svelte/motion'
|
|
5
|
-
import { fly } from 'svelte/transition'
|
|
6
|
-
|
|
7
|
-
interface Props {
|
|
8
|
-
playlink: PlaylinkData
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
const { playlink }: Props = $props()
|
|
12
|
-
|
|
13
|
-
const { name, url, logo_url, cta_text } = $derived(playlink)
|
|
14
|
-
</script>
|
|
15
|
-
|
|
16
|
-
<a href={url} target="_blank" class="floating-playlink" rel="sponsored" transition:fly|global={{ x: -100, duration: prefersReducedMotion.current ? 0 : 500, delay: 2000 }}>
|
|
17
|
-
<img src={removeImageUrlPrefix(logo_url)} alt="" height="24" width="24" />
|
|
18
|
-
|
|
19
|
-
<div>
|
|
20
|
-
<span class="name">{name}</span>
|
|
21
|
-
<div class="cta">{cta_text || 'Free trial for 30 days!'}</div>
|
|
22
|
-
</div>
|
|
23
|
-
</a>
|
|
24
|
-
|
|
25
|
-
<style lang="scss">
|
|
26
|
-
.floating-playlink {
|
|
27
|
-
z-index: 1;
|
|
28
|
-
position: absolute;
|
|
29
|
-
top: margin(1);
|
|
30
|
-
left: margin(1);
|
|
31
|
-
display: flex;
|
|
32
|
-
align-items: center;
|
|
33
|
-
gap: margin(0.75);
|
|
34
|
-
padding: margin(0.5) margin(0.75);
|
|
35
|
-
outline: 2px solid rgba(255, 255, 255, 0.5);
|
|
36
|
-
border-radius: margin(0.5);
|
|
37
|
-
background: linear-gradient(to right, var(--playpilot-content), transparent);
|
|
38
|
-
font-family: inherit;
|
|
39
|
-
color: var(--playpilot-text-color) !important;
|
|
40
|
-
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.35);
|
|
41
|
-
font-size: margin(0.875);
|
|
42
|
-
font-style: normal !important;
|
|
43
|
-
line-height: 1.2;
|
|
44
|
-
text-decoration: none;
|
|
45
|
-
|
|
46
|
-
&:hover {
|
|
47
|
-
outline: 2px solid rgba(255, 255, 255, 0.75);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
img {
|
|
51
|
-
border-radius: margin(0.25);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
.name {
|
|
56
|
-
font-weight: 500;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
.cta {
|
|
60
|
-
font-size: margin(0.75);
|
|
61
|
-
}
|
|
62
|
-
</style>
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
const sources = [
|
|
3
|
-
'https://pub-6f03bccd9247476c9b84407f45af8155.r2.dev/apple-tv-plus-the-morning-show-cropped.mp4',
|
|
4
|
-
]
|
|
5
|
-
|
|
6
|
-
const src = sources[Math.floor(Math.random() * sources.length)]
|
|
7
|
-
</script>
|
|
8
|
-
|
|
9
|
-
<div class="video-background">
|
|
10
|
-
<video class="video" autoplay muted playsinline loop>
|
|
11
|
-
<source {src} type="video/mp4">
|
|
12
|
-
<track kind="captions" />
|
|
13
|
-
</video>
|
|
14
|
-
</div>
|
|
15
|
-
|
|
16
|
-
<style lang="scss">
|
|
17
|
-
.video-background {
|
|
18
|
-
height: 100%;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
.video {
|
|
22
|
-
position: absolute;
|
|
23
|
-
object-fit: cover;
|
|
24
|
-
object-position: center;
|
|
25
|
-
height: 100%;
|
|
26
|
-
width: 100%;
|
|
27
|
-
}
|
|
28
|
-
</style>
|