var wd = require('wd'); var http = require('http'); var https = require('https'); var url = require('url'); var path = require('path'); var Promise = require('bluebird'); var _ = require('lodash'); var humanizeDuration = require('humanize-duration'); var utils = require('../utils'); var colors = utils.colors; var port = 8080; function runTestWithRetries(browser, test, retries) { retries = retries || 0; return runTest(browser, test).timeout(30000).catch(Promise.TimeoutError, function() { if (retries < 3) { console.log(colors.violet, 'Retry', retries + 1, test); return runTestWithRetries(browser, test, retries + 1); } else { throw new Error("Couldn't run test after 3 retries"); } }); } function getResults(browser) { return function() { return Promise.props({ dataUrl: browser .waitForElementByCss("body[data-complete='true']", 90000) .then(function() { return browser.elementsByCssSelector('.test.fail'); }) .then(function(nodes) { return Array.isArray(nodes) ? Promise.map(nodes, function(node) { return browser.text(node).then(function(error) { return Promise.reject(error); }); }) : Promise.resolve([]); }) }); }; } function runTest(browser, test) { return Promise.resolve( browser.then(utils.loadTestPage(browser, test, port)).then(getResults(browser)) ).cancellable(); } exports.tests = function(browsers, singleTest) { var path = 'tests/mocha'; return (singleTest ? Promise.resolve([singleTest]) : utils.getTests(path)).then(function( tests ) { return Promise.map( browsers, function(settings) { var name = [settings.browserName, settings.version, settings.platform].join('-'); var count = 0; var browser = utils.initBrowser(settings); return Promise.using(browser, function() { return Promise.map( tests, function(test, index, total) { console.log( colors.green, 'STARTING', '(' + ++count + '/' + total + ')', name, test, colors.clear ); var start = Date.now(); return runTestWithRetries(browser, test).then(function() { console.log( colors.green, 'COMPLETE', humanizeDuration(Date.now() - start), '(' + count + '/' + total + ')', name, colors.clear ); }); }, {concurrency: 1} ) .settle() .catch(function(error) { console.error(colors.red, 'ERROR', name, error); throw error; }); }); }, {concurrency: 3} ); }); };