<commit_before>'use strict';

var through = require('through2'),
    gutil = require('gulp-util'),
    Mocha = require('mocha'),
    SauceLabs = require('saucelabs'),
    SauceTunnel = require('sauce-tunnel'),
    selenium = require('selenium-standalone'),
    webdriverio = require('webdriverio'),
    http = require('http'),
    async = require('async'),
    path = require('path'),
    merge = require('deepmerge'),
    server = null,
    isSeleniumServerRunning = false,
    tunnel = null,
    seleniumServer = null,
    isSauceTunnelRunning = false,
    isHookedUp = false;


var GulpWebdriverIO = function(args) {

    var that = this,
        options = args || {},
        base = process.cwd(),
        sessionID = null,
        seleniumOptions = options.seleniumOptions || {},
        seleniumInstallOptions = options.seleniumInstallOptions || {},
        tunnelIdentifier = options.desiredCapabilities && options.desiredCapabilities['tunnel-identifier'] ? options.desiredCapabilities['tunnel-identifier'] : null,
        tunnelFlags = options.desiredCapabilities && options.desiredCapabilities['tunnel-flags'] ? options.desiredCapabilities['tunnel-flags'] : [];

    /**
     * initialise tunnel
     */
    if (!tunnel && options.user && options.key && tunnelIdentifier) {
        gutil.log('initialise test session using sauce tunnel from user ' + options.user);
        tunnel = new SauceTunnel(options.user, options.key, tunnelIdentifier, true, tunnelFlags);
        tunnel.on('verbose:debug', gutil.log);

        options.host = undefined;
        options.port = 4445;
    }

    /**
     * initialize WebdriverIO
     */
    gutil.log('run webdriverio with following capabilities: ' + JSON.stringify(options));
    options.logLevel = options.quiet ? 'silent' : options.logLevel;
    GLOBAL.browser = webdriverio.remote(options);

    /**
     * initialize Mocha
     */
    var mocha = new Mocha(merge({
        reporter: 'spec',
        ui: 'bdd',
        slow: 75,
        bail: false,
        grep: null,
        timeout: 1000000
    }, options));

    /**
     * helper function for asyncjs
     */
    var next = function(cb, param) {
        return function() {
            var args = Array.prototype.slice.call(arguments, 1);

            if(typeof param !== 'undefined') {
                args.unshift(param);
            } else if (arguments.length === 1) {
                args.unshift(arguments[0]);
            }

            args.unshift(null);
            cb.apply(null, args);
        }
    };

    /**
     * check if selenium server is already running
     */
    var pingSelenium = function(callback) {

        if (tunnel) {
            return callback(null);
        }

        gutil.log('checking if selenium is running');

        var opts = {
            host: options.host || 'localhost',
            port: options.port || 4444,
            path: '/wd/hub/status'
        };

        http.get(opts, function() {
            gutil.log('selenium is running');
            isSeleniumServerRunning = true;
            callback(null);
        }).on('error', function() {
            gutil.log('selenium is not running');
            callback(null);
        });

    };

    /**
     *  install drivers if needed
     */
    var installDrivers = function(callback) {
        if (tunnel || isSeleniumServerRunning) {
            return callback(null);
        }

        gutil.log('installing driver if needed');
        selenium.install(seleniumInstallOptions, function(err) {
            if (err) {
                return callback(err);
            }

            gutil.log('driver installed');
            callback(null);
        });
    };

    /**
     * start selenium server or sauce tunnel (if not already started)
     */
    var startServer = function(callback) {

        if (tunnel) {

            if (isSauceTunnelRunning) {
                return callback(null, true);
            }

            gutil.log('start sauce tunnel');

            /**
             * start sauce tunnel
             */
            tunnel.start(function(hasTunnelStarted) {
                // output here means if tunnel was created successfully
                if (hasTunnelStarted === false) {
                    callback(new Error('Sauce-Tunnel couldn\'t created successfully'));
                }

                gutil.log('tunnel created successfully');
                isSauceTunnelRunning = true;
                callback(null);
            });

        } else if (!server && !isSeleniumServerRunning && !options.nospawn) {

            gutil.log('start selenium standalone server');

            /**
             * starts selenium standalone server if its not running
             */

            server = selenium.start(seleniumOptions, function(err, child) {
                if (err) {
                    return callback(err);
                }

                gutil.log('selenium successfully started');
                seleniumServer = child;
                isSeleniumServerRunning = true;
                callback(null, true);
            });

        } else {
            gutil.log('standalone server or sauce tunnel is running');
            callback(null, true);
        }

    };

    /**
     * init WebdriverIO instance
     */
    var initWebdriver = function() {
        var callback = arguments[arguments.length - 1];
        gutil.log('init WebdriverIO instance');

        GLOBAL.browser.init(function(err) {
            /**
             * gracefully kill process if init fails<commit_msg>Add support for custom extensions<commit_after>'use strict';

var through = require('through2'),
    gutil = require('gulp-util'),
    Mocha = require('mocha'),
    SauceLabs = require('saucelabs'),
    SauceTunnel = require('sauce-tunnel'),
    selenium = require('selenium-standalone'),
    webdriverio = require('webdriverio'),
    http = require('http'),
    async = require('async'),
    path = require('path'),
    merge = require('deepmerge'),
    server = null,
    isSeleniumServerRunning = false,
    tunnel = null,
    seleniumServer = null,
    isSauceTunnelRunning = false,
    isHookedUp = false;


var GulpWebdriverIO = function(args) {

    var that = this,
        options = args || {},
        base = process.cwd(),
        sessionID = null,
        seleniumOptions = options.seleniumOptions || {},
        seleniumInstallOptions = options.seleniumInstallOptions || {},
        tunnelIdentifier = options.desiredCapabilities && options.desiredCapabilities['tunnel-identifier'] ? options.desiredCapabilities['tunnel-identifier'] : null,
        tunnelFlags = options.desiredCapabilities && options.desiredCapabilities['tunnel-flags'] ? options.desiredCapabilities['tunnel-flags'] : [];

    /**
     * initialise tunnel
     */
    if (!tunnel && options.user && options.key && tunnelIdentifier) {
        gutil.log('initialise test session using sauce tunnel from user ' + options.user);
        tunnel = new SauceTunnel(options.user, options.key, tunnelIdentifier, true, tunnelFlags);
        tunnel.on('verbose:debug', gutil.log);

        options.host = undefined;
        options.port = 4445;
    }

    /**
     * initialize WebdriverIO
     */
    gutil.log('run webdriverio with following capabilities: ' + JSON.stringify(options));
    options.logLevel = options.quiet ? 'silent' : options.logLevel;
    GLOBAL.browser = webdriverio.remote(options);

    /**
     * initialize Mocha
     */
    var mocha = new Mocha(merge({
        reporter: 'spec',
        ui: 'bdd',
        slow: 75,
        bail: false,
        grep: null,
        timeout: 1000000
    }, options));

    /**
     * helper function for asyncjs
     */
    var next = function(cb, param) {
        return function() {
            var args = Array.prototype.slice.call(arguments, 1);

            if(typeof param !== 'undefined') {
                args.unshift(param);
            } else if (arguments.length === 1) {
                args.unshift(arguments[0]);
            }

            args.unshift(null);
            cb.apply(null, args);
        }
    };

    /**
     * check if selenium server is already running
     */
    var pingSelenium = function(callback) {

        if (tunnel) {
            return callback(null);
        }

        gutil.log('checking if selenium is running');

        var opts = {
            host: options.host || 'localhost',
            port: options.port || 4444,
            path: '/wd/hub/status'
        };

        http.get(opts, function() {
            gutil.log('selenium is running');
            isSeleniumServerRunning = true;
            callback(null);
        }).on('error', function() {
            gutil.log('selenium is not running');
            callback(null);
        });

    };

    /**
     *  install drivers if needed
     */
    var installDrivers = function(callback) {
        if (tunnel || isSeleniumServerRunning) {
            return callback(null);
        }

        gutil.log('installing driver if needed');
        selenium.install(seleniumInstallOptions, function(err) {
            if (err) {
                return callback(err);
            }

            gutil.log('driver installed');
            callback(null);
        });
    };

    /**
     * start selenium server or sauce tunnel (if not already started)
     */
    var startServer = function(callback) {

        if (tunnel) {

            if (isSauceTunnelRunning) {
                return callback(null, true);
            }

            gutil.log('start sauce tunnel');

            /**
             * start sauce tunnel
             */
            tunnel.start(function(hasTunnelStarted) {
                // output here means if tunnel was created successfully
                if (hasTunnelStarted === false) {
                    callback(new Error('Sauce-Tunnel couldn\'t created successfully'));
                }

                gutil.log('tunnel created successfully');
                isSauceTunnelRunning = true;
                callback(null);
            });

        } else if (!server && !isSeleniumServerRunning && !options.nospawn) {

            gutil.log('start selenium standalone server');

            /**
             * starts selenium standalone server if its not running
             */

            server = selenium.start(seleniumOptions, function(err, child) {
                if (err) {
                    return callback(err);
                }

                gutil.log('selenium successfully started');
                seleniumServer = child;
                isSeleniumServerRunning = true;
                callback(null, true);
            });

        } else {
            gutil.log('standalone server or sauce tunnel is running');
            callback(null, true);
        }

    };

    /**
     * init WebdriverIO instance
     */
    var initWebdriver = function() {
        var callback = arguments[arguments.length - 1];
        gutil.log('init WebdriverIO instance');

        GLOBAL.browser.init(function(err) {
            /**
             *  Allow for adding custom commands
             */
            if("function" === typeof args.applyExtensions){
                args.applyExtensions.call(null, this);
            }
            
            /**
             * gracefully kill process if init fails
{'fraction_non_alphanumeric': 0.1165768789190144, 'fraction_numerical': 0.0038858959639671464, 'mean_word_length': 1.8359629351364888, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4363586', 'n_tokens_mistral': 3124, 'n_tokens_neox': 2930, 'n_words': 677}