@financial-times/cp-content-pipeline-ui 6.13.0-beta.0 → 6.13.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/CHANGELOG.md +7 -0
- package/lib/client.d.ts +0 -1
- package/lib/client.js +1 -3
- package/lib/client.js.map +1 -1
- package/lib/components/Flourish/index.js +1 -1
- package/lib/components/Flourish/index.js.map +1 -1
- package/lib/components/LiveBlogWrapper/index.js +1 -1
- package/lib/components/LiveBlogWrapper/index.js.map +1 -1
- package/package.json +2 -2
- package/src/client.ts +0 -1
- package/src/components/Flourish/index.tsx +0 -5
- package/src/components/Flourish/test/__snapshots__/snapshot.spec.tsx.snap +0 -18
- package/src/components/LiveBlogWrapper/index.tsx +1 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/lib/components/Topper/client/flourish-tracking.d.ts +0 -14
- package/lib/components/Topper/client/flourish-tracking.js +0 -69
- package/lib/components/Topper/client/flourish-tracking.js.map +0 -1
- package/lib/components/Topper/client/index.d.ts +0 -2
- package/lib/components/Topper/client/index.js +0 -6
- package/lib/components/Topper/client/index.js.map +0 -1
- package/lib/components/Topper/test/client/flourish-tracking.spec.d.ts +0 -1
- package/lib/components/Topper/test/client/flourish-tracking.spec.js +0 -117
- package/lib/components/Topper/test/client/flourish-tracking.spec.js.map +0 -1
- package/src/components/Topper/client/flourish-tracking.ts +0 -83
- package/src/components/Topper/client/index.ts +0 -3
- package/src/components/Topper/test/client/flourish-tracking.spec.ts +0 -135
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
declare class FlourishTopperTracker {
|
|
2
|
-
private startTime;
|
|
3
|
-
private totalVisibleTime;
|
|
4
|
-
private timeElapsedSeconds;
|
|
5
|
-
private component;
|
|
6
|
-
private id;
|
|
7
|
-
private observer;
|
|
8
|
-
constructor();
|
|
9
|
-
init(): void;
|
|
10
|
-
private dispatchEvent;
|
|
11
|
-
private onChange;
|
|
12
|
-
disconnect(): void;
|
|
13
|
-
}
|
|
14
|
-
export { FlourishTopperTracker };
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.FlourishTopperTracker = void 0;
|
|
4
|
-
class FlourishTopperTracker {
|
|
5
|
-
constructor() {
|
|
6
|
-
this.startTime = 0;
|
|
7
|
-
this.totalVisibleTime = 0;
|
|
8
|
-
this.timeElapsedSeconds = null;
|
|
9
|
-
this.component = document.querySelector('[data-component-type="flourish-topper"]');
|
|
10
|
-
this.id = this.component?.getAttribute('data-component-id') || null;
|
|
11
|
-
this.observer = null;
|
|
12
|
-
}
|
|
13
|
-
init() {
|
|
14
|
-
if (!window.IntersectionObserver || !this.component) {
|
|
15
|
-
return;
|
|
16
|
-
}
|
|
17
|
-
if (this.component) {
|
|
18
|
-
this.dispatchEvent('mount');
|
|
19
|
-
}
|
|
20
|
-
this.observer = new IntersectionObserver(this.onChange.bind(this), {
|
|
21
|
-
threshold: [1.0],
|
|
22
|
-
});
|
|
23
|
-
this.observer.observe(this.component);
|
|
24
|
-
}
|
|
25
|
-
dispatchEvent(action) {
|
|
26
|
-
let component = {
|
|
27
|
-
name: 'flourish-topper',
|
|
28
|
-
id: this.id,
|
|
29
|
-
};
|
|
30
|
-
if (this.timeElapsedSeconds) {
|
|
31
|
-
component = { ...component, timeElapsedSeconds: this.timeElapsedSeconds };
|
|
32
|
-
}
|
|
33
|
-
const event = new CustomEvent('oTracking.event', {
|
|
34
|
-
detail: {
|
|
35
|
-
category: 'component',
|
|
36
|
-
action: action,
|
|
37
|
-
component,
|
|
38
|
-
},
|
|
39
|
-
bubbles: true,
|
|
40
|
-
});
|
|
41
|
-
document.body.dispatchEvent(event);
|
|
42
|
-
}
|
|
43
|
-
onChange(changes) {
|
|
44
|
-
changes.forEach((change) => {
|
|
45
|
-
if (change.target !== this.component) {
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
if (change.isIntersecting || change.intersectionRatio >= 1) {
|
|
49
|
-
this.dispatchEvent('view');
|
|
50
|
-
this.startTime = performance.now();
|
|
51
|
-
}
|
|
52
|
-
if (!change.isIntersecting || change.intersectionRatio === 0) {
|
|
53
|
-
this.totalVisibleTime = performance.now() - this.startTime;
|
|
54
|
-
this.timeElapsedSeconds = parseFloat((this.totalVisibleTime / 1000).toFixed(2));
|
|
55
|
-
this.dispatchEvent('stop-view');
|
|
56
|
-
this.totalVisibleTime = 0;
|
|
57
|
-
this.timeElapsedSeconds = null;
|
|
58
|
-
}
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
disconnect() {
|
|
62
|
-
if (this.observer && this.component) {
|
|
63
|
-
this.observer.unobserve(this.component);
|
|
64
|
-
this.observer.disconnect();
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
exports.FlourishTopperTracker = FlourishTopperTracker;
|
|
69
|
-
//# sourceMappingURL=flourish-tracking.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"flourish-tracking.js","sourceRoot":"","sources":["../../../../src/components/Topper/client/flourish-tracking.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.FlourishTopperTracker = void 0;
|
|
4
|
-
const flourish_tracking_1 = require("./flourish-tracking");
|
|
5
|
-
Object.defineProperty(exports, "FlourishTopperTracker", { enumerable: true, get: function () { return flourish_tracking_1.FlourishTopperTracker; } });
|
|
6
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/components/Topper/client/index.ts"],"names":[],"mappings":";;;AAAA,2DAA2D;AAElD,sGAFA,yCAAqB,OAEA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const client_1 = require("../../client");
|
|
4
|
-
// const CustomEventMock = jest.fn()
|
|
5
|
-
// global.CustomEvent = CustomEventMock
|
|
6
|
-
describe('FlourishTopperTracker', () => {
|
|
7
|
-
let mockIntersectionObserver;
|
|
8
|
-
let mockObserve;
|
|
9
|
-
let mockUnobserve;
|
|
10
|
-
let mockDisconnect;
|
|
11
|
-
let mockComponent;
|
|
12
|
-
let dispatchEventSpy;
|
|
13
|
-
beforeEach(() => {
|
|
14
|
-
mockObserve = jest.fn();
|
|
15
|
-
mockUnobserve = jest.fn();
|
|
16
|
-
mockDisconnect = jest.fn();
|
|
17
|
-
mockIntersectionObserver = jest.fn(() => {
|
|
18
|
-
return {
|
|
19
|
-
observe: mockObserve,
|
|
20
|
-
unobserve: mockUnobserve,
|
|
21
|
-
disconnect: mockDisconnect,
|
|
22
|
-
};
|
|
23
|
-
});
|
|
24
|
-
window.IntersectionObserver = mockIntersectionObserver;
|
|
25
|
-
mockComponent = document.createElement('div');
|
|
26
|
-
mockComponent.setAttribute('data-component-type', 'flourish-topper');
|
|
27
|
-
mockComponent.setAttribute('data-component-id', 'test-id');
|
|
28
|
-
document.body.appendChild(mockComponent);
|
|
29
|
-
jest.spyOn(document, 'querySelector').mockReturnValue(mockComponent);
|
|
30
|
-
jest
|
|
31
|
-
.spyOn(performance, 'now')
|
|
32
|
-
.mockImplementationOnce(() => 1)
|
|
33
|
-
.mockImplementationOnce(() => 12344);
|
|
34
|
-
dispatchEventSpy = jest.spyOn(document.body, 'dispatchEvent');
|
|
35
|
-
});
|
|
36
|
-
afterEach(() => {
|
|
37
|
-
jest.clearAllMocks();
|
|
38
|
-
document.body.removeChild(mockComponent);
|
|
39
|
-
});
|
|
40
|
-
it('should initialise and observe the component', () => {
|
|
41
|
-
const tracker = new client_1.FlourishTopperTracker();
|
|
42
|
-
tracker.init();
|
|
43
|
-
expect(mockIntersectionObserver).toHaveBeenCalled();
|
|
44
|
-
expect(mockObserve).toHaveBeenCalledWith(mockComponent);
|
|
45
|
-
});
|
|
46
|
-
it('should dispatch a mount event on intialisation', () => {
|
|
47
|
-
const tracker = new client_1.FlourishTopperTracker();
|
|
48
|
-
tracker.init();
|
|
49
|
-
const mountEvent = dispatchEventSpy.mock.calls[0][0];
|
|
50
|
-
expect(mountEvent.type).toBe('oTracking.event');
|
|
51
|
-
expect(mountEvent.detail).toEqual({
|
|
52
|
-
category: 'component',
|
|
53
|
-
action: 'mount',
|
|
54
|
-
component: {
|
|
55
|
-
name: 'flourish-topper',
|
|
56
|
-
id: 'test-id',
|
|
57
|
-
},
|
|
58
|
-
});
|
|
59
|
-
});
|
|
60
|
-
it('should handle component visibility changes', () => {
|
|
61
|
-
const tracker = new client_1.FlourishTopperTracker();
|
|
62
|
-
tracker.init();
|
|
63
|
-
const mockChanges = [
|
|
64
|
-
{
|
|
65
|
-
target: mockComponent,
|
|
66
|
-
isIntersecting: true,
|
|
67
|
-
intersectionRatio: 1.0,
|
|
68
|
-
boundingClientRect: {},
|
|
69
|
-
intersectionRect: {},
|
|
70
|
-
rootBounds: null,
|
|
71
|
-
time: 1,
|
|
72
|
-
},
|
|
73
|
-
];
|
|
74
|
-
tracker['onChange'](mockChanges);
|
|
75
|
-
const viewEvent = dispatchEventSpy.mock.calls[1][0];
|
|
76
|
-
expect(viewEvent.type).toBe('oTracking.event');
|
|
77
|
-
expect(viewEvent.detail).toEqual({
|
|
78
|
-
category: 'component',
|
|
79
|
-
action: 'view',
|
|
80
|
-
component: {
|
|
81
|
-
name: 'flourish-topper',
|
|
82
|
-
id: 'test-id',
|
|
83
|
-
},
|
|
84
|
-
});
|
|
85
|
-
const mockChangesAfter = [
|
|
86
|
-
{
|
|
87
|
-
target: mockComponent,
|
|
88
|
-
isIntersecting: false,
|
|
89
|
-
intersectionRatio: 0.0,
|
|
90
|
-
boundingClientRect: {},
|
|
91
|
-
intersectionRect: {},
|
|
92
|
-
rootBounds: null,
|
|
93
|
-
time: 12.3444,
|
|
94
|
-
},
|
|
95
|
-
];
|
|
96
|
-
tracker['onChange'](mockChangesAfter);
|
|
97
|
-
const stopViewEvent = dispatchEventSpy.mock.calls[2][0];
|
|
98
|
-
expect(stopViewEvent.type).toBe('oTracking.event');
|
|
99
|
-
expect(stopViewEvent.detail).toEqual({
|
|
100
|
-
category: 'component',
|
|
101
|
-
action: 'stop-view',
|
|
102
|
-
component: {
|
|
103
|
-
name: 'flourish-topper',
|
|
104
|
-
id: 'test-id',
|
|
105
|
-
timeElapsedSeconds: 12.34,
|
|
106
|
-
},
|
|
107
|
-
});
|
|
108
|
-
});
|
|
109
|
-
it('should disconnect the observer', () => {
|
|
110
|
-
const tracker = new client_1.FlourishTopperTracker();
|
|
111
|
-
tracker.init();
|
|
112
|
-
tracker.disconnect();
|
|
113
|
-
expect(mockUnobserve).toHaveBeenCalledWith(mockComponent);
|
|
114
|
-
expect(mockDisconnect).toHaveBeenCalled();
|
|
115
|
-
});
|
|
116
|
-
});
|
|
117
|
-
//# sourceMappingURL=flourish-tracking.spec.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"flourish-tracking.spec.js","sourceRoot":"","sources":["../../../../../src/components/Topper/test/client/flourish-tracking.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
class FlourishTopperTracker {
|
|
2
|
-
private startTime: number
|
|
3
|
-
private totalVisibleTime: number
|
|
4
|
-
private timeElapsedSeconds: number | null
|
|
5
|
-
private component: Element | null
|
|
6
|
-
private id: string | null
|
|
7
|
-
private observer: IntersectionObserver | null
|
|
8
|
-
|
|
9
|
-
constructor() {
|
|
10
|
-
this.startTime = 0
|
|
11
|
-
this.totalVisibleTime = 0
|
|
12
|
-
this.timeElapsedSeconds = null
|
|
13
|
-
this.component = document.querySelector(
|
|
14
|
-
'[data-component-type="flourish-topper"]'
|
|
15
|
-
)
|
|
16
|
-
this.id = this.component?.getAttribute('data-component-id') || null
|
|
17
|
-
this.observer = null
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
init(): void {
|
|
21
|
-
if (!window.IntersectionObserver || !this.component) {
|
|
22
|
-
return
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
if (this.component) {
|
|
26
|
-
this.dispatchEvent('mount')
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
this.observer = new IntersectionObserver(this.onChange.bind(this), {
|
|
30
|
-
threshold: [1.0],
|
|
31
|
-
})
|
|
32
|
-
this.observer.observe(this.component)
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
private dispatchEvent(action: string): void {
|
|
36
|
-
let component: object = {
|
|
37
|
-
name: 'flourish-topper',
|
|
38
|
-
id: this.id,
|
|
39
|
-
}
|
|
40
|
-
if (this.timeElapsedSeconds) {
|
|
41
|
-
component = { ...component, timeElapsedSeconds: this.timeElapsedSeconds }
|
|
42
|
-
}
|
|
43
|
-
const event = new CustomEvent('oTracking.event', {
|
|
44
|
-
detail: {
|
|
45
|
-
category: 'component',
|
|
46
|
-
action: action,
|
|
47
|
-
component,
|
|
48
|
-
},
|
|
49
|
-
bubbles: true,
|
|
50
|
-
})
|
|
51
|
-
document.body.dispatchEvent(event)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
private onChange(changes: IntersectionObserverEntry[]): void {
|
|
55
|
-
changes.forEach((change) => {
|
|
56
|
-
if (change.target !== this.component) {
|
|
57
|
-
return
|
|
58
|
-
}
|
|
59
|
-
if (change.isIntersecting || change.intersectionRatio >= 1) {
|
|
60
|
-
this.dispatchEvent('view')
|
|
61
|
-
this.startTime = performance.now()
|
|
62
|
-
}
|
|
63
|
-
if (!change.isIntersecting || change.intersectionRatio === 0) {
|
|
64
|
-
this.totalVisibleTime = performance.now() - this.startTime
|
|
65
|
-
this.timeElapsedSeconds = parseFloat(
|
|
66
|
-
(this.totalVisibleTime / 1000).toFixed(2)
|
|
67
|
-
)
|
|
68
|
-
this.dispatchEvent('stop-view')
|
|
69
|
-
this.totalVisibleTime = 0
|
|
70
|
-
this.timeElapsedSeconds = null
|
|
71
|
-
}
|
|
72
|
-
})
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
disconnect(): void {
|
|
76
|
-
if (this.observer && this.component) {
|
|
77
|
-
this.observer.unobserve(this.component)
|
|
78
|
-
this.observer.disconnect()
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
export { FlourishTopperTracker }
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
import { FlourishTopperTracker } from '../../client'
|
|
2
|
-
|
|
3
|
-
// const CustomEventMock = jest.fn()
|
|
4
|
-
// global.CustomEvent = CustomEventMock
|
|
5
|
-
|
|
6
|
-
describe('FlourishTopperTracker', () => {
|
|
7
|
-
let mockIntersectionObserver: jest.Mock
|
|
8
|
-
let mockObserve: jest.Mock
|
|
9
|
-
let mockUnobserve: jest.Mock
|
|
10
|
-
let mockDisconnect: jest.Mock
|
|
11
|
-
let mockComponent: HTMLElement
|
|
12
|
-
let dispatchEventSpy: jest.SpyInstance
|
|
13
|
-
|
|
14
|
-
beforeEach(() => {
|
|
15
|
-
mockObserve = jest.fn()
|
|
16
|
-
mockUnobserve = jest.fn()
|
|
17
|
-
mockDisconnect = jest.fn()
|
|
18
|
-
|
|
19
|
-
mockIntersectionObserver = jest.fn(() => {
|
|
20
|
-
return {
|
|
21
|
-
observe: mockObserve,
|
|
22
|
-
unobserve: mockUnobserve,
|
|
23
|
-
disconnect: mockDisconnect,
|
|
24
|
-
}
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
window.IntersectionObserver = mockIntersectionObserver
|
|
28
|
-
|
|
29
|
-
mockComponent = document.createElement('div')
|
|
30
|
-
mockComponent.setAttribute('data-component-type', 'flourish-topper')
|
|
31
|
-
mockComponent.setAttribute('data-component-id', 'test-id')
|
|
32
|
-
document.body.appendChild(mockComponent)
|
|
33
|
-
|
|
34
|
-
jest.spyOn(document, 'querySelector').mockReturnValue(mockComponent)
|
|
35
|
-
jest
|
|
36
|
-
.spyOn(performance, 'now')
|
|
37
|
-
.mockImplementationOnce(() => 1)
|
|
38
|
-
.mockImplementationOnce(() => 12344)
|
|
39
|
-
dispatchEventSpy = jest.spyOn(document.body, 'dispatchEvent')
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
afterEach(() => {
|
|
43
|
-
jest.clearAllMocks()
|
|
44
|
-
document.body.removeChild(mockComponent)
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
it('should initialise and observe the component', () => {
|
|
48
|
-
const tracker = new FlourishTopperTracker()
|
|
49
|
-
tracker.init()
|
|
50
|
-
|
|
51
|
-
expect(mockIntersectionObserver).toHaveBeenCalled()
|
|
52
|
-
expect(mockObserve).toHaveBeenCalledWith(mockComponent)
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
it('should dispatch a mount event on intialisation', () => {
|
|
56
|
-
const tracker = new FlourishTopperTracker()
|
|
57
|
-
tracker.init()
|
|
58
|
-
|
|
59
|
-
const mountEvent = dispatchEventSpy.mock.calls[0][0] as CustomEvent
|
|
60
|
-
expect(mountEvent.type).toBe('oTracking.event')
|
|
61
|
-
expect(mountEvent.detail).toEqual({
|
|
62
|
-
category: 'component',
|
|
63
|
-
action: 'mount',
|
|
64
|
-
component: {
|
|
65
|
-
name: 'flourish-topper',
|
|
66
|
-
id: 'test-id',
|
|
67
|
-
},
|
|
68
|
-
})
|
|
69
|
-
})
|
|
70
|
-
|
|
71
|
-
it('should handle component visibility changes', () => {
|
|
72
|
-
const tracker = new FlourishTopperTracker()
|
|
73
|
-
tracker.init()
|
|
74
|
-
|
|
75
|
-
const mockChanges: IntersectionObserverEntry[] = [
|
|
76
|
-
{
|
|
77
|
-
target: mockComponent,
|
|
78
|
-
isIntersecting: true,
|
|
79
|
-
intersectionRatio: 1.0,
|
|
80
|
-
boundingClientRect: {} as DOMRectReadOnly,
|
|
81
|
-
intersectionRect: {} as DOMRectReadOnly,
|
|
82
|
-
rootBounds: null,
|
|
83
|
-
time: 1,
|
|
84
|
-
},
|
|
85
|
-
]
|
|
86
|
-
|
|
87
|
-
tracker['onChange'](mockChanges)
|
|
88
|
-
|
|
89
|
-
const viewEvent = dispatchEventSpy.mock.calls[1][0] as CustomEvent
|
|
90
|
-
expect(viewEvent.type).toBe('oTracking.event')
|
|
91
|
-
expect(viewEvent.detail).toEqual({
|
|
92
|
-
category: 'component',
|
|
93
|
-
action: 'view',
|
|
94
|
-
component: {
|
|
95
|
-
name: 'flourish-topper',
|
|
96
|
-
id: 'test-id',
|
|
97
|
-
},
|
|
98
|
-
})
|
|
99
|
-
|
|
100
|
-
const mockChangesAfter: IntersectionObserverEntry[] = [
|
|
101
|
-
{
|
|
102
|
-
target: mockComponent,
|
|
103
|
-
isIntersecting: false,
|
|
104
|
-
intersectionRatio: 0.0,
|
|
105
|
-
boundingClientRect: {} as DOMRectReadOnly,
|
|
106
|
-
intersectionRect: {} as DOMRectReadOnly,
|
|
107
|
-
rootBounds: null,
|
|
108
|
-
time: 12.3444,
|
|
109
|
-
},
|
|
110
|
-
]
|
|
111
|
-
|
|
112
|
-
tracker['onChange'](mockChangesAfter)
|
|
113
|
-
|
|
114
|
-
const stopViewEvent = dispatchEventSpy.mock.calls[2][0] as CustomEvent
|
|
115
|
-
expect(stopViewEvent.type).toBe('oTracking.event')
|
|
116
|
-
expect(stopViewEvent.detail).toEqual({
|
|
117
|
-
category: 'component',
|
|
118
|
-
action: 'stop-view',
|
|
119
|
-
component: {
|
|
120
|
-
name: 'flourish-topper',
|
|
121
|
-
id: 'test-id',
|
|
122
|
-
timeElapsedSeconds: 12.34,
|
|
123
|
-
},
|
|
124
|
-
})
|
|
125
|
-
})
|
|
126
|
-
|
|
127
|
-
it('should disconnect the observer', () => {
|
|
128
|
-
const tracker = new FlourishTopperTracker()
|
|
129
|
-
tracker.init()
|
|
130
|
-
tracker.disconnect()
|
|
131
|
-
|
|
132
|
-
expect(mockUnobserve).toHaveBeenCalledWith(mockComponent)
|
|
133
|
-
expect(mockDisconnect).toHaveBeenCalled()
|
|
134
|
-
})
|
|
135
|
-
})
|