Skip to content

Commit

Permalink
Merge branch 'master' into prebid-7
Browse files Browse the repository at this point in the history
  • Loading branch information
dgirardi committed Apr 28, 2022
2 parents 418fe56 + 061eb3c commit fa20923
Show file tree
Hide file tree
Showing 88 changed files with 3,954 additions and 2,228 deletions.
12 changes: 1 addition & 11 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ aliases:

- &run_endtoend_test
name: BrowserStack End to end testing
command: echo "127.0.0.1 test.localhost" | sudo tee -a /etc/hosts && gulp e2e-test --host=test.localhost
command: gulp e2e-test

# Download and run BrowserStack local
- &setup_browserstack
Expand Down Expand Up @@ -82,16 +82,6 @@ workflows:
commit:
jobs:
- build
nightly:
triggers:
- schedule:
cron: "0 0 * * *"
filters:
branches:
only:
- master
jobs:
- e2etest

experimental:
pipelines: true
123 changes: 52 additions & 71 deletions gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ var prebid = require('./package.json');
var dateString = 'Updated : ' + (new Date()).toISOString().substring(0, 10);
var banner = '/* <%= prebid.name %> v<%= prebid.version %>\n' + dateString + '*/\n';
var port = 9999;
const FAKE_SERVER_HOST = argv.host ? argv.host : 'localhost';
const FAKE_SERVER_PORT = 4444;
const INTEG_SERVER_HOST = argv.host ? argv.host : 'localhost';
const INTEG_SERVER_PORT = 4444;
const { spawn } = require('child_process');

// these modules must be explicitly listed in --modules to be included in the build, won't be part of "all" modules
Expand Down Expand Up @@ -167,9 +167,9 @@ function gulpBundle(dev) {
return bundle(dev).pipe(gulp.dest('build/' + (dev ? 'dev' : 'dist')));
}

function nodeBundle(modules) {
function nodeBundle(modules, dev = false) {
return new Promise((resolve, reject) => {
bundle(false, modules)
bundle(dev, modules)
.on('error', (err) => {
reject(err);
})
Expand Down Expand Up @@ -243,41 +243,18 @@ function testTaskMaker(options = {}) {
if (options.notest) {
done();
} else if (options.e2e) {
let wdioCmd = path.join(__dirname, 'node_modules/.bin/wdio');
let wdioConf = path.join(__dirname, 'wdio.conf.js');
let wdioOpts;

if (options.file) {
wdioOpts = [
wdioConf,
`--spec`,
`${options.file}`
]
} else {
wdioOpts = [
wdioConf
];
}

// run fake-server
const fakeServer = spawn('node', ['./test/fake-server/index.js', `--port=${FAKE_SERVER_PORT}`]);
fakeServer.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
fakeServer.stderr.on('data', (data) => {
console.log(`stderr: ${data}`);
});

execa(wdioCmd, wdioOpts, { stdio: 'inherit' })
const integ = startIntegServer();
startLocalServer();
runWebdriver(options)
.then(stdout => {
// kill fake server
fakeServer.kill('SIGINT');
integ.kill('SIGINT');
done();
process.exit(0);
})
.catch(err => {
// kill fake server
fakeServer.kill('SIGINT');
integ.kill('SIGINT');
done(new Error(`Tests failed with error: ${err}`));
process.exit(1);
});
Expand All @@ -296,6 +273,26 @@ function testTaskMaker(options = {}) {

const test = testTaskMaker();

function runWebdriver({file}) {
process.env.TEST_SERVER_HOST = argv.host || 'localhost';
let wdioCmd = path.join(__dirname, 'node_modules/.bin/wdio');
let wdioConf = path.join(__dirname, 'wdio.conf.js');
let wdioOpts;

if (file) {
wdioOpts = [
wdioConf,
`--spec`,
`${file}`
]
} else {
wdioOpts = [
wdioConf
];
}
return execa(wdioCmd, wdioOpts, { stdio: 'inherit' });
}

function newKarmaCallback(done) {
return function (exitCode) {
if (exitCode) {
Expand Down Expand Up @@ -335,41 +332,29 @@ function buildPostbid() {
.pipe(gulp.dest('build/postbid/'));
}

function setupE2e(done) {
if (!argv.host) {
throw new gutil.PluginError({
plugin: 'E2E test',
message: gutil.colors.red('Host should be defined e.g. ap.localhost, anlocalhost. localhost cannot be used as safari browserstack is not able to connect to localhost')
});
function startIntegServer(dev = false) {
const args = ['./test/fake-server/index.js', `--port=${INTEG_SERVER_PORT}`, `--host=${INTEG_SERVER_HOST}`];
if (dev) {
args.push('--dev=true')
}
process.env.TEST_SERVER_HOST = argv.host;
if (argv.https) {
process.env.TEST_SERVER_PROTOCOL = argv.https;
}
argv.e2e = true;
done();
}

function injectFakeServerEndpoint() {
return gulp.src(['build/dist/*.js'])
.pipe(replace('https://ib.adnxs.com/ut/v3/prebid', `http://${FAKE_SERVER_HOST}:${FAKE_SERVER_PORT}`))
.pipe(gulp.dest('build/dist'));
}

function injectFakeServerEndpointDev() {
return gulp.src(['build/dev/*.js'])
.pipe(replace('https://ib.adnxs.com/ut/v3/prebid', `http://${FAKE_SERVER_HOST}:${FAKE_SERVER_PORT}`))
.pipe(gulp.dest('build/dev'));
}

function startFakeServer() {
const fakeServer = spawn('node', ['./test/fake-server/index.js', `--port=${FAKE_SERVER_PORT}`]);
fakeServer.stdout.on('data', (data) => {
const srv = spawn('node', args);
srv.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
fakeServer.stderr.on('data', (data) => {
srv.stderr.on('data', (data) => {
console.log(`stderr: ${data}`);
});
return srv;
}

function startLocalServer(options = {}) {
connect.server({
https: argv.https,
port: port,
host: INTEG_SERVER_HOST,
root: './',
livereload: options.livereload
});
}

// Watch Task with Live Reload
Expand All @@ -385,13 +370,7 @@ function watchTaskMaker(options = {}) {
'modules/**/*.js',
].concat(options.alsoWatch));

connect.server({
https: argv.https,
port: port,
host: FAKE_SERVER_HOST,
root: './',
livereload: options.livereload
});
startLocalServer(options);

mainWatcher.on('all', options.task());
done();
Expand Down Expand Up @@ -427,11 +406,13 @@ gulp.task('build-postbid', gulp.series(escapePostbidConfig, buildPostbid));
gulp.task('serve', gulp.series(clean, lint, gulp.parallel('build-bundle-dev', watch, test)));
gulp.task('serve-fast', gulp.series(clean, gulp.parallel('build-bundle-dev', watchFast)));
gulp.task('serve-and-test', gulp.series(clean, gulp.parallel('build-bundle-dev', watchFast, testTaskMaker({watch: true}))));
gulp.task('serve-fake', gulp.series(clean, gulp.parallel('build-bundle-dev', watch), injectFakeServerEndpointDev, test, startFakeServer));
gulp.task('serve-e2e', gulp.series(clean, 'build-bundle-prod', gulp.parallel(() => startIntegServer(), startLocalServer)))
gulp.task('serve-e2e-dev', gulp.series(clean, 'build-bundle-dev', gulp.parallel(() => startIntegServer(true), startLocalServer)))

gulp.task('default', gulp.series(clean, 'build-bundle-prod'));

gulp.task('e2e-test', gulp.series(clean, setupE2e, gulp.parallel('build-bundle-prod', watch), injectFakeServerEndpoint, test));
gulp.task('e2e-test-only', () => runWebdriver({file: argv.file}))
gulp.task('e2e-test', gulp.series(clean, 'build-bundle-prod', testTaskMaker({e2e: true})));
// other tasks
gulp.task(bundleToStdout);
gulp.task('bundle', gulpBundle.bind(null, false)); // used for just concatenating pre-built files with no build step
Expand Down
110 changes: 67 additions & 43 deletions modules/adomikAnalyticsAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import adapterManager from '../src/adapterManager.js';
import {logInfo} from '../src/utils.js';
import {find, findIndex} from '../src/polyfill.js';

// Events used in adomik analytics adapter
// Events used in adomik analytics adapter.
const auctionInit = CONSTANTS.EVENTS.AUCTION_INIT;
const auctionEnd = CONSTANTS.EVENTS.AUCTION_END;
const bidRequested = CONSTANTS.EVENTS.BID_REQUESTED;
Expand All @@ -30,17 +30,13 @@ let adomikAdapter = Object.assign(adapter({}),
break;

case bidResponse:
adomikAdapter.bucketEvents.push({
type: 'response',
event: adomikAdapter.buildBidResponse(args)
});
adomikAdapter.saveBidResponse(args);
break;

case bidWon:
adomikAdapter.sendWonEvent({
id: args.adId,
placementCode: args.adUnitCode
});
args.id = args.adId;
args.placementCode = args.adUnitCode;
adomikAdapter.sendWonEvent(args);
break;

case bidRequested:
Expand Down Expand Up @@ -69,16 +65,28 @@ adomikAdapter.initializeBucketEvents = function() {
adomikAdapter.bucketEvents = [];
}

adomikAdapter.saveBidResponse = function(args) {
let responseSaved = adomikAdapter.bucketEvents.find((bucketEvent) =>
bucketEvent.type == 'response' && bucketEvent.event.id == args.id
);
if (responseSaved) { return true; }
adomikAdapter.bucketEvents.push({
type: 'response',
event: adomikAdapter.buildBidResponse(args)
});
}

adomikAdapter.maxPartLength = function () {
return (ua.includes(' MSIE ')) ? 1600 : 60000;
};

adomikAdapter.sendTypedEvent = function() {
let [testId, testValue] = adomikAdapter.getKeyValues();
const groupedTypedEvents = adomikAdapter.buildTypedEvents();

const bulkEvents = {
testId: adomikAdapter.currentContext.testId,
testValue: adomikAdapter.currentContext.testValue,
testId: testId,
testValue: testValue,
uid: adomikAdapter.currentContext.uid,
ahbaid: adomikAdapter.currentContext.id,
hostname: window.location.hostname,
Expand Down Expand Up @@ -114,10 +122,8 @@ adomikAdapter.sendTypedEvent = function() {
const stringBulkEvents = JSON.stringify(bulkEvents)
logInfo('Events sent to adomik prebid analytic ' + stringBulkEvents);

// Encode object in base64
const encodedBuf = window.btoa(stringBulkEvents);

// Create final url and split it (+endpoint length)
const encodedUri = encodeURIComponent(encodedBuf);
const maxLength = adomikAdapter.maxPartLength();
const splittedUrl = encodedUri.match(new RegExp(`.{1,${maxLength}}`, 'g'));
Expand All @@ -130,16 +136,18 @@ adomikAdapter.sendTypedEvent = function() {
};

adomikAdapter.sendWonEvent = function (wonEvent) {
let keyValues = { testId: adomikAdapter.currentContext.testId, testValue: adomikAdapter.currentContext.testValue }
wonEvent = {...wonEvent, ...keyValues}
const stringWonEvent = JSON.stringify(wonEvent)
let [testId, testValue] = adomikAdapter.getKeyValues();
let keyValues = { testId: testId, testValue: testValue };
let samplingInfo = { sampling: adomikAdapter.currentContext.sampling };
wonEvent = { ...adomikAdapter.buildBidResponse(wonEvent), ...keyValues, ...samplingInfo };

const stringWonEvent = JSON.stringify(wonEvent);
logInfo('Won event sent to adomik prebid analytic ' + stringWonEvent);

// Encode object in base64
const encodedBuf = window.btoa(stringWonEvent);
const encodedUri = encodeURIComponent(encodedBuf);
const img = new Image(1, 1);
img.src = `https://${adomikAdapter.currentContext.url}/?q=${encodedUri}&id=${adomikAdapter.currentContext.id}&won=true`
img.src = `https://${adomikAdapter.currentContext.url}/?q=${encodedUri}&id=${adomikAdapter.currentContext.id}&won=true`;
}

adomikAdapter.buildBidResponse = function (bid) {
Expand Down Expand Up @@ -201,33 +209,49 @@ adomikAdapter.buildTypedEvents = function () {
return groupedTypedEvents;
}

adomikAdapter.adapterEnableAnalytics = adomikAdapter.enableAnalytics;
adomikAdapter.getKeyValues = function () {
let preventTest = sessionStorage.getItem(window.location.hostname + '_NoAdomikTest')
let inScope = sessionStorage.getItem(window.location.hostname + '_AdomikTestInScope')
let keyValues = JSON.parse(sessionStorage.getItem(window.location.hostname + '_AdomikTest'))
let testId;
let testValue;
if (typeof (keyValues) === 'object' && keyValues != undefined && !preventTest && inScope) {
testId = keyValues.testId
testValue = keyValues.testOptionLabel
}
return [testId, testValue]
}

adomikAdapter.enableAnalytics = function (config) {
adomikAdapter.currentContext = {};
const initOptions = config.options;

_sampled = typeof config === 'undefined' ||
typeof config.sampling === 'undefined' ||
Math.random() < parseFloat(config.sampling);

if (_sampled) {
if (initOptions) {
adomikAdapter.currentContext = {
uid: initOptions.id,
url: initOptions.url,
testId: initOptions.testId,
testValue: initOptions.testValue,
id: '',
timeouted: false,
sampling: config.sampling
}
logInfo('Adomik Analytics enabled with config', initOptions);
adomikAdapter.adapterEnableAnalytics(config);
}
} else {
logInfo('Adomik Analytics ignored for sampling', config.sampling);
adomikAdapter.enable = function(options) {
adomikAdapter.currentContext = {
uid: options.id,
url: options.url,
id: '',
timeouted: false,
sampling: options.sampling
}
logInfo('Adomik Analytics enabled with config', options);
adomikAdapter.adapterEnableAnalytics(options);
};

adomikAdapter.checkOptions = function(options) {
if (typeof options !== 'undefined') {
if (options.id && options.url) { adomikAdapter.enable(options); } else { logInfo('Adomik Analytics disabled because id and/or url is missing from config', options); }
} else { logInfo('Adomik Analytics disabled because config is missing'); }
};

adomikAdapter.checkSampling = function(options) {
_sampled = typeof options === 'undefined' ||
typeof options.sampling === 'undefined' ||
(options.sampling > 0 && Math.random() < parseFloat(options.sampling));
if (_sampled) { adomikAdapter.checkOptions(options) } else { logInfo('Adomik Analytics ignored for sampling', options.sampling); }
};

adomikAdapter.adapterEnableAnalytics = adomikAdapter.enableAnalytics;

adomikAdapter.enableAnalytics = function ({ provider, options }) {
logInfo('Adomik Analytics enableAnalytics', provider);
adomikAdapter.checkSampling(options);
};

adapterManager.registerAnalyticsAdapter({
Expand Down
2 changes: 1 addition & 1 deletion modules/adotBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const BIDDER_CODE = 'adot';
const ADAPTER_VERSION = 'v2.0.0';
const BID_METHOD = 'POST';
const BIDDER_URL = 'https://dsp.adotmob.com/headerbidding{PUBLISHER_PATH}/bidrequest';
const REQUIRED_VIDEO_PARAMS = ['mimes', 'minduration', 'maxduration', 'protocols'];
const REQUIRED_VIDEO_PARAMS = ['mimes', 'protocols'];
const DOMAIN_REGEX = new RegExp('//([^/]*)');
const FIRST_PRICE = 1;
const IMP_BUILDER = { banner: buildBanner, video: buildVideo, native: buildNative };
Expand Down
Loading

0 comments on commit fa20923

Please sign in to comment.