@playpilot/tpi 6.4.0-beta.8 → 6.4.1
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 +8 -8
- package/package.json +1 -1
- package/src/lib/actions/focustrap.ts +1 -1
- package/src/lib/enums/SplitTest.ts +5 -0
- package/src/lib/types/global.d.ts +6 -0
- package/src/lib/types/playlink.d.ts +1 -0
- package/src/routes/components/Consent.svelte +10 -2
- package/src/routes/components/Debugger.svelte +3 -0
- package/src/routes/components/Playlinks/Playlink.svelte +12 -2
- package/src/routes/components/Playlinks/PlaylinkIcon.svelte +7 -1
- package/src/routes/components/PostersScrollReveal.svelte +29 -1
- package/src/routes/components/TitlePopover.svelte +0 -4
- package/src/routes/components/TrackingPixels.svelte +11 -5
- package/src/tests/routes/components/Consent.test.js +5 -1
- package/src/tests/routes/components/Playlinks/Playlink.test.js +35 -4
- package/src/tests/routes/components/Playlinks/PlaylinkIcon.test.js +12 -0
- package/src/tests/routes/components/PostersScrollReveal.test.js +43 -1
- package/src/tests/routes/components/TrackingPixels.test.js +19 -1
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export function focustrap(node: HTMLElement) {
|
|
1
|
+
export function focustrap(node: HTMLElement): { destroy(): void } {
|
|
2
2
|
function getFocusableElements(): HTMLElement[] {
|
|
3
3
|
return Array.from(node.querySelectorAll<HTMLElement>('button:not([disabled]), [href], [tabindex]:not([tabindex="-1"])'))
|
|
4
4
|
}
|
|
@@ -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
|
+
update()
|
|
21
21
|
return
|
|
22
22
|
}
|
|
23
23
|
|
|
@@ -66,7 +66,15 @@
|
|
|
66
66
|
affiliate: consent(1) && consent(7),
|
|
67
67
|
})
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
update()
|
|
70
70
|
})
|
|
71
71
|
}
|
|
72
|
+
|
|
73
|
+
function update() {
|
|
74
|
+
window.dispatchEvent(new CustomEvent('updateconsent', {
|
|
75
|
+
bubbles: true,
|
|
76
|
+
}))
|
|
77
|
+
|
|
78
|
+
onchange()
|
|
79
|
+
}
|
|
72
80
|
</script>
|
|
@@ -27,6 +27,8 @@
|
|
|
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
|
+
|
|
30
32
|
return {
|
|
31
33
|
'Config': [
|
|
32
34
|
{ label: 'Domain', data: data.domain_sid },
|
|
@@ -38,6 +40,7 @@
|
|
|
38
40
|
[`Failed injections (${failedInjections.length})`]: failedInjections.map(injection => ({ label: injection.title, data: `Reason: ${injection.failed_message} | Sentence: ${injection.sentence}` })),
|
|
39
41
|
[`Fetched ads (${data.ads?.length || 0})`]: data.ads?.map(ad => ({ label: ad.campaign_name, data: ad })),
|
|
40
42
|
[`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 })),
|
|
41
44
|
}
|
|
42
45
|
}
|
|
43
46
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import Disclaimer from '../Ads/Disclaimer.svelte'
|
|
3
|
+
import TrackingPixels from '../TrackingPixels.svelte'
|
|
3
4
|
import { hasConsentedTo } from '$lib/consent'
|
|
4
5
|
import { removeImageUrlPrefix } from '$lib/image'
|
|
5
6
|
import { t } from '$lib/localization'
|
|
@@ -14,7 +15,7 @@
|
|
|
14
15
|
|
|
15
16
|
const { playlink, disclaimer = '', hideCategory = false, onclick = () => null }: Props = $props()
|
|
16
17
|
|
|
17
|
-
const { name, url, logo_url, highlighted, cta_text, action_text, extra_info: { category } } = $derived(playlink)
|
|
18
|
+
const { name, url, logo_url, highlighted, cta_text, action_text, pixels, extra_info: { category } } = $derived(playlink)
|
|
18
19
|
|
|
19
20
|
const categoryStrings = {
|
|
20
21
|
SVOD: t('Stream'),
|
|
@@ -31,8 +32,9 @@
|
|
|
31
32
|
href={url}
|
|
32
33
|
target="_blank"
|
|
33
34
|
class="playlink"
|
|
34
|
-
class:highlighted={highlighted
|
|
35
|
+
class:highlighted={highlighted}
|
|
35
36
|
class:no-category={hideCategory}
|
|
37
|
+
class:no-subtext={!cta_text && hideCategory}
|
|
36
38
|
data-playlink={name}
|
|
37
39
|
rel="sponsored">
|
|
38
40
|
|
|
@@ -57,6 +59,10 @@
|
|
|
57
59
|
<Disclaimer {disclaimer} small />
|
|
58
60
|
{/if}
|
|
59
61
|
</div>
|
|
62
|
+
|
|
63
|
+
{#if pixels?.length}
|
|
64
|
+
<TrackingPixels {pixels} />
|
|
65
|
+
{/if}
|
|
60
66
|
</svelte:element>
|
|
61
67
|
|
|
62
68
|
<style lang="scss">
|
|
@@ -162,6 +168,10 @@
|
|
|
162
168
|
.no-category & {
|
|
163
169
|
grid-template-areas: "image name action" "image cta action";
|
|
164
170
|
}
|
|
171
|
+
|
|
172
|
+
.no-subtext & {
|
|
173
|
+
grid-template-areas: "image name action";
|
|
174
|
+
}
|
|
165
175
|
}
|
|
166
176
|
|
|
167
177
|
.name {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import TrackingPixels from '../TrackingPixels.svelte'
|
|
2
3
|
import { removeImageUrlPrefix } from '$lib/image'
|
|
3
4
|
import type { PlaylinkData } from '$lib/types/playlink'
|
|
4
5
|
|
|
@@ -11,13 +12,18 @@
|
|
|
11
12
|
|
|
12
13
|
const { playlink, size = 30, onclick = () => null }: Props = $props()
|
|
13
14
|
|
|
14
|
-
const { name, url, logo_url } = $derived(playlink)
|
|
15
|
+
const { name, url, logo_url, pixels } = $derived(playlink)
|
|
15
16
|
</script>
|
|
16
17
|
|
|
17
18
|
<a href={url} target="_blank" class="playlink" data-playlink={name} rel="sponsored" {onclick} style:--size="{size}px">
|
|
18
19
|
<img src={removeImageUrlPrefix(logo_url)} alt={name} height={size} width={size} />
|
|
20
|
+
|
|
21
|
+
{#if pixels?.length}
|
|
22
|
+
<TrackingPixels {pixels} />
|
|
23
|
+
{/if}
|
|
19
24
|
</a>
|
|
20
25
|
|
|
26
|
+
|
|
21
27
|
<style lang="scss">
|
|
22
28
|
.playlink {
|
|
23
29
|
display: inline-block;
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import { mobileBreakpoint } from '$lib/constants'
|
|
3
|
+
import { SplitTest } from '$lib/enums/SplitTest'
|
|
4
|
+
import { isInSplitTestVariant, trackSplitTestAction, trackSplitTestView } from '$lib/splitTest'
|
|
2
5
|
import { onMount } from 'svelte'
|
|
3
6
|
|
|
4
7
|
const linksWithPosters = Array.from(document.querySelectorAll<HTMLElement>('[data-playpilot-poster-url]'))
|
|
@@ -6,14 +9,39 @@
|
|
|
6
9
|
const targetThreshold = 0.7
|
|
7
10
|
const posterSelector = '[data-playpilot-poster]'
|
|
8
11
|
|
|
12
|
+
let windowWidth = $state(0)
|
|
9
13
|
let postersShownForLink: Record<string, HTMLElement> = {}
|
|
10
14
|
let scrollTimeout: ReturnType<typeof setTimeout> | null = null
|
|
11
15
|
|
|
16
|
+
const isMobile = $derived(windowWidth < mobileBreakpoint)
|
|
17
|
+
|
|
12
18
|
onMount(() => {
|
|
19
|
+
if (!isMobile) return
|
|
20
|
+
|
|
21
|
+
trackSplitTestView(SplitTest.PostersScrollReveal)
|
|
22
|
+
|
|
13
23
|
return destroyAllPosters
|
|
14
24
|
})
|
|
15
25
|
|
|
26
|
+
$effect(() => {
|
|
27
|
+
if (!isMobile) return
|
|
28
|
+
if (!linksWithPosters.length) return
|
|
29
|
+
|
|
30
|
+
const onclick = () => trackSplitTestAction(SplitTest.PostersScrollReveal, 'click')
|
|
31
|
+
|
|
32
|
+
if (!isInSplitTestVariant(SplitTest.PostersScrollReveal)) return
|
|
33
|
+
|
|
34
|
+
for(const link of linksWithPosters) link.addEventListener('click', onclick)
|
|
35
|
+
|
|
36
|
+
return () => {
|
|
37
|
+
for(const link of linksWithPosters) link.removeEventListener('click', onclick)
|
|
38
|
+
}
|
|
39
|
+
})
|
|
40
|
+
|
|
16
41
|
function onscroll(): void {
|
|
42
|
+
if (!isMobile) return
|
|
43
|
+
if (!isInSplitTestVariant(SplitTest.PostersScrollReveal)) return
|
|
44
|
+
|
|
17
45
|
setScrollTimeout()
|
|
18
46
|
|
|
19
47
|
const windowHeight = window.innerHeight
|
|
@@ -84,4 +112,4 @@
|
|
|
84
112
|
}
|
|
85
113
|
</script>
|
|
86
114
|
|
|
87
|
-
<svelte:window {onscroll} />
|
|
115
|
+
<svelte:window {onscroll} bind:innerWidth={windowWidth} />
|
|
@@ -8,7 +8,6 @@
|
|
|
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'
|
|
12
11
|
|
|
13
12
|
interface Props {
|
|
14
13
|
event: MouseEvent
|
|
@@ -68,9 +67,6 @@
|
|
|
68
67
|
<div class="title-popover" bind:this={element} data-playpilot-title-popover role="region" aria-labelledby="title">
|
|
69
68
|
<Popover append={displayAd ? append : null} bubble={topScroll ? bubble : null}>
|
|
70
69
|
<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()}`]} />
|
|
74
70
|
</Popover>
|
|
75
71
|
</div>
|
|
76
72
|
|
|
@@ -6,13 +6,19 @@
|
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
const { pixels }: Props = $props()
|
|
9
|
+
|
|
10
|
+
let key = $state(Math.random())
|
|
9
11
|
</script>
|
|
10
12
|
|
|
11
|
-
{
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
{
|
|
15
|
-
{
|
|
13
|
+
<svelte:window onupdateconsent={() => key = Math.random()} />
|
|
14
|
+
|
|
15
|
+
{#key key}
|
|
16
|
+
{#if hasConsentedTo('pixels')}
|
|
17
|
+
{#each pixels as src}
|
|
18
|
+
<img {src} alt="" data-playpilot-pixel />
|
|
19
|
+
{/each}
|
|
20
|
+
{/if}
|
|
21
|
+
{/key}
|
|
16
22
|
|
|
17
23
|
<style lang="scss">
|
|
18
24
|
img {
|
|
@@ -15,10 +15,13 @@ describe('Consent.svelte', () => {
|
|
|
15
15
|
expect(onchange).toHaveBeenCalled()
|
|
16
16
|
})
|
|
17
17
|
|
|
18
|
-
it('Should call onchange after user has consented', () => {
|
|
18
|
+
it('Should call onchange and fire window event 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
|
+
|
|
22
25
|
// @ts-ignore
|
|
23
26
|
window.__tcfapi = (command, _version, callback) => {
|
|
24
27
|
if (command !== 'addEventListener') return
|
|
@@ -39,6 +42,7 @@ describe('Consent.svelte', () => {
|
|
|
39
42
|
window.__tcfapi()
|
|
40
43
|
|
|
41
44
|
expect(onchange).toHaveBeenCalled()
|
|
45
|
+
expect(mock).toHaveBeenCalled()
|
|
42
46
|
})
|
|
43
47
|
|
|
44
48
|
it('Should not call onchange after user has consented but eventStatus is invalid', () => {
|
|
@@ -79,12 +79,11 @@ describe('Playlink.svelte', () => {
|
|
|
79
79
|
expect(getByText('Some CTA')).toBeTruthy()
|
|
80
80
|
})
|
|
81
81
|
|
|
82
|
-
it('Should
|
|
82
|
+
it('Should highlight playlinks that have highlighted as true even if they have no cta_text', () => {
|
|
83
83
|
// @ts-ignore
|
|
84
|
-
const { getByText
|
|
84
|
+
const { getByText } = render(Playlink, { playlink: { name: 'Some playlink', logo_url: 'logo', highlighted: true, cta_text: '', extra_info: { category: 'BUY' } } })
|
|
85
85
|
|
|
86
|
-
expect(getByText('Some playlink').closest('.playlink')?.classList).
|
|
87
|
-
expect(queryByText('Some CTA')).not.toBeTruthy()
|
|
86
|
+
expect(getByText('Some playlink').closest('.playlink')?.classList).toContain('highlighted')
|
|
88
87
|
})
|
|
89
88
|
|
|
90
89
|
it('Should not highlight playlinks that do not have highlighted set to true', () => {
|
|
@@ -131,4 +130,36 @@ describe('Playlink.svelte', () => {
|
|
|
131
130
|
|
|
132
131
|
expect(getByTestId('disclaimer')).toBeTruthy()
|
|
133
132
|
})
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
it('Should render given tracking pixels', () => {
|
|
136
|
+
vi.mocked(hasConsentedTo).mockImplementation(() => true)
|
|
137
|
+
|
|
138
|
+
const playlink = { name: 'Some playlink', logo_url: 'logo', pixels: ['https://some-pixel.com/a.jpg'], extra_info: { category: 'SVOD' } }
|
|
139
|
+
// @ts-ignore
|
|
140
|
+
const { container } = render(Playlink, { playlink })
|
|
141
|
+
|
|
142
|
+
expect(container.querySelector('img[src*="https://some-pixel.com/a.jpg"]')).toBeTruthy()
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
it('Should include no-subtext class if no cta_text is given and hideCategory is true', () => {
|
|
146
|
+
// @ts-ignore
|
|
147
|
+
const { container } = render(Playlink, { playlink: { ...playlink, cta_text: '' }, hideCategory: true })
|
|
148
|
+
|
|
149
|
+
expect(container.querySelector('.no-subtext')).toBeTruthy()
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
it('Should not include no-subtext class if no cta_text is given but hideCategory is false', () => {
|
|
153
|
+
// @ts-ignore
|
|
154
|
+
const { container } = render(Playlink, { playlink: { ...playlink, cta_text: '' }, hideCategory: false })
|
|
155
|
+
|
|
156
|
+
expect(container.querySelector('.no-subtext')).not.toBeTruthy()
|
|
157
|
+
})
|
|
158
|
+
|
|
159
|
+
it('Should not include no-subtext class if cta_text is given and hideCategory is true', () => {
|
|
160
|
+
// @ts-ignore
|
|
161
|
+
const { container } = render(Playlink, { playlink: { ...playlink, cta_text: 'Some text' }, hideCategory: true })
|
|
162
|
+
|
|
163
|
+
expect(container.querySelector('.no-subtext')).not.toBeTruthy()
|
|
164
|
+
})
|
|
134
165
|
})
|
|
@@ -3,6 +3,10 @@ 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
|
+
|
|
6
10
|
describe('PlaylinkIcon.svelte', () => {
|
|
7
11
|
const playlink = { name: 'Some playlink', logo_url: 'logo', extra_info: { category: 'SVOD' } }
|
|
8
12
|
|
|
@@ -24,4 +28,12 @@ describe('PlaylinkIcon.svelte', () => {
|
|
|
24
28
|
expect(getByAltText(playlink.name).getAttribute('width')).toBe('20')
|
|
25
29
|
expect(getByAltText(playlink.name).getAttribute('height')).toBe('20')
|
|
26
30
|
})
|
|
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
|
+
})
|
|
27
39
|
})
|
|
@@ -1,6 +1,14 @@
|
|
|
1
|
-
import { render } from '@testing-library/svelte'
|
|
1
|
+
import { fireEvent, render } from '@testing-library/svelte'
|
|
2
2
|
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
|
3
3
|
import PostersScrollReveal from '../../../routes/components/PostersScrollReveal.svelte'
|
|
4
|
+
import { mobileBreakpoint } from '$lib/constants'
|
|
5
|
+
import { isInSplitTestVariant, trackSplitTestAction } from '$lib/splitTest'
|
|
6
|
+
|
|
7
|
+
vi.mock('$lib/splitTest', () => ({
|
|
8
|
+
trackSplitTestView: vi.fn(),
|
|
9
|
+
trackSplitTestAction: vi.fn(),
|
|
10
|
+
isInSplitTestVariant: vi.fn(() => true),
|
|
11
|
+
}))
|
|
4
12
|
|
|
5
13
|
function createPosterLink(top = 0, url = 'poster.jpg') {
|
|
6
14
|
const link = document.createElement('a')
|
|
@@ -22,8 +30,15 @@ describe('FloatingPoster', () => {
|
|
|
22
30
|
writable: true,
|
|
23
31
|
})
|
|
24
32
|
|
|
33
|
+
Object.defineProperty(window, 'innerWidth', {
|
|
34
|
+
value: mobileBreakpoint - 1,
|
|
35
|
+
writable: true,
|
|
36
|
+
})
|
|
37
|
+
|
|
25
38
|
vi.useFakeTimers()
|
|
26
39
|
vi.resetAllMocks()
|
|
40
|
+
|
|
41
|
+
vi.mocked(isInSplitTestVariant).mockReturnValue(true)
|
|
27
42
|
})
|
|
28
43
|
|
|
29
44
|
it('Should create poster when link is in viewport', async () => {
|
|
@@ -38,6 +53,21 @@ describe('FloatingPoster', () => {
|
|
|
38
53
|
expect(poster?.getAttribute('src')).toBe('poster.jpg')
|
|
39
54
|
})
|
|
40
55
|
|
|
56
|
+
it('Should not create posters on desktop when link is in viewport', async () => {
|
|
57
|
+
createPosterLink(500)
|
|
58
|
+
|
|
59
|
+
Object.defineProperty(window, 'innerWidth', {
|
|
60
|
+
value: mobileBreakpoint + 1,
|
|
61
|
+
writable: true,
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
render(PostersScrollReveal)
|
|
65
|
+
|
|
66
|
+
window.dispatchEvent(new Event('scroll'))
|
|
67
|
+
|
|
68
|
+
expect(document.querySelector('[data-playpilot-poster]')).not.toBeTruthy()
|
|
69
|
+
})
|
|
70
|
+
|
|
41
71
|
it('Should not create poster when link is below in viewport', async () => {
|
|
42
72
|
createPosterLink(2000)
|
|
43
73
|
|
|
@@ -117,4 +147,16 @@ describe('FloatingPoster', () => {
|
|
|
117
147
|
window.dispatchEvent(new Event('scroll'))
|
|
118
148
|
expect(document.querySelector('[data-playpilot-poster]')).toBeTruthy()
|
|
119
149
|
})
|
|
150
|
+
|
|
151
|
+
it('Should fire split test tracking on click', async () => {
|
|
152
|
+
createPosterLink(500)
|
|
153
|
+
|
|
154
|
+
render(PostersScrollReveal)
|
|
155
|
+
|
|
156
|
+
window.dispatchEvent(new Event('scroll'))
|
|
157
|
+
|
|
158
|
+
await fireEvent.click(/** @type {HTMLElement} */ (document.querySelector('[data-playpilot-poster]')))
|
|
159
|
+
|
|
160
|
+
expect(trackSplitTestAction).toHaveBeenCalled()
|
|
161
|
+
})
|
|
120
162
|
})
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { render } from '@testing-library/svelte'
|
|
1
|
+
import { render, waitFor } 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,4 +26,22 @@ 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
|
+
})
|
|
29
47
|
})
|