prebid-universal-creative 1.16.0 → 1.17.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.
Files changed (51) hide show
  1. package/.circleci/config.yml +44 -30
  2. package/.github/workflows/codeql.yml +98 -0
  3. package/README.md +2 -2
  4. package/dist/amp.js +3 -3
  5. package/dist/banner.js +3 -3
  6. package/dist/caf7688498213fb0c19f.max.js +1046 -0
  7. package/dist/creative.js +3 -3
  8. package/dist/load-cookie-with-consent.html +1 -1
  9. package/dist/load-cookie.html +1 -1
  10. package/dist/mobile.js +3 -3
  11. package/dist/native-render.js +3 -3
  12. package/dist/native-trk.js +3 -3
  13. package/dist/native.js +3 -3
  14. package/dist/uid.js +2 -2
  15. package/dist/video.js +3 -3
  16. package/gulpfile.js +12 -24
  17. package/integ-test/fixtures/test.js +79 -0
  18. package/integ-test/pages/amp.html +80 -0
  19. package/integ-test/pages/banner.html +96 -0
  20. package/integ-test/pages/native_legacy.html +107 -0
  21. package/integ-test/spec/amp_spec.js +111 -0
  22. package/integ-test/spec/banner_spec.js +85 -0
  23. package/integ-test/spec/native_legacy_spec.js +213 -0
  24. package/package.json +7 -13
  25. package/playwright.config.js +108 -0
  26. package/src/adHtmlRender.js +11 -0
  27. package/src/cookieSync.js +3 -0
  28. package/src/cookieSyncWithConsent.js +3 -0
  29. package/src/domHelper.js +25 -15
  30. package/src/dynamicRenderer.js +56 -0
  31. package/src/messaging.js +23 -2
  32. package/src/mobileAndAmpRender.js +17 -20
  33. package/src/nativeAssetManager.js +98 -79
  34. package/src/nativeORTBTrackerManager.js +1 -1
  35. package/src/nativeRenderManager.js +7 -12
  36. package/src/nativeTrackerManager.js +2 -2
  37. package/src/renderingManager.js +13 -19
  38. package/test/helpers/mocks.js +1 -0
  39. package/test/spec/dynamicRenderer_spec.js +167 -0
  40. package/test/spec/messaging_spec.js +98 -3
  41. package/test/spec/mobileAndAmpRender_spec.js +47 -65
  42. package/test/spec/nativeAssetManager_spec.js +73 -23
  43. package/test/spec/renderingManager_spec.js +20 -6
  44. package/webpack.conf.js +0 -1
  45. package/.nvmrc +0 -1
  46. package/dist/creative.max.js +0 -3102
  47. package/src/postscribeRender.js +0 -10
  48. package/test/e2e/specs/hello_world_banner_non_sf.spec.js +0 -14
  49. package/test/e2e/specs/outstream_non_sf.spec.js +0 -14
  50. package/test/e2e/specs/outstream_sf.spec.js +0 -14
  51. package/wdio.conf.js +0 -50
@@ -1,5 +1,11 @@
1
1
  import {mocks} from '../helpers/mocks.js';
2
- import {prebidMessenger} from '../../src/messaging.js';
2
+ import {
3
+ AD_RENDER_FAILED,
4
+ AD_RENDER_SUCCEEDED,
5
+ PREBID_EVENT,
6
+ prebidMessenger,
7
+ renderEventMessage
8
+ } from '../../src/messaging.js';
3
9
 
4
10
  describe('prebidMessenger',() => {
5
11
  let win;
@@ -25,7 +31,6 @@ describe('prebidMessenger',() => {
25
31
  describe('when publisher URL is available', () => {
26
32
  const URL = 'https://www.publisher.com/page.html';
27
33
  const ORIGIN = 'https://www.publisher.com'
28
- let sendMessage;
29
34
  let callback, handler;
30
35
 
31
36
  beforeEach(() => {
@@ -33,15 +38,73 @@ describe('prebidMessenger',() => {
33
38
  handler = h;
34
39
  }
35
40
  win.removeEventListener = sinon.spy();
36
- sendMessage = prebidMessenger(URL, win);
37
41
  callback = sinon.spy();
38
42
  })
39
43
 
44
+ function sendMessage(...args) {
45
+ return prebidMessenger(URL, win)(...args);
46
+ }
47
+
40
48
  it('should use origin for postMessage', () => {
41
49
  sendMessage('test');
42
50
  sinon.assert.calledWith(win.parent.postMessage, JSON.stringify('test'), ORIGIN);
43
51
  });
44
52
 
53
+ describe('when window has multiple ancestors', () => {
54
+ let target;
55
+ beforeEach(() => {
56
+ const top = mocks.createFakeWindow('top');
57
+ target = {
58
+ ...win.parent,
59
+ frames: {},
60
+ parent: {
61
+ top,
62
+ frames: {},
63
+ parent: top
64
+ }
65
+ };
66
+ win = {
67
+ top,
68
+ frames: {},
69
+ parent: {
70
+ top,
71
+ frames: {},
72
+ parent: target
73
+ }
74
+ };
75
+ })
76
+ Object.entries({
77
+ throws() { throw new DOMException() },
78
+ 'does not throw'() { return {} }
79
+ }).forEach(([t, getFrames]) => {
80
+ describe(`when ancestor ${t}`, () => {
81
+ beforeEach(() => {
82
+ Object.defineProperty(target.parent.parent, 'frames', {get: getFrames});
83
+ })
84
+ it('should post to first ancestor that has a __pb_locator__ child', () => {
85
+ [target, target.parent].forEach(win => {
86
+ win.frames = {
87
+ __pb_locator__: {}
88
+ };
89
+ })
90
+ sendMessage('test');
91
+ sinon.assert.called(target.postMessage);
92
+ });
93
+ })
94
+ })
95
+ it('should post to immediate parent when no ancestor has __pb_locator__', () => {
96
+ win.parent.postMessage = sinon.spy();
97
+ delete target.postMessage;
98
+ sendMessage('test');
99
+ sinon.assert.called(win.parent.postMessage);
100
+ });
101
+ it('should post to first restricted frame if no __pb_locator__ can be found', () => {
102
+ Object.defineProperty(target, 'frames', {get() { throw new DOMException() }});
103
+ sendMessage('test');
104
+ sinon.assert.called(target.postMessage)
105
+ })
106
+ });
107
+
45
108
  it('should not run callback on response if origin does not mach', ()=> {
46
109
  sendMessage('test', callback);
47
110
  handler({origin: 'different'});
@@ -62,3 +125,35 @@ describe('prebidMessenger',() => {
62
125
 
63
126
  });
64
127
  })
128
+
129
+ describe('renderEventMessage', () => {
130
+ Object.entries({
131
+ 'success': {
132
+ input: {adId: '123'},
133
+ output: {
134
+ event: AD_RENDER_SUCCEEDED
135
+ }
136
+ },
137
+ 'failure': {
138
+ input: {
139
+ adId: '321',
140
+ errorInfo: {
141
+ reason: 'failureReason',
142
+ message: 'error message'
143
+ }
144
+ },
145
+ output: {
146
+ event: AD_RENDER_FAILED,
147
+ info: {
148
+ reason: 'failureReason',
149
+ message: 'error message'
150
+ }
151
+ }
152
+ }
153
+ }).forEach(([t, {input: {adId, errorInfo}, output}]) => {
154
+ Object.assign(output, {message: PREBID_EVENT, adId});
155
+ it(t, () => {
156
+ expect(renderEventMessage(adId, errorInfo)).to.eql(output);
157
+ })
158
+ })
159
+ })
@@ -1,10 +1,10 @@
1
1
  import { renderAmpOrMobileAd } from 'src/mobileAndAmpRender';
2
- import * as postscribeRender from 'src/postscribeRender'
2
+ import * as postscribeRender from 'src/adHtmlRender'
3
3
  import * as utils from 'src/utils';
4
4
  import { expect } from 'chai';
5
5
  import { mocks } from 'test/helpers/mocks';
6
6
  import { merge } from 'lodash';
7
- import {writeAdHtml} from 'src/postscribeRender';
7
+ import {writeAdHtml} from 'src/adHtmlRender';
8
8
 
9
9
 
10
10
  function renderingMocks() {
@@ -188,51 +188,58 @@ describe("renderingManager", function () {
188
188
  });
189
189
 
190
190
  describe("amp creative", function () {
191
+ let sandbox;
191
192
  let writeHtmlSpy;
192
193
  let sendRequestSpy;
193
194
  let triggerPixelSpy;
194
195
  let mockWin;
195
-
196
- before(function () {
197
- writeHtmlSpy = sinon.spy(postscribeRender, "writeAdHtml");
198
- sendRequestSpy = sinon.spy(utils, "sendRequest");
199
- triggerPixelSpy = sinon.spy(utils, "triggerPixel");
200
- mockWin = merge(
201
- mocks.createFakeWindow("http://example.com"),
202
- renderingMocks().getWindowObject()
203
- );
204
- });
205
-
206
- afterEach(function () {
207
- writeHtmlSpy.resetHistory();
208
- sendRequestSpy.resetHistory();
209
- triggerPixelSpy.resetHistory();
210
- });
211
-
212
- after(function () {
213
- writeHtmlSpy.restore();
214
- sendRequestSpy.restore();
215
- triggerPixelSpy.restore();
216
- });
217
-
218
- it("should render amp creative", function () {
219
- let ucTagData = {
196
+ let ucTagData;
197
+ let response;
198
+
199
+ beforeEach(function () {
200
+ sandbox = sinon.sandbox.create();
201
+ writeHtmlSpy = sandbox.spy(postscribeRender, "writeAdHtml");
202
+ sendRequestSpy = sandbox.spy(utils, "sendRequest");
203
+ triggerPixelSpy = sandbox.spy(utils, "triggerPixel");
204
+ ucTagData = {
220
205
  cacheHost: "example.com",
221
206
  cachePath: "/path",
222
207
  uuid: "123",
223
208
  size: "300x250",
224
- hbPb: "10.00",
225
209
  };
226
-
227
- renderAmpOrMobileAd(ucTagData);
228
-
229
- let response = {
210
+ response = {
230
211
  width: 300,
231
212
  height: 250,
232
213
  crid: 123,
233
214
  adm: "ad-markup${AUCTION_PRICE}",
234
215
  wurl: "https://test.prebidcache.wurl",
235
216
  };
217
+ });
218
+
219
+
220
+
221
+ afterEach(function () {
222
+ sandbox.restore();
223
+ });
224
+
225
+ it('should send embed-resize message', () => {
226
+ sandbox.spy(window.parent, 'postMessage');
227
+ ucTagData.size = '400x500'
228
+ renderAmpOrMobileAd(ucTagData);
229
+ requests[0].respond(200, {}, JSON.stringify(response));
230
+ sinon.assert.calledWith(window.parent.postMessage, {
231
+ sentinel: "amp",
232
+ type: "embed-size",
233
+ width: 400,
234
+ height: 500,
235
+ });
236
+ })
237
+
238
+ it("should render amp creative", function () {
239
+ ucTagData.hbPb = "10.00";
240
+ renderAmpOrMobileAd(ucTagData);
241
+
242
+
236
243
  requests[0].respond(200, {}, JSON.stringify(response));
237
244
  expect(writeHtmlSpy.args[0][0]).to.equal(
238
245
  "<!--Creative 123 served by Prebid.js Header Bidding-->ad-markup10.00"
@@ -246,24 +253,8 @@ describe("renderingManager", function () {
246
253
  });
247
254
 
248
255
  it("should replace AUCTION_PRICE with response.price over hbPb", function () {
249
- let ucTagData = {
250
- cacheHost: "example.com",
251
- cachePath: "/path",
252
- uuid: "123",
253
- size: "300x250",
254
- hbPb: "10.00",
255
- };
256
-
257
256
  renderAmpOrMobileAd(ucTagData);
258
-
259
- let response = {
260
- width: 300,
261
- height: 250,
262
- crid: 123,
263
- price: 12.5,
264
- adm: "ad-markup${AUCTION_PRICE}",
265
- wurl: "https://test.prebidcache.wurl",
266
- };
257
+ response.price = 12.5;
267
258
  requests[0].respond(200, {}, JSON.stringify(response));
268
259
  expect(writeHtmlSpy.args[0][0]).to.equal(
269
260
  "<!--Creative 123 served by Prebid.js Header Bidding-->ad-markup12.5"
@@ -277,22 +268,7 @@ describe("renderingManager", function () {
277
268
  });
278
269
 
279
270
  it("should replace AUCTION_PRICE with with empty value when neither price nor hbPb exist", function () {
280
- let ucTagData = {
281
- cacheHost: "example.com",
282
- cachePath: "/path",
283
- uuid: "123",
284
- size: "300x250",
285
- };
286
-
287
271
  renderAmpOrMobileAd(ucTagData);
288
-
289
- let response = {
290
- width: 300,
291
- height: 250,
292
- crid: 123,
293
- adm: "ad-markup${AUCTION_PRICE}",
294
- wurl: "https://test.prebidcache.wurl",
295
- };
296
272
  requests[0].respond(200, {}, JSON.stringify(response));
297
273
  expect(writeHtmlSpy.args[0][0]).to.equal(
298
274
  "<!--Creative 123 served by Prebid.js Header Bidding-->ad-markup"
@@ -312,5 +288,11 @@ describe('writeAdHtml', () => {
312
288
  const ps = sinon.stub();
313
289
  writeAdHtml('<!DOCTYPE html><div>mock-ad</div>', ps);
314
290
  sinon.assert.calledWith(ps, sinon.match.any, '<div>mock-ad</div>')
315
- })
291
+ });
292
+
293
+ it('removes lowercase doctype from markup', () => {
294
+ const ps = sinon.stub();
295
+ writeAdHtml('<!doctype html><div>mock-ad</div>', ps);
296
+ sinon.assert.calledWith(ps, sinon.match.any, '<div>mock-ad</div>')
297
+ });
316
298
  })
@@ -3,7 +3,9 @@ import {merge} from 'lodash';
3
3
  import {newNativeAssetManager} from 'src/nativeAssetManager';
4
4
  import {mocks} from 'test/helpers/mocks';
5
5
  import * as utils from 'src/utils';
6
+ import * as dynamic from 'src/dynamicRenderer.js';
6
7
  import {prebidMessenger} from '../../src/messaging.js';
8
+ import {MIN_RENDERER_VERSION} from "src/dynamicRenderer.js";
7
9
 
8
10
  const ORIGIN = 'https://origin.com'
9
11
  const AD_ID = 'abc123';
@@ -90,7 +92,7 @@ function generateRenderer(assets) {
90
92
  }
91
93
 
92
94
  describe('nativeAssetManager', () => {
93
- let win;
95
+ let win, sandbox;
94
96
 
95
97
  function makeManager(args, mkMessenger = prebidMessenger) {
96
98
  return newNativeAssetManager(win, {
@@ -101,6 +103,29 @@ describe('nativeAssetManager', () => {
101
103
 
102
104
  beforeEach(() => {
103
105
  win = merge(mocks.createFakeWindow(), mockDocument.getWindowObject());
106
+ sandbox = sinon.createSandbox();
107
+ });
108
+
109
+ afterEach(() => {
110
+ sandbox.restore();
111
+ })
112
+
113
+ it(`should run dynamic renderer`, () => {
114
+ const data = {
115
+ renderer: 'mock-renderer',
116
+ rendererVersion: MIN_RENDERER_VERSION,
117
+ native: 'data'
118
+ }
119
+ sandbox.stub(dynamic, 'runDynamicRenderer');
120
+ const sendMessage = sinon.stub().callsFake((msg, reply) => {
121
+ reply({data: JSON.stringify(Object.assign({adId: '123', message: 'assetResponse'}, data))});
122
+ })
123
+ win.pbNativeData = {
124
+ requestAllAssets: true
125
+ };
126
+ const mgr = makeManager({}, () => sendMessage);
127
+ mgr.loadAssets('123');
128
+ sinon.assert.calledWith(dynamic.runDynamicRenderer, '123', sinon.match(data));
104
129
  });
105
130
 
106
131
  describe('safe frames enabled', () => {
@@ -256,7 +281,7 @@ describe('nativeAssetManager', () => {
256
281
  ],null,null);
257
282
 
258
283
  const nativeAssetManager = makeManager();
259
- nativeAssetManager.loadAssets(AD_ID);
284
+ nativeAssetManager.loadAssets(win.pbNativeData.adId);
260
285
 
261
286
  expect(win.document.body.innerHTML).to.equal(`<script>
262
287
  let nativeTag = {};
@@ -558,8 +583,9 @@ describe('nativeAssetManager', () => {
558
583
  }
559
584
  })
560
585
 
561
- it('should set the iframe to the width of the container', () => {
562
- const html = `<script>
586
+ describe('body width resizing', () => {
587
+ beforeEach(() => {
588
+ const html = `<script>
563
589
  let nativeTag = {};
564
590
  nativeTag.adTemplate = "<div class=\"sponsored-post\">\r\n <div class=\"thumbnail\"><\/div>\r\n <div class=\"content\">\r\n <h1>\r\n <a href=\"##hb_native_linkurl##\" target=\"_blank\" class=\"pb-click\">##hb_native_title##<\/a>\r\n <\/h1>\r\n <p>##hb_native_body##<\/p>\r\n \t<div class=\"attribution\">\r\n \t<img class=\"pb-icon\" src=\"##hb_native_image##\" alt=\"icon\" height=\"150\" width=\"50\">\r\n \t\r\n \t<\/div>\r\n\t<\/div>\r\n<\/div>";
565
591
  nativeTag.pubUrl = "https://www.url.com";
@@ -567,27 +593,51 @@ describe('nativeAssetManager', () => {
567
593
  nativeTag.requestAllAssets = true;
568
594
  window.pbNativeTag.renderNativeAd(nativeTag);
569
595
  </script>`;
570
- win.pbNativeData = {
571
- pubUrl : 'https://www.url.com',
572
- adId : AD_ID,
573
- adTemplate : '<div class=\"sponsored-post\">\r\n <div class=\"thumbnail\"><\/div>\r\n <div class=\"content\">\r\n <h1>\r\n <a href=\"##hb_native_linkurl##\" target=\"_blank\" class=\"pb-click\">##hb_native_title##<\/a>\r\n <\/h1>\r\n <p>##hb_native_body##<\/p>\r\n \t<div class=\"attribution\">\r\n \t<img class=\"pb-icon\" src=\"##hb_native_image##\" alt=\"icon\" height=\"150\" width=\"50\">\r\n \t\r\n \t<\/div>\r\n\t<\/div>\r\n<\/div>'
574
- };
575
-
576
- win.document.body.innerHTML = html;
577
- win.addEventListener = createResponder([
578
- { key: 'body', value: 'Body content' },
579
- { key: 'title', value: 'new value' },
580
- { key: 'clickUrl', value: 'http://www.example.com' },
581
- { key: 'image', value: 'http://www.image.com/picture.jpg' },
582
- ]);
596
+ win.pbNativeData = {
597
+ pubUrl : 'https://www.url.com',
598
+ adId : AD_ID,
599
+ adTemplate : '<div class=\"sponsored-post\">\r\n <div class=\"thumbnail\"><\/div>\r\n <div class=\"content\">\r\n <h1>\r\n <a href=\"##hb_native_linkurl##\" target=\"_blank\" class=\"pb-click\">##hb_native_title##<\/a>\r\n <\/h1>\r\n <p>##hb_native_body##<\/p>\r\n \t<div class=\"attribution\">\r\n \t<img class=\"pb-icon\" src=\"##hb_native_image##\" alt=\"icon\" height=\"150\" width=\"50\">\r\n \t\r\n \t<\/div>\r\n\t<\/div>\r\n<\/div>'
600
+ };
601
+
602
+ win.document.body.innerHTML = html;
603
+ win.addEventListener = createResponder([
604
+ { key: 'body', value: 'Body content' },
605
+ { key: 'title', value: 'new value' },
606
+ { key: 'clickUrl', value: 'http://www.example.com' },
607
+ { key: 'image', value: 'http://www.image.com/picture.jpg' },
608
+ ]);
609
+ });
583
610
 
584
- const nativeAssetManager = makeManager();
585
- nativeAssetManager.loadAssets(AD_ID);
611
+ it('should not choke when parent window is not available',() => {
612
+ win.parent.frames = [win];
613
+ Object.defineProperty(win.parent, 'document', {
614
+ get() {
615
+ throw new Error('unvailable');
616
+ }
617
+ })
618
+ const nativeAssetManager = makeManager();
619
+ nativeAssetManager.loadAssets(AD_ID);
620
+ expect(win.document.body.innerHTML).to.include(`<a href="http://www.example.com" target="_blank" class="pb-click">new value</a>`);
621
+ });
586
622
 
587
- expect(win.document.body.innerHTML).to.include(`<a href="http://www.example.com" target="_blank" class="pb-click">new value</a>`);
588
- expect(win.document.body.innerHTML).to.include(`<img class="pb-icon" src="http://www.image.com/picture.jpg" alt="icon" height="150" width="50">`);
589
- expect(win.document.body.innerHTML).to.include(`<p>Body content</p>`);
590
- expect(win.document.body.style.width).to.equal('600px');
623
+ it('should not request width resize if width is 1', () => {
624
+ sandbox.stub(document.body, 'clientWidth').get(() => 1);
625
+ const nativeAssetManager = makeManager();
626
+ nativeAssetManager.loadAssets(AD_ID);
627
+ const resizeRequest = win.parent.postMessage.args
628
+ .map(([msg]) => JSON.parse(msg))
629
+ .find((msg) => msg.action === 'resizeNativeHeight')
630
+ expect(resizeRequest.width).to.not.exist;
631
+ })
632
+
633
+ it('should set the iframe to the width of the container', () => {
634
+ const nativeAssetManager = makeManager();
635
+ nativeAssetManager.loadAssets(AD_ID);
636
+ expect(win.document.body.innerHTML).to.include(`<a href="http://www.example.com" target="_blank" class="pb-click">new value</a>`);
637
+ expect(win.document.body.innerHTML).to.include(`<img class="pb-icon" src="http://www.image.com/picture.jpg" alt="icon" height="150" width="50">`);
638
+ expect(win.document.body.innerHTML).to.include(`<p>Body content</p>`);
639
+ expect(win.document.body.style.width).to.equal('600px');
640
+ });
591
641
  });
592
642
  });
593
643
 
@@ -1,9 +1,11 @@
1
1
  import { renderCrossDomain, renderLegacy } from 'src/renderingManager';
2
2
  import * as utils from 'src/utils';
3
3
  import * as domHelper from 'src/domHelper';
4
+ import * as dynamic from 'src/dynamicRenderer.js';
4
5
  import { expect } from 'chai';
5
6
  import { mocks } from 'test/helpers/mocks';
6
7
  import { merge } from 'lodash';
8
+ import {MIN_RENDERER_VERSION} from "src/dynamicRenderer.js";
7
9
 
8
10
  function renderingMocks() {
9
11
  return {
@@ -72,6 +74,7 @@ describe('renderingManager', function() {
72
74
 
73
75
  describe('cross domain creative', function() {
74
76
  const ORIGIN = 'http://example.com';
77
+ let sandbox;
75
78
  let parseStub;
76
79
  let iframeStub;
77
80
  let triggerPixelSpy;
@@ -81,10 +84,11 @@ describe('renderingManager', function() {
81
84
  let eventSource;
82
85
 
83
86
  beforeEach(function(){
87
+ sandbox = sinon.createSandbox();
84
88
  mockIframe = createMockIframe();
85
- parseStub = sinon.stub(utils, 'parseUrl');
86
- iframeStub = sinon.stub(domHelper, 'getEmptyIframe').returns(mockIframe);
87
- triggerPixelSpy = sinon.stub(utils, 'triggerPixel');
89
+ parseStub = sandbox.stub(utils, 'parseUrl');
90
+ iframeStub = sandbox.stub(domHelper, 'getEmptyIframe').returns(mockIframe);
91
+ triggerPixelSpy = sandbox.stub(utils, 'triggerPixel');
88
92
  parseStub.returns({
89
93
  protocol: 'http',
90
94
  host: 'example.com'
@@ -102,9 +106,7 @@ describe('renderingManager', function() {
102
106
  });
103
107
 
104
108
  afterEach(function () {
105
- parseStub.restore();
106
- iframeStub.restore();
107
- triggerPixelSpy.restore();
109
+ sandbox.restore();
108
110
  });
109
111
 
110
112
  function mockPrebidResponse(msg) {
@@ -114,6 +116,18 @@ describe('renderingManager', function() {
114
116
  });
115
117
  }
116
118
 
119
+ it('should run renderer if present', () => {
120
+ sandbox.stub(dynamic, 'runDynamicRenderer');
121
+ const data = {
122
+ adId: '123',
123
+ renderer: 'mock-renderer',
124
+ rendererVersion: MIN_RENDERER_VERSION,
125
+ ad: 'markup'
126
+ };
127
+ mockPrebidResponse(data);
128
+ sinon.assert.calledWith(dynamic.runDynamicRenderer, data.adId, sinon.match(data))
129
+ })
130
+
117
131
  it("should render cross domain creative", function () {
118
132
  mockPrebidResponse({
119
133
  ad: "ad",
package/webpack.conf.js CHANGED
@@ -12,7 +12,6 @@ module.exports = {
12
12
  ],
13
13
  },
14
14
  output: {
15
- filename: 'creative.js',
16
15
  },
17
16
  module: {
18
17
  rules: [
package/.nvmrc DELETED
@@ -1 +0,0 @@
1
- 8.7.0