@playpilot/tpi 6.3.0 → 6.4.0-beta.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 +10 -10
- package/package.json +1 -1
- package/src/lib/injection.ts +1 -0
- package/src/lib/scss/global.scss +36 -0
- package/src/lib/types/global.d.ts +0 -6
- package/src/lib/types/playlink.d.ts +0 -1
- package/src/routes/+page.svelte +2 -0
- package/src/routes/components/Consent.svelte +2 -10
- package/src/routes/components/Debugger.svelte +0 -3
- package/src/routes/components/Playlinks/Playlink.svelte +1 -11
- package/src/routes/components/Playlinks/PlaylinkIcon.svelte +1 -7
- package/src/routes/components/PostersScrollReveal.svelte +82 -0
- package/src/routes/components/TitlePopover.svelte +4 -0
- package/src/routes/components/TrackingPixels.svelte +5 -11
- package/src/tests/routes/components/Consent.test.js +1 -5
- package/src/tests/routes/components/Playlinks/Playlink.test.js +0 -32
- package/src/tests/routes/components/Playlinks/PlaylinkIcon.test.js +0 -12
- package/src/tests/routes/components/PostersScrollReveal.test.js +107 -0
- package/src/tests/routes/components/TrackingPixels.test.js +1 -19
package/package.json
CHANGED
package/src/lib/injection.ts
CHANGED
|
@@ -291,6 +291,7 @@ function createLinkInjectionElement(injection: LinkInjection): { injectionElemen
|
|
|
291
291
|
injectionElement.dataset.playpilotInjectionKey = injection.key
|
|
292
292
|
|
|
293
293
|
const linkElement = document.createElement('a')
|
|
294
|
+
linkElement.dataset.playpilotPosterUrl = injection.title_details?.standing_poster
|
|
294
295
|
linkElement.innerText = injection.title
|
|
295
296
|
linkElement.href = injection.playpilot_url
|
|
296
297
|
linkElement.target = '_blank'
|
package/src/lib/scss/global.scss
CHANGED
|
@@ -99,3 +99,39 @@ h1, h2, h3, h4, h5 {
|
|
|
99
99
|
::view-transition-new(playpilot-title-content) {
|
|
100
100
|
height: 100%;
|
|
101
101
|
}
|
|
102
|
+
|
|
103
|
+
@keyframes playpilot-poster-fly-in {
|
|
104
|
+
from {
|
|
105
|
+
opacity: 0;
|
|
106
|
+
transform: translateX(-50%) translateY(1.5rem);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
@keyframes playpilot-poster-fly-out {
|
|
111
|
+
to {
|
|
112
|
+
opacity: 0;
|
|
113
|
+
transform: translateX(-50%) translateY(0.5rem);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.playpilot-floating-poster {
|
|
118
|
+
opacity: 0;
|
|
119
|
+
position: absolute;
|
|
120
|
+
bottom: calc(100% + 0.15em);
|
|
121
|
+
left: 50%;
|
|
122
|
+
transform: translateX(-50%);
|
|
123
|
+
width: 40px;
|
|
124
|
+
height: auto;
|
|
125
|
+
border-radius: theme(border-radius-small);
|
|
126
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
127
|
+
transform-origin: bottom center;
|
|
128
|
+
|
|
129
|
+
&.loaded {
|
|
130
|
+
animation: playpilot-poster-fly-in 600ms cubic-bezier(0.35, 1.75, 0.75, 1);
|
|
131
|
+
opacity: 1;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
&.animating-out {
|
|
135
|
+
animation: playpilot-poster-fly-out 150ms forwards;
|
|
136
|
+
}
|
|
137
|
+
}
|
package/src/routes/+page.svelte
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
import Consent from './components/Consent.svelte'
|
|
19
19
|
import Debugger from './components/Debugger.svelte'
|
|
20
20
|
import UserJourney from './components/UserJourney.svelte'
|
|
21
|
+
import PostersScrollReveal from './components/PostersScrollReveal.svelte'
|
|
21
22
|
|
|
22
23
|
let parentElement: HTMLElement | null = $state(null)
|
|
23
24
|
let elements: HTMLElement[] = $state([])
|
|
@@ -233,6 +234,7 @@
|
|
|
233
234
|
|
|
234
235
|
{#key linkInjections}
|
|
235
236
|
<UserJourney />
|
|
237
|
+
<PostersScrollReveal />
|
|
236
238
|
{/key}
|
|
237
239
|
|
|
238
240
|
<Consent onchange={afterConsent} />
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
// If require_consent has been explicitely turned off we return right away and call `onchange`.
|
|
18
18
|
// We don't need to set consent values as require_consent=false will mean all consent is true.
|
|
19
19
|
if (window.PlayPilotLinkInjections.require_consent === false) {
|
|
20
|
-
|
|
20
|
+
onchange()
|
|
21
21
|
return
|
|
22
22
|
}
|
|
23
23
|
|
|
@@ -66,15 +66,7 @@
|
|
|
66
66
|
affiliate: consent(1) && consent(7),
|
|
67
67
|
})
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
onchange()
|
|
70
70
|
})
|
|
71
71
|
}
|
|
72
|
-
|
|
73
|
-
function update() {
|
|
74
|
-
window.dispatchEvent(new CustomEvent('updateconsent', {
|
|
75
|
-
bubbles: true,
|
|
76
|
-
}))
|
|
77
|
-
|
|
78
|
-
onchange()
|
|
79
|
-
}
|
|
80
72
|
</script>
|
|
@@ -27,8 +27,6 @@
|
|
|
27
27
|
const succesfulInjections = data.evaluated_link_injections?.filter(injection => !injection.failed) || []
|
|
28
28
|
const failedInjections = data.evaluated_link_injections?.filter(injection => injection.failed) || []
|
|
29
29
|
|
|
30
|
-
const visiblePixels = Array.from(document.querySelectorAll<HTMLImageElement>('[data-playpilot-pixel]'))
|
|
31
|
-
|
|
32
30
|
return {
|
|
33
31
|
'Config': [
|
|
34
32
|
{ label: 'Domain', data: data.domain_sid },
|
|
@@ -40,7 +38,6 @@
|
|
|
40
38
|
[`Failed injections (${failedInjections.length})`]: failedInjections.map(injection => ({ label: injection.title, data: `Reason: ${injection.failed_message} | Sentence: ${injection.sentence}` })),
|
|
41
39
|
[`Fetched ads (${data.ads?.length || 0})`]: data.ads?.map(ad => ({ label: ad.campaign_name, data: ad })),
|
|
42
40
|
[`Tracking events (${data.tracked_events?.length || 0})`]: data.tracked_events?.map(event => ({ label: event.event, data: event.payload })),
|
|
43
|
-
[`Visible pixels (${visiblePixels.length})`]: visiblePixels.map((pixel, index) => ({ label: index + 1, data: pixel.src })),
|
|
44
41
|
}
|
|
45
42
|
}
|
|
46
43
|
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import Disclaimer from '../Ads/Disclaimer.svelte'
|
|
3
|
-
import TrackingPixels from '../TrackingPixels.svelte'
|
|
4
3
|
import { hasConsentedTo } from '$lib/consent'
|
|
5
4
|
import { removeImageUrlPrefix } from '$lib/image'
|
|
6
5
|
import { t } from '$lib/localization'
|
|
@@ -15,7 +14,7 @@
|
|
|
15
14
|
|
|
16
15
|
const { playlink, disclaimer = '', hideCategory = false, onclick = () => null }: Props = $props()
|
|
17
16
|
|
|
18
|
-
const { name, url, logo_url, highlighted, cta_text, action_text,
|
|
17
|
+
const { name, url, logo_url, highlighted, cta_text, action_text, extra_info: { category } } = $derived(playlink)
|
|
19
18
|
|
|
20
19
|
const categoryStrings = {
|
|
21
20
|
SVOD: t('Stream'),
|
|
@@ -34,7 +33,6 @@
|
|
|
34
33
|
class="playlink"
|
|
35
34
|
class:highlighted={highlighted && cta_text}
|
|
36
35
|
class:no-category={hideCategory}
|
|
37
|
-
class:no-subtext={!cta_text && hideCategory}
|
|
38
36
|
data-playlink={name}
|
|
39
37
|
rel="sponsored">
|
|
40
38
|
|
|
@@ -59,10 +57,6 @@
|
|
|
59
57
|
<Disclaimer {disclaimer} small />
|
|
60
58
|
{/if}
|
|
61
59
|
</div>
|
|
62
|
-
|
|
63
|
-
{#if pixels?.length}
|
|
64
|
-
<TrackingPixels {pixels} />
|
|
65
|
-
{/if}
|
|
66
60
|
</svelte:element>
|
|
67
61
|
|
|
68
62
|
<style lang="scss">
|
|
@@ -168,10 +162,6 @@
|
|
|
168
162
|
.no-category & {
|
|
169
163
|
grid-template-areas: "image name action" "image cta action";
|
|
170
164
|
}
|
|
171
|
-
|
|
172
|
-
.no-subtext & {
|
|
173
|
-
grid-template-areas: "image name action";
|
|
174
|
-
}
|
|
175
165
|
}
|
|
176
166
|
|
|
177
167
|
.name {
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import TrackingPixels from '../TrackingPixels.svelte'
|
|
3
2
|
import { removeImageUrlPrefix } from '$lib/image'
|
|
4
3
|
import type { PlaylinkData } from '$lib/types/playlink'
|
|
5
4
|
|
|
@@ -12,18 +11,13 @@
|
|
|
12
11
|
|
|
13
12
|
const { playlink, size = 30, onclick = () => null }: Props = $props()
|
|
14
13
|
|
|
15
|
-
const { name, url, logo_url
|
|
14
|
+
const { name, url, logo_url } = $derived(playlink)
|
|
16
15
|
</script>
|
|
17
16
|
|
|
18
17
|
<a href={url} target="_blank" class="playlink" data-playlink={name} rel="sponsored" {onclick} style:--size="{size}px">
|
|
19
18
|
<img src={removeImageUrlPrefix(logo_url)} alt={name} height={size} width={size} />
|
|
20
|
-
|
|
21
|
-
{#if pixels?.length}
|
|
22
|
-
<TrackingPixels {pixels} />
|
|
23
|
-
{/if}
|
|
24
19
|
</a>
|
|
25
20
|
|
|
26
|
-
|
|
27
21
|
<style lang="scss">
|
|
28
22
|
.playlink {
|
|
29
23
|
display: inline-block;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { onMount } from 'svelte'
|
|
3
|
+
|
|
4
|
+
const linksWithPosters = Array.from(document.querySelectorAll<HTMLElement>('[data-playpilot-poster-url]'))
|
|
5
|
+
const linksWithCurrentlyVisiblePosters = new Set<HTMLElement>()
|
|
6
|
+
const targetThreshold = 0.7
|
|
7
|
+
const posterSelector = '[data-playpilot-poster]'
|
|
8
|
+
|
|
9
|
+
let scrollTimeout: ReturnType<typeof setTimeout> | null = null
|
|
10
|
+
|
|
11
|
+
onMount(() => {
|
|
12
|
+
return destroyAllPosters
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
function onscroll(): void {
|
|
16
|
+
setScrollTimeout()
|
|
17
|
+
|
|
18
|
+
const windowHeight = window.innerHeight
|
|
19
|
+
const linksWithinTargetViewport = new Set<HTMLElement>()
|
|
20
|
+
const targetFromBottom = windowHeight * targetThreshold
|
|
21
|
+
const targetFromTop = windowHeight - targetFromBottom
|
|
22
|
+
|
|
23
|
+
for (const link of linksWithPosters) {
|
|
24
|
+
const { top } = link.getBoundingClientRect()
|
|
25
|
+
|
|
26
|
+
const isInsideTargetViewport = top < targetFromBottom && top > targetFromTop
|
|
27
|
+
|
|
28
|
+
if (!isInsideTargetViewport) continue
|
|
29
|
+
|
|
30
|
+
linksWithinTargetViewport.add(link)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
for (const link of linksWithinTargetViewport) {
|
|
34
|
+
if (linksWithCurrentlyVisiblePosters.has(link)) continue
|
|
35
|
+
|
|
36
|
+
createPosterForLink(link)
|
|
37
|
+
linksWithCurrentlyVisiblePosters.add(link)
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function createPosterForLink(link: HTMLElement): void {
|
|
42
|
+
const posterUrl = link.dataset.playpilotPosterUrl!
|
|
43
|
+
|
|
44
|
+
const element = document.createElement('img')
|
|
45
|
+
element.classList.add('playpilot-floating-poster')
|
|
46
|
+
element.dataset.playpilotPoster = ''
|
|
47
|
+
element.src = posterUrl
|
|
48
|
+
element.alt = ''
|
|
49
|
+
element.onload = () => element.classList.add('loaded')
|
|
50
|
+
|
|
51
|
+
link.insertAdjacentElement('afterbegin', element)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function destroyPosterForLink(link: HTMLElement): void {
|
|
55
|
+
const poster = link.querySelector(posterSelector)
|
|
56
|
+
|
|
57
|
+
if (!poster) return
|
|
58
|
+
|
|
59
|
+
poster.classList.add('animating-out')
|
|
60
|
+
|
|
61
|
+
setTimeout(() => poster.remove(), 500)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function destroyAllPosters(): void {
|
|
65
|
+
for (const poster of Array.from(document.querySelectorAll(posterSelector))) {
|
|
66
|
+
poster.remove()
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function setScrollTimeout() {
|
|
71
|
+
if (scrollTimeout) clearTimeout(scrollTimeout)
|
|
72
|
+
|
|
73
|
+
scrollTimeout = setTimeout(() => {
|
|
74
|
+
for (const link of linksWithCurrentlyVisiblePosters) {
|
|
75
|
+
destroyPosterForLink(link)
|
|
76
|
+
linksWithCurrentlyVisiblePosters.delete(link)
|
|
77
|
+
}
|
|
78
|
+
}, 500)
|
|
79
|
+
}
|
|
80
|
+
</script>
|
|
81
|
+
|
|
82
|
+
<svelte:window {onscroll} />
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import Title from './Title.svelte'
|
|
9
9
|
import TopScroll from './Ads/TopScroll.svelte'
|
|
10
10
|
import Display from './Ads/Display.svelte'
|
|
11
|
+
import TrackingPixels from './TrackingPixels.svelte'
|
|
11
12
|
|
|
12
13
|
interface Props {
|
|
13
14
|
event: MouseEvent
|
|
@@ -67,6 +68,9 @@
|
|
|
67
68
|
<div class="title-popover" bind:this={element} data-playpilot-title-popover role="region" aria-labelledby="title">
|
|
68
69
|
<Popover append={displayAd ? append : null} bubble={topScroll ? bubble : null}>
|
|
69
70
|
<Title {title} small />
|
|
71
|
+
|
|
72
|
+
<!-- Temporary tracking pixel to verify our own tracking works as expected. The random id exists to bypass cache on subsequent requests. -->
|
|
73
|
+
<TrackingPixels pixels={[`https://imp.pxf.io/i/2439446/837174/9358?id=${Math.random()}`]} />
|
|
70
74
|
</Popover>
|
|
71
75
|
</div>
|
|
72
76
|
|
|
@@ -6,19 +6,13 @@
|
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
const { pixels }: Props = $props()
|
|
9
|
-
|
|
10
|
-
let key = $state(Math.random())
|
|
11
9
|
</script>
|
|
12
10
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
{
|
|
16
|
-
{
|
|
17
|
-
|
|
18
|
-
<img {src} alt="" data-playpilot-pixel />
|
|
19
|
-
{/each}
|
|
20
|
-
{/if}
|
|
21
|
-
{/key}
|
|
11
|
+
{#if hasConsentedTo('pixels')}
|
|
12
|
+
{#each pixels as src}
|
|
13
|
+
<img {src} alt="" />
|
|
14
|
+
{/each}
|
|
15
|
+
{/if}
|
|
22
16
|
|
|
23
17
|
<style lang="scss">
|
|
24
18
|
img {
|
|
@@ -15,13 +15,10 @@ describe('Consent.svelte', () => {
|
|
|
15
15
|
expect(onchange).toHaveBeenCalled()
|
|
16
16
|
})
|
|
17
17
|
|
|
18
|
-
it('Should call onchange
|
|
18
|
+
it('Should call onchange after user has consented', () => {
|
|
19
19
|
// @ts-ignore
|
|
20
20
|
window.PlayPilotLinkInjections = { require_consent: true }
|
|
21
21
|
|
|
22
|
-
const mock = vi.fn()
|
|
23
|
-
window.addEventListener('updateconsent', mock)
|
|
24
|
-
|
|
25
22
|
// @ts-ignore
|
|
26
23
|
window.__tcfapi = (command, _version, callback) => {
|
|
27
24
|
if (command !== 'addEventListener') return
|
|
@@ -42,7 +39,6 @@ describe('Consent.svelte', () => {
|
|
|
42
39
|
window.__tcfapi()
|
|
43
40
|
|
|
44
41
|
expect(onchange).toHaveBeenCalled()
|
|
45
|
-
expect(mock).toHaveBeenCalled()
|
|
46
42
|
})
|
|
47
43
|
|
|
48
44
|
it('Should not call onchange after user has consented but eventStatus is invalid', () => {
|
|
@@ -131,36 +131,4 @@ describe('Playlink.svelte', () => {
|
|
|
131
131
|
|
|
132
132
|
expect(getByTestId('disclaimer')).toBeTruthy()
|
|
133
133
|
})
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
it('Should render given tracking pixels', () => {
|
|
137
|
-
vi.mocked(hasConsentedTo).mockImplementation(() => true)
|
|
138
|
-
|
|
139
|
-
const playlink = { name: 'Some playlink', logo_url: 'logo', pixels: ['https://some-pixel.com/a.jpg'], extra_info: { category: 'SVOD' } }
|
|
140
|
-
// @ts-ignore
|
|
141
|
-
const { container } = render(Playlink, { playlink })
|
|
142
|
-
|
|
143
|
-
expect(container.querySelector('img[src*="https://some-pixel.com/a.jpg"]')).toBeTruthy()
|
|
144
|
-
})
|
|
145
|
-
|
|
146
|
-
it('Should include no-subtext class if no cta_text is given and hideCategory is true', () => {
|
|
147
|
-
// @ts-ignore
|
|
148
|
-
const { container } = render(Playlink, { playlink: { ...playlink, cta_text: '' }, hideCategory: true })
|
|
149
|
-
|
|
150
|
-
expect(container.querySelector('.no-subtext')).toBeTruthy()
|
|
151
|
-
})
|
|
152
|
-
|
|
153
|
-
it('Should not include no-subtext class if no cta_text is given but hideCategory is false', () => {
|
|
154
|
-
// @ts-ignore
|
|
155
|
-
const { container } = render(Playlink, { playlink: { ...playlink, cta_text: '' }, hideCategory: false })
|
|
156
|
-
|
|
157
|
-
expect(container.querySelector('.no-subtext')).not.toBeTruthy()
|
|
158
|
-
})
|
|
159
|
-
|
|
160
|
-
it('Should not include no-subtext class if cta_text is given and hideCategory is true', () => {
|
|
161
|
-
// @ts-ignore
|
|
162
|
-
const { container } = render(Playlink, { playlink: { ...playlink, cta_text: 'Some text' }, hideCategory: true })
|
|
163
|
-
|
|
164
|
-
expect(container.querySelector('.no-subtext')).not.toBeTruthy()
|
|
165
|
-
})
|
|
166
134
|
})
|
|
@@ -3,10 +3,6 @@ import { describe, expect, it, vi } from 'vitest'
|
|
|
3
3
|
|
|
4
4
|
import PlaylinkIcon from '../../../../routes/components/Playlinks/PlaylinkIcon.svelte'
|
|
5
5
|
|
|
6
|
-
vi.mock('$lib/consent', () => ({
|
|
7
|
-
hasConsentedTo: vi.fn(() => true),
|
|
8
|
-
}))
|
|
9
|
-
|
|
10
6
|
describe('PlaylinkIcon.svelte', () => {
|
|
11
7
|
const playlink = { name: 'Some playlink', logo_url: 'logo', extra_info: { category: 'SVOD' } }
|
|
12
8
|
|
|
@@ -28,12 +24,4 @@ describe('PlaylinkIcon.svelte', () => {
|
|
|
28
24
|
expect(getByAltText(playlink.name).getAttribute('width')).toBe('20')
|
|
29
25
|
expect(getByAltText(playlink.name).getAttribute('height')).toBe('20')
|
|
30
26
|
})
|
|
31
|
-
|
|
32
|
-
it('Should render given tracking pixels', () => {
|
|
33
|
-
const playlink = { name: 'Some playlink', logo_url: 'logo', pixels: ['https://some-pixel.com/a.jpg'], extra_info: { category: 'SVOD' } }
|
|
34
|
-
// @ts-ignore
|
|
35
|
-
const { container } = render(PlaylinkIcon, { playlink })
|
|
36
|
-
|
|
37
|
-
expect(container.querySelector('img[src*="https://some-pixel.com/a.jpg"]')).toBeTruthy()
|
|
38
|
-
})
|
|
39
27
|
})
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { render } from '@testing-library/svelte'
|
|
2
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
|
3
|
+
import PostersScrollReveal from '../../../routes/components/PostersScrollReveal.svelte'
|
|
4
|
+
|
|
5
|
+
function createPosterLink(top = 0, url = 'poster.jpg') {
|
|
6
|
+
const link = document.createElement('a')
|
|
7
|
+
link.dataset.playpilotPosterUrl = url
|
|
8
|
+
|
|
9
|
+
// @ts-ignore
|
|
10
|
+
link.getBoundingClientRect = () => ({ top })
|
|
11
|
+
|
|
12
|
+
document.body.appendChild(link)
|
|
13
|
+
return link
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
describe('FloatingPoster', () => {
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
document.body.innerHTML = ''
|
|
19
|
+
|
|
20
|
+
Object.defineProperty(window, 'innerHeight', {
|
|
21
|
+
value: 1000,
|
|
22
|
+
writable: true,
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
vi.useFakeTimers()
|
|
26
|
+
vi.resetAllMocks()
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
it('Should create poster when link is in viewport', async () => {
|
|
30
|
+
createPosterLink(500)
|
|
31
|
+
|
|
32
|
+
render(PostersScrollReveal)
|
|
33
|
+
|
|
34
|
+
window.dispatchEvent(new Event('scroll'))
|
|
35
|
+
|
|
36
|
+
const poster = document.querySelector('[data-playpilot-poster]')
|
|
37
|
+
expect(poster).toBeTruthy()
|
|
38
|
+
expect(poster?.getAttribute('src')).toBe('poster.jpg')
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
it('Should not create poster when link is below in viewport', async () => {
|
|
42
|
+
createPosterLink(2000)
|
|
43
|
+
|
|
44
|
+
render(PostersScrollReveal)
|
|
45
|
+
|
|
46
|
+
window.dispatchEvent(new Event('scroll'))
|
|
47
|
+
|
|
48
|
+
expect(document.querySelector('[data-playpilot-poster]')).not.toBeTruthy()
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
it('Should not create poster when link is above in viewport', async () => {
|
|
52
|
+
createPosterLink(-100)
|
|
53
|
+
|
|
54
|
+
render(PostersScrollReveal)
|
|
55
|
+
|
|
56
|
+
window.dispatchEvent(new Event('scroll'))
|
|
57
|
+
|
|
58
|
+
expect(document.querySelector('[data-playpilot-poster]')).not.toBeTruthy()
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
it('Should not create poster when link is in viewport but before threshold', async () => {
|
|
62
|
+
createPosterLink(50)
|
|
63
|
+
createPosterLink(900)
|
|
64
|
+
|
|
65
|
+
render(PostersScrollReveal)
|
|
66
|
+
|
|
67
|
+
window.dispatchEvent(new Event('scroll'))
|
|
68
|
+
|
|
69
|
+
expect(document.querySelector('[data-playpilot-poster]')).not.toBeTruthy()
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
it('Should create poster for each link in viewport', async () => {
|
|
73
|
+
createPosterLink(10)
|
|
74
|
+
createPosterLink(500)
|
|
75
|
+
createPosterLink(500)
|
|
76
|
+
createPosterLink(510)
|
|
77
|
+
createPosterLink(520)
|
|
78
|
+
createPosterLink(2000)
|
|
79
|
+
|
|
80
|
+
render(PostersScrollReveal)
|
|
81
|
+
|
|
82
|
+
window.dispatchEvent(new Event('scroll'))
|
|
83
|
+
|
|
84
|
+
expect(document.querySelectorAll('[data-playpilot-poster]')).toHaveLength(4)
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
it('Should hide poster after not scrolling for given timeout', async () => {
|
|
88
|
+
createPosterLink(500)
|
|
89
|
+
|
|
90
|
+
render(PostersScrollReveal)
|
|
91
|
+
|
|
92
|
+
window.dispatchEvent(new Event('scroll'))
|
|
93
|
+
expect(document.querySelector('[data-playpilot-poster]')).toBeTruthy()
|
|
94
|
+
|
|
95
|
+
vi.advanceTimersByTime(200)
|
|
96
|
+
expect(document.querySelector('[data-playpilot-poster]')).toBeTruthy()
|
|
97
|
+
|
|
98
|
+
vi.advanceTimersByTime(400)
|
|
99
|
+
expect(document.querySelector('[data-playpilot-poster]')).toBeTruthy()
|
|
100
|
+
|
|
101
|
+
vi.advanceTimersByTime(1000)
|
|
102
|
+
expect(document.querySelector('[data-playpilot-poster]')).not.toBeTruthy()
|
|
103
|
+
|
|
104
|
+
window.dispatchEvent(new Event('scroll'))
|
|
105
|
+
expect(document.querySelector('[data-playpilot-poster]')).toBeTruthy()
|
|
106
|
+
})
|
|
107
|
+
})
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { render
|
|
1
|
+
import { render } from '@testing-library/svelte'
|
|
2
2
|
import { describe, expect, it, vi } from 'vitest'
|
|
3
3
|
|
|
4
4
|
import TrackingPixels from '../../../routes/components/TrackingPixels.svelte'
|
|
@@ -26,22 +26,4 @@ describe('TrackingPixels.svelte', () => {
|
|
|
26
26
|
|
|
27
27
|
expect(queryByRole('presentation')).not.toBeTruthy()
|
|
28
28
|
})
|
|
29
|
-
|
|
30
|
-
it('Should re-render when updateconsent is fired', async () => {
|
|
31
|
-
vi.mocked(hasConsentedTo).mockImplementation(() => false)
|
|
32
|
-
|
|
33
|
-
const pixels = ['https://image.com/a.jpg']
|
|
34
|
-
const { queryByRole } = render(TrackingPixels, { pixels })
|
|
35
|
-
|
|
36
|
-
expect(queryByRole('presentation')).not.toBeTruthy()
|
|
37
|
-
|
|
38
|
-
vi.mocked(hasConsentedTo).mockImplementation(() => true)
|
|
39
|
-
window.dispatchEvent(new CustomEvent('updateconsent', {
|
|
40
|
-
bubbles: true,
|
|
41
|
-
}))
|
|
42
|
-
|
|
43
|
-
await waitFor(() => {
|
|
44
|
-
expect(queryByRole('presentation')).toBeTruthy()
|
|
45
|
-
})
|
|
46
|
-
})
|
|
47
29
|
})
|