prebid.js 7.14.0 → 7.16.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/.circleci/config.yml +3 -0
- package/dist/1plusXRtdProvider.js +1 -1
- package/dist/33acrossBidAdapter.js +1 -1
- package/dist/adagioBidAdapter.js +1 -1
- package/dist/adbookpspBidAdapter.js +1 -1
- package/dist/adfBidAdapter.js +1 -1
- package/dist/adgenerationBidAdapter.js +1 -1
- package/dist/adkernelAdnBidAdapter.js +1 -1
- package/dist/adkernelBidAdapter.js +1 -1
- package/dist/adlooxAdServerVideo.js +1 -1
- package/dist/adlooxRtdProvider.js +1 -1
- package/dist/adrelevantisBidAdapter.js +1 -1
- package/dist/adtrgtmeBidAdapter.js +1 -1
- package/dist/adtrueBidAdapter.js +1 -1
- package/dist/adxcgBidAdapter.js +1 -1
- package/dist/airgridRtdProvider.js +1 -1
- package/dist/ajaBidAdapter.js +1 -1
- package/dist/amxBidAdapter.js +1 -1
- package/dist/amxIdSystem.js +1 -1
- package/dist/aolBidAdapter.js +1 -1
- package/dist/appierAnalyticsAdapter.js +1 -1
- package/dist/appnexusBidAdapter.js +1 -1
- package/dist/asoBidAdapter.js +1 -1
- package/dist/axonixBidAdapter.js +1 -1
- package/dist/beachfrontBidAdapter.js +1 -1
- package/dist/bidglassBidAdapter.js +1 -1
- package/dist/big-richmediaBidAdapter.js +1 -1
- package/dist/bizzclickBidAdapter.js +1 -1
- package/dist/bliinkBidAdapter.js +1 -1
- package/dist/bluebillywigBidAdapter.js +1 -1
- package/dist/brandmetricsRtdProvider.js +1 -1
- package/dist/bridgewellBidAdapter.js +1 -1
- package/dist/brightMountainMediaBidAdapter.js +1 -1
- package/dist/brightcomBidAdapter.js +1 -1
- package/dist/browsiRtdProvider.js +1 -1
- package/dist/categoryTranslation.js +1 -1
- package/dist/concertBidAdapter.js +1 -1
- package/dist/connectadBidAdapter.js +1 -1
- package/dist/consentManagement.js +1 -1
- package/dist/consentManagementUsp.js +1 -1
- package/dist/consumableBidAdapter.js +1 -1
- package/dist/conversantBidAdapter.js +1 -1
- package/dist/cpmstarBidAdapter.js +1 -1
- package/dist/craftBidAdapter.js +1 -1
- package/dist/criteoBidAdapter.js +1 -1
- package/dist/currency.js +1 -1
- package/dist/dataControllerModule.js +1 -1
- package/dist/dchain.js +1 -1
- package/dist/deepintentBidAdapter.js +1 -1
- package/dist/dependencies.json +3 -0
- package/dist/dgkeywordRtdProvider.js +1 -1
- package/dist/dianomiBidAdapter.js +1 -1
- package/dist/distroscaleBidAdapter.js +1 -1
- package/dist/dspxBidAdapter.js +1 -1
- package/dist/eplanningBidAdapter.js +1 -1
- package/dist/etargetBidAdapter.js +1 -1
- package/dist/feedadBidAdapter.js +1 -1
- package/dist/finativeBidAdapter.js +1 -1
- package/dist/fpdModule.js +1 -1
- package/dist/gamoshiBidAdapter.js +1 -1
- package/dist/glimpseBidAdapter.js +1 -1
- package/dist/gmosspBidAdapter.js +1 -1
- package/dist/goldbachBidAdapter.js +1 -1
- package/dist/gothamadsBidAdapter.js +1 -1
- package/dist/gridBidAdapter.js +1 -1
- package/dist/gridNMBidAdapter.js +1 -1
- package/dist/gumgumBidAdapter.js +1 -1
- package/dist/h12mediaBidAdapter.js +1 -1
- package/dist/iasRtdProvider.js +1 -1
- package/dist/id5IdSystem.js +1 -1
- package/dist/imRtdProvider.js +1 -1
- package/dist/impactifyBidAdapter.js +1 -1
- package/dist/improvedigitalBidAdapter.js +1 -1
- package/dist/inmarBidAdapter.js +1 -1
- package/dist/insticatorBidAdapter.js +1 -1
- package/dist/ixBidAdapter.js +1 -1
- package/dist/justpremiumBidAdapter.js +1 -1
- package/dist/konduitAnalyticsAdapter.js +1 -1
- package/dist/kueezBidAdapter.js +1 -1
- package/dist/lassoBidAdapter.js +1 -1
- package/dist/lifestreetBidAdapter.js +1 -1
- package/dist/liveIntentAnalyticsAdapter.js +1 -0
- package/dist/liveyieldAnalyticsAdapter.js +1 -1
- package/dist/logicadBidAdapter.js +1 -1
- package/dist/loglyliftBidAdapter.js +1 -1
- package/dist/luponmediaBidAdapter.js +1 -1
- package/dist/malltvAnalyticsAdapter.js +1 -1
- package/dist/marsmediaBidAdapter.js +1 -1
- package/dist/mass.js +1 -1
- package/dist/mediafuseBidAdapter.js +1 -1
- package/dist/mediakeysBidAdapter.js +1 -1
- package/dist/mediasniperBidAdapter.js +1 -1
- package/dist/mediasquareBidAdapter.js +1 -1
- package/dist/mgidBidAdapter.js +1 -1
- package/dist/minutemediaBidAdapter.js +1 -1
- package/dist/multibid.js +1 -1
- package/dist/naveggIdSystem.js +1 -1
- package/dist/newspassidBidAdapter.js +1 -1
- package/dist/nextMillenniumBidAdapter.js +1 -1
- package/dist/not-for-prod/prebid.js +172 -171
- package/dist/oguryBidAdapter.js +1 -1
- package/dist/oneKeyRtdProvider.js +1 -1
- package/dist/onetagBidAdapter.js +1 -1
- package/dist/ooloAnalyticsAdapter.js +1 -1
- package/dist/openxBidAdapter.js +1 -1
- package/dist/openxOrtbBidAdapter.js +1 -1
- package/dist/operaadsBidAdapter.js +1 -1
- package/dist/outbrainBidAdapter.js +1 -1
- package/dist/ozoneBidAdapter.js +1 -1
- package/dist/parrableIdSystem.js +1 -1
- package/dist/permutiveRtdProvider.js +1 -1
- package/dist/pixfutureBidAdapter.js +1 -1
- package/dist/prebid-core.js +2 -2
- package/dist/prebidServerBidAdapter.js +1 -1
- package/dist/priceFloors.js +1 -1
- package/dist/pubCommonId.js +1 -1
- package/dist/pubgeniusBidAdapter.js +1 -1
- package/dist/publinkIdSystem.js +1 -1
- package/dist/pubmaticBidAdapter.js +1 -1
- package/dist/pubwiseAnalyticsAdapter.js +1 -1
- package/dist/pubwiseBidAdapter.js +1 -1
- package/dist/pubxBidAdapter.js +1 -1
- package/dist/pxyzBidAdapter.js +1 -1
- package/dist/quantcastBidAdapter.js +1 -1
- package/dist/readpeakBidAdapter.js +1 -1
- package/dist/relaidoBidAdapter.js +1 -1
- package/dist/rhythmoneBidAdapter.js +1 -1
- package/dist/riseBidAdapter.js +1 -1
- package/dist/rtdModule.js +1 -1
- package/dist/rubiconAnalyticsAdapter.js +1 -1
- package/dist/rubiconBidAdapter.js +1 -1
- package/dist/seedingAllianceBidAdapter.js +1 -1
- package/dist/seedtagBidAdapter.js +1 -1
- package/dist/sharethroughAnalyticsAdapter.js +1 -1
- package/dist/sharethroughBidAdapter.js +1 -1
- package/dist/shinezBidAdapter.js +1 -1
- package/dist/sirdataRtdProvider.js +1 -1
- package/dist/smaatoBidAdapter.js +1 -1
- package/dist/smartadserverBidAdapter.js +1 -1
- package/dist/smartxBidAdapter.js +1 -1
- package/dist/smilewantedBidAdapter.js +1 -1
- package/dist/sonobiBidAdapter.js +1 -1
- package/dist/sovrnAnalyticsAdapter.js +1 -1
- package/dist/sovrnBidAdapter.js +1 -1
- package/dist/spotxBidAdapter.js +1 -1
- package/dist/sspBCBidAdapter.js +1 -1
- package/dist/stroeerCoreBidAdapter.js +1 -1
- package/dist/sublimeBidAdapter.js +1 -1
- package/dist/synacormediaBidAdapter.js +1 -1
- package/dist/targetVideoBidAdapter.js +1 -1
- package/dist/teadsBidAdapter.js +1 -1
- package/dist/trionBidAdapter.js +1 -1
- package/dist/tripleliftBidAdapter.js +1 -1
- package/dist/ttdBidAdapter.js +1 -1
- package/dist/ucfunnelAnalyticsAdapter.js +1 -1
- package/dist/ucfunnelBidAdapter.js +1 -1
- package/dist/underdogmediaBidAdapter.js +1 -1
- package/dist/undertoneBidAdapter.js +1 -1
- package/dist/userId.js +1 -1
- package/dist/vidazooBidAdapter.js +1 -1
- package/dist/videobyteBidAdapter.js +1 -1
- package/dist/viewability.js +1 -1
- package/dist/visxBidAdapter.js +1 -1
- package/dist/vuukleBidAdapter.js +1 -1
- package/dist/weboramaRtdProvider.js +1 -1
- package/dist/widespaceBidAdapter.js +1 -1
- package/dist/winrBidAdapter.js +1 -1
- package/dist/yahoosspBidAdapter.js +1 -1
- package/dist/yieldliftBidAdapter.js +1 -1
- package/dist/yieldmoBidAdapter.js +1 -1
- package/dist/yieldoneAnalyticsAdapter.js +1 -1
- package/dist/zeta_global_sspBidAdapter.js +1 -1
- package/modules/amxBidAdapter.js +98 -78
- package/modules/appnexusBidAdapter.js +73 -12
- package/modules/categoryTranslation.js +9 -8
- package/modules/consentManagement.js +4 -2
- package/modules/consentManagementUsp.js +17 -14
- package/modules/cpmstarBidAdapter.js +2 -1
- package/modules/currency.js +4 -3
- package/modules/dataControllerModule/index.js +4 -3
- package/modules/dchain.js +3 -2
- package/modules/dianomiBidAdapter.js +17 -14
- package/modules/dianomiBidAdapter.md +1 -1
- package/modules/feedadBidAdapter.js +40 -8
- package/modules/fpdModule/index.js +3 -2
- package/modules/iasRtdProvider.js +17 -3
- package/modules/ixBidAdapter.js +2 -5
- package/modules/liveIntentAnalyticsAdapter.js +148 -0
- package/modules/liveIntentAnalyticsAdapter.md +22 -0
- package/modules/mass.js +5 -3
- package/modules/multibid/index.js +4 -2
- package/modules/naveggIdSystem.js +53 -22
- package/modules/nextMillenniumBidAdapter.js +168 -55
- package/modules/openxOrtbBidAdapter.js +1 -1
- package/modules/prebidServerBidAdapter/index.js +18 -4
- package/modules/priceFloors.js +5 -4
- package/modules/pubCommonId.js +3 -2
- package/modules/rtdModule/index.js +3 -2
- package/modules/sharethroughBidAdapter.js +8 -6
- package/modules/spotxBidAdapter.js +1 -0
- package/modules/stroeerCoreBidAdapter.js +129 -92
- package/modules/stroeerCoreBidAdapter.md +52 -14
- package/modules/teadsBidAdapter.js +32 -10
- package/modules/ucfunnelBidAdapter.js +9 -10
- package/modules/userId/index.js +73 -48
- package/modules/viewability.js +2 -170
- package/package.json +3 -3
- package/src/adapterManager.js +21 -13
- package/src/adapters/bidderFactory.js +28 -6
- package/src/auction.js +17 -4
- package/src/auctionManager.js +5 -0
- package/src/constants.json +2 -0
- package/src/native.js +5 -2
- package/src/prebid.js +52 -23
- package/src/secureCreatives.js +1 -1
- package/src/utils/perfMetrics.js +386 -0
- package/src/utils.js +1 -1
- package/test/helpers/testing-utils.js +4 -3
- package/test/spec/modules/adriverIdSystem_spec.js +7 -3
- package/test/spec/modules/amxBidAdapter_spec.js +250 -192
- package/test/spec/modules/appnexusBidAdapter_spec.js +61 -6
- package/test/spec/modules/consentManagementUsp_spec.js +6 -2
- package/test/spec/modules/dianomiBidAdapter_spec.js +326 -6
- package/test/spec/modules/feedadBidAdapter_spec.js +147 -11
- package/test/spec/modules/iasRtdProvider_spec.js +3 -1
- package/test/spec/modules/ixBidAdapter_spec.js +0 -64
- package/test/spec/modules/liveIntentAnalyticsAdapter_spec.js +297 -0
- package/test/spec/modules/nextMillenniumBidAdapter_spec.js +103 -1
- package/test/spec/modules/openxOrtbBidAdapter_spec.js +31 -0
- package/test/spec/modules/sharethroughBidAdapter_spec.js +23 -2
- package/test/spec/modules/spotxBidAdapter_spec.js +6 -0
- package/test/spec/modules/stroeerCoreBidAdapter_spec.js +315 -33
- package/test/spec/modules/teadsBidAdapter_spec.js +65 -11
- package/test/spec/modules/ucfunnelBidAdapter_spec.js +24 -10
- package/test/spec/native_spec.js +11 -0
- package/test/spec/unit/utils/perfMetrics_spec.js +394 -0
- package/wdio.conf.js +1 -0
- package/modules/viewability.md +0 -87
- package/test/spec/modules/viewability_spec.js +0 -280
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
import {CONFIG_TOGGLE, metricsFactory, newMetrics, useMetrics} from '../../../../src/utils/perfMetrics.js';
|
|
2
|
+
import {defer} from '../../../../src/utils/promise.js';
|
|
3
|
+
import {hook} from '../../../../src/hook.js';
|
|
4
|
+
import {config} from 'src/config.js';
|
|
5
|
+
|
|
6
|
+
describe('metricsFactory', () => {
|
|
7
|
+
let metrics, now, enabled, newMetrics;
|
|
8
|
+
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
now = 0;
|
|
11
|
+
newMetrics = metricsFactory({now: () => now});
|
|
12
|
+
metrics = newMetrics();
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('can measure time with startTiming', () => {
|
|
16
|
+
now = 10;
|
|
17
|
+
const measure = metrics.startTiming('test');
|
|
18
|
+
now = 25.2;
|
|
19
|
+
measure();
|
|
20
|
+
expect(metrics.getMetrics()).to.eql({
|
|
21
|
+
test: 15.2
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
describe('measureTime', () => {
|
|
26
|
+
it('can measure time', () => {
|
|
27
|
+
metrics.measureTime('test', () => now += 3);
|
|
28
|
+
expect(metrics.getMetrics()).to.eql({
|
|
29
|
+
test: 3
|
|
30
|
+
})
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('still measures if fn throws', () => {
|
|
34
|
+
expect(() => {
|
|
35
|
+
metrics.measureTime('test', () => {
|
|
36
|
+
now += 4;
|
|
37
|
+
throw new Error();
|
|
38
|
+
});
|
|
39
|
+
}).to.throw();
|
|
40
|
+
expect(metrics.getMetrics()).to.eql({
|
|
41
|
+
test: 4
|
|
42
|
+
});
|
|
43
|
+
})
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
describe('measureHookTime', () => {
|
|
47
|
+
let testHook;
|
|
48
|
+
before(() => {
|
|
49
|
+
testHook = hook('sync', () => null, 0, 'testName');
|
|
50
|
+
hook.ready();
|
|
51
|
+
});
|
|
52
|
+
beforeEach(() => {
|
|
53
|
+
testHook.getHooks().remove();
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
['before', 'after'].forEach(hookType => {
|
|
57
|
+
describe(`on ${hookType} hooks`, () => {
|
|
58
|
+
Object.entries({
|
|
59
|
+
next: (n) => n,
|
|
60
|
+
bail: (n) => n.bail
|
|
61
|
+
}).forEach(([t, fn]) => {
|
|
62
|
+
it(`can time when hooks call ${t}`, () => {
|
|
63
|
+
const q = defer();
|
|
64
|
+
testHook[hookType]((next) => {
|
|
65
|
+
metrics.measureHookTime('test', next, (next) => {
|
|
66
|
+
setTimeout(() => {
|
|
67
|
+
now += 10;
|
|
68
|
+
fn(next)();
|
|
69
|
+
q.resolve();
|
|
70
|
+
})
|
|
71
|
+
})
|
|
72
|
+
});
|
|
73
|
+
testHook();
|
|
74
|
+
return q.promise.then(() => {
|
|
75
|
+
expect(metrics.getMetrics()).to.eql({
|
|
76
|
+
test: 10
|
|
77
|
+
});
|
|
78
|
+
})
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
})
|
|
82
|
+
})
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
describe('checkpoints', () => {
|
|
86
|
+
it('can measure time from checkpoint with timeSince', () => {
|
|
87
|
+
now = 10;
|
|
88
|
+
metrics.checkpoint('A');
|
|
89
|
+
now = 15;
|
|
90
|
+
expect(metrics.timeSince('A')).to.eql(5);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it('timeSince is null if checkpoint does not exist', () => {
|
|
94
|
+
expect(metrics.timeSince('missing')).to.equal(null);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it('timeSince saves a metric if given a name', () => {
|
|
98
|
+
now = 10;
|
|
99
|
+
metrics.checkpoint('A');
|
|
100
|
+
now = 15;
|
|
101
|
+
metrics.timeSince('A', 'test');
|
|
102
|
+
expect(metrics.getMetrics()).to.eql({test: 5});
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it('can measure time between checkpoints with timeBetween', () => {
|
|
106
|
+
now = 10;
|
|
107
|
+
metrics.checkpoint('A');
|
|
108
|
+
now = 15;
|
|
109
|
+
metrics.checkpoint('B');
|
|
110
|
+
now = 20;
|
|
111
|
+
expect(metrics.timeBetween('A', 'B')).to.eql(5);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
Object.entries({
|
|
115
|
+
'first checkpoint': [false, true],
|
|
116
|
+
'second checkpoint': [true, false],
|
|
117
|
+
'both checkpoints': [false, false]
|
|
118
|
+
}).forEach(([t, [checkFirst, checkSecond]]) => {
|
|
119
|
+
it(`timeBetween measures to null if missing ${t}`, () => {
|
|
120
|
+
if (checkFirst) {
|
|
121
|
+
metrics.checkpoint('A');
|
|
122
|
+
}
|
|
123
|
+
if (checkSecond) {
|
|
124
|
+
metrics.checkpoint('B');
|
|
125
|
+
}
|
|
126
|
+
expect(metrics.timeBetween('A', 'B')).to.equal(null)
|
|
127
|
+
})
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
it('saves a metric with timeBetween if given a name', () => {
|
|
131
|
+
now = 10;
|
|
132
|
+
metrics.checkpoint('A');
|
|
133
|
+
now = 15;
|
|
134
|
+
metrics.checkpoint('B');
|
|
135
|
+
metrics.timeBetween('A', 'B', 'test');
|
|
136
|
+
expect(metrics.getMetrics()).to.eql({test: 5});
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
describe('setMetrics', () => {
|
|
141
|
+
it('sets metric', () => {
|
|
142
|
+
metrics.setMetric('test', 1);
|
|
143
|
+
expect(metrics.getMetrics()).to.eql({test: 1});
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
describe('fork', () => {
|
|
148
|
+
it('keeps metrics from ancestors', () => {
|
|
149
|
+
const m2 = metrics.fork();
|
|
150
|
+
const m3 = m2.fork();
|
|
151
|
+
metrics.setMetric('1', 'one');
|
|
152
|
+
m2.setMetric('2', 'two');
|
|
153
|
+
m3.setMetric('3', 'three');
|
|
154
|
+
sinon.assert.match(metrics.getMetrics(), {
|
|
155
|
+
1: 'one'
|
|
156
|
+
})
|
|
157
|
+
sinon.assert.match(m2.getMetrics(), {
|
|
158
|
+
1: 'one',
|
|
159
|
+
2: 'two'
|
|
160
|
+
});
|
|
161
|
+
sinon.assert.match(m3.getMetrics(), {
|
|
162
|
+
1: 'one',
|
|
163
|
+
2: 'two',
|
|
164
|
+
3: 'three'
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
it('keeps checkpoints from ancestors', () => {
|
|
169
|
+
const m2 = metrics.fork();
|
|
170
|
+
const m3 = m2.fork();
|
|
171
|
+
now = 10;
|
|
172
|
+
metrics.checkpoint('1');
|
|
173
|
+
now = 20;
|
|
174
|
+
m2.checkpoint('2');
|
|
175
|
+
now = 30;
|
|
176
|
+
m3.checkpoint('3');
|
|
177
|
+
now = 40;
|
|
178
|
+
expect(m2.timeSince('1')).to.eql(30);
|
|
179
|
+
expect(m3.timeSince('2')).to.eql(20);
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
it('groups metrics into ancestors', () => {
|
|
183
|
+
const c1 = metrics.fork().fork();
|
|
184
|
+
const c2 = metrics.fork().fork();
|
|
185
|
+
c1.setMetric('test', 10);
|
|
186
|
+
c2.setMetric('test', 20);
|
|
187
|
+
expect(metrics.getMetrics().test).to.eql([10, 20]);
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
it('does not group metrics into ancestors if the name clashes', () => {
|
|
191
|
+
metrics.setMetric('test', {});
|
|
192
|
+
metrics.fork().setMetric('test', 1);
|
|
193
|
+
expect(metrics.getMetrics().test).to.eql({});
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
it('does not propagate further if stopPropagation = true', () => {
|
|
197
|
+
const c1 = metrics.fork();
|
|
198
|
+
const c2 = c1.fork({stopPropagation: true});
|
|
199
|
+
c2.setMetric('test', 1);
|
|
200
|
+
expect(c1.getMetrics().test).to.eql([1]);
|
|
201
|
+
expect(metrics.getMetrics().test).to.not.exist;
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
it('does not propagate at all if propagate = false', () => {
|
|
205
|
+
metrics.fork({propagate: false}).setMetric('test', 1);
|
|
206
|
+
expect(metrics.getMetrics()).to.eql({});
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
it('replicates grouped metrics if includeGroups = true', () => {
|
|
210
|
+
const child = metrics.fork({includeGroups: true});
|
|
211
|
+
metrics.fork().setMetric('test', 1);
|
|
212
|
+
expect(child.getMetrics()).to.eql({
|
|
213
|
+
test: [1]
|
|
214
|
+
});
|
|
215
|
+
})
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
describe('join', () => {
|
|
219
|
+
let other;
|
|
220
|
+
beforeEach(() => {
|
|
221
|
+
other = newMetrics();
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
it('joins metrics', () => {
|
|
225
|
+
metrics.setMetric('test', 1);
|
|
226
|
+
metrics.join(other);
|
|
227
|
+
expect(other.getMetrics()).to.eql({
|
|
228
|
+
test: 1
|
|
229
|
+
});
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
it('joins checkpoints', () => {
|
|
233
|
+
now = 10;
|
|
234
|
+
metrics.checkpoint('test');
|
|
235
|
+
metrics.join(other);
|
|
236
|
+
now = 20;
|
|
237
|
+
expect(other.timeSince('test')).to.eql(10);
|
|
238
|
+
})
|
|
239
|
+
|
|
240
|
+
it('groups metrics after joining', () => {
|
|
241
|
+
metrics.join(other);
|
|
242
|
+
other.setMetric('test', 1);
|
|
243
|
+
expect(metrics.getMetrics().test).to.eql([1]);
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
it('gives precedence to first join\'s metrics', () => {
|
|
247
|
+
metrics.join(other);
|
|
248
|
+
const metrics2 = newMetrics();
|
|
249
|
+
metrics2.join(other);
|
|
250
|
+
metrics.setMetric('test', 1);
|
|
251
|
+
metrics2.setMetric('test', 2);
|
|
252
|
+
expect(other.getMetrics()).to.eql({
|
|
253
|
+
test: 1
|
|
254
|
+
});
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
it('gives precedence to first joins\'s checkpoints', () => {
|
|
258
|
+
metrics.join(other);
|
|
259
|
+
const metrics2 = newMetrics();
|
|
260
|
+
metrics2.join(other);
|
|
261
|
+
now = 10;
|
|
262
|
+
metrics.checkpoint('testcp');
|
|
263
|
+
now = 20;
|
|
264
|
+
metrics2.checkpoint('testcp');
|
|
265
|
+
now = 30;
|
|
266
|
+
expect(other.timeSince('testcp')).to.eql(20);
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
it('does not propagate further if stopPropagation = true', () => {
|
|
270
|
+
const m2 = metrics.fork();
|
|
271
|
+
m2.join(other, {stopPropagation: true});
|
|
272
|
+
other.setMetric('test', 1);
|
|
273
|
+
expect(m2.getMetrics().test).to.eql([1]);
|
|
274
|
+
expect(metrics.getMetrics()).to.eql({});
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
it('does not propagate at all if propagate = false', () => {
|
|
278
|
+
metrics.join(other, {propagate: false});
|
|
279
|
+
other.setMetric('test', 1);
|
|
280
|
+
expect(metrics.getMetrics()).to.eql({});
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
it('replicates grouped metrics if includeGroups = true', () => {
|
|
284
|
+
const m2 = metrics.fork();
|
|
285
|
+
metrics.join(other, {includeGroups: true});
|
|
286
|
+
m2.setMetric('test', 1);
|
|
287
|
+
expect(other.getMetrics()).to.eql({
|
|
288
|
+
test: [1]
|
|
289
|
+
});
|
|
290
|
+
})
|
|
291
|
+
|
|
292
|
+
Object.entries({
|
|
293
|
+
'join with a common ancestor': () => [metrics.fork(), metrics.fork()],
|
|
294
|
+
'join with self': () => [metrics, metrics],
|
|
295
|
+
}).forEach(([t, makePair]) => {
|
|
296
|
+
it(`can ${t}`, () => {
|
|
297
|
+
const [m1, m2] = makePair();
|
|
298
|
+
m1.join(m2);
|
|
299
|
+
m1.setMetric('test', 1);
|
|
300
|
+
const expected = {'test': 1};
|
|
301
|
+
expect(m1.getMetrics()).to.eql(expected);
|
|
302
|
+
expect(m2.getMetrics()).to.eql(expected);
|
|
303
|
+
})
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
it('can join into a cycle', () => {
|
|
307
|
+
const c = metrics.fork();
|
|
308
|
+
c.join(metrics);
|
|
309
|
+
c.setMetric('child', 1);
|
|
310
|
+
metrics.setMetric('parent', 1);
|
|
311
|
+
expect(c.getMetrics()).to.eql({
|
|
312
|
+
child: 1,
|
|
313
|
+
parent: [1]
|
|
314
|
+
})
|
|
315
|
+
expect(metrics.getMetrics()).to.eql({
|
|
316
|
+
parent: 1,
|
|
317
|
+
child: [1]
|
|
318
|
+
})
|
|
319
|
+
});
|
|
320
|
+
});
|
|
321
|
+
describe('newMetrics', () => {
|
|
322
|
+
it('returns related, but independent, metrics', () => {
|
|
323
|
+
const m0 = metrics.newMetrics();
|
|
324
|
+
const m1 = newMetrics();
|
|
325
|
+
m1.join(m0);
|
|
326
|
+
m0.setMetric('m0', 1);
|
|
327
|
+
m1.setMetric('m1', 1);
|
|
328
|
+
expect(metrics.getMetrics()).to.eql({});
|
|
329
|
+
expect(m0.getMetrics()).to.eql({
|
|
330
|
+
m0: 1,
|
|
331
|
+
m1: 1
|
|
332
|
+
})
|
|
333
|
+
})
|
|
334
|
+
})
|
|
335
|
+
})
|
|
336
|
+
|
|
337
|
+
describe('nullMetrics', () => {
|
|
338
|
+
let nullMetrics;
|
|
339
|
+
beforeEach(() => {
|
|
340
|
+
nullMetrics = useMetrics(null);
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
Object.entries({
|
|
344
|
+
'stopBefore': (fn) => nullMetrics.startTiming('n').stopBefore(fn),
|
|
345
|
+
'stopAfter': (fn) => nullMetrics.startTiming('n').stopAfter(fn),
|
|
346
|
+
'measureTime': (fn) => (...args) => nullMetrics.measureTime('n', () => fn(...args)),
|
|
347
|
+
'measureHookTime': (fn) => (...args) => nullMetrics.measureHookTime('n', {}, () => fn(...args))
|
|
348
|
+
}).forEach(([t, wrapFn]) => {
|
|
349
|
+
describe(t, () => {
|
|
350
|
+
it('invokes the wrapped fn', () => {
|
|
351
|
+
const fn = sinon.stub();
|
|
352
|
+
wrapFn(fn)('one', 'two');
|
|
353
|
+
sinon.assert.calledWith(fn, 'one', 'two');
|
|
354
|
+
});
|
|
355
|
+
it('does not register timing metrics', () => {
|
|
356
|
+
wrapFn(sinon.stub())();
|
|
357
|
+
expect(nullMetrics.getMetrics()).to.eql({});
|
|
358
|
+
})
|
|
359
|
+
})
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
it('does not save checkpoints', () => {
|
|
363
|
+
nullMetrics.checkpoint('A');
|
|
364
|
+
expect(nullMetrics.timeSince('A')).to.equal(null);
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
it('does not save metrics', () => {
|
|
368
|
+
nullMetrics.setMetric('test', 1);
|
|
369
|
+
expect(nullMetrics.getMetrics()).to.eql({});
|
|
370
|
+
});
|
|
371
|
+
})
|
|
372
|
+
|
|
373
|
+
describe('configuration toggle', () => {
|
|
374
|
+
afterEach(() => {
|
|
375
|
+
config.resetConfig();
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
Object.entries({
|
|
379
|
+
'useMetrics': () => useMetrics(metricsFactory()()),
|
|
380
|
+
'newMetrics': newMetrics
|
|
381
|
+
}).forEach(([t, mkMetrics]) => {
|
|
382
|
+
it(`${t} returns no-op metrics when disabled`, () => {
|
|
383
|
+
config.setConfig({[CONFIG_TOGGLE]: false});
|
|
384
|
+
const metrics = mkMetrics();
|
|
385
|
+
metrics.setMetric('test', 'value');
|
|
386
|
+
expect(metrics.getMetrics()).to.eql({});
|
|
387
|
+
});
|
|
388
|
+
it(`returns actual metrics by default`, () => {
|
|
389
|
+
const metrics = mkMetrics();
|
|
390
|
+
metrics.setMetric('test', 'value');
|
|
391
|
+
expect(metrics.getMetrics()).to.eql({test: 'value'});
|
|
392
|
+
});
|
|
393
|
+
});
|
|
394
|
+
});
|
package/wdio.conf.js
CHANGED
|
@@ -51,6 +51,7 @@ exports.config = {
|
|
|
51
51
|
user: process.env.BROWSERSTACK_USERNAME,
|
|
52
52
|
key: process.env.BROWSERSTACK_ACCESS_KEY,
|
|
53
53
|
maxInstances: 5, // Do not increase this, since we have only 5 parallel tests in browserstack account
|
|
54
|
+
maxInstancesPerCapability: 1,
|
|
54
55
|
capabilities: getCapabilities(),
|
|
55
56
|
logLevel: 'info', // put option here: info | trace | debug | warn| error | silent
|
|
56
57
|
bail: 0,
|
package/modules/viewability.md
DELETED
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
# Overview
|
|
2
|
-
|
|
3
|
-
Module Name: Viewability
|
|
4
|
-
|
|
5
|
-
Purpose: Track when a given HTML element becomes viewable
|
|
6
|
-
|
|
7
|
-
Maintainer: atrajkovic@magnite.com
|
|
8
|
-
|
|
9
|
-
# Configuration
|
|
10
|
-
|
|
11
|
-
Module does not need any configuration, as long as you include it in your PBJS bundle.
|
|
12
|
-
Viewability module has only two functions `startMeasurement` and `stopMeasurement` which can be used to enable more complex viewability measurements. Since it allows tracking from within creative (possibly inside a safe frame) this module registers a message listener, for messages with a format that is described bellow.
|
|
13
|
-
|
|
14
|
-
## `startMeasurement`
|
|
15
|
-
|
|
16
|
-
| startMeasurement Arg Object | Scope | Type | Description | Example |
|
|
17
|
-
| --------------------- | -------- | ------------ | -------------------------------------------------------------------------------- | --------- |
|
|
18
|
-
| vid | Required | String | Unique viewability identifier, used to reference particular observer | `"ae0f9"` |
|
|
19
|
-
| element | Required | HTMLElement | Reference to an HTML element that needs to be tracked | `document.getElementById('test_div')` |
|
|
20
|
-
| tracker | Required | ViewabilityTracker | How viewaility event is communicated back to the parties of interest | `{ method: 'img', value: 'http://my.tracker/123' }` |
|
|
21
|
-
| criteria | Required | ViewabilityCriteria| Defines custom viewability criteria using the threshold and duration provided | `{ inViewThreshold: 0.5, timeInView: 1000 }` |
|
|
22
|
-
|
|
23
|
-
| ViewabilityTracker | Scope | Type | Description | Example |
|
|
24
|
-
| --------------------- | -------- | ------------ | -------------------------------------------------------------------------------- | --------- |
|
|
25
|
-
| method | Required | String | Type of method for Tracker | `'img' OR 'js' OR 'callback'` |
|
|
26
|
-
| value | Required | String | URL string for 'img' and 'js' Trackers, or a function for 'callback' Tracker | `'http://my.tracker/123'` |
|
|
27
|
-
|
|
28
|
-
| ViewabilityCriteria | Scope | Type | Description | Example |
|
|
29
|
-
| --------------------- | -------- | ------------ | -------------------------------------------------------------------------------- | --------- |
|
|
30
|
-
| inViewThreshold | Required | Number | Represents a percentage threshold for the Element to be registered as in view | `0.5` |
|
|
31
|
-
| timeInView | Required | Number | Number of milliseconds that a given element needs to be in view continuously, above the threshold | `1000` |
|
|
32
|
-
|
|
33
|
-
## Please Note:
|
|
34
|
-
- `vid` allows for multiple trackers, with different criteria to be registered for a given HTML element, independently. It's not autogenerated by `startMeasurement()`, it needs to be provided by the caller so that it doesn't have to be posted back to the source iframe (in case viewability is started from within the creative).
|
|
35
|
-
- In case of 'callback' method, HTML element is being passed back to the callback function.
|
|
36
|
-
- When a tracker needs to be started, without direct access to pbjs, postMessage mechanism can be used to invoke `startMeasurement`, with a following payload: `vid`, `tracker` and `criteria` as described above, but also with `message: 'Prebid Viewability'` and `action: 'startMeasurement'`. Optionally payload can provide `elementId`, if available at that time (for ad servers where name of the iframe is known, or adservers that render outside an iframe). If `elementId` is not provided, viewability module will try to find the iframe that corresponds to the message source.
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
## `stopMeasurement`
|
|
40
|
-
|
|
41
|
-
| stopMeasurement Arg Object | Scope | Type | Description | Example |
|
|
42
|
-
| --------------------- | -------- | ------------ | -------------------------------------------------------------------------------- | --------- |
|
|
43
|
-
| vid | Required | String | Unique viewability identifier, referencing an already started viewability tracker. | `"ae0f9"` |
|
|
44
|
-
|
|
45
|
-
## Please Note:
|
|
46
|
-
- When a tracker needs to be stopped, without direct access to pbjs, postMessage mechanism can be used here as well. To invoke `stopMeasurement`, you provide the payload with `vid`, `message: 'Prebid Viewability'` and `action: 'stopMeasurement`. Check the example bellow.
|
|
47
|
-
|
|
48
|
-
# Examples
|
|
49
|
-
|
|
50
|
-
## Example of starting a viewability measurement, when you have direct access to pbjs
|
|
51
|
-
```
|
|
52
|
-
pbjs.viewability.startMeasurement(
|
|
53
|
-
'ae0f9',
|
|
54
|
-
document.getElementById('test_div'),
|
|
55
|
-
{ method: 'img', value: 'http://my.tracker/123' },
|
|
56
|
-
{ inViewThreshold: 0.5, timeInView: 1000 }
|
|
57
|
-
);
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
## Example of starting a viewability measurement from within a rendered creative
|
|
61
|
-
```
|
|
62
|
-
let viewabilityRecord = {
|
|
63
|
-
vid: 'ae0f9',
|
|
64
|
-
tracker: { method: 'img', value: 'http://my.tracker/123'},
|
|
65
|
-
criteria: { inViewThreshold: 0.5, timeInView: 1000 },
|
|
66
|
-
message: 'Prebid Viewability',
|
|
67
|
-
action: 'startMeasurement'
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
window.parent.postMessage(JSON.stringify(viewabilityRecord), '*');
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
## Example of stopping the viewability measurement, when you have direct access to pbjs
|
|
74
|
-
```
|
|
75
|
-
pbjs.viewability.stopMeasurement('ae0f9');
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
## Example of stopping the viewability measurement from within a rendered creative
|
|
79
|
-
```
|
|
80
|
-
let viewabilityRecord = {
|
|
81
|
-
vid: 'ae0f9',
|
|
82
|
-
message: 'Prebid Viewability',
|
|
83
|
-
action: 'stopMeasurement'
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
window.parent.postMessage(JSON.stringify(viewabilityRecord), '*');
|
|
87
|
-
```
|