diff options
author | Jocelyn Turcotte <jocelyn.turcotte@digia.com> | 2014-08-08 14:30:41 +0200 |
---|---|---|
committer | Jocelyn Turcotte <jocelyn.turcotte@digia.com> | 2014-08-12 13:49:54 +0200 |
commit | ab0a50979b9eb4dfa3320eff7e187e41efedf7a9 (patch) | |
tree | 498dfb8a97ff3361a9f7486863a52bb4e26bb898 /chromium/third_party/WebKit/Tools/GardeningServer | |
parent | 4ce69f7403811819800e7c5ae1318b2647e778d1 (diff) |
Update Chromium to beta version 37.0.2062.68
Change-Id: I188e3b5aff1bec75566014291b654eb19f5bc8ca
Reviewed-by: Andras Becsi <andras.becsi@digia.com>
Diffstat (limited to 'chromium/third_party/WebKit/Tools/GardeningServer')
39 files changed, 1326 insertions, 1188 deletions
diff --git a/chromium/third_party/WebKit/Tools/GardeningServer/garden-o-matic.html b/chromium/third_party/WebKit/Tools/GardeningServer/garden-o-matic.html index 62f21082b9b..7ed524cfb06 100644 --- a/chromium/third_party/WebKit/Tools/GardeningServer/garden-o-matic.html +++ b/chromium/third_party/WebKit/Tools/GardeningServer/garden-o-matic.html @@ -51,6 +51,7 @@ James, a web developer from Birmingham, UK. <link rel="stylesheet" href="styles/results.css"> <link rel="stylesheet" href="styles/notifications.css"> <link rel="stylesheet" href="styles/pixelzoomer.css"> +<meta name="viewport" content="width=device-width, user-scalable=no"> </head> <body> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script> diff --git a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/base.js b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/base.js index d96c3b8a885..7a783b3a3f6 100644 --- a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/base.js +++ b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/base.js @@ -76,7 +76,7 @@ base.flattenArray = function(arrayOfArrays) if (!arrayOfArrays.length) return []; return arrayOfArrays.reduce(function(left, right) { - return left.concat(right); + return left.concat(right); }); }; @@ -156,79 +156,30 @@ base.parseJSONP = function(jsonp) return JSON.parse(jsonp.substr(startIndex, endIndex - startIndex)); }; -base.RequestTracker = function(requestsInFlight, callback, args) -{ - this._requestsInFlight = requestsInFlight; - this._callback = callback; - this._args = args || []; - this._tryCallback(); -}; - -base.RequestTracker.prototype = { - _tryCallback: function() - { - if (!this._requestsInFlight && this._callback) - this._callback.apply(null, this._args); - }, - requestComplete: function() - { - --this._requestsInFlight; - this._tryCallback(); - } -} - -base.callInParallel = function(functionList, callback) -{ - var requestTracker = new base.RequestTracker(functionList.length, callback); - - $.each(functionList, function(index, func) { - func(function() { - requestTracker.requestComplete(); - }); - }); -}; - +// This is effectively a cache of possibly-resolved promises. base.AsynchronousCache = function(fetch) { this._fetch = fetch; - this._dataCache = {}; - this._callbackCache = {}; + this._promiseCache = {}; }; -base.AsynchronousCache.prototype.get = function(key, callback) +base.AsynchronousCache._sentinel = new Object(); +base.AsynchronousCache.prototype.get = function(key) { - var self = this; - - if (self._dataCache[key]) { - // FIXME: Consider always calling callback asynchronously. - callback(self._dataCache[key]); - return; + if (!(key in this._promiseCache)) { + this._promiseCache[key] = base.AsynchronousCache._sentinel; + this._promiseCache[key] = this._fetch.call(null, key); } + if (this._promiseCache[key] === base.AsynchronousCache._sentinel) + return Promise.reject(Error("Reentrant request for ", key)); - if (key in self._callbackCache) { - self._callbackCache[key].push(callback); - return; - } - - self._callbackCache[key] = [callback]; - - self._fetch.call(null, key, function(data) { - self._dataCache[key] = data; - - var callbackList = self._callbackCache[key]; - delete self._callbackCache[key]; - - callbackList.forEach(function(cachedCallback) { - cachedCallback(data); - }); - }); + return this._promiseCache[key]; }; base.AsynchronousCache.prototype.clear = function() { - this._dataCache = {}; - this._callbackCache = {}; -} + this._promiseCache = {}; +}; /* Maintains a dictionary of items, tracking their updates and removing items that haven't been updated. @@ -310,55 +261,6 @@ base.extends = function(base, prototype) return extended; } -function createRelativeTimeDescriptor(divisorInMilliseconds, unit) -{ - return function(delta) { - var deltaInUnits = delta / divisorInMilliseconds; - return (deltaInUnits).toFixed(0) + ' ' + unit + (deltaInUnits >= 1.5 ? 's' : '') + ' ago'; - } -} - -var kMinuteInMilliseconds = 60 * 1000; -var kRelativeTimeSlots = [ - { - maxMilliseconds: kMinuteInMilliseconds, - describe: function(delta) { return 'Just now'; } - }, - { - maxMilliseconds: 60 * kMinuteInMilliseconds, - describe: createRelativeTimeDescriptor(kMinuteInMilliseconds, 'minute') - }, - { - maxMilliseconds: 24 * 60 * kMinuteInMilliseconds, - describe: createRelativeTimeDescriptor(60 * kMinuteInMilliseconds, 'hour') - }, - { - maxMilliseconds: Number.MAX_VALUE, - describe: createRelativeTimeDescriptor(24 * 60 * kMinuteInMilliseconds, 'day') - } -]; - -/* - Represent time as descriptive text, relative to now and gradually decreasing in precision: - delta < 1 minutes => Just Now - delta < 60 minutes => X minute[s] ago - delta < 24 hours => X hour[s] ago - delta < inf => X day[s] ago -*/ -base.relativizeTime = function(time) -{ - var result; - var delta = new Date().getTime() - time; - kRelativeTimeSlots.some(function(slot) { - if (delta >= slot.maxMilliseconds) - return false; - - result = slot.describe(delta); - return true; - }); - return result; -} - base.getURLParameter = function(name) { var match = RegExp(name + '=' + '(.+?)(&|$)').exec(location.search); @@ -372,14 +274,4 @@ base.underscoredBuilderName = function(builderName) return builderName.replace(/[ .()]/g, '_'); } -base.createLinkNode = function(url, textContent, opt_target) -{ - var link = document.createElement('a'); - link.href = url; - if (opt_target) - link.target = opt_target; - link.appendChild(document.createTextNode(textContent)); - return link; -} - })(); diff --git a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/base_unittests.js b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/base_unittests.js index 3a69d0a2553..a416c8d82d0 100644 --- a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/base_unittests.js +++ b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/base_unittests.js @@ -80,61 +80,6 @@ test("flattenArray", 5, function() { deepEqual(base.flattenArray([["a"], [], ["b"]]), ["a", "b"]); }); -test("callInParallel", 4, function() { - var expectedCall = [true, true, true]; - var expectCompletionCallback = true; - - base.callInParallel([ - function(callback) { - ok(expectedCall[0]); - expectedCall[0] = false; - callback(); - }, - function(callback) { - ok(expectedCall[1]); - expectedCall[1] = false; - callback(); - }, - function(callback) { - ok(expectedCall[2]); - expectedCall[2] = false; - callback(); - }, - ], function() { - ok(expectCompletionCallback); - expectCompletionCallback = false; - }) -}); - -test("RequestTracker", 5, function() { - var ready = false; - var tracker = new base.RequestTracker(1, function() { - ok(ready); - }); - ready = true; - tracker.requestComplete(); - ready = false; - - tracker = new base.RequestTracker(2, function(parameter) { - ok(ready); - equals(parameter, 'argument'); - }, ['argument']); - tracker.requestComplete(); - ready = true; - tracker.requestComplete(); - ready = false; - - tracker = new base.RequestTracker(0, function() { - ok(true); - }); - tracker.requestComplete(); - - tracker = new base.RequestTracker(0); - tracker.requestComplete(); - // Should not barf. - ok(true); -}); - test("filterDictionary", 3, function() { var dictionary = { 'foo': 43, @@ -369,37 +314,6 @@ test("extends", 14, function() { document.body.removeChild(document.body.lastChild); }); -test("relativizeTime", 14, function() { - var time = new Date(); - equals(base.relativizeTime(time), "Just now"); - time.setMinutes(time.getMinutes() - 1); - equals(base.relativizeTime(time), "1 minute ago"); - time.setMinutes(time.getMinutes() - 1); - equals(base.relativizeTime(time), "2 minutes ago"); - time.setMinutes(time.getMinutes() - 1); - equals(base.relativizeTime(time), "3 minutes ago"); - time.setMinutes(time.getMinutes() - 56); - equals(base.relativizeTime(time), "59 minutes ago"); - time.setMinutes(time.getMinutes() - 1); - equals(base.relativizeTime(time), "1 hour ago"); - time.setMinutes(time.getMinutes() - 29); - equals(base.relativizeTime(time), "1 hour ago"); - time.setMinutes(time.getMinutes() - 2); - equals(base.relativizeTime(time), "2 hours ago"); - time.setMinutes(time.getMinutes() - 29); - equals(base.relativizeTime(time), "2 hours ago"); - time.setHours(time.getHours() - 1); - equals(base.relativizeTime(time), "3 hours ago"); - time.setHours(time.getHours() - 20); - equals(base.relativizeTime(time), "23 hours ago"); - time.setHours(time.getHours() - 1); - equals(base.relativizeTime(time), "1 day ago"); - time.setDate(time.getDate() - 1); - equals(base.relativizeTime(time), "2 days ago"); - time.setDate(time.getDate() - 998); - equals(base.relativizeTime(time), "1000 days ago"); -}); - test("getURLParameter", 1, function() { ok(!base.getURLParameter('non-existant')); }); diff --git a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/builders.js b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/builders.js index f5527ec9f9d..29be9f5164c 100644 --- a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/builders.js +++ b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/builders.js @@ -34,14 +34,9 @@ var kWebKitTestsStepNames = ['webkit_tests', 'layout-test']; var kCrashedOrHungOutputMarker = 'crashed or hung'; -function buildBotURL(platform) +function urlForBuildInfo(builderName, buildNumber) { - return config.kPlatforms[platform].buildConsoleURL; -} - -function urlForBuildInfo(platform, builderName, buildNumber) -{ - return buildBotURL(platform) + '/json/builders/' + encodeURIComponent(builderName) + '/builds/' + encodeURIComponent(buildNumber); + return config.buildConsoleURL + '/json/builders/' + encodeURIComponent(builderName) + '/builds/' + encodeURIComponent(buildNumber); } function didFail(step) @@ -75,46 +70,45 @@ function mostRecentCompletedBuildNumber(individualBuilderStatus) return null; } -var g_buildInfoCache = new base.AsynchronousCache(function(key, callback) { +var g_buildInfoCache = new base.AsynchronousCache(function(key) { var explodedKey = key.split('\n'); - net.get(urlForBuildInfo(explodedKey[0], explodedKey[1], explodedKey[2]), callback); + return net.json(urlForBuildInfo(explodedKey[0], explodedKey[1])); }); builders.clearBuildInfoCache = function() { g_buildInfoCache.clear(); -} +}; -function fetchMostRecentBuildInfoByBuilder(platform, callback) +function fetchMostRecentBuildInfoByBuilder() { - net.get(buildBotURL(platform) + '/json/builders', function(builderStatus) { - var buildInfoByBuilder = {}; + var buildInfoByBuilder = {}; + var requestPromises = []; + return net.json(config.buildConsoleURL + '/json/builders').then(function(builderStatus) { var builderNames = Object.keys(builderStatus); - var requestTracker = new base.RequestTracker(builderNames.length, callback, [buildInfoByBuilder]); builderNames.forEach(function(builderName) { - if (!config.builderApplies(builderName)) { - requestTracker.requestComplete(); + if (!config.builderApplies(builderName)) return; - } var buildNumber = mostRecentCompletedBuildNumber(builderStatus[builderName]); - if (!buildNumber) { - buildInfoByBuilder[builderName] = null; - requestTracker.requestComplete(); + if (!buildNumber) return; - } - g_buildInfoCache.get(platform + '\n' + builderName + '\n' + buildNumber, function(buildInfo) { - buildInfoByBuilder[builderName] = buildInfo; - requestTracker.requestComplete(); - }); + requestPromises.push(g_buildInfoCache.get(builderName + '\n' + buildNumber) + .then(function(buildInfo) { + buildInfoByBuilder[builderName] = buildInfo; + })); + }); + + return Promise.all(requestPromises).then(function() { + return buildInfoByBuilder; }); }); } -builders.buildersFailingNonLayoutTests = function(callback) +builders.buildersFailingNonLayoutTests = function() { - fetchMostRecentBuildInfoByBuilder(config.currentPlatform, function(buildInfoByBuilder) { + return fetchMostRecentBuildInfoByBuilder().then(function(buildInfoByBuilder) { var failureList = {}; $.each(buildInfoByBuilder, function(builderName, buildInfo) { if (!buildInfo) @@ -123,15 +117,15 @@ builders.buildersFailingNonLayoutTests = function(callback) if (failures.length) failureList[builderName] = failures.map(function(failure) { return failure.name; }); }); - callback(failureList); + return failureList; }); }; -builders.mostRecentBuildForBuilder = function(platform, builderName, callback) { - net.get(buildBotURL(platform) + '/json/builders/' + builderName, function(builderStatus) { +builders.mostRecentBuildForBuilder = function(builderName) { + return net.json(config.buildConsoleURL + '/json/builders/' + builderName).then(function(builderStatus) { var cachedBuilds = builderStatus.cachedBuilds; var mostRecentBuild = Math.max.apply(Math, cachedBuilds); - callback(mostRecentBuild); + return mostRecentBuild; }); }; diff --git a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/builders_unittests.js b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/builders_unittests.js index d1dc53fbfd9..fe5bca9c1c7 100644 --- a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/builders_unittests.js +++ b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/builders_unittests.js @@ -690,9 +690,7 @@ var kExampleBuildInfoWithTaskKillWarning = { "times": [1318364210.066524, 1318366408.0732119] }; - - -test("buildersFailing", 3, function() { +asyncTest("buildersFailing", 3, function() { var simulator = new NetworkSimulator(); builders.clearBuildInfoCache(); @@ -701,27 +699,25 @@ test("buildersFailing", 3, function() { failingBuildInfoJSON.steps[2].results[0] = 1; var requestedURLs = []; - simulator.get = function(url, callback) + simulator.json = function(url) { requestedURLs.push(url); - simulator.scheduleCallback(function() { - if (/\/json\/builders$/.exec(url)) - callback(kExampleBuilderStatusJSON); - else if (/WebKit%20Linux/.exec(url)) - callback(kExampleBuildInfoJSON); - else if (/WebKit%20Mac10\.6/.exec(url)) - callback(failingBuildInfoJSON); - else if (/WebKit%20ASAN/.exec(url)) - callback(failingBuildInfoJSON); - else { - ok(false, "Unexpected URL: " + url); - callback(); - } - }); + if (/\/json\/builders$/.exec(url)) + return Promise.resolve(kExampleBuilderStatusJSON); + else if (/WebKit%20Linux/.exec(url)) + return Promise.resolve(kExampleBuildInfoJSON); + else if (/WebKit%20Mac10\.6/.exec(url)) + return Promise.resolve(failingBuildInfoJSON); + else if (/WebKit%20ASAN/.exec(url)) + return Promise.resolve(failingBuildInfoJSON); + else { + ok(false, "Unexpected URL: " + url); + return Promise.reject("Unexpected URL: " + url); + }; }; simulator.runTest(function() { - builders.buildersFailingNonLayoutTests(function(builderNameList) { + builders.buildersFailingNonLayoutTests().then(function(builderNameList) { deepEqual(builderNameList, { "WebKit Linux": [ "webkit_gpu_tests" @@ -734,17 +730,19 @@ test("buildersFailing", 3, function() { ], }); }); - }); + }).then(function() { - deepEqual(requestedURLs, [ - "http://build.chromium.org/p/chromium.webkit/json/builders", - "http://build.chromium.org/p/chromium.webkit/json/builders/WebKit%20Linux/builds/11461", - "http://build.chromium.org/p/chromium.webkit/json/builders/WebKit%20Mac10.6/builds/11460", - "http://build.chromium.org/p/chromium.webkit/json/builders/WebKit%20ASAN/builds/11460", - ]); + deepEqual(requestedURLs, [ + "http://build.chromium.org/p/chromium.webkit/json/builders", + "http://build.chromium.org/p/chromium.webkit/json/builders/WebKit%20Linux/builds/11461", + "http://build.chromium.org/p/chromium.webkit/json/builders/WebKit%20Mac10.6/builds/11460", + "http://build.chromium.org/p/chromium.webkit/json/builders/WebKit%20ASAN/builds/11460", + ]); + start(); + }); }); -test("buildersFailing (run-webkit-tests crash)", 3, function() { +asyncTest("buildersFailing (run-webkit-tests crash)", 3, function() { var simulator = new NetworkSimulator(); builders.clearBuildInfoCache(); @@ -757,25 +755,23 @@ test("buildersFailing (run-webkit-tests crash)", 3, function() { failingBuildInfoJSON.number = 21460; var requestedURLs = []; - simulator.get = function(url, callback) + simulator.json = function(url) { requestedURLs.push(url); - simulator.scheduleCallback(function() { - if (/\/json\/builders$/.exec(url)) - callback(builderStatusJSON); - else if (/WebKit%20Linux/.exec(url)) - callback(failingBuildInfoJSON); - else if (/WebKit%20ASAN/.exec(url)) - callback(failingBuildInfoJSON); - else { - ok(false, "Unexpected URL: " + url); - callback(); - } - }); + if (/\/json\/builders$/.exec(url)) + return Promise.resolve(builderStatusJSON); + else if (/WebKit%20Linux/.exec(url)) + return Promise.resolve(failingBuildInfoJSON); + else if (/WebKit%20ASAN/.exec(url)) + return Promise.resolve(failingBuildInfoJSON); + else { + ok(false, "Unexpected URL: " + url); + return Promise.reject("Unexpected URL: " + url); + } }; simulator.runTest(function() { - builders.buildersFailingNonLayoutTests(function(builderNameList) { + builders.buildersFailingNonLayoutTests().then(function(builderNameList) { deepEqual(builderNameList, { "WebKit Linux": [ "webkit_tests", @@ -791,17 +787,18 @@ test("buildersFailing (run-webkit-tests crash)", 3, function() { ], }); }); + }).then(function() { + deepEqual(requestedURLs, [ + "http://build.chromium.org/p/chromium.webkit/json/builders", + "http://build.chromium.org/p/chromium.webkit/json/builders/WebKit%20Linux/builds/21460", + // FIXME: This looks wrong? Why is ASAN here and with the wrong build number? + "http://build.chromium.org/p/chromium.webkit/json/builders/WebKit%20ASAN/builds/11460" + ]); + start(); }); - - deepEqual(requestedURLs, [ - "http://build.chromium.org/p/chromium.webkit/json/builders", - "http://build.chromium.org/p/chromium.webkit/json/builders/WebKit%20Linux/builds/21460", - // FIXME: This looks wrong? Why is ASAN here and with the wrong build number? - "http://build.chromium.org/p/chromium.webkit/json/builders/WebKit%20ASAN/builds/11460" - ]); }); -test("buildersFailing (taskkill warning)", 3, function() { +asyncTest("buildersFailing (taskkill warning)", 3, function() { var simulator = new NetworkSimulator(); builders.clearBuildInfoCache(); @@ -814,34 +811,34 @@ test("buildersFailing (taskkill warning)", 3, function() { failingBuildInfoJSON.number = 21460; var requestedURLs = []; - simulator.get = function(url, callback) + simulator.json = function(url) { requestedURLs.push(url); - simulator.scheduleCallback(function() { - if (/\/json\/builders$/.exec(url)) - callback(builderStatusJSON); - else if (/WebKit%20Linux/.exec(url)) - callback(failingBuildInfoJSON); - else if (/WebKit%20ASAN/.exec(url)) - callback(failingBuildInfoJSON); - else { - ok(false, "Unexpected URL: " + url); - callback(); - } - }); + if (/\/json\/builders$/.exec(url)) + return Promise.resolve(builderStatusJSON); + else if (/WebKit%20Linux/.exec(url)) + return Promise.resolve(failingBuildInfoJSON); + else if (/WebKit%20ASAN/.exec(url)) + return Promise.resolve(failingBuildInfoJSON); + else { + ok(false, "Unexpected URL: " + url); + return Promise.reject("Unexpected URL: " + url); + } }; simulator.runTest(function() { - builders.buildersFailingNonLayoutTests(function(builderNameList) { + builders.buildersFailingNonLayoutTests().then(function(builderNameList) { deepEqual(builderNameList, {}); }); - }); + }).then(function() { - deepEqual(requestedURLs, [ - "http://build.chromium.org/p/chromium.webkit/json/builders", - "http://build.chromium.org/p/chromium.webkit/json/builders/WebKit%20Linux/builds/21460", - "http://build.chromium.org/p/chromium.webkit/json/builders/WebKit%20ASAN/builds/11460", - ]); + deepEqual(requestedURLs, [ + "http://build.chromium.org/p/chromium.webkit/json/builders", + "http://build.chromium.org/p/chromium.webkit/json/builders/WebKit%20Linux/builds/21460", + "http://build.chromium.org/p/chromium.webkit/json/builders/WebKit%20ASAN/builds/11460", + ]); + start(); + }); }); })(); diff --git a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/checkout.js b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/checkout.js index 5c45d6c596c..07b54c2a8f0 100644 --- a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/checkout.js +++ b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/checkout.js @@ -29,58 +29,48 @@ var checkout = checkout || {}; var g_haveSeenCheckoutAvailable = false; -function callIfCheckoutAvailable(callback, checkoutUnavailable) +function checkoutAvailable() { if (g_haveSeenCheckoutAvailable) { - callback(); - return; + return Promise.resolve(); } - checkout.isAvailable(function(isAvailable) { + + return checkout.isAvailable().then(function(isAvailable) { if (isAvailable) { g_haveSeenCheckoutAvailable = true; - callback(); return; } - if (checkoutUnavailable) - checkoutUnavailable(); }); -} +}; -checkout.isAvailable = function(callback) +checkout.isAvailable = function() { - net.ajax({ + return net.ajax({ url: '/ping', - success: function() { - callback(true); - }, - error: function() { - callback(false); - }, - }); + }).then(function() { return true; }, + function() { return false; }); }; -checkout.lastBlinkRollRevision = function(callback, checkoutUnavailable) +checkout.lastBlinkRollRevision = function() { - callIfCheckoutAvailable(function() { - net.get('/lastroll', callback); - }, checkoutUnavailable); -} + return checkoutAvailable().then(function() { + return net.get('/lastroll'); + }); +}; -checkout.rollout = function(revision, reason, callback, checkoutUnavailable) +checkout.rollout = function(revision, reason) { - callIfCheckoutAvailable(function() { - net.post('/rollout?' + $.param({ + return checkoutAvailable().then(function() { + return net.post('/rollout?' + $.param({ 'revision': revision, 'reason': reason - }), function() { - callback(); - }); - }, checkoutUnavailable); + })); + }); }; -checkout.rebaseline = function(failureInfoList, callback, progressCallback, checkoutUnavailable, debugBotsCallback) +checkout.rebaseline = function(failureInfoList, progressCallback, debugBotsCallback) { - callIfCheckoutAvailable(function() { + return checkoutAvailable().then(function() { var tests = {}; for (var i = 0; i < failureInfoList.length; i++) { var failureInfo = failureInfoList[i]; @@ -92,8 +82,8 @@ checkout.rebaseline = function(failureInfoList, callback, progressCallback, chec tests[failureInfo.testName][failureInfo.builderName] = base.uniquifyArray(base.flattenArray(failureInfo.failureTypeList.map(results.failureTypeToExtensionList))); } - net.post('/rebaselineall', JSON.stringify(tests), function() { callback() }); - }, checkoutUnavailable); + net.post('/rebaselineall', JSON.stringify(tests)).then(progressCallback, progressCallback); + }); }; })(); diff --git a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/checkout_unittests.js b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/checkout_unittests.js index 646a7cd2119..b99d2de4cf9 100644 --- a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/checkout_unittests.js +++ b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/checkout_unittests.js @@ -27,20 +27,23 @@ module("checkout"); -test("lastBlinkRollRevision", 0, function() { +asyncTest("lastBlinkRollRevision", 0, function() { var simulator = new NetworkSimulator(); var requests = []; - simulator.get = function(url, callback) + simulator.get = function(url) { requests.push([url]); - simulator.scheduleCallback(callback); + return Promise.resolve(); }; + simulator.ajax = function(options) { - if (options.url.indexOf('/ping') == -1) + if (options.url.indexOf('/ping') == -1) { ok(false, 'Received non-ping ajax request: ' + options.url); - simulator.scheduleCallback(options.success); + return Promise.reject('Received non-ping ajax request: ' + options.url); + } + return Promise.resolve(); }; simulator.runTest(function() { @@ -49,27 +52,30 @@ test("lastBlinkRollRevision", 0, function() { }, function() { ok(false, 'Checkout should be available.'); }); - }); - - deepEqual(requests, [ - ["/lastroll"] - ]); + }).then(function() { + deepEqual(requests, [ + ["/lastroll"] + ]); + start(); + });; }); -test("rebaseline", 3, function() { +asyncTest("rebaseline", 3, function() { var simulator = new NetworkSimulator(); var requests = []; - simulator.post = function(url, body, callback) + simulator.post = function(url, body) { requests.push([url, body]); - simulator.scheduleCallback(callback); + return Promise.resolve(); }; simulator.ajax = function(options) { - if (options.url.indexOf('/ping') == -1) + if (options.url.indexOf('/ping') == -1) { ok(false, 'Received non-ping ajax request: ' + options.url); - simulator.scheduleCallback(options.success); + return Promise.reject('Received non-ping ajax request: ' + options.url); + } + return Promise.resolve(); }; var kExpectedTestNameProgressStack = [ @@ -91,38 +97,40 @@ test("rebaseline", 3, function() { 'builderName': 'Webkit Win7', 'testName': 'fast/test.html', 'failureTypeList': ['IMAGE+TEXT'], - }], function() { - ok(true); - }, function(failureInfo) { + }], function(failureInfo) { equals(failureInfo.testName, kExpectedTestNameProgressStack.pop()); }, function() { - ok(false, 'Checkout should be available.'); - }, function() { ok(false, 'There are no debug bots in the list'); + }).catch().then(function() { + ok(true); + }, function() { + ok(false, 'Checkout should be available.'); }); - }); + }).then(function() { - deepEqual(requests, [ - ["/rebaselineall", - JSON.stringify({ - "another/test.svg": { - "WebKit Linux": ["png"], - "WebKit Mac10.6": ["png","txt"]}, - "fast/test.html": { - "Webkit Win7": ["txt","png"] - }})] - ]); + deepEqual(requests, [ + ["/rebaselineall", + JSON.stringify({ + "another/test.svg": { + "WebKit Linux": ["png"], + "WebKit Mac10.6": ["png","txt"]}, + "fast/test.html": { + "Webkit Win7": ["txt","png"] + }})] + ]); + start(); + }); }); -test("rebaseline-debug-bot", 3, function() { +asyncTest("rebaseline-debug-bot", 4, function() { var simulator = new NetworkSimulator(); - simulator.post = function(url, body, callback) + simulator.post = function(url, body) { - simulator.scheduleCallback(callback); + return Promise.resolve(); }; simulator.ajax = function(options) { - simulator.scheduleCallback(options.success); + return Promise.resolve(); }; simulator.runTest(function() { @@ -130,16 +138,16 @@ test("rebaseline-debug-bot", 3, function() { 'builderName': 'WebKit Linux (dbg)', 'testName': 'another/test.svg', 'failureTypeList': ['IMAGE'], - }], function() { + }], function(failureInfo) { ok(true); }, function(failureInfo) { - ok(false); - }, function() { - ok(false, 'Checkout should be available.'); - }, function(failureInfo) { ok(true); + }).then(function() { + ok(true); + }, function() { + ok(false); }); - }); + }).then(start); }); })(); diff --git a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/config.js b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/config.js index 7346ab6a793..c965198ebcd 100644 --- a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/config.js +++ b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/config.js @@ -27,61 +27,44 @@ var config = config || {}; (function() { -config.kBuildNumberLimit = 20; +config = { + kRelativeTimeUpdateFrequency: 1000 * 60, + kTreeStatusUpdateFrequency: 1000 * 30, + kUpdateFrequency: 10 * 60 * 1000, -config.kPlatforms = { - 'chromium' : { - label : 'Chromium', - buildConsoleURL: 'http://build.chromium.org/p/chromium.webkit', + kBlinkRevisionURL: 'http://src.chromium.org/viewvc/blink', + kRietveldURL: 'https://codereview.chromium.org', - layoutTestResultsURL: 'https://storage.googleapis.com/chromium-layout-test-archives', - waterfallURL: 'http://build.chromium.org/p/chromium.webkit/waterfall', - builders: { - 'WebKit XP': {version: 'xp'}, - 'WebKit Win7': {version: 'win7'}, - 'WebKit Win7 (dbg)': {version: 'win7', debug: true}, - 'WebKit Linux': {version: 'lucid', is64bit: true}, - 'WebKit Linux 32': {version: 'lucid'}, - 'WebKit Linux (dbg)': {version: 'lucid', is64bit: true, debug: true}, - 'WebKit Mac10.6': {version: 'snowleopard'}, - 'WebKit Mac10.6 (dbg)': {version: 'snowleopard', debug: true}, - 'WebKit Mac10.7': {version: 'lion'}, - 'WebKit Mac10.7 (dbg)': {version: 'lion', debug: true}, - 'WebKit Mac10.8': {version: 'mountainlion'}, - 'WebKit Mac10.8 (retina)': {version: 'retina'}, - 'WebKit Mac10.9': {version: 'mavericks'}, - 'WebKit Android (Nexus4)': {version: 'android'}, - }, - resultsDirectoryNameFromBuilderName: function(builderName) { - return base.underscoredBuilderName(builderName); - }, - _builderApplies: function(builderName) { - // FIXME: Remove the Perf check once the bots are gone. - return builderName.indexOf('GPU') == -1 && - builderName.indexOf('Perf') == -1; - }, - }, -}; - -config.currentPlatform = 'chromium'; -config.kBlinkSvnURL = 'svn://svn.chromium.org/blink/trunk'; -config.kBlinkRevisionURL = 'http://src.chromium.org/viewvc/blink'; -config.kSvnLogURL = 'http://build.chromium.org/cgi-bin/svn-log'; -config.kRietveldURL = "https://codereview.chromium.org"; - -var kTenMinutesInMilliseconds = 10 * 60 * 1000; -config.kUpdateFrequency = kTenMinutesInMilliseconds; -config.kRelativeTimeUpdateFrequency = 1000 * 60; -config.kTreeStatusUpdateFrequency = 1000 * 30; - -config.currentBuilders = function() { - return config.kPlatforms[config.currentPlatform].builders; -}; + buildConsoleURL: 'http://build.chromium.org/p/chromium.webkit', -config.builderApplies = function(builderName) { - return config.kPlatforms[config.currentPlatform]._builderApplies(builderName); + layoutTestResultsURL: 'https://storage.googleapis.com/chromium-layout-test-archives', + waterfallURL: 'http://build.chromium.org/p/chromium.webkit/waterfall', + builders: { + 'WebKit XP': {version: 'xp'}, + 'WebKit Win7': {version: 'win7'}, + 'WebKit Win7 (dbg)': {version: 'win7', debug: true}, + 'WebKit Linux': {version: 'lucid', is64bit: true}, +// FIXME: Temporarily disabled, because it makes garden-o-matic unusably slow. +// 'WebKit Linux ASAN': {version: 'lucid', is64bit: true}, + 'WebKit Linux 32': {version: 'lucid'}, + 'WebKit Linux (dbg)': {version: 'lucid', is64bit: true, debug: true}, + 'WebKit Mac10.6': {version: 'snowleopard'}, + 'WebKit Mac10.6 (dbg)': {version: 'snowleopard', debug: true}, + 'WebKit Mac10.7': {version: 'lion'}, + 'WebKit Mac10.7 (dbg)': {version: 'lion', debug: true}, + 'WebKit Mac10.8': {version: 'mountainlion'}, + 'WebKit Mac10.8 (retina)': {version: 'retina'}, + 'WebKit Mac10.9': {version: 'mavericks'}, + 'WebKit Android (Nexus4)': {version: 'android'}, + }, + resultsDirectoryNameFromBuilderName: function(builderName) { + return base.underscoredBuilderName(builderName); + }, + builderApplies: function(builderName) { + return builderName.indexOf('GPU') == -1 && + builderName.indexOf('Oilpan') == -1; + }, + useLocalResults: !!base.getURLParameter('useLocalResults') || false, }; -config.useLocalResults = Boolean(base.getURLParameter('useLocalResults')) || false; - })(); diff --git a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/controllers.js b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/controllers.js index 5a6d07e353d..964d9e84c88 100644 --- a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/controllers.js +++ b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/controllers.js @@ -53,8 +53,19 @@ function rebaselineWithStatusUpdates(failureInfoList, resultsByTest) }); if (failuresToRebaseline.length) { - checkout.rebaseline(failuresToRebaseline, function() { - statusView.addFinalMessage(id, 'Rebaseline done! Please land with "webkit-patch land-cowhand".'); + // FIXME: checkout.rebaseline() accepts only 3 arguments, we pass 5. + checkout.rebaseline(failuresToRebaseline, function(response) { + try { + var json = JSON.parse(response); + if (!json.result_code) { + statusView.addFinalMessage(id, 'Rebaseline done! Please commit locally and land with "git cl dcommit".'); + } else { + statusView.addMessage(id, 'Rebaseline failed (code=' + json.result_code + ')!'); + statusView.addFinalMessage(id, json.output); + } + } catch (e) { + statusView.addFinalMessage(id, 'Invalid response received: "' + response + '"'); + } }, function(failureInfo) { statusView.addMessage(id, failureInfo.testName + ' on ' + ui.displayNameForBuilder(failureInfo.builderName)); }, function() { @@ -88,7 +99,7 @@ function updateExpectationsWithStatusUpdates(failureInfoList) statusView.addMessage(id, 'Updating expectations of ' + testName + '...'); checkout.updateExpectations(failureInfoList, function() { - statusView.addFinalMessage(id, 'Expectations update done! Please land with "webkit-patch land-cowhand".'); + statusView.addFinalMessage(id, 'Expectations update done! Please commit them locally and land with "git cl dcommit".'); }, function() { statusView.addFinalMessage(id, kCheckoutUnavailableMessage); }); @@ -294,26 +305,13 @@ controllers.UnexpectedFailures = base.extends(FailureStreamController, { }, onRollout: function(revision, testNameList) { - checkout.rollout(revision, ui.rolloutReasonForTestNameList(testNameList), $.noop, function() { + checkout.rollout(revision, ui.rolloutReasonForTestNameList(testNameList)).then($.noop, function() { // FIXME: We should have a better error UI. alert(kCheckoutUnavailableMessage); }); } }); -controllers.Failures = base.extends(FailureStreamController, { - _resultsFilter: results.expectedFailuresByTest, - - _keyFor: function(failureAnalysis) - { - return base.dirName(failureAnalysis.testName); - }, - _createFailureView: function(failureAnalysis) - { - return new ui.notifications.FailingTests(); - }, -}); - controllers.FailingBuilders = base.extends(Object, { init: function(view, message) { diff --git a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/controllers_unittests.js b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/controllers_unittests.js index 914159ab681..ae170bdd52c 100644 --- a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/controllers_unittests.js +++ b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/controllers_unittests.js @@ -31,10 +31,11 @@ var kExampleResultsByBuilder = { module("controllers"); -test("UnexpectedFailures", 3, function() { +asyncTest("UnexpectedFailures", 3, function() { var simulator = new NetworkSimulator(); simulator.probe = function() { + return Promise.resolve(); }; simulator.runTest(function() { @@ -71,7 +72,7 @@ test("UnexpectedFailures", 3, function() { } }; controller.onExamine(mockFailures); - }); + }).then(start); }); test("controllers.FailingBuilders", 3, function() { @@ -89,11 +90,11 @@ test("controllers.FailingBuilders", 3, function() { equal(view.outerHTML, '<div>' + '<li style="opacity: 0;">' + - '<div class="how"><time class="relative"></time></div>' + + '<div class="how"></div>' + '<div class="what">' + '<div class="problem">dummy message:' + '<ul class="effects">' + - '<li class="builder"><a class="failing-builder" target="_blank" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=DummyBuilder">' + + '<li class="builder"><a class="failing-builder" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=DummyBuilder">' + '<span class="version">DummyBuilder</span><span class="failures"> webkit_tests</span></a>' + '</li>' + '</ul>' + diff --git a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/garden-o-matic.js b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/garden-o-matic.js index 8e10dcb09a0..74c406ce065 100644 --- a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/garden-o-matic.js +++ b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/garden-o-matic.js @@ -36,6 +36,9 @@ var g_failuresController = null; var g_nonLayoutTestFailureBuilders = null; +var g_updating = false; +var g_updateButton = null; + function updatePartyTime() { if (!g_unexpectedFailuresController.length() && !g_nonLayoutTestFailureBuilders.hasFailures()) @@ -55,40 +58,43 @@ function updateTreeStatus() function update() { + if (g_updating) + return; + + g_updating = true; + if (g_updateButton) + g_updateButton.disabled = true; + if (g_revisionHint) g_revisionHint.dismiss(); - var gtestIframe = document.querySelector('#chromium-gtests iframe'); - if (gtestIframe) - gtestIframe.src = gtestIframe.src; - // FIXME: This should be a button with a progress element. var numberOfTestsAnalyzed = 0; var updating = new ui.notifications.Info('Loading commit data ...'); g_info.add(updating); - builders.buildersFailingNonLayoutTests(function(failuresList) { + builders.buildersFailingNonLayoutTests().then(function(failuresList) { g_nonLayoutTestFailureBuilders.update(failuresList); updatePartyTime(); }); - base.callInParallel([model.updateRecentCommits, model.updateResultsByBuilder], function() { + Promise.all([model.updateRecentCommits(), model.updateResultsByBuilder()]).then(function() { if (g_failuresController) g_failuresController.update(); updating.update('Analyzing test failures ...'); - model.analyzeUnexpectedFailures(function(failureAnalysis) { - updating.update('Analyzing test failures ... ' + ++numberOfTestsAnalyzed + ' tests analyzed.'); + model.analyzeUnexpectedFailures(function(failureAnalysis, total) { + updating.update('Analyzing test failures ... ' + ++numberOfTestsAnalyzed + '/' + total + ' tests analyzed.'); g_unexpectedFailuresController.update(failureAnalysis); - }, function() { + }).then(function() { updatePartyTime(); g_unexpectedFailuresController.purge(); - Object.keys(config.currentBuilders()).forEach(function(builderName) { + Object.keys(config.builders).forEach(function(builderName) { if (!model.state.resultsByBuilder[builderName]) - g_info.add(new ui.notifications.Info('Could not find test results for ' + builderName + ' in the last ' + config.kBuildNumberLimit + ' runs.')); + g_info.add(new ui.notifications.Info('Could not find test results for ' + builderName + '.')); }); updating.dismiss(); @@ -96,6 +102,10 @@ function update() g_revisionHint = new ui.notifications.Info(''); g_revisionHint.updateWithNode(new ui.revisionDetails()); g_info.add(g_revisionHint); + + g_updating = false; + if (g_updateButton) + g_updateButton.disabled = false; }); }); } @@ -136,6 +146,7 @@ $(document).ready(function() { updateButton.addEventListener("click", update); updateButton.textContent = 'update'; topBar.appendChild(updateButton); + g_updateButton = updateButton; var treeStatus = new ui.TreeStatus(); topBar.appendChild(treeStatus); diff --git a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/model.js b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/model.js index d037af1cc3e..b70d9fa6040 100644 --- a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/model.js +++ b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/model.js @@ -99,13 +99,12 @@ model.takeExpectationUpdateQueue = function() var g_commitIndex = {}; -model.updateRecentCommits = function(callback) +model.updateRecentCommits = function() { - trac.recentCommitData('trunk', kCommitLogLength, function(commitDataList) { + return trac.recentCommitData('trunk', kCommitLogLength).then(function(commitDataList) { model.state.recentCommits = commitDataList; updateCommitIndex(); findAndMarkRevertedRevisions(model.state.recentCommits); - callback(); }); }; @@ -141,7 +140,7 @@ model.buildersInFlightForRevision = function(revision) model.latestRevision = function() { return model.state.recentCommits[0].revision; -} +}; model.latestRevisionWithNoBuildersInFlight = function() { @@ -165,16 +164,15 @@ model.latestRevisionByBuilder = function() return revision; } -model.updateResultsByBuilder = function(callback) +model.updateResultsByBuilder = function() { - var platformBuilders = config.currentBuilders(); - results.fetchResultsByBuilder(Object.keys(platformBuilders), function(resultsByBuilder) { + return results.fetchResultsByBuilder(Object.keys(config.builders)).then(function(resultsByBuilder) { model.state.resultsByBuilder = resultsByBuilder; - callback(); }); }; -model.analyzeUnexpectedFailures = function(callback, completionCallback) +// failureCallback is called multiple times: once for each failure +model.analyzeUnexpectedFailures = function(failureCallback) { var unexpectedFailures = results.unexpectedFailuresByTest(model.state.resultsByBuilder); @@ -183,10 +181,12 @@ model.analyzeUnexpectedFailures = function(callback, completionCallback) delete model.state.failureAnalysisByTest[testName]; }); - var tracker = new base.RequestTracker(Object.keys(unexpectedFailures).length, completionCallback); + var failurePromises = []; $.each(unexpectedFailures, function(testName, resultNodesByBuilder) { var builderNameList = Object.keys(resultNodesByBuilder); - results.unifyRegressionRanges(builderNameList, testName, function(oldestFailingRevision, newestPassingRevision) { + failurePromises.push(results.unifyRegressionRanges(builderNameList, testName).then(function(result) { + var oldestFailingRevision = result[0]; + var newestPassingRevision = result[1]; var failureAnalysis = { 'testName': testName, 'resultNodesByBuilder': resultNodesByBuilder, @@ -205,11 +205,11 @@ model.analyzeUnexpectedFailures = function(callback, completionCallback) } model.state.failureAnalysisByTest[testName] = failureAnalysis; - - callback(failureAnalysis); - tracker.requestComplete(); - }); + + failureCallback(failureAnalysis, failurePromises.length); + })); }); + return Promise.all(failurePromises); }; model.unexpectedFailureInfoForTestName = function(testName) @@ -221,7 +221,8 @@ model.unexpectedFailureInfoForTestName = function(testName) }); }; -model.analyzeexpectedFailures = function(callback) +// failureCallback is called multiple times: once for each failure +model.analyzeexpectedFailures = function(failureCallback) { var expectedFailures = results.expectedFailuresByTest(model.state.resultsByBuilder); $.each(expectedFailures, function(testName, resultNodesByBuilder) { @@ -233,7 +234,7 @@ model.analyzeexpectedFailures = function(callback) // FIXME: Consider looking at the history to see how long this test // has been failing. - callback(failureAnalysis); + failureCallback(failureAnalysis); }); }; diff --git a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/model_unittests.js b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/model_unittests.js index 8caebc56340..38522c99e05 100644 --- a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/model_unittests.js +++ b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/model_unittests.js @@ -117,20 +117,18 @@ test("rebaselineQueue", 3, function() { deepEqual(queue, []); }); -test("updateRecentCommits", 2, function() { +asyncTest("updateRecentCommits", 2, function() { var simulator = new NetworkSimulator(); - simulator.get = function(url, callback) + simulator.xml = function(url) { - simulator.scheduleCallback(function() { - var parser = new DOMParser(); - var responseDOM = parser.parseFromString(kExampleCommitDataXML, "application/xml"); - callback(responseDOM); - }); + var parser = new DOMParser(); + var responseDOM = parser.parseFromString(kExampleCommitDataXML, "application/xml"); + return Promise.resolve(responseDOM); }; simulator.runTest(function() { - model.updateRecentCommits(function() { + model.updateRecentCommits().then(function() { var recentCommits = model.state.recentCommits; delete model.state.recentCommits; $.each(recentCommits, function(index, commitData) { @@ -138,66 +136,64 @@ test("updateRecentCommits", 2, function() { }); deepEqual(recentCommits, [{ "revision": 3, - "title": "This matches Gecko's behavior for these types of properties.", + "title": "Throw SecurityError when setting 'Replaceable' properties cross-origin.", "time": "2013-09-30T20:22:01Z", "summary": "This matches Gecko's behavior for these types of properties.", "author": "mkwst@chromium.org", - "reviewer": "jochen@chromium", - "bugID": 13, + "reviewer": "jochen@chromium.org", + "bugID": [13], "revertedRevision": undefined, }, { "revision": 2, - "title": "core/platform may not depend on core/ even for testing.", + "title": "Fix one more layering violation caught by check-blink-deps", "time": "2013-09-30T19:36:21Z", "summary": "core/platform may not depend on core/ even for testing.", "author": "eseidel@chromium.org", - "reviewer": "abarth@chromium", - "bugID": 12, + "reviewer": "abarth@chromium.org, abarth", + "bugID": [12], "revertedRevision": undefined }, { "revision": 1, - "title": "These were all failures noticed when running check-blink-deps", + "title": "Update DEPS include_rules after addition of root-level platform directory", "time": "2013-09-30T19:28:49Z", "summary": "These were all failures noticed when running check-blink-deps", "author": "eseidel@chromium.org", - "reviewer": "abarth@chromium", - "bugID": 11, + "reviewer": "abarth@chromium.org, abarth", + "bugID": [11], "revertedRevision": undefined } ]); }); - }); + }).then(start); }); -test("commitDataListForRevisionRange", 6, function() { +asyncTest("commitDataListForRevisionRange", 6, function() { var simulator = new NetworkSimulator(); - simulator.get = function(url, callback) + simulator.xml = function(url) { - simulator.scheduleCallback(function() { - var parser = new DOMParser(); - var responseDOM = parser.parseFromString(kExampleCommitDataXML, "application/xml"); - callback(responseDOM); - }); + var parser = new DOMParser(); + var responseDOM = parser.parseFromString(kExampleCommitDataXML, "application/xml"); + return Promise.resolve(responseDOM); }; simulator.runTest(function() { - model.updateRecentCommits(function() { + model.updateRecentCommits().then(function() { function extractBugIDs(commitData) { return commitData.bugID; } - deepEqual(model.commitDataListForRevisionRange(3, 3).map(extractBugIDs), [13]); - deepEqual(model.commitDataListForRevisionRange(1, 3).map(extractBugIDs), [11, 12, 13]); - deepEqual(model.commitDataListForRevisionRange(0, 1).map(extractBugIDs), [11]); - deepEqual(model.commitDataListForRevisionRange(0, 4).map(extractBugIDs), [11, 12, 13]); + deepEqual(model.commitDataListForRevisionRange(3, 3).map(extractBugIDs), [[13]]); + deepEqual(model.commitDataListForRevisionRange(1, 3).map(extractBugIDs), [[11], [12], [13]]); + deepEqual(model.commitDataListForRevisionRange(0, 1).map(extractBugIDs), [[11]]); + deepEqual(model.commitDataListForRevisionRange(0, 4).map(extractBugIDs), [[11], [12], [13]]); deepEqual(model.commitDataListForRevisionRange(4, 0).map(extractBugIDs), []); delete model.state.recentCommits; }); - }); + }).then(start); }); test("buildersInFlightForRevision", 3, function() { diff --git a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/net.js b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/net.js index a5fa5643a86..379a5b311d2 100644 --- a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/net.js +++ b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/net.js @@ -27,70 +27,89 @@ var net = net || {}; (function () { -// FIXME: Excise this last bit of jquery ajax code. -// There are callers that depend on automatically parsing the content as JSON or XML -// based off the content-type. Instead we should add net.json and net.xml for those cases. -net.get = function(url, success) +net.get = function(url) { - $.get(url, success); + return net.ajax({ + url: url + }); +}; + +net.json = function(url) +{ + return net.ajax({ + url: url, + parse: function(xhr) { + return JSON.parse(xhr.responseText); + } + }); +}; + +net.xml = function(url) +{ + return net.ajax({ + url: url, + parse: function(xhr) { + return xhr.responseXML; + } + }); }; net.ajax = function(options) { - var xhr = new XMLHttpRequest(); - var method = options.type || 'GET'; - var async = true; - xhr.open(method, options.url, async); - xhr.onload = function() { - if (xhr.status == 200 && options.success) - options.success(xhr.responseText); - else if (xhr.status != 200 && options.error) - options.error(); - }; - xhr.onerror = function() { - if (options.error) - options.error(); - }; - var data = options.data || null; - if (data) - xhr.setRequestHeader("content-type","application/x-www-form-urlencoded"); - xhr.send(data); + return new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + var method = options.type || 'GET'; + var async = true; + xhr.open(method, options.url, async); + xhr.onload = function() { + if (xhr.status == 200) { + if (options.parse) + resolve(options.parse(xhr)); + else + resolve(xhr.responseText); + } + else if (xhr.status != 200) + reject(Error(xhr.statusText)); + }; + xhr.onerror = function(error) { + reject(error); + }; + var data = options.data || null; + if (data) + xhr.setRequestHeader("content-type","application/x-www-form-urlencoded"); + xhr.send(data); + }); }; -net.post = function(url, data, success) +net.post = function(url, data) { - net.ajax({ + return net.ajax({ url: url, type: 'POST', data: data, - success: success, }); }; -net.probe = function(url, options) +net.probe = function(url) { - net.ajax({ + return net.ajax({ url: url, type: 'HEAD', - success: options.success, - error: options.error, }); }; // We use XMLHttpRequest and CORS to fetch JSONP rather than using script tags. // That's better for security and performance, but we need the server to cooperate // by setting CORS headers. -net.jsonp = function(url, callback) +net.jsonp = function(url) { - net.ajax({ + return net.ajax({ url: url, - success: function(jsonp) { - callback(base.parseJSONP(jsonp)); - }, - error: function() { - callback({}); - }, + }).then(function(jsonp) { + return base.parseJSONP(jsonp); + }).catch(function(error) { + return {}; }); }; diff --git a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/net_unittests.js b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/net_unittests.js index 15bcffea8ec..c8fe102c713 100644 --- a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/net_unittests.js +++ b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/net_unittests.js @@ -26,40 +26,57 @@ // Export NetworkSimulator for use by other unittests. function NetworkSimulator() { - this._pendingCallbacks = []; + this._pendingPromises = []; }; -NetworkSimulator.prototype.scheduleCallback = function(callback) -{ - this._pendingCallbacks.push(callback); +NetworkSimulator.prototype.schedulePromise = function(promise) { + this._pendingPromises.push(promise); + return promise; +}; + +NetworkSimulator.prototype.resolvePromises = function() { + var self = this; + return new Promise(function(resolve, reject) { + var pendingPromises = self._pendingPromises; + self._pendingPromises = []; + function all_resolved (results) { + if (self._pendingPromises.length) { + resolve(self.resolvePromises()); + return; + } + resolve(results); + } + Promise.all(pendingPromises).then(all_resolved, all_resolved); + }); }; NetworkSimulator.prototype.runTest = function(testCase) { var self = this; var realNet = window.net; + return new Promise(function(resolve, reject) { - window.net = {}; - if (self.probe) - net.probe = self.probe; - if (self.jsonp) - net.jsonp = self.jsonp; - if (self.get) - net.get = self.get; - if (self.post) - net.post = self.post; - if (self.ajax) - net.ajax = self.ajax; - - testCase(); - - while (this._pendingCallbacks.length) { - var callback = this._pendingCallbacks.shift(); - callback(); - } + // All net.* methods should return promises. This watches all + // promises generated by test-overridden methods. + window.net = {}; + ['probe', 'jsonp', 'get', 'post', + 'ajax', 'json', 'xml'].forEach(function(method) { + if (method in self) { + net[method] = function() { + return self.schedulePromise(self[method].apply(self, arguments)); + }; + }; + }); - window.net = realNet; - equal(window.net, realNet); + testCase(); + self.resolvePromises().then(function() { + window.net = realNet; + equal(window.net, realNet); + resolve(); + }).catch(function(e) { + ok(false, "Failed to finish test: " + e); + }); + }); }; (function () { diff --git a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/pixelzoomer.js b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/pixelzoomer.js index a88e22a0aca..5e63e9a1ee9 100644 --- a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/pixelzoomer.js +++ b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/pixelzoomer.js @@ -74,10 +74,12 @@ function zoomImageContainer(url) var image = new Image(); image.src = url; - image.style.width = kZoomedResultWidth + 'px'; - image.style.height = kZoomedResultHeight + 'px'; - image.style.border = '1px solid black'; + image.style.display = 'none'; + + var canvas = document.createElement('canvas'); + imageContainer.appendChild(image); + imageContainer.appendChild(canvas); container.appendChild(imageContainer); return container; @@ -102,9 +104,26 @@ function createContainer(e) function draw(imageContainer) { var image = imageContainer.querySelector('img'); - var containerBounds = imageContainer.getBoundingClientRect(); - image.style.left = (containerBounds.width / 2 - pixelzoomer._percentX * kZoomedResultWidth) + 'px'; - image.style.top = (containerBounds.height / 2 - pixelzoomer._percentY * kZoomedResultHeight) + 'px'; + var canvas = imageContainer.querySelector('canvas'); + + if (!image.complete) { + image.onload = function() { + draw(imageContainer); + }; + return; + } + + canvas.width = imageContainer.clientWidth; + canvas.height = imageContainer.clientHeight; + + var ctx = canvas.getContext('2d'); + ctx.mozImageSmoothingEnabled = false; + ctx.imageSmoothingEnabled = false; + ctx.translate(imageContainer.clientWidth / 2, imageContainer.clientHeight / 2); + ctx.translate(-pixelzoomer._percentX * kZoomedResultWidth, -pixelzoomer._percentY * kZoomedResultHeight); + ctx.strokeRect(-1.5, -1.5, kZoomedResultWidth + 2, kZoomedResultHeight + 2); + ctx.scale(kZoomFactor, kZoomFactor); + ctx.drawImage(image, 0, 0); } function drawAll() diff --git a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/results.js b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/results.js index 34cb3ebdb9e..2e59d03492e 100644 --- a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/results.js +++ b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/results.js @@ -74,16 +74,11 @@ results.kDiffKind = 'diff'; results.kUnknownKind = 'unknown'; // Types of tests. -results.kImageType = 'image' -results.kAudioType = 'audio' -results.kTextType = 'text' +results.kImageType = 'image'; +results.kAudioType = 'audio'; +results.kTextType = 'text'; // FIXME: There are more types of tests. -function layoutTestResultsURL(platform) -{ - return config.kPlatforms[platform].layoutTestResultsURL; -} - function possibleSuffixListFor(failureTypeList) { var suffixList = []; @@ -170,43 +165,30 @@ results.failureTypeList = function(failureBlob) return failureBlob.split(' '); }; -results.directoryForBuilder = function(builderName) -{ - return config.kPlatforms[config.currentPlatform].resultsDirectoryNameFromBuilderName(builderName); -} - -function resultsDirectoryURL(platform, builderName) +function resultsDirectoryURL(builderName) { if (config.useLocalResults) return '/localresult?path='; - return layoutTestResultsURL(platform) + '/' + results.directoryForBuilder(builderName) + '/results/layout-test-results/'; -} - -function resultsPrefixListingURL(platform, builderName, marker) -{ - var url = layoutTestResultsURL(platform) + '/?prefix=' + results.directoryForBuilder(builderName) + '/&delimiter=/'; - if (marker) - return url + '&marker=' + marker; - return url; + return config.layoutTestResultsURL + '/' + config.resultsDirectoryNameFromBuilderName(builderName) + '/results/layout-test-results/'; } -function resultsDirectoryURLForBuildNumber(platform, builderName, buildNumber) +function resultsDirectoryURLForBuildNumber(builderName, buildNumber) { - return layoutTestResultsURL(platform) + '/' + results.directoryForBuilder(builderName) + '/' + buildNumber + '/' ; + return config.layoutTestResultsURL + '/' + config.resultsDirectoryNameFromBuilderName(builderName) + '/' + buildNumber + '/' ; } -function resultsSummaryURL(platform, builderName) +function resultsSummaryURL(builderName) { - return resultsDirectoryURL(platform, builderName) + kResultsName; + return resultsDirectoryURL(builderName) + kResultsName; } -function resultsSummaryURLForBuildNumber(platform, builderName, buildNumber) +function resultsSummaryURLForBuildNumber(builderName, buildNumber) { - return resultsDirectoryURLForBuildNumber(platform, builderName, buildNumber) + kResultsName; + return resultsDirectoryURLForBuildNumber(builderName, buildNumber) + kResultsName; } -var g_resultsCache = new base.AsynchronousCache(function (key, callback) { - net.jsonp(key, callback); +var g_resultsCache = new base.AsynchronousCache(function(key) { + return net.jsonp(key); }); results.ResultAnalyzer = base.extends(Object, { @@ -248,7 +230,7 @@ results.ResultAnalyzer = base.extends(Object, { { return this._isUnexpected; } -}) +}); function isExpectedFailure(resultNode) { @@ -323,39 +305,23 @@ results.collectUnexpectedResults = function(dictionaryOfResultNodes) }; // Callback data is [{ buildNumber:, url: }] -function historicalResultsLocations(platform, builderName, callback) +function historicalResultsLocations(builderName) { - var historicalResultsData = []; - - function parseListingDocument(prefixListingDocument) { - $(prefixListingDocument).find("Prefix").each(function() { - var buildString = this.textContent.replace(results.directoryForBuilder(builderName) + '/', ''); - if (buildString.match(/\d+\//)) { - var buildNumber = parseInt(buildString); - var resultsData = { - 'buildNumber': buildNumber, - 'url': resultsSummaryURLForBuildNumber(platform, builderName, buildNumber) - }; - historicalResultsData.unshift(resultsData); - } - }); - var nextMarker = $(prefixListingDocument).find('NextMarker').get(); - if (nextMarker.length) { - var nextListingURL = resultsPrefixListingURL(platform, builderName, nextMarker[0].textContent); - net.get(nextListingURL, parseListingDocument); - } else { - callback(historicalResultsData); + return builders.mostRecentBuildForBuilder(builderName).then(function (mostRecentBuildNumber) { + var resultsLocations = []; + // Return the builds in reverse chronological order in order to load the most recent data first. + for (var buildNumber = mostRecentBuildNumber; buildNumber > mostRecentBuildNumber - 100; --buildNumber) { + resultsLocations.push({ + 'buildNumber': buildNumber, + 'url': resultsDirectoryURLForBuildNumber(builderName, buildNumber) + "failing_results.json" + }); } - } - - builders.mostRecentBuildForBuilder(platform, builderName, function (mostRecentBuildNumber) { - var marker = results.directoryForBuilder(builderName) + "/" + (mostRecentBuildNumber - 100) + "/"; - var listingURL = resultsPrefixListingURL(platform, builderName, marker); - net.get(listingURL, parseListingDocument); + return resultsLocations; }); } -function walkHistory(platform, builderName, testName, callback) +// This will repeatedly call continueCallback(revision, resultNode) until it returns false. +function walkHistory(builderName, testName, continueCallback) { var indexOfNextKeyToFetch = 0; var keyList = []; @@ -369,13 +335,13 @@ function walkHistory(platform, builderName, testName, callback) var resultsURL = keyList[indexOfNextKeyToFetch].url; ++indexOfNextKeyToFetch; - g_resultsCache.get(resultsURL, function(resultsTree) { + g_resultsCache.get(resultsURL).then(function(resultsTree) { if ($.isEmptyObject(resultsTree)) { continueWalk(); return; } var resultNode = results.resultNodeForTest(resultsTree, testName); - var revision = parseInt(resultsTree['blink_revision']) + var revision = parseInt(resultsTree['blink_revision']); if (isNaN(revision)) revision = 0; processResultNode(revision, resultNode); @@ -384,43 +350,43 @@ function walkHistory(platform, builderName, testName, callback) function processResultNode(revision, resultNode) { - var shouldContinue = callback(revision, resultNode); + var shouldContinue = continueCallback(revision, resultNode); if (!shouldContinue) return; continueWalk(); } - historicalResultsLocations(platform, builderName, function(resultsLocations) { + historicalResultsLocations(builderName).then(function(resultsLocations) { keyList = resultsLocations; continueWalk(); }); } -results.regressionRangeForFailure = function(builderName, testName, callback) -{ - var oldestFailingRevision = 0; - var newestPassingRevision = 0; +results.regressionRangeForFailure = function(builderName, testName) { + return new Promise(function(resolve, reject) { + var oldestFailingRevision = 0; + var newestPassingRevision = 0; - // FIXME: should treat {platform, builderName} as a tuple - walkHistory(config.currentPlatform, builderName, testName, function(revision, resultNode) { - if (!revision) { - callback(oldestFailingRevision, newestPassingRevision); - return false; - } - if (!resultNode) { + walkHistory(builderName, testName, function(revision, resultNode) { + if (!revision) { + resolve([oldestFailingRevision, newestPassingRevision]); + return false; + } + if (!resultNode) { + newestPassingRevision = revision; + resolve([oldestFailingRevision, newestPassingRevision]); + return false; + } + if (isUnexpectedFailure(resultNode)) { + oldestFailingRevision = revision; + return true; + } + if (!oldestFailingRevision) + return true; // We need to keep looking for a failing revision. newestPassingRevision = revision; - callback(oldestFailingRevision, newestPassingRevision); + resolve([oldestFailingRevision, newestPassingRevision]); return false; - } - if (isUnexpectedFailure(resultNode)) { - oldestFailingRevision = revision; - return true; - } - if (!oldestFailingRevision) - return true; // We need to keep looking for a failing revision. - newestPassingRevision = revision; - callback(oldestFailingRevision, newestPassingRevision); - return false; + }); }); }; @@ -449,23 +415,24 @@ function mergeRegressionRanges(regressionRanges) return mergedRange; } -results.unifyRegressionRanges = function(builderNameList, testName, callback) -{ +results.unifyRegressionRanges = function(builderNameList, testName) { var regressionRanges = {}; - var tracker = new base.RequestTracker(builderNameList.length, function() { - var mergedRange = mergeRegressionRanges(regressionRanges); - callback(mergedRange.oldestFailingRevision, mergedRange.newestPassingRevision); - }); - + var rangePromises = []; $.each(builderNameList, function(index, builderName) { - results.regressionRangeForFailure(builderName, testName, function(oldestFailingRevision, newestPassingRevision) { - var range = {}; - range.oldestFailingRevision = oldestFailingRevision; - range.newestPassingRevision = newestPassingRevision; - regressionRanges[builderName] = range; - tracker.requestComplete(); - }); + rangePromises.push(results.regressionRangeForFailure(builderName, testName) + .then(function(result) { + var oldestFailingRevision = result[0]; + var newestPassingRevision = result[1]; + var range = {}; + range.oldestFailingRevision = oldestFailingRevision; + range.newestPassingRevision = newestPassingRevision; + regressionRanges[builderName] = range; + })); + }); + return Promise.all(rangePromises).then(function() { + var mergedRange = mergeRegressionRanges(regressionRanges); + return [mergedRange.oldestFailingRevision, mergedRange.newestPassingRevision]; }); }; @@ -512,46 +479,43 @@ function sortResultURLsBySuffix(urls) }); }); if (sortedURLs.length != urls.length) - throw "sortResultURLsBySuffix failed to return the same number of URLs." + throw "sortResultURLsBySuffix failed to return the same number of URLs."; return sortedURLs; } -results.fetchResultsURLs = function(failureInfo, callback) +results.fetchResultsURLs = function(failureInfo) { var testNameStem = base.trimExtension(failureInfo.testName); - var urlStem = resultsDirectoryURL(config.currentPlatform, failureInfo.builderName); + var urlStem = resultsDirectoryURL(failureInfo.builderName); var suffixList = possibleSuffixListFor(failureInfo.failureTypeList); var resultURLs = []; - var tracker = new base.RequestTracker(suffixList.length, function() { - callback(sortResultURLsBySuffix(resultURLs)); - }); + var probePromises = []; $.each(suffixList, function(index, suffix) { var url = urlStem + testNameStem + suffix; - net.probe(url, { - success: function() { + probePromises.push(net.probe(url).then( + function() { resultURLs.push(url); - tracker.requestComplete(); }, - error: function() { - tracker.requestComplete(); - }, - }); + function() {})); + }); + return Promise.all(probePromises).then(function() { + return sortResultURLsBySuffix(resultURLs); }); }; -results.fetchResultsByBuilder = function(builderNameList, callback) +results.fetchResultsByBuilder = function(builderNameList) { var resultsByBuilder = {}; - var tracker = new base.RequestTracker(builderNameList.length, function() { - callback(resultsByBuilder); - }); + var fetchPromises = []; $.each(builderNameList, function(index, builderName) { - var resultsURL = resultsSummaryURL(config.currentPlatform, builderName); - net.jsonp(resultsURL, function(resultsTree) { + var resultsURL = resultsSummaryURL(builderName); + fetchPromises.push(net.jsonp(resultsURL).then(function(resultsTree) { resultsByBuilder[builderName] = resultsTree; - tracker.requestComplete(); - }); + })); + }); + return Promise.all(fetchPromises).then(function() { + return resultsByBuilder; }); }; diff --git a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/results_unittests.js b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/results_unittests.js index ceed950c4d4..484b1ad27ff 100644 --- a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/results_unittests.js +++ b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/results_unittests.js @@ -246,7 +246,7 @@ test("resultNodeForTest", 4, function() { equals(results.resultNodeForTest(unittest.kExampleResultsJSON, "userscripts/foo/bar.html"), null); }); -test("walkHistory", 5, function() { +asyncTest("walkHistory", 1, function() { var simulator = new NetworkSimulator(); var keyMap = { @@ -326,54 +326,39 @@ test("walkHistory", 5, function() { }, }; - simulator.jsonp = function(url, callback) { - simulator.scheduleCallback(function() { - var result = keyMap[/[^/]+_Builder/.exec(url)][/\d+/.exec(url)]; - callback(result ? result : {}); - }); + simulator.jsonp = function(url) { + var result = keyMap[/[^/]+_Builder/.exec(url)][/\d+/.exec(url)]; + return Promise.resolve(result ? result : {}); }; - simulator.get = function(url, callback) { - simulator.scheduleCallback(function() { - if (/Mock_Builder/.test(url)) - callback('<ListBucketResult>' + - '<Prefix>Mock_Builder/11101/</Prefix>' + - '<Prefix>Mock_Builder/11102/</Prefix>' + - '<Prefix>Mock_Builder/11103/</Prefix>' + - '<Prefix>Mock_Builder/11104/</Prefix>' + - '<Prefix>Mock_Builder/11105/</Prefix>' + - '<Prefix>Mock_Builder/11106/</Prefix>' + - '<Prefix>Mock_Builder/11107/</Prefix>' + - '<Prefix>Mock_Builder/11108/</Prefix>' + - '</ListBucketResult>'); - else if (/Another_Builder/.test(url)) - callback('<ListBucketResult>' + - '<Prefix>Another_Builder/22201/</Prefix>' + - '<Prefix>Another_Builder/22202/</Prefix>' + - '</ListBucketResult>'); - else if (/Mock Builder/.test(url)) - callback({cachedBuilds: [11101, 11102, 11103, 11104, 11105, 11106, 11107, 11108]}); - else if (/Another Builder/.test(url)) - callback({cachedBuilds: [22201, 22202]}); - else - ok(false, 'Unexpected URL: ' + url); - }); + simulator.json = function(url) { + if (/Mock Builder/.test(url)) + return Promise.resolve({cachedBuilds: [11101, 11102, 11103, 11104, 11105, 11106, 11107, 11108]}); + else if (/Another Builder/.test(url)) + return Promise.resolve({cachedBuilds: [22201, 22202]}); + else + return Promise.reject(false, 'Unexpected URL: ' + url); }; simulator.runTest(function() { - results.regressionRangeForFailure("Mock Builder", "userscripts/another-test.html", function(oldestFailingRevision, newestPassingRevision) { - equals(oldestFailingRevision, 90426); - equals(newestPassingRevision, 90424); - }); - - results.unifyRegressionRanges(["Mock Builder", "Another Builder"], "userscripts/another-test.html", function(oldestFailingRevision, newestPassingRevision) { - equals(oldestFailingRevision, 90426); - equals(newestPassingRevision, 90425); - }); - }); + results.regressionRangeForFailure("Mock Builder", "userscripts/another-test.html") + .then(function(result) { + var oldestFailingRevision = result[0]; + var newestPassingRevision = result[1]; + equals(oldestFailingRevision, 90426); + equals(newestPassingRevision, 90424); + }); + results.unifyRegressionRanges(["Mock Builder", "Another Builder"], "userscripts/another-test.html") + .then(function(result) { + var oldestFailingRevision = result[0]; + var newestPassingRevision = result[1]; + equals(oldestFailingRevision, 90426); + equals(newestPassingRevision, 90425); + }); + }).then(start); }); -test("walkHistory (no revision)", 3, function() { +asyncTest("walkHistory (no revision)", 3, function() { var simulator = new NetworkSimulator(); var keyMap = { @@ -397,25 +382,22 @@ test("walkHistory (no revision)", 3, function() { }, }; - simulator.jsonp = function(url, callback) { - simulator.scheduleCallback(function() { - var result = keyMap[/[^/]+_Builder/.exec(url)][/\d+/.exec(url)]; - callback(result ? result : {}); - }); + simulator.jsonp = function(url) { + var result = keyMap[/[^/]+_Builder/.exec(url)][/\d+/.exec(url)]; + return Promise.resolve(result ? result : {}); }; - simulator.get = function(url, callback) { - simulator.scheduleCallback(function() { - callback('<a href="11101/"></a><a href="11102/"></a><a href="11103/"></a>'); - }); + simulator.json = function(url) { + return Promise.resolve({}); }; - simulator.runTest(function() { - results.regressionRangeForFailure("Mock Builder", "userscripts/another-test.html", function(oldestFailingRevision, newestPassingRevision) { + results.regressionRangeForFailure("Mock Builder", "userscripts/another-test.html").then(function(result) { + var oldestFailingRevision = result[0]; + var newestPassingRevision = result[1]; equals(oldestFailingRevision, 0); equals(newestPassingRevision, 0); - }); + }).then(start); }); }); @@ -455,21 +437,19 @@ test("failureTypeToExtensionList", 5, function() { deepEqual(results.failureTypeToExtensionList('TIMEOUT'), []); }); -test("fetchResultsURLs", 5, function() { +asyncTest("fetchResultsURLs", 5, function() { var simulator = new NetworkSimulator(); var probedURLs = []; - simulator.probe = function(url, options) + simulator.probe = function(url) { - simulator.scheduleCallback(function() { - probedURLs.push(url); - if (base.endsWith(url, '.txt')) - options.success.call(); - else if (/taco.+png$/.test(url)) - options.success.call(); - else - options.error.call(); - }); + probedURLs.push(url); + if (base.endsWith(url, '.txt')) + return Promise.resolve(); + else if (/taco.+png$/.test(url)) + return Promise.resolve(); + else + return Promise.reject(); }; simulator.runTest(function() { @@ -477,7 +457,7 @@ test("fetchResultsURLs", 5, function() { 'builderName': "Mock Builder", 'testName': "userscripts/another-test.html", 'failureTypeList': ['IMAGE', 'CRASH'], - }, function(resultURLs) { + }).then(function(resultURLs) { deepEqual(resultURLs, [ MockResultsBaseURL + "/userscripts/another-test-crash-log.txt" ]); @@ -486,14 +466,14 @@ test("fetchResultsURLs", 5, function() { 'builderName': "Mock Builder", 'testName': "userscripts/another-test.html", 'failureTypeList': ['TIMEOUT'], - }, function(resultURLs) { + }).then(function(resultURLs) { deepEqual(resultURLs, []); }); results.fetchResultsURLs({ 'builderName': "Mock Builder", 'testName': "userscripts/taco.html", 'failureTypeList': ['IMAGE', 'IMAGE+TEXT'], - }, function(resultURLs) { + }).then(function(resultURLs) { deepEqual(resultURLs, [ MockResultsBaseURL + "/userscripts/taco-expected.png", MockResultsBaseURL + "/userscripts/taco-actual.png", @@ -503,42 +483,41 @@ test("fetchResultsURLs", 5, function() { MockResultsBaseURL + "/userscripts/taco-diff.txt", ]); }); + }).then(function() { + deepEqual(probedURLs, [ + MockResultsBaseURL + "/userscripts/another-test-expected.png", + MockResultsBaseURL + "/userscripts/another-test-actual.png", + MockResultsBaseURL + "/userscripts/another-test-diff.png", + MockResultsBaseURL + "/userscripts/another-test-crash-log.txt", + MockResultsBaseURL + "/userscripts/taco-expected.png", + MockResultsBaseURL + "/userscripts/taco-actual.png", + MockResultsBaseURL + "/userscripts/taco-diff.png", + MockResultsBaseURL + "/userscripts/taco-actual.txt", + MockResultsBaseURL + "/userscripts/taco-expected.txt", + MockResultsBaseURL + "/userscripts/taco-diff.txt", + ]); + start(); }); - - deepEqual(probedURLs, [ - MockResultsBaseURL + "/userscripts/another-test-expected.png", - MockResultsBaseURL + "/userscripts/another-test-actual.png", - MockResultsBaseURL + "/userscripts/another-test-diff.png", - MockResultsBaseURL + "/userscripts/another-test-crash-log.txt", - MockResultsBaseURL + "/userscripts/taco-expected.png", - MockResultsBaseURL + "/userscripts/taco-actual.png", - MockResultsBaseURL + "/userscripts/taco-diff.png", - MockResultsBaseURL + "/userscripts/taco-actual.txt", - MockResultsBaseURL + "/userscripts/taco-expected.txt", - MockResultsBaseURL + "/userscripts/taco-diff.txt", - ]); }); -test("fetchResultsByBuilder", 3, function() { +asyncTest("fetchResultsByBuilder", 3, function() { var simulator = new NetworkSimulator(); var probedURLs = []; - simulator.jsonp = function(url, callback) + simulator.jsonp = function(url) { - simulator.scheduleCallback(function() { - probedURLs.push(url); - callback(base.endsWith(url, 'results/layout-test-results/failing_results.json')); - }); + probedURLs.push(url); + return Promise.resolve(base.endsWith(url, 'results/layout-test-results/failing_results.json')); }; simulator.runTest(function() { - results.fetchResultsByBuilder(['MockBuilder1', 'MockBuilder2'], function(resultsByBuilder) { + results.fetchResultsByBuilder(['MockBuilder1', 'MockBuilder2']).then(function(resultsByBuilder) { deepEqual(resultsByBuilder, { "MockBuilder1": true, "MockBuilder2": true, }); }); - }); + }).then(start); deepEqual(probedURLs, [ MockResultsBaseURL.replace('Mock_Builder', 'MockBuilder1') + "/failing_results.json", diff --git a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/rollbot.js b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/rollbot.js index 7937b7f17f8..bbf9e9272ba 100644 --- a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/rollbot.js +++ b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/rollbot.js @@ -39,7 +39,7 @@ var issueSearchURL = config.kRietveldURL + "/search?" + $.param({ var rollSubjectRegexp = /Blink roll (\d+):(\d+)/; function findRollIssue(results) { - var results = results['results']; + results = results['results']; for (var i = 0; i < results.length; i++) { var result = results[i]; if (result['subject'].match(rollSubjectRegexp)) @@ -53,23 +53,21 @@ function isRollbotStopped(issue) { return issue.messages.slice(1).some(function(message) { return message.text.match(/STOP/); }); } -rollbot.fetchCurrentRoll = function(callback) { - net.get(issueSearchURL, function(searchJSON) { +rollbot.fetchCurrentRoll = function() { + return net.json(issueSearchURL).then(function(searchJSON) { var issue = findRollIssue(searchJSON); - if (!issue) { - callback(null); - return; - } + if (!issue) + return null; var issueNumber = issue['issue']; var subjectMatch = issue['subject'].match(rollSubjectRegexp); - callback({ + return { 'issue': issueNumber, 'url': config.kRietveldURL + "/" + issueNumber, 'isStopped': isRollbotStopped(issue), 'fromRevision': subjectMatch[1], 'toRevision': subjectMatch[2], - }); + }; }); }; diff --git a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/rollbot_unittests.js b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/rollbot_unittests.js index 7ce62fdebb8..34f8a418353 100644 --- a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/rollbot_unittests.js +++ b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/rollbot_unittests.js @@ -154,24 +154,22 @@ var kStoppedIssue = { "issue": 16606004 }; -test("fetchCurrentRoll", 6, function() { +asyncTest("fetchCurrentRoll", 6, function() { var simulator = new NetworkSimulator(); - simulator.get = function(url, callback) + simulator.json = function(url) { - simulator.scheduleCallback(function() { - callback(kSearchResults); - }); + return Promise.resolve(kSearchResults); }; simulator.runTest(function() { - rollbot.fetchCurrentRoll(function(roll) { + rollbot.fetchCurrentRoll().then(function(roll) { equals(roll.issue, 16337011); equals(roll.url, "https://codereview.chromium.org/16337011"); equals(roll.isStopped, false); equals(roll.fromRevision, "151668"); equals(roll.toRevision, "151677"); }); - }); + }).then(start); }); test("_isRollbotStopped", 1, function() { diff --git a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/summary-mock.js b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/summary-mock.js index eb3c2a2a126..2943c7f6b5d 100644 --- a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/summary-mock.js +++ b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/summary-mock.js @@ -96,7 +96,7 @@ var testNames = new Cycler([ 'tables/mozilla/bugs/bug52505.html' ]); -var builders = new Cycler(Object.keys(config.currentBuilders()), 3); +var builders = new Cycler(Object.keys(config.builders), 3); var expectations = new Cycler([ 'TEXT', diff --git a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/svn-log.js b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/svn-log.js index ad65c800322..de903cc6e6f 100644 --- a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/svn-log.js +++ b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/svn-log.js @@ -38,16 +38,26 @@ function findUsingRegExp(string, regexp) function findReviewer(message) { - var regexp = /R=([^.]+)/; - return findUsingRegExp(message, regexp); + var regexp = /(?:^|\n)\s*(?:TB)?R=(.+)/; + var reviewers = findUsingRegExp(message, regexp); + if (!reviewers) + return null; + return reviewers.replace(/\s*,\s*/g, ', '); } function findBugID(message) { - var regexp = /BUG=(\d+)/; - var bugID = parseInt(findUsingRegExp(message, regexp), 10); - return isNaN(bugID) ? 0 : bugID; - + var regexp = /(?:^|\n)\s*BUG=(.+)/; + var value = findUsingRegExp(message, regexp); + if (!value) + return null; + var result = value.split(/\s*,\s*/).map(function(id) { + var parsedID = parseInt(id.replace(/[^\d]/g, ''), 10); + return isNaN(parsedID) ? 0 : parsedID; + }).filter(function(id) { + return !!id; + }); + return result.length ? result : null; } function findRevision(message) @@ -59,7 +69,13 @@ function findRevision(message) function parseCommitMessage(message) { var lines = message.split('\n'); - var title = lines[1]; + var title = ''; + lines.some(function(line) { + if (line) { + title = line; + return true; + } + }); var summary = lines.join('\n').trim(); return { title: title, @@ -67,7 +83,7 @@ function parseCommitMessage(message) { bugID: findBugID(summary), reviewer: findReviewer(summary), revision: findRevision(summary), - } + }; } // FIXME: Consider exposing this method for unit testing. @@ -76,6 +92,8 @@ function parseCommitData(responseXML) var commits = Array.prototype.map.call(responseXML.getElementsByTagName('entry'), function(logentry) { var author = $.trim(logentry.getElementsByTagName('author')[0].textContent); var time = logentry.getElementsByTagName('published')[0].textContent; + var titleElement = logentry.getElementsByTagName('title')[0]; + var title = titleElement ? titleElement.textContent : null; // FIXME: This isn't a very high-fidelity reproduction of the commit message, // but it's good enough for our purposes. @@ -83,7 +101,7 @@ function parseCommitData(responseXML) return { 'revision': message.revision, - 'title': message.title, + 'title': title || message.title, 'time': time, 'summary': message.title, 'author': author, @@ -105,17 +123,11 @@ trac.changesetURL = function(revision) return config.kBlinkRevisionURL + '?' + $.param(queryParameters); }; -trac.recentCommitData = function(path, limit, callback) +trac.recentCommitData = function(path, limit) { - net.get('http://blink.lc/blink/atom', function(commitData) { - callback(parseCommitData(commitData)); + return net.xml('http://blink.lc/blink/atom').then(function(commitData) { + return parseCommitData(commitData); }); }; -trac.commitDataForRevisionRange = function(path, startRevision, endRevision, callback) -{ - var key = [path, startRevision, endRevision].join('\n'); - g_cache.get(key, callback); -}; - })(); diff --git a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/svn-log_unittests.js b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/svn-log_unittests.js index 8992985b59d..bb045f9bf9c 100644 --- a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/svn-log_unittests.js +++ b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/svn-log_unittests.js @@ -81,7 +81,7 @@ var kExampleCommitDataXML = "core/platform may not depend on core/ even for testing.\n" + "\n" + "BUG=301947\n" + - "R=abarth@chromium.org, abarth\n" + + "TBR=abarth@chromium.org, abarth\n" + "\n" + "Review URL: https://codereview.chromium.org/25284004\n" + "\n" + @@ -93,7 +93,7 @@ var kExampleCommitDataXML = "core/platform may not depend on core/ even for testing.\n" + "\n" + "BUG=301947\n" + - "R=abarth@chromium.org, abarth\n" + + "TBR=abarth@chromium.org, abarth\n" + "\n" + "Review URL: https://codereview.chromium.org/25284004\n" + "\n" + @@ -114,7 +114,7 @@ var kExampleCommitDataXML = "<content type='text'>\n" + "These were all failures noticed when running check-blink-deps\n" + "\n" + - "R=abarth@chromium.org, abarth\n" + + "R=abarth@chromium.org,abarth,abarth\n" + "BUG=301947\n" + "\n" + "Review URL: https://codereview.chromium.org/25275005\n" + @@ -126,7 +126,7 @@ var kExampleCommitDataXML = "<pre>\n" + "These were all failures noticed when running check-blink-deps\n" + "\n" + - "R=abarth@chromium.org, abarth\n" + + "R=abarth@chromium.org,abarth,abarth\n" + "BUG=301947\n" + "\n" + "Review URL: https://codereview.chromium.org/25275005\n" + @@ -135,38 +135,123 @@ var kExampleCommitDataXML = "</pre>\n" + "</div>\n" + "</content>\n" + + "<entry>\n" + + "<title>Mark Skia suppressions for rebasline.</title>\n" + + "<updated>2014-02-27T14:44:41Z</updated>\n" + + "<author>\n" + + "<name>fmalita@chromium.org</name>\n" + + "</author>\n" + + "<published>2014-02-27T14:44:41Z</published>\n" + + "<link rel='alternate' type='text/html' href='http://blink.lc/blink/commit/?id=35030357db3c0967974273faf5e65fe3d7cc041b'/>\n" + + "<id>35030357db3c0967974273faf5e65fe3d7cc041b</id>\n" + + "<content type='text'>\n" + + "Unreviewed gardening.\n" + + "Stray R=123 in the middle...\n" + + "\n" + + "BUG=/341448,344497\n" + + "TBR=robertphillips@google.com\n" + + "\n" + + "Review URL: https://codereview.chromium.org/183123002\n" + + "\n" + + "git-svn-id: svn://svn.chromium.org/blink/trunk@168027 bbb929c8-8fbe-4397-9dbb-9b2b20218538\n" + + "</content>\n" + + "<content type='xhtml'>\n" + + "<div xmlns='http://www.w3.org/1999/xhtml'>\n" + + "<pre>\n" + + "Unreviewed gardening.\n" + + "Stray R=123 in the middle...\n" + + "\n" + + "BUG=/341448 , 344497/ \n" + + "TBR=robertphillips@google.com\n" + + "\n" + + "Review URL: https://codereview.chromium.org/183123002\n" + + "\n" + + "git-svn-id: svn://svn.chromium.org/blink/trunk@168027 bbb929c8-8fbe-4397-9dbb-9b2b20218538\n" + + "</pre>\n" + + "</div>\n" + + "</content>\n" + "</entry>\n" + - "</feed>\n"; + "<entry>\n" + + "<title>Remove yurys and loislo from WTF watchlist</title>\n" + + "<updated>2014-03-03T07:23:31Z</updated>\n" + + "<author>\n" + + "<name>yurys@chromium.org</name>\n" + + "</author>\n" + + "<published>2014-03-03T07:23:31Z</published>\n" + + "<link rel='alternate' type='text/html' href='http://blink.lc/blink/commit/?id=43118424ccd1d65ea7ec9ba26c32195e5fdde6e4'/>\n" + + "<id>43118424ccd1d65ea7ec9ba26c32195e5fdde6e4</id>\n" + + "<content type='text'>\n" + + "BUG=None\n" + + "R=loislo@chromium.org\n" + + "\n" + + "Review URL: https://codereview.chromium.org/176883013\n" + + "\n" + + "git-svn-id: svn://svn.chromium.org/blink/trunk@168268 bbb929c8-8fbe-4397-9dbb-9b2b20218538\n" + + "</content>\n" + + "<content type='xhtml'>\n" + + "<div xmlns='http://www.w3.org/1999/xhtml'>\n" + + "<pre>\n" + + "BUG=None\n" + + "R=loislo@chromium.org\n" + + "\n" + + "Review URL: https://codereview.chromium.org/176883013\n" + + "\n" + + "git-svn-id: svn://svn.chromium.org/blink/trunk@168268 bbb929c8-8fbe-4397-9dbb-9b2b20218538\n" + + "</pre>\n" + + "</div>\n" + + "</content>\n" + + "</entry>\n" + + "</feed>\n"; var kExampleCommitDataList = [{ "revision": 158545, - "title": "This matches Gecko's behavior for these types of properties.", + "title": "Throw SecurityError when setting 'Replaceable' properties cross-origin.", "time": "2013-09-30T20:22:01Z", "summary": "This matches Gecko's behavior for these types of properties.", "author": "mkwst@chromium.org", - "reviewer": "jochen@chromium", - "bugID": 17325, + "reviewer": "jochen@chromium.org", + "bugID": [17325], "revertedRevision": undefined }, { "revision": 158544, - "title": "core/platform may not depend on core/ even for testing.", + "title": "Fix one more layering violation caught by check-blink-deps", "time": "2013-09-30T19:36:21Z", "summary": "core/platform may not depend on core/ even for testing.", "author": "eseidel@chromium.org", - "reviewer": "abarth@chromium", - "bugID": 301947, + "reviewer": "abarth@chromium.org, abarth", + "bugID": [301947], "revertedRevision": undefined }, { "revision": 158543, - "title": "These were all failures noticed when running check-blink-deps", + "title": "Update DEPS include_rules after addition of root-level platform directory", "time": "2013-09-30T19:28:49Z", "summary": "These were all failures noticed when running check-blink-deps", "author": "eseidel@chromium.org", - "reviewer": "abarth@chromium", - "bugID": 301947, + "reviewer": "abarth@chromium.org, abarth, abarth", + "bugID": [301947], + "revertedRevision": undefined + }, + { + "revision": 168027, + "title": "Mark Skia suppressions for rebasline.", + "time": "2014-02-27T14:44:41Z", + "summary": "Unreviewed gardening.", + "author": "fmalita@chromium.org", + "reviewer": "robertphillips@google.com", + "bugID": [341448, 344497], + "revertedRevision": undefined + }, + { + "revision": 168268, + "title": "Remove yurys and loislo from WTF watchlist", + "time": "2014-03-03T07:23:31Z", + "summary": "BUG=None", + "author": "yurys@chromium.org", + "reviewer": "loislo@chromium.org", + "bugID": null, "revertedRevision": undefined } ]; @@ -175,27 +260,25 @@ test("changesetURL", 1, function() { equals(trac.changesetURL(1234), "http://src.chromium.org/viewvc/blink?view=rev&revision=1234"); }); -test("recentCommitData", 3, function() { +asyncTest("recentCommitData", 3, function() { var simulator = new NetworkSimulator(); - simulator.get = function(url, callback) + simulator.xml = function(url) { equals(url, 'http://blink.lc/blink/atom'); - simulator.scheduleCallback(function() { - var parser = new DOMParser(); - var responseDOM = parser.parseFromString(kExampleCommitDataXML, "application/xml"); - callback(responseDOM); - }); + var parser = new DOMParser(); + var responseDOM = parser.parseFromString(kExampleCommitDataXML, "application/xml"); + return Promise.resolve(responseDOM); }; simulator.runTest(function() { - trac.recentCommitData('trunk', 10, function(commitDataList) { + return trac.recentCommitData('trunk', 10).then(function(commitDataList) { $.each(commitDataList, function(index, commitData) { // Including the entire message makes the deepEqual below to unwieldy. delete commitData.message; }); deepEqual(commitDataList, kExampleCommitDataList); }); - }); + }).then(start); }); })(); diff --git a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/treestatus.js b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/treestatus.js index 7d6d5ce7500..0b2e00e1ff0 100644 --- a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/treestatus.js +++ b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/treestatus.js @@ -36,7 +36,7 @@ treestatus.urlByName = function(name) { } treestatus.fetchTreeStatus = function(statusURL, resultSpan) { - net.get(statusURL, function(statusJSON) { + return net.json(statusURL).then(function(statusJSON) { if (statusJSON.can_commit_freely) resultSpan.textContent = "OPEN"; else diff --git a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/treestatus_unittests.js b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/treestatus_unittests.js index e9704394569..5c4a7d9824f 100644 --- a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/treestatus_unittests.js +++ b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/treestatus_unittests.js @@ -49,30 +49,33 @@ test('urlByName', 3, function() { equal(treestatus.urlByName('foo'), null); }); -test('fetchTreeStatus', 4, function() { +asyncTest('fetchTreeStatus', 4, function() { var simulator = new NetworkSimulator(); - simulator.get = function(url, callback) + simulator.json = function(url) { - simulator.scheduleCallback(function() { - if (url.indexOf('closed') != -1) - callback(closedTreeJson); - else - callback(openTreeJson); - }); + if (url.indexOf('closed') != -1) + return Promise.resolve(closedTreeJson); + else + return Promise.resolve(openTreeJson); }; var span = document.createElement('span'); simulator.runTest(function() { - treestatus.fetchTreeStatus('http://opentree', span); - }); - equal(span.textContent, 'OPEN'); + treestatus.fetchTreeStatus('http://opentree', span) + .then(function(result) { + equal(span.textContent, 'OPEN'); - var span = document.createElement('span'); - simulator.runTest(function() { - treestatus.fetchTreeStatus('http://closedtree', span); + span = document.createElement('span'); + simulator.runTest(function() { + treestatus.fetchTreeStatus('http://closedtree', span) + .then(function() { + equal(span.textContent, 'Tree is closed by ojan@chromium.org'); + start(); + }); + }); + }); }); - equal(span.textContent, 'Tree is closed by ojan@chromium.org'); }); })(); diff --git a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/ui.js b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/ui.js index 1ed0b4cc494..a6203cf9e46 100644 --- a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/ui.js +++ b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/ui.js @@ -29,11 +29,13 @@ var ui = ui || {}; ui.displayURLForBuilder = function(builderName) { - return config.kPlatforms[config.currentPlatform].waterfallURL + '?' + $.param({ + return config.waterfallURL + '?' + $.param({ 'builder': builderName }); } +ui.kUseNewWindowForLinksSetting = 'gardenomatic.use-new-window-for-links'; + ui.displayNameForBuilder = function(builderName) { return builderName.replace(/Webkit /, ''); @@ -44,6 +46,11 @@ ui.urlForTest = function(testName) return 'http://trac.webkit.org/browser/trunk/LayoutTests/' + testName; } +ui.urlForCrbug = function(bugID) +{ + return 'http://crbug.com/' + bugID; +} + ui.urlForFlakinessDashboard = function(opt_testNameList) { var testsParameter = opt_testNameList ? opt_testNameList.join(',') : ''; @@ -62,6 +69,39 @@ ui.rolloutReasonForTestNameList = function(testNameList) }).join('\n'); } +ui.setTargetForLink = function(anchor) +{ + if (anchor.href.indexOf('#') === 0) + return; + if (ui.useNewWindowForLinks) + anchor.target = '_blank'; + else + anchor.removeAttribute('target'); +} + +ui.setUseNewWindowForLinks = function(enabled) +{ + ui.useNewWindowForLinks = enabled; + if (enabled) + localStorage[ui.kUseNewWindowForLinksSetting] = 'true'; + else + delete localStorage[ui.kUseNewWindowForLinksSetting]; + + $('a').each(function() { + ui.setTargetForLink(this); + }); +} +ui.setUseNewWindowForLinks(!!localStorage[ui.kUseNewWindowForLinksSetting]); + +ui.createLinkNode = function(url, textContent) +{ + var link = document.createElement('a'); + link.href = url; + ui.setTargetForLink(link); + link.appendChild(document.createTextNode(textContent)); + return link; +} + ui.onebar = base.extends('div', { init: function() { @@ -72,6 +112,7 @@ ui.onebar = base.extends('div', { '<li><a href="#expected">Expected Failures</a></li>' + '<li><a href="#results">Results</a></li>' + '</ul>' + + '<div id="link-handling"><input type="checkbox" id="new-window-for-links"><label for="new-window-for-links">Open links in new window</label></div>' + '<div id="unexpected"></div>' + '<div id="expected"></div>' + '<div id="results"></div>'; @@ -85,6 +126,10 @@ ui.onebar = base.extends('div', { this._tabs = $(this).tabs({ disabled: [2], show: function(event, ui) { this._restoreScrollOffset(ui.index); }, + select: function(event, ui) { + this._saveScrollOffset(); + window.location.hash = ui.tab.hash; + }.bind(this) }); }, _saveScrollOffset: function() { @@ -103,15 +148,6 @@ ui.onebar = base.extends('div', { } var self = this; - $('.ui-tabs-nav a').bind('mouseup', function(event) { - var href = event.target.getAttribute('href'); - var hash = currentHash(); - if (href != hash) { - self._saveScrollOffset(); - window.location = href - } - }); - window.onhashchange = function(event) { var tabName = currentHash().substring(1); self._selectInternal(tabName); @@ -124,9 +160,17 @@ ui.onebar = base.extends('div', { self._saveScrollOffset(); }; }, + _setupLinkSettingHandler: function() + { + $('#new-window-for-links').attr('checked', ui.useNewWindowForLinks); + $('#new-window-for-links').change(function(event) { + ui.setUseNewWindowForLinks(this.checked); + }); + }, attach: function() { document.body.insertBefore(this, document.body.firstChild); + this._setupLinkSettingHandler(); this._setupHistoryHandlers(); }, tabNamed: function(tabName) @@ -167,33 +211,6 @@ ui.onebar = base.extends('div', { } }); -// FIXME: Loading a module shouldn't set off a timer. The controller should kick this off. -setInterval(function() { - Array.prototype.forEach.call(document.querySelectorAll("time.relative"), function(time) { - time.update && time.update(); - }); -}, config.kRelativeTimeUpdateFrequency); - -ui.RelativeTime = base.extends('time', { - init: function() - { - this.className = 'relative'; - }, - date: function() - { - return this._date; - }, - update: function() - { - this.textContent = this._date ? base.relativizeTime(this._date) : ''; - }, - setDate: function(date) - { - this._date = date; - this.update(); - } -}); - ui.TreeStatus = base.extends('div', { addStatus: function(name) { @@ -221,6 +238,35 @@ ui.StatusArea = base.extends('div', { return ui.StatusArea._instance; ui.StatusArea._instance = this; + var kMinimumStatusAreaHeightPx = 60; + var dragger = document.createElement('div'); + var initialY; + var initialHeight; + dragger.className = 'dragger'; + $(dragger).mousedown(function(e) { + initialY = e.pageY; + initialHeight = $(this).height(); + $(document.body).addClass('status-resizing'); + }.bind(this)); + $(document.body).mouseup(function(e) { + initialY = 0; + initialHeight = 0; + $(document.body).removeClass('status-resizing'); + }); + $(document.body).mousemove(function(e) { + if (initialY) { + var newHeight = initialHeight + initialY - e.pageY; + if (newHeight >= kMinimumStatusAreaHeightPx) + $(this).height(newHeight); + e.preventDefault(); + } + }.bind(this)); + this.appendChild(dragger); + + this.contents = document.createElement('div'); + this.contents.className = 'contents'; + this.appendChild(this.contents); + this.className = 'status'; document.body.appendChild(this); this._currentId = 0; @@ -254,7 +300,7 @@ ui.StatusArea = base.extends('div', { content = document.createElement('div'); content.id = id; content.className = 'status-content'; - this.appendChild(content); + this.contents.appendChild(content); } content.appendChild(element); @@ -278,6 +324,36 @@ ui.StatusArea = base.extends('div', { }); ui.revisionDetails = base.extends('span', { + // We only support 2 levels of visual escalation levels: warning and critical. + warnRollRevisionSpanThreshold: 45, + criticalRollRevisionSpanThreshold: 80, + classNameForUrgencyLevel: function(rollRevisionSpan) { + if (rollRevisionSpan < this.criticalRollRevisionSpanThreshold) + return "warning"; + return "critical"; + }, + updateUI: function(totRevision) { + this.appendChild(document.createElement("br")); + this.appendChild(document.createTextNode('Last roll is to ')); + this.appendChild(ui.createLinkNode(trac.changesetURL(this.lastRolledRevision), this.lastRolledRevision)); + var rollRevisionSpan = totRevision - this.lastRolledRevision; + // Don't clutter the UI if we haven't run behind. + if (rollRevisionSpan > this.warnRollRevisionSpanThreshold) { + var wrapper = document.createElement("span"); + wrapper.className = this.classNameForUrgencyLevel(rollRevisionSpan); + wrapper.appendChild(document.createTextNode("(" + rollRevisionSpan + " revisions behind)")); + this.appendChild(wrapper); + } + this.appendChild(document.createTextNode(', current autoroll ')); + if (this.roll) { + var linkText = "" + this.roll.fromRevision + ":" + this.roll.toRevision; + this.appendChild(ui.createLinkNode(this.roll.url, linkText)); + if (this.roll.isStopped) + this.appendChild(document.createTextNode(' (STOPPED) ')); + } else { + this.appendChild(document.createTextNode(' None')); + } + }, init: function() { var theSpan = this; theSpan.appendChild(document.createTextNode('Latest revision processed by every bot: ')); @@ -287,10 +363,10 @@ ui.revisionDetails = base.extends('span', { // Get the list of builders sorted with the most recent one first. var builders = Object.keys(latestRevisions); - builders.sort(function (a, b) { return parseInt(latestRevisions[b]) - parseInt(latestRevisions[a])}); + builders.sort(function (a, b) { return parseInt(latestRevisions[b]) - parseInt(latestRevisions[a]);}); var summaryNode = document.createElement('summary'); - var summaryLinkNode = base.createLinkNode(trac.changesetURL(latestRevision), latestRevision); + var summaryLinkNode = ui.createLinkNode(trac.changesetURL(latestRevision), latestRevision); summaryNode.appendChild(summaryLinkNode); var revisionsTableNode = document.createElement('table'); @@ -298,14 +374,14 @@ ui.revisionDetails = base.extends('span', { var trNode = document.createElement('tr'); var tdNode = document.createElement('td'); - tdNode.appendChild(base.createLinkNode(ui.displayURLForBuilder(builderName), builderName.replace('WebKit ', ''))); + tdNode.appendChild(ui.createLinkNode(ui.displayURLForBuilder(builderName), builderName.replace('WebKit ', ''))); trNode.appendChild(tdNode); var tdNode = document.createElement('td'); tdNode.appendChild(document.createTextNode(latestRevisions[builderName])); - trNode.appendChild(tdNode) + trNode.appendChild(tdNode); - revisionsTableNode.appendChild(trNode) + revisionsTableNode.appendChild(trNode); }); var revisionsNode = document.createElement('details'); @@ -321,7 +397,7 @@ ui.revisionDetails = base.extends('span', { var tPosX = $(summaryNode).position().left; var tPosY = $(summaryNode).position().top + 16; $(revisionsPopUp).css({'position': 'absolute', 'top': tPosY, 'left': tPosX}); - $(revisionsPopUp).addClass('active') + $(revisionsPopUp).addClass('active'); } }); $(summaryLinkNode).mouseout(function(ev) { @@ -332,23 +408,12 @@ ui.revisionDetails = base.extends('span', { var totRevision = model.latestRevision(); theSpan.appendChild(document.createTextNode(', trunk is at ')); - theSpan.appendChild(base.createLinkNode(trac.changesetURL(totRevision), totRevision)); - - checkout.lastBlinkRollRevision(function(revision) { - theSpan.appendChild(document.createTextNode(', last roll is to ')); - theSpan.appendChild(base.createLinkNode(trac.changesetURL(revision), revision)); - }, function() {}); - - rollbot.fetchCurrentRoll(function(roll) { - theSpan.appendChild(document.createTextNode(', current autoroll ')); - if (roll) { - var linkText = "" + roll.fromRevision + ":" + roll.toRevision; - theSpan.appendChild(base.createLinkNode(roll.url, linkText)); - if (roll.isStopped) - theSpan.appendChild(document.createTextNode(' (STOPPED) ')); - } else { - theSpan.appendChild(document.createTextNode(' None')); - } + theSpan.appendChild(ui.createLinkNode(trac.changesetURL(totRevision), totRevision)); + + Promise.all([checkout.lastBlinkRollRevision(), rollbot.fetchCurrentRoll()]).then(function(results) { + theSpan.lastRolledRevision = results[0]; + theSpan.roll = results[1]; + theSpan.updateUI(totRevision); }); } }); diff --git a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/ui/failures.js b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/ui/failures.js index b4948b28c37..fbdb5a64274 100644 --- a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/ui/failures.js +++ b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/ui/failures.js @@ -33,8 +33,7 @@ var kBuildingResult = 'BUILDING'; ui.failures.Builder = base.extends('a', { init: function(builderName, failures) { - var platformBuilders = config.currentBuilders(); - var configuration = platformBuilders[builderName]; + var configuration = config.builders[builderName]; if (configuration) { if (configuration.version) this._addSpan('version', configuration.version); @@ -45,8 +44,8 @@ ui.failures.Builder = base.extends('a', { this._addSpan('version', builderName); this.className = 'failing-builder'; - this.target = '_blank'; this.href = ui.displayURLForBuilder(builderName); + ui.setTargetForLink(this); if (failures) this._addSpan('failures', ' ' + failures.join(', ')); }, @@ -58,7 +57,7 @@ ui.failures.Builder = base.extends('a', { }, equals: function(configuration) { - return this._configuration && this._configuration.is64bit == configuration.is64bit && this._configuration.version == configuration.version; + return this._configuration && this._configuration.is64bit == configuration.is64bit && this._configuration.version == configuration.version; } }); @@ -79,9 +78,9 @@ ui.failures.FailureGrid = base.extends('table', { { this.className = 'failures'; var titles = this.createTHead().insertRow(); - titles.insertCell().textContent = 'debug'; - titles.insertCell().textContent = 'release'; titles.insertCell().textContent = 'type'; + titles.insertCell().textContent = 'release'; + titles.insertCell().textContent = 'debug'; this._body = this.appendChild(document.createElement('tbody')); this._reset(); }, @@ -94,10 +93,10 @@ ui.failures.FailureGrid = base.extends('table', { row = this._resultRows[result] = this._body.insertRow(0); row.className = result; - row.insertCell(); - row.insertCell(); var titleCell = row.insertCell(); titleCell.appendChild(document.createElement('span')).textContent = result; + row.insertCell(); + row.insertCell(); return row; }, update: function(resultsByBuilder) @@ -109,7 +108,7 @@ ui.failures.FailureGrid = base.extends('table', { return; Object.keys(resultsByBuilder).forEach(function(builderName) { - var configuration = config.kPlatforms[config.currentPlatform].builders[builderName]; + var configuration = config.builders[builderName]; if (!configuration) throw "Unknown builder name: " + builderName; var row = this._rowByResult(resultsByBuilder[builderName].actual); diff --git a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/ui/failures_unittests.js b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/ui/failures_unittests.js index 1bfbb5c40f5..62b638baf53 100644 --- a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/ui/failures_unittests.js +++ b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/ui/failures_unittests.js @@ -35,11 +35,11 @@ test('Builder', 6, function() { 'equals', 'init', ]); - equal(configuration.outerHTML, '<a class="failing-builder" target="_blank" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+Linux"><span class="version">lucid</span><span class="architecture">64-bit</span><span class="failures"> update, webkit_tests</span></a>'); + equal(configuration.outerHTML, '<a class="failing-builder" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+Linux"><span class="version">lucid</span><span class="architecture">64-bit</span><span class="failures"> update, webkit_tests</span></a>'); configuration = new ui.failures.Builder("WebKit XP"); - equal(configuration.outerHTML, '<a class="failing-builder" target="_blank" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+XP"><span class="version">xp</span></a>'); + equal(configuration.outerHTML, '<a class="failing-builder" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+XP"><span class="version">xp</span></a>'); configuration._addSpan('foo', 'bar'); - equal(configuration.outerHTML, '<a class="failing-builder" target="_blank" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+XP"><span class="version">xp</span><span class="foo">bar</span></a>'); + equal(configuration.outerHTML, '<a class="failing-builder" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+XP"><span class="version">xp</span><span class="foo">bar</span></a>'); ok(configuration.equals({version: 'xp'})); ok(!configuration.equals({version: 'lucid', is64bit: true})); }); @@ -88,7 +88,7 @@ test('FailureGrid', 10, function() { '<tr class="TEXT">' + '<td><span>TEXT</span></td>' + '<td></td>' + - '<td><a class="failing-builder" target="_blank" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+Linux+(dbg)"><span class="version">lucid</span><span class="architecture">64-bit</span></a></td>' + + '<td><a class="failing-builder" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+Linux+(dbg)"><span class="version">lucid</span><span class="architecture">64-bit</span></a></td>' + '</tr>' + '<tr class="BUILDING" style="display: none;"><td><span>BUILDING</span></td><td></td><td></td></tr>' + '</tbody>' + @@ -99,13 +99,13 @@ test('FailureGrid', 10, function() { '<tbody>' + '<tr class="IMAGE+TEXT">' + '<td><span>IMAGE+TEXT</span></td>' + - '<td><a class="failing-builder" target="_blank" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+Mac10.6"><span class="version">snowleopard</span></a></td>' + + '<td><a class="failing-builder" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+Mac10.6"><span class="version">snowleopard</span></a></td>' + '<td></td>' + '</tr>' + '<tr class="TEXT">' + '<td><span>TEXT</span></td>' + '<td></td>' + - '<td><a class="failing-builder" target="_blank" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+Linux+(dbg)"><span class="version">lucid</span><span class="architecture">64-bit</span></a></td>' + + '<td><a class="failing-builder" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+Linux+(dbg)"><span class="version">lucid</span><span class="architecture">64-bit</span></a></td>' + '</tr>' + '<tr class="BUILDING" style="display: none;"><td><span>BUILDING</span></td><td></td><td></td></tr>' + '</tbody>' + @@ -116,13 +116,13 @@ test('FailureGrid', 10, function() { '<tbody>' + '<tr class="IMAGE+TEXT">' + '<td><span>IMAGE+TEXT</span></td>' + - '<td><a class="failing-builder" target="_blank" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+Mac10.6"><span class="version">snowleopard</span></a></td>' + + '<td><a class="failing-builder" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+Mac10.6"><span class="version">snowleopard</span></a></td>' + '<td></td>' + '</tr>' + '<tr class="TEXT">' + '<td><span>TEXT</span></td>' + '<td></td>' + - '<td><a class="failing-builder" target="_blank" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+Linux+(dbg)"><span class="version">lucid</span><span class="architecture">64-bit</span></a></td>' + + '<td><a class="failing-builder" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+Linux+(dbg)"><span class="version">lucid</span><span class="architecture">64-bit</span></a></td>' + '</tr>' + '<tr class="BUILDING" style="display: none;"><td><span>BUILDING</span></td><td></td><td></td></tr>' + '</tbody>' + @@ -135,7 +135,7 @@ test('FailureGrid', 10, function() { '<tr class="TEXT">' + '<td><span>TEXT</span></td>' + '<td></td>' + - '<td><a class="failing-builder" target="_blank" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+Linux+(dbg)"><span class="version">lucid</span><span class="architecture">64-bit</span></a></td>' + + '<td><a class="failing-builder" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+Linux+(dbg)"><span class="version">lucid</span><span class="architecture">64-bit</span></a></td>' + '</tr>' + '<tr class="BUILDING" style="display: none;"><td><span>BUILDING</span></td><td></td><td></td></tr>' + '</tbody>' + diff --git a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/ui/notifications.js b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/ui/notifications.js index 40d2539c8bc..459a87d033c 100644 --- a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/ui/notifications.js +++ b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/ui/notifications.js @@ -37,14 +37,7 @@ ui.notifications.Stream = base.extends('ol', { }, add: function(notification) { - var insertBefore = null; - Array.prototype.some.call(this.children, function(existingNotification) { - if (existingNotification.index() < notification.index()) { - insertBefore = existingNotification; - return true; - } - }); - this.insertBefore(notification, insertBefore); + this.appendChild(notification); return notification; } }); @@ -59,14 +52,6 @@ ui.notifications.Notification = base.extends('li', { this._index = 0; $(this).hide().fadeIn('fast'); }, - index: function() - { - return this._index; - }, - setIndex: function(index) - { - this._index = index; - }, dismiss: function() { // FIXME: These fade in/out effects are lame. @@ -96,7 +81,7 @@ ui.notifications.Info = base.extends(ui.notifications.Notification, { ui.notifications.FailingTestGroup = base.extends('li', { init: function(groupName, testNameList) { - this.appendChild(base.createLinkNode(ui.urlForFlakinessDashboard(testNameList), groupName, '_blank')); + this.appendChild(ui.createLinkNode(ui.urlForFlakinessDashboard(testNameList), groupName)); } }); @@ -112,13 +97,17 @@ ui.notifications.SuspiciousCommit = base.extends(Cause, { init: function(commitData) { this._revision = commitData.revision; - this._description.appendChild(base.createLinkNode(trac.changesetURL(commitData.revision), commitData.revision, '_blank')); + this._description.appendChild(ui.createLinkNode(trac.changesetURL(commitData.revision), commitData.revision)); this._details = this._description.appendChild(document.createElement('span')); - this._addDetail('summary', commitData); + this._addDetail('title', commitData); this._addDetail('author', commitData); this._addDetail('reviewer', commitData); - // FIXME: Add bugID detail. - // this._addDetail('bugID', commitData, bugzilla.bugURL); + this._addDetail('bugID', commitData, + ui.urlForCrbug, + function(value) { + return value.split(/\s*,\s*/); + } + ); }, hasRevision: function(revision) { @@ -132,19 +121,25 @@ ui.notifications.SuspiciousCommit = base.extends(Cause, { var span = this._details.appendChild(document.createElement('span')); span.className = part; - + if (linkFunction) { - var link = base.createLinkNode(linkFunction(content), content, '_blank'); - span.appendChild(link); - } else + var parts = $.isArray(content) ? content : [content]; + parts.forEach(function(item, index) { + if (index > 0) + span.appendChild(document.createTextNode(', ')); + var link = ui.createLinkNode(linkFunction(item), item); + link.className = part + '-item'; + span.appendChild(link); + }); + } else { span.textContent = content; + } } }); ui.notifications.Failure = base.extends(ui.notifications.Notification, { init: function() { - this._time = this._how.appendChild(new ui.RelativeTime()); this._problem = this._what.appendChild(document.createElement('div')); this._problem.className = 'problem'; this._effects = this._problem.appendChild(document.createElement('ul')); @@ -152,10 +147,6 @@ ui.notifications.Failure = base.extends(ui.notifications.Notification, { this._causes = this._what.appendChild(document.createElement('ul')); this._causes.className = 'causes'; }, - date: function() - { - return this._time.date; - } }); ui.notifications.FailingTests = base.extends(ui.notifications.Failure, { @@ -235,11 +226,6 @@ ui.notifications.FailingTestsSummary = base.extends(ui.notifications.FailingTest { if (this._commitDataPinned) return null; - var commitDataDate = new Date(commitData.time); - if (this._time.date > commitDataDate); { - this.setIndex(commitDataDate.getTime()); - this._time.setDate(commitDataDate); - } return this._causes.appendChild(new ui.notifications.SuspiciousCommit(commitData)); } }); diff --git a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/ui/notifications_unittests.js b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/ui/notifications_unittests.js index 18934cca3d4..b14917d8991 100644 --- a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/ui/notifications_unittests.js +++ b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/ui/notifications_unittests.js @@ -27,46 +27,28 @@ module('ui.notifications'); -test('Notification', 5, function() { +test('Notification', 3, function() { var notification = new ui.notifications.Notification(); equal(notification.tagName, 'LI'); equal(notification.innerHTML, '<div class="how"></div><div class="what"></div>'); - equal(notification.index(), 0); - notification.setIndex(1); - equal(notification.index(), 1); // FIXME: Really need to figure out how to mock/test animated removal. ok(notification.dismiss); }); -test('Stream', 11, function() { +test('Stream', 7, function() { var stream = new ui.notifications.Stream(); equal(stream.tagName, 'OL'); equal(stream.className, 'notifications'); equal(stream.childElementCount, 0); - var notification; - - notification = new ui.notifications.Info('-o-matic'); - notification.setIndex(2); + var notification = new ui.notifications.Info('garden-o-matic is '); stream.add(notification); equal(stream.childElementCount, 1); - equal(stream.textContent, '-o-matic'); - - notification = new ui.notifications.Info('garden'); - notification.setIndex(3); - stream.add(notification); - equal(stream.childElementCount, 2); - equal(stream.textContent, 'garden-o-matic'); - - notification = new ui.notifications.Info(' is '); - notification.setIndex(1); - stream.add(notification); - equal(stream.childElementCount, 3); equal(stream.textContent, 'garden-o-matic is '); notification = new ui.notifications.Info('awesome!'); stream.add(notification); - equal(stream.childElementCount, 4); + equal(stream.childElementCount, 2); equal(stream.textContent, 'garden-o-matic is awesome!'); }); @@ -79,29 +61,28 @@ test('Info', 2, function() { test('FailingTestGroup', 2, function() { var failingTest = new ui.notifications.FailingTestGroup('test', ['test.html']); equal(failingTest.tagName, 'LI'); - equal(failingTest.innerHTML, '<a href="http://test-results.appspot.com/dashboards/flakiness_dashboard.html#tests=test.html" target="_blank">test</a>'); + equal(failingTest.innerHTML, '<a href="http://test-results.appspot.com/dashboards/flakiness_dashboard.html#tests=test.html">test</a>'); }); test('SuspiciousCommit', 2, function() { - var suspiciousCommit = new ui.notifications.SuspiciousCommit({revision: 1, summary: "summary", author: "author", reviewer: "reviewer"}); + var suspiciousCommit = new ui.notifications.SuspiciousCommit({revision: 1, title: "title", author: "author", reviewer: "reviewer"}); equal(suspiciousCommit.tagName, 'LI'); equal(suspiciousCommit.innerHTML, '<div class="description">' + - '<a href="http://src.chromium.org/viewvc/blink?view=rev&revision=1" target="_blank">1</a>' + + '<a href="http://src.chromium.org/viewvc/blink?view=rev&revision=1">1</a>' + '<span>' + - '<span class="summary">summary</span>' + + '<span class="title">title</span>' + '<span class="author">author</span>' + '<span class="reviewer">reviewer</span>' + '</span>' + '</div>'); }); -test('FailingTestsSummary', 12, function() { +test('FailingTestsSummary', 10, function() { var testFailures = new ui.notifications.FailingTestsSummary(); equal(testFailures.tagName, 'LI'); equal(testFailures.innerHTML, '<div class="how">' + - '<time class="relative"></time>' + '<table class="failures">' + '<thead><tr><td>type</td><td>release</td><td>debug</td></tr></thead>' + '<tbody><tr class="BUILDING" style="display: none;"><td><span>BUILDING</span></td><td></td><td></td></tr></tbody>' + @@ -118,10 +99,8 @@ test('FailingTestsSummary', 12, function() { '<ul class="causes"></ul>' + '</div>'); testFailures.addFailureAnalysis({testName: 'test', resultNodesByBuilder: {}}); - equal(testFailures.index(), 0); equal(testFailures.innerHTML, '<div class="how">' + - '<time class="relative"></time>' + '<table class="failures">' + '<thead><tr><td>type</td><td>release</td><td>debug</td></tr></thead>' + '<tbody><tr class="BUILDING" style="display: none;"><td><span>BUILDING</span></td><td></td><td></td></tr></tbody>' + @@ -130,7 +109,7 @@ test('FailingTestsSummary', 12, function() { '<div class="what">' + '<div class="problem">' + '<ul class="effects">' + - '<li><a href="http://test-results.appspot.com/dashboards/flakiness_dashboard.html#tests=test" target="_blank">test</a></li>' + + '<li><a href="http://test-results.appspot.com/dashboards/flakiness_dashboard.html#tests=test">test</a></li>' + '</ul>' + '<ul class="actions">' + '<li><button class="action default" title="Examine these failures in detail.">Examine</button></li>' + @@ -144,7 +123,6 @@ test('FailingTestsSummary', 12, function() { testFailures.addFailureAnalysis({testName: 'test'}); equal(testFailures.innerHTML, '<div class="how">' + - '<time class="relative"></time>' + '<table class="failures">' + '<thead><tr><td>type</td><td>release</td><td>debug</td></tr></thead>' + '<tbody><tr class="BUILDING" style="display: none;"><td><span>BUILDING</span></td><td></td><td></td></tr></tbody>' + @@ -153,7 +131,7 @@ test('FailingTestsSummary', 12, function() { '<div class="what">' + '<div class="problem">' + '<ul class="effects">' + - '<li><a href="http://test-results.appspot.com/dashboards/flakiness_dashboard.html#tests=test" target="_blank">test</a></li>' + + '<li><a href="http://test-results.appspot.com/dashboards/flakiness_dashboard.html#tests=test">test</a></li>' + '</ul>' + '<ul class="actions">' + '<li><button class="action default" title="Examine these failures in detail.">Examine</button></li>' + @@ -165,11 +143,9 @@ test('FailingTestsSummary', 12, function() { deepEqual(testFailures.testNameList(), ['test']); var time = new Date(); time.setMinutes(time.getMinutes() - 10); - testFailures.addCommitData({revision: 1, time: time, summary: "summary", author: "author", reviewer: "reviewer"}); - equal(testFailures.index(), time.getTime()); + testFailures.addCommitData({revision: 1, time: time, title: "title", author: "author", reviewer: "reviewer"}); equal(testFailures.innerHTML, '<div class="how">' + - '<time class="relative">10 minutes ago</time>' + '<table class="failures">' + '<thead><tr><td>type</td><td>release</td><td>debug</td></tr></thead>' + '<tbody><tr class="BUILDING" style="display: none;"><td><span>BUILDING</span></td><td></td><td></td></tr></tbody>' + @@ -178,7 +154,7 @@ test('FailingTestsSummary', 12, function() { '<div class="what">' + '<div class="problem">' + '<ul class="effects">' + - '<li><a href="http://test-results.appspot.com/dashboards/flakiness_dashboard.html#tests=test" target="_blank">test</a></li>' + + '<li><a href="http://test-results.appspot.com/dashboards/flakiness_dashboard.html#tests=test">test</a></li>' + '</ul>' + '<ul class="actions">' + '<li><button class="action default" title="Examine these failures in detail.">Examine</button></li>' + @@ -188,9 +164,9 @@ test('FailingTestsSummary', 12, function() { '<ul class="causes">' + '<li>' + '<div class="description">' + - '<a href="http://src.chromium.org/viewvc/blink?view=rev&revision=1" target="_blank">1</a>' + + '<a href="http://src.chromium.org/viewvc/blink?view=rev&revision=1">1</a>' + '<span>' + - '<span class="summary">summary</span>' + + '<span class="title">title</span>' + '<span class="author">author</span>' + '<span class="reviewer">reviewer</span>' + '</span>' + @@ -202,14 +178,13 @@ test('FailingTestsSummary', 12, function() { testFailures.addFailureAnalysis({testName: 'foo', resultNodesByBuilder: {'WebKit Linux (dbg)': { actual: 'TEXT'}}}); equal(testFailures.innerHTML, '<div class="how">' + - '<time class="relative">10 minutes ago</time>' + '<table class="failures">' + '<thead><tr><td>type</td><td>release</td><td>debug</td></tr></thead>' + '<tbody>' + '<tr class="TEXT">' + '<td><span>TEXT</span></td>' + '<td></td>' + - '<td><a class="failing-builder" target="_blank" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+Linux+(dbg)"><span class="version">lucid</span><span class="architecture">64-bit</span></a></td>' + + '<td><a class="failing-builder" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+Linux+(dbg)"><span class="version">lucid</span><span class="architecture">64-bit</span></a></td>' + '</tr>' + '<tr class="BUILDING" style="display: none;"><td><span>BUILDING</span></td><td></td><td></td></tr>' + '</tbody>' + @@ -218,8 +193,8 @@ test('FailingTestsSummary', 12, function() { '<div class="what">' + '<div class="problem">' + '<ul class="effects">' + - '<li><a href="http://test-results.appspot.com/dashboards/flakiness_dashboard.html#tests=foo" target="_blank">foo</a></li>' + - '<li><a href="http://test-results.appspot.com/dashboards/flakiness_dashboard.html#tests=test" target="_blank">test</a></li>' + + '<li><a href="http://test-results.appspot.com/dashboards/flakiness_dashboard.html#tests=foo">foo</a></li>' + + '<li><a href="http://test-results.appspot.com/dashboards/flakiness_dashboard.html#tests=test">test</a></li>' + '</ul>' + '<ul class="actions">' + '<li><button class="action default" title="Examine these failures in detail.">Examine</button></li>' + @@ -229,9 +204,9 @@ test('FailingTestsSummary', 12, function() { '<ul class="causes">' + '<li>' + '<div class="description">' + - '<a href="http://src.chromium.org/viewvc/blink?view=rev&revision=1" target="_blank">1</a>' + + '<a href="http://src.chromium.org/viewvc/blink?view=rev&revision=1">1</a>' + '<span>' + - '<span class="summary">summary</span>' + + '<span class="title">title</span>' + '<span class="author">author</span>' + '<span class="reviewer">reviewer</span>' + '</span>' + @@ -243,18 +218,17 @@ test('FailingTestsSummary', 12, function() { testFailures.updateBuilderResults({'WebKit Mac10.6': { actual: 'BUILDING'}}); equal(testFailures.innerHTML, '<div class="how">' + - '<time class="relative">10 minutes ago</time>' + '<table class="failures">' + '<thead><tr><td>type</td><td>release</td><td>debug</td></tr></thead>' + '<tbody>' + '<tr class="TEXT">' + '<td><span>TEXT</span></td>' + '<td></td>' + - '<td><a class="failing-builder" target="_blank" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+Linux+(dbg)"><span class="version">lucid</span><span class="architecture">64-bit</span></a></td>' + + '<td><a class="failing-builder" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+Linux+(dbg)"><span class="version">lucid</span><span class="architecture">64-bit</span></a></td>' + '</tr>' + '<tr class="BUILDING" style="">' + '<td><span>BUILDING</span></td>' + - '<td><a class="failing-builder" target="_blank" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+Mac10.6"><span class="version">snowleopard</span></a></td>' + + '<td><a class="failing-builder" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+Mac10.6"><span class="version">snowleopard</span></a></td>' + '<td></td>' + '</tr>' + '</tbody>' + @@ -263,8 +237,8 @@ test('FailingTestsSummary', 12, function() { '<div class="what">' + '<div class="problem">' + '<ul class="effects">' + - '<li><a href="http://test-results.appspot.com/dashboards/flakiness_dashboard.html#tests=foo" target="_blank">foo</a></li>' + - '<li><a href="http://test-results.appspot.com/dashboards/flakiness_dashboard.html#tests=test" target="_blank">test</a></li>' + + '<li><a href="http://test-results.appspot.com/dashboards/flakiness_dashboard.html#tests=foo">foo</a></li>' + + '<li><a href="http://test-results.appspot.com/dashboards/flakiness_dashboard.html#tests=test">test</a></li>' + '</ul>' + '<ul class="actions">' + '<li><button class="action default" title="Examine these failures in detail.">Examine</button></li>' + @@ -274,9 +248,9 @@ test('FailingTestsSummary', 12, function() { '<ul class="causes">' + '<li>' + '<div class="description">' + - '<a href="http://src.chromium.org/viewvc/blink?view=rev&revision=1" target="_blank">1</a>' + + '<a href="http://src.chromium.org/viewvc/blink?view=rev&revision=1">1</a>' + '<span>' + - '<span class="summary">summary</span>' + + '<span class="title">title</span>' + '<span class="author">author</span>' + '<span class="reviewer">reviewer</span>' + '</span>' + @@ -295,7 +269,6 @@ test('FailingTestsSummary (grouping)', 1, function() { testFailures.addFailureAnalysis({testName: 'path/another/test.html', resultNodesByBuilder: {}}); equal(testFailures.innerHTML, '<div class="how">' + - '<time class="relative"></time>' + '<table class="failures">' + '<thead><tr><td>type</td><td>release</td><td>debug</td></tr></thead>' + '<tbody><tr class="BUILDING" style="display: none;"><td><span>BUILDING</span></td><td></td><td></td></tr></tbody>' + @@ -304,8 +277,8 @@ test('FailingTestsSummary (grouping)', 1, function() { '<div class="what">' + '<div class="problem">' + '<ul class="effects">' + - '<li><a href="http://test-results.appspot.com/dashboards/flakiness_dashboard.html#tests=path%2Fto%2Ftest1.html%2Cpath%2Fto%2Ftest2.html%2Cpath%2Fto%2Ftest3.html%2Cpath%2Fto%2Ftest4.html" target="_blank">path/to (4 tests)</a></li>' + - '<li><a href="http://test-results.appspot.com/dashboards/flakiness_dashboard.html#tests=path%2Fanother%2Ftest.html" target="_blank">path/another/test.html</a></li>' + + '<li><a href="http://test-results.appspot.com/dashboards/flakiness_dashboard.html#tests=path%2Fto%2Ftest1.html%2Cpath%2Fto%2Ftest2.html%2Cpath%2Fto%2Ftest3.html%2Cpath%2Fto%2Ftest4.html">path/to (4 tests)</a></li>' + + '<li><a href="http://test-results.appspot.com/dashboards/flakiness_dashboard.html#tests=path%2Fanother%2Ftest.html">path/another/test.html</a></li>' + '</ul>' + '<ul class="actions">' + '<li><button class="action default" title="Examine these failures in detail.">Examine</button></li>' + @@ -321,13 +294,12 @@ test('BuildersFailing', 1, function() { builderFailing.setFailingBuilders({'WebKit Linux': ['compile'], 'WebKit Win7': ['webkit_tests', 'update']}); equal(builderFailing.innerHTML, '<div class="how">' + - '<time class="relative"></time>' + '</div>' + '<div class="what">' + '<div class="problem">Disasterifying:' + '<ul class="effects">' + - '<li class="builder"><a class="failing-builder" target="_blank" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+Linux"><span class="version">lucid</span><span class="architecture">64-bit</span><span class="failures"> compile</span></a></li>' + - '<li class="builder"><a class="failing-builder" target="_blank" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+Win7"><span class="version">win7</span><span class="failures"> webkit_tests, update</span></a></li>' + + '<li class="builder"><a class="failing-builder" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+Linux"><span class="version">lucid</span><span class="architecture">64-bit</span><span class="failures"> compile</span></a></li>' + + '<li class="builder"><a class="failing-builder" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+Win7"><span class="version">win7</span><span class="failures"> webkit_tests, update</span></a></li>' + '</ul>' + '</div>' + '<ul class="causes"></ul>' + diff --git a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/ui/results.js b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/ui/results.js index e52d042adaa..4f1cd9eb5af 100644 --- a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/ui/results.js +++ b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/ui/results.js @@ -30,13 +30,13 @@ ui.results = ui.results || {}; var kResultsPrefetchDelayMS = 500; -// FIXME: Rather than using table, should we be using something fancier? -ui.results.Comparison = base.extends('table', { +ui.results.Comparison = base.extends('div', { init: function() { this.className = 'comparison'; - this.innerHTML = '<thead><tr><th>Expected</th><th>Actual</th><th>Diff</th></tr></thead>' + - '<tbody><tr><td class="expected result-container"></td><td class="actual result-container"></td><td class="diff result-container"></td></tr></tbody>'; + this.innerHTML = '<div><h2>Expected</h2><div class="results-container expected"></div></div>' + + '<div><h2>Actual</h2><div class="results-container actual"></div></div>' + + '<div><h2>Diff</h2><div class="results-container diff"></div></div>'; }, _selectorForKind: function(kind) { @@ -149,7 +149,6 @@ ui.results.ResultsGrid = base.extends('div', { } this.addComparison(resultType, resultsURLsByKind); }.bind(this)); - if (!this.children.length) this.textContent = 'No results to display.' } @@ -167,7 +166,7 @@ ui.results.ResultsDetails = base.extends('div', { if (this._haveShownOnce) return; this._haveShownOnce = true; - this._delegate.fetchResultsURLs(this._failureInfo, function(resultsURLs) { + this._delegate.fetchResultsURLs(this._failureInfo).then(function(resultsURLs) { var resultsGrid = new ui.results.ResultsGrid(); resultsGrid.addResults(resultsURLs); @@ -205,7 +204,6 @@ ui.results.FlakinessData = base.extends('iframe', { return; if (event.data.command != 'heightChanged') { - console.log('Unknown postMessage command: ' + event.data); return; } @@ -240,8 +238,8 @@ ui.results.TestSelector = base.extends('div', { var linkTitle = document.createElement('a'); linkTitle.classList.add('link-title'); - linkTitle.setAttribute('href', ui.urlForFlakinessDashboard([testName])) - linkTitle.target = '_blank'; + linkTitle.setAttribute('href', ui.urlForFlakinessDashboard([testName])); + ui.setTargetForLink(linkTitle); linkTitle.textContent = testName; var header = document.createElement('h3'); @@ -252,7 +250,7 @@ ui.results.TestSelector = base.extends('div', { }, this); // If we have a small amount of content, don't show the resize handler. - // Otherwise, set the minHeight so that the percentage height of the + // Otherwise, set the minHeight so that the percentage height of the // topPanel is not too small. if (testNames.length <= 4) this.removeChild(this.querySelector('.resize-handle')); @@ -434,9 +432,9 @@ ui.results.View = base.extends('div', { this._testSelector = new ui.results.TestSelector(this, resultsByTest); this.appendChild(this._testSelector); }, - fetchResultsURLs: function(failureInfo, callback) + fetchResultsURLs: function(failureInfo) { - this._delegate.fetchResultsURLs(failureInfo, callback) + return this._delegate.fetchResultsURLs(failureInfo); }, nextResult: function() { diff --git a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/ui/results_unittests.js b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/ui/results_unittests.js index 4dd546f33a5..66ef774084f 100644 --- a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/ui/results_unittests.js +++ b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/ui/results_unittests.js @@ -124,7 +124,7 @@ var kExampleGreaterThanFourResultsByTest = { test('View', 18, function() { var delegate = { - fetchResultsURLs: function(failureInfo, callback) { return; } + fetchResultsURLs: function(failureInfo) { return Promise.resolve(); } }; var view = new ui.results.View(delegate); @@ -166,7 +166,7 @@ test('View', 18, function() { test('View with more than four tests', 2, function() { var delegate = { - fetchResultsURLs: function(failureInfo, callback) { return; } + fetchResultsURLs: function(failureInfo) { return Promise.resolve(); } }; var view = new ui.results.View(delegate); @@ -181,7 +181,7 @@ test('View with more than four tests', 2, function() { test('View with reftests', 2, function() { var delegate = { - fetchResultsURLs: function(failureInfo, callback) { return; } + fetchResultsURLs: function(failureInfo) { return Promise.resolve(); } }; var view = new ui.results.View(delegate); @@ -192,16 +192,19 @@ test('View with reftests', 2, function() { equals($('.action', view).length, 0); }); -test('View of timeouts', 1, function() { +asyncTest('View of timeouts', 1, function() { + var emptyPromise = Promise.resolve([]); var delegate = { - fetchResultsURLs: function(failureInfo, callback) { callback([]); } + fetchResultsURLs: function(failureInfo) { return emptyPromise; } }; var view = new ui.results.View(delegate); view.setResultsByTest(kExampleResultsWithTimeoutByTest); view.firstResult(); - - equals($('.results-grid', view).html(), 'No results to display.'); + emptyPromise.then(function() { + equals($('.results-grid', view).html(), 'No results to display.'); + start(); + }); }); })(); diff --git a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/ui_unittests.js b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/ui_unittests.js index b7bcdc1b45d..3e785d2c8fc 100644 --- a/chromium/third_party/WebKit/Tools/GardeningServer/scripts/ui_unittests.js +++ b/chromium/third_party/WebKit/Tools/GardeningServer/scripts/ui_unittests.js @@ -59,6 +59,7 @@ test("ui.onebar", 3, function() { '<li class="ui-state-default ui-corner-top"><a href="#expected">Expected Failures</a></li>' + '<li class="ui-state-default ui-corner-top ui-state-disabled"><a href="#results">Results</a></li>' + '</ul>' + + '<div id="link-handling"><input type="checkbox" id="new-window-for-links"><label for="new-window-for-links">Open links in new window</label></div>' + '<div id="unexpected" class="ui-tabs-panel ui-widget-content ui-corner-bottom"></div>' + '<div id="expected" class="ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide"></div>' + '<div id="results" class="ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide"></div>'); @@ -71,6 +72,7 @@ test("ui.onebar", 3, function() { $(onebar).detach(); }); +// FIXME: These three results.* tests should be moved ot ui/results_unittests.js. test("results.ResultsGrid", 1, function() { var grid = new ui.results.ResultsGrid() grid.addResults([ @@ -80,38 +82,42 @@ test("results.ResultsGrid", 1, function() { 'http://example.com/layout-test-results/foo-bar-diff.png', ]); equal(grid.innerHTML, - '<table class="comparison">' + - '<thead>' + - '<tr>' + - '<th>Expected</th>' + - '<th>Actual</th>' + - '<th>Diff</th>' + - '</tr>' + - '</thead>' + - '<tbody>' + - '<tr>' + - '<td class="expected result-container"><img class="image-result" src="http://example.com/layout-test-results/foo-bar-expected.png"></td>' + - '<td class="actual result-container"><img class="image-result" src="http://example.com/layout-test-results/foo-bar-actual.png"></td>' + - '<td class="diff result-container"><img class="image-result" src="http://example.com/layout-test-results/foo-bar-diff.png"></td>' + - '</tr>' + - '</tbody>' + - '</table>' + - '<table class="comparison">' + - '<thead>' + - '<tr>' + - '<th>Expected</th>' + - '<th>Actual</th>' + - '<th>Diff</th>' + - '</tr>' + - '</thead>' + - '<tbody>' + - '<tr>' + - '<td class="expected result-container"></td>' + - '<td class="actual result-container"></td>' + - '<td class="diff result-container"><iframe class="text-result" src="http://example.com/layout-test-results/foo-bar-diff.txt"></iframe></td>' + - '</tr>' + - '</tbody>' + - '</table>'); + '<div class="comparison">' + + '<div>' + + '<h2>Expected</h2>' + + '<div class="results-container expected">' + + '<img class="image-result" src="http://example.com/layout-test-results/foo-bar-expected.png">' + + '</div>' + + '</div>' + + '<div>' + + '<h2>Actual</h2>' + + '<div class="results-container actual">' + + '<img class="image-result" src="http://example.com/layout-test-results/foo-bar-actual.png">' + + '</div>' + + '</div>' + + '<div>' + + '<h2>Diff</h2>' + + '<div class="results-container diff">' + + '<img class="image-result" src="http://example.com/layout-test-results/foo-bar-diff.png">' + + '</div>' + + '</div>' + + '</div>' + + '<div class="comparison">' + + '<div>' + + '<h2>Expected</h2>' + + '<div class="results-container expected"></div>' + + '</div>' + + '<div>' + + '<h2>Actual</h2>' + + '<div class="results-container actual"></div>' + + '</div>' + + '<div>' + + '<h2>Diff</h2>' + + '<div class="results-container diff">' + + '<iframe class="text-result" src="http://example.com/layout-test-results/foo-bar-diff.txt"></iframe>' + + '</div>' + + '</div>' + + '</div>'); }); test("results.ResultsGrid (crashlog)", 1, function() { @@ -126,24 +132,6 @@ test("results.ResultsGrid (empty)", 1, function() { equal(grid.innerHTML, 'No results to display.'); }); -test("time", 6, function() { - var time = new ui.RelativeTime(); - equal(time.tagName, 'TIME'); - equal(time.className, 'relative'); - deepEqual(Object.getOwnPropertyNames(time.__proto__).sort(), [ - 'date', - 'init', - 'setDate', - 'update', - ]); - equal(time.outerHTML, '<time class="relative"></time>'); - var tenMinutesAgo = new Date(); - tenMinutesAgo.setMinutes(tenMinutesAgo.getMinutes() - 10); - time.setDate(tenMinutesAgo); - equal(time.outerHTML, '<time class="relative">10 minutes ago</time>'); - equal(time.date().getTime(), tenMinutesAgo.getTime()); -}); - test("StatusArea", 3, function() { var statusArea = new ui.StatusArea(); var id = statusArea.newId(); @@ -151,12 +139,15 @@ test("StatusArea", 3, function() { statusArea.addMessage(id, 'Second Message'); equal(statusArea.outerHTML, '<div class="status processing" style="visibility: visible;">' + + '<div class="dragger"></div>' + + '<div class="contents">' + + '<div id="status-content-1" class="status-content">' + + '<div class="message">First Message</div>' + + '<div class="message">Second Message</div>' + + '</div>' + + '</div>' + '<ul class="actions"><li><button class="action">Close</button></li></ul>' + '<progress class="process-text">Processing...</progress>' + - '<div id="status-content-1" class="status-content">' + - '<div class="message">First Message</div>' + - '<div class="message">Second Message</div>' + - '</div>' + '</div>'); var secondStatusArea = new ui.StatusArea(); @@ -165,15 +156,18 @@ test("StatusArea", 3, function() { equal(statusArea.outerHTML, '<div class="status processing" style="visibility: visible;">' + + '<div class="dragger"></div>' + + '<div class="contents">' + + '<div id="status-content-1" class="status-content">' + + '<div class="message">First Message</div>' + + '<div class="message">Second Message</div>' + + '</div>' + + '<div id="status-content-2" class="status-content">' + + '<div class="message">First Message second id</div>' + + '</div>' + + '</div>' + '<ul class="actions"><li><button class="action">Close</button></li></ul>' + '<progress class="process-text">Processing...</progress>' + - '<div id="status-content-1" class="status-content">' + - '<div class="message">First Message</div>' + - '<div class="message">Second Message</div>' + - '</div>' + - '<div id="status-content-2" class="status-content">' + - '<div class="message">First Message second id</div>' + - '</div>' + '</div>'); statusArea.addFinalMessage(id, 'Final Message 1'); @@ -181,17 +175,20 @@ test("StatusArea", 3, function() { equal(statusArea.outerHTML, '<div class="status" style="visibility: visible;">' + + '<div class="dragger"></div>' + + '<div class="contents">' + + '<div id="status-content-1" class="status-content">' + + '<div class="message">First Message</div>' + + '<div class="message">Second Message</div>' + + '<div class="message">Final Message 1</div>' + + '</div>' + + '<div id="status-content-2" class="status-content">' + + '<div class="message">First Message second id</div>' + + '<div class="message">Final Message 2</div>' + + '</div>' + + '</div>' + '<ul class="actions"><li><button class="action">Close</button></li></ul>' + '<progress class="process-text">Processing...</progress>' + - '<div id="status-content-1" class="status-content">' + - '<div class="message">First Message</div>' + - '<div class="message">Second Message</div>' + - '<div class="message">Final Message 1</div>' + - '</div>' + - '<div id="status-content-2" class="status-content">' + - '<div class="message">First Message second id</div>' + - '<div class="message">Final Message 2</div>' + - '</div>' + '</div>'); statusArea.close(); @@ -205,22 +202,201 @@ var openTreeJson = { "general_state": "open" }; -test("TreeStatus", 2, function() { +asyncTest("TreeStatus", 2, function() { var simulator = new NetworkSimulator(); - simulator.get = function(url, callback) + simulator.json = function(url) { - simulator.scheduleCallback(function() { - callback(openTreeJson); - }); + return Promise.resolve(openTreeJson); }; var treestatus; simulator.runTest(function() { treeStatus = new ui.TreeStatus(); + }).then(function() { + equal(treeStatus.innerHTML, '<div> blink status: <span>OPEN</span></div><div> chromium status: <span>OPEN</span></div>'); + start(); }); - equal(treeStatus.innerHTML, '<div> blink status: <span>OPEN</span></div><div> chromium status: <span>OPEN</span></div>'); }); +function generateRoll(fromRevision, toRevision) +{ + return { + "results": [ + {"messages":[], "base_url":"svn://svn.chromium.org/chrome/trunk/src", "subject":"Blink roll " + fromRevision + ":" + toRevision, "closed":false, "issue":1000} + ] + }; +} + +asyncTest("RevisionDetailsSmallRoll", 2, function() { + var rollFromRevision = 540; + var rollToRevision = 550; + var simulator = new NetworkSimulator(); + simulator.json = function(url) + { + return Promise.resolve(generateRoll(rollFromRevision, rollToRevision)); + } + + simulator.get = function (url) + { + return Promise.resolve(rollFromRevision); + } + + model.state.resultsByBuilder = { + "Linux": { + "blink_revision": "554", + } + }; + model.state.recentCommits = [ + { + "revision": "555", + }]; + + var revisionDetails; + simulator.runTest(function() { + revisionDetails = ui.revisionDetails(); + }).then(function() { + equal(revisionDetails.innerHTML, + 'Latest revision processed by every bot: ' + + '<details>' + + '<summary>' + + '<a href="http://src.chromium.org/viewvc/blink?view=rev&revision=554">554' + + '<span id="revisionPopUp">' + + '<table>' + + '<tr>' + + '<td><a href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=Linux">Linux</a></td>' + + '<td>554</td>' + + '</tr>' + + '</table>' + + '</span>' + + '</a>' + + '</summary>' + + '<table>' + + '<tr>' + + '<td><a href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=Linux">Linux</a></td>' + + '<td>554</td>' + + '</tr>' + + '</table>' + + '</details>' + + ', trunk is at <a href="http://src.chromium.org/viewvc/blink?view=rev&revision=555">555</a>' + + '<br>' + + 'Last roll is to <a href="http://src.chromium.org/viewvc/blink?view=rev&revision=540">540</a>, current autoroll <a href="https://codereview.chromium.org/1000">540:550</a>'); + start(); + }); +}); + +asyncTest("RevisionDetailsMediumRoll", 2, function() { + var rollFromRevision = 500; + var rollToRevision = 550; + var simulator = new NetworkSimulator(); + simulator.json = function(url) + { + return Promise.resolve(generateRoll(rollFromRevision, rollToRevision)); + } + + simulator.get = function (url) + { + return Promise.resolve(rollFromRevision); + } + + model.state.resultsByBuilder = { + "Linux": { + "blink_revision": "554", + } + }; + model.state.recentCommits = [ + { + "revision": "555", + }]; + + var revisionDetails; + simulator.runTest(function() { + revisionDetails = ui.revisionDetails(); + }).then(function() { + equal(revisionDetails.innerHTML, + 'Latest revision processed by every bot: ' + + '<details>' + + '<summary>' + + '<a href="http://src.chromium.org/viewvc/blink?view=rev&revision=554">554' + + '<span id="revisionPopUp">' + + '<table>' + + '<tr>' + + '<td><a href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=Linux">Linux</a></td>' + + '<td>554</td>' + + '</tr>' + + '</table>' + + '</span>' + + '</a>' + + '</summary>' + + '<table>' + + '<tr>' + + '<td><a href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=Linux">Linux</a></td>' + + '<td>554</td>' + + '</tr>' + + '</table>' + + '</details>' + + ', trunk is at <a href="http://src.chromium.org/viewvc/blink?view=rev&revision=555">555</a>' + + '<br>' + + 'Last roll is to <a href="http://src.chromium.org/viewvc/blink?view=rev&revision=500">500</a><span class="warning">(55 revisions behind)</span>, current autoroll <a href="https://codereview.chromium.org/1000">500:550</a>'); + start(); + }); +}); + +asyncTest("RevisionDetailsBigRoll", 2, function() { + var rollFromRevision = 440; + var rollToRevision = 550; + var simulator = new NetworkSimulator(); + simulator.json = function(url) + { + return Promise.resolve(generateRoll(rollFromRevision, rollToRevision)); + } + + simulator.get = function (url) + { + return Promise.resolve(rollFromRevision); + } + + model.state.resultsByBuilder = { + "Linux": { + "blink_revision": "554", + } + }; + model.state.recentCommits = [ + { + "revision": "555", + }]; + + var revisionDetails; + simulator.runTest(function() { + revisionDetails = ui.revisionDetails(); + }).then(function() { + equal(revisionDetails.innerHTML, + 'Latest revision processed by every bot: ' + + '<details>' + + '<summary>' + + '<a href="http://src.chromium.org/viewvc/blink?view=rev&revision=554">554' + + '<span id="revisionPopUp">' + + '<table>' + + '<tr>' + + '<td><a href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=Linux">Linux</a></td>' + + '<td>554</td>' + + '</tr>' + + '</table>' + + '</span>' + + '</a>' + + '</summary>' + + '<table>' + + '<tr>' + + '<td><a href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=Linux">Linux</a></td>' + + '<td>554</td>' + + '</tr>' + + '</table>' + + '</details>' + + ', trunk is at <a href="http://src.chromium.org/viewvc/blink?view=rev&revision=555">555</a>' + + '<br>' + + 'Last roll is to <a href="http://src.chromium.org/viewvc/blink?view=rev&revision=440">440</a><span class="critical">(115 revisions behind)</span>, current autoroll <a href="https://codereview.chromium.org/1000">440:550</a>'); + start(); + }); +}); })(); diff --git a/chromium/third_party/WebKit/Tools/GardeningServer/styles/common.css b/chromium/third_party/WebKit/Tools/GardeningServer/styles/common.css index 9f7e8c081df..c3f48cae8d7 100644 --- a/chromium/third_party/WebKit/Tools/GardeningServer/styles/common.css +++ b/chromium/third_party/WebKit/Tools/GardeningServer/styles/common.css @@ -44,7 +44,7 @@ a { .ui-widget button, button { font-family: 'Open Sans'; border-radius: 2px; - background-image: -webkit-linear-gradient(top,#f5f5f5,#f1f1f1); + background-image: linear-gradient(#f5f5f5, #f1f1f1); border: 1px solid rgba(0, 0, 0, 0.1); border-radius: 2px; color: #666; @@ -70,8 +70,9 @@ button[disabled] { visibility: hidden; } +/* FIXME: This hover effect can't work on mobile. */ button:hover { - background-image: -webkit-linear-gradient(top,#f8f8f8,#f1f1f1); + background-image: linear-gradient(#f8f8f8, #f1f1f1); -webkit-box-shadow: 0 1px 1px rgba(0,0,0,0.1); background-color: #f8f8f8; background-image: linear-gradient(top,#f8f8f8,#f1f1f1); @@ -88,9 +89,10 @@ button:focus { button.default { border: 1px solid #3079ED; color: white; - background-image: -webkit-linear-gradient(top,#4d90fe,#4787ed); + background-image: linear-gradient(#4d90fe, #4787ed); } +/* FIXME: This hover effect can't work on mobile. */ button.default:hover { border: 1px solid #2f5bb7; color: white; @@ -101,3 +103,19 @@ button.default:hover { .clear { clear: both; } + +/*** Visual escalation ***/ + +.warning { + color: white; + background-color: #ffc343; + font-weight: bold; + font-size: 2em; +} + +.critical { + color: white; + background-color: #e98080; + font-weight: bold; + font-size: 3em; +} diff --git a/chromium/third_party/WebKit/Tools/GardeningServer/styles/failures.css b/chromium/third_party/WebKit/Tools/GardeningServer/styles/failures.css index 2027415320f..43523d94d81 100644 --- a/chromium/third_party/WebKit/Tools/GardeningServer/styles/failures.css +++ b/chromium/third_party/WebKit/Tools/GardeningServer/styles/failures.css @@ -37,23 +37,23 @@ a.failing-builder { text-decoration: none; } - a.failing-builder>span.version { + a.failing-builder > span.version { text-transform: uppercase; background-color: #555; color: White; padding: 0 2px; } - a.failing-builder>span.architecture { + a.failing-builder > span.architecture { padding: 0 2px; } - .effects a.failing-builder>span.architecture { + .effects a.failing-builder > span.architecture { background-color: #555; color: White; } - a.failing-builder>span.graphics { + a.failing-builder > span.graphics { padding: 0 2px; } @@ -62,20 +62,21 @@ ul.failures { padding: 0px; } - ul.failures>li { + ul.failures > li { display: -webkit-box; position: relative; } - ul.failures>li label { + ul.failures > li label { margin-left: 10px; } - ul.failures>li ul.actions { + ul.failures > li ul.actions { padding: 0px; visibility: hidden; } - ul.failures>li:hover ul.actions { +/* FIXME: This hover effect can't work on mobile. */ + ul.failures > li:hover ul.actions { visibility: visible; } diff --git a/chromium/third_party/WebKit/Tools/GardeningServer/styles/main.css b/chromium/third_party/WebKit/Tools/GardeningServer/styles/main.css index 6c54507c9d2..ce0a8482f38 100644 --- a/chromium/third_party/WebKit/Tools/GardeningServer/styles/main.css +++ b/chromium/third_party/WebKit/Tools/GardeningServer/styles/main.css @@ -56,7 +56,7 @@ th { button { border-radius: 2px; - background-image: -webkit-linear-gradient(top,#f5f5f5,#f1f1f1); + background-image: linear-gradient(#f5f5f5, #f1f1f1); border: 1px solid rgba(0, 0, 0, 0.1); border-radius: 2px; color: #666; @@ -83,8 +83,9 @@ button[disabled] { visibility: hidden; } +/* FIXME: This hover effect can't work on mobile. */ button:hover { - background-image: -webkit-linear-gradient(top,#f8f8f8,#f1f1f1); + background-image: linear-gradient(#f8f8f8, #f1f1f1); -webkit-box-shadow: 0 1px 1px rgba(0,0,0,0.1); background-color: #f8f8f8; background-image: linear-gradient(top,#f8f8f8,#f1f1f1); @@ -101,9 +102,10 @@ button:focus { button.default { border: 1px solid #3079ED; color: white; - background-image: -webkit-linear-gradient(top,#4d90fe,#4787ed); + background-image: linear-gradient(#4d90fe, #4787ed); } +/* FIXME: This hover effect can't work on mobile. */ button.default:hover { border: 1px solid #2f5bb7; color: white; diff --git a/chromium/third_party/WebKit/Tools/GardeningServer/styles/notifications.css b/chromium/third_party/WebKit/Tools/GardeningServer/styles/notifications.css index 7e3902521a0..00144971f2f 100644 --- a/chromium/third_party/WebKit/Tools/GardeningServer/styles/notifications.css +++ b/chromium/third_party/WebKit/Tools/GardeningServer/styles/notifications.css @@ -24,7 +24,7 @@ */ /* FIXME: This should really be in actions.css. */ -ul.actions>li { +ul.actions > li { display: inline-block; } @@ -39,8 +39,9 @@ ol.notifications ul { padding: 0; } -ol.notifications>li { - display: -webkit-box; +ol.notifications > li { + display: flex; + flex-wrap: wrap; position: relative; width: 100%; padding: 10px; @@ -52,25 +53,19 @@ ol.notifications div.how { width: 350px; } -ol.notifications time { - display: block; - color: #888; - padding: 0 0 20px 0; -} - ol.notifications div.what { display: -webkit-box; -webkit-box-orient: vertical; padding: 0 0 0 10px; - -webkit-box-flex: 1; + flex: 1; } - ol.notifications>li div.what ul.effects>li.builder { + ol.notifications > li div.what ul.effects > li.builder { display: inline; padding-right: 5px; } -ol.notifications ul.causes>li, ol.notifications div.problem { +ol.notifications ul.causes > li, ol.notifications div.problem { display: -webkit-box; } @@ -78,48 +73,48 @@ ol.notifications ul.causes div.description, ol.notifications div.problem ul.effe -webkit-box-flex: 1; } -ol.notifications>li div.problem { +ol.notifications > li div.problem { padding-bottom: 10px; } - ol.notifications>li div.problem>ul.actions { + ol.notifications > li div.problem > ul.actions { visibility: hidden; } - ol.notifications>li:hover div.problem>ul.actions { + ol.notifications > li:hover div.problem > ul.actions { visibility: visible; } - ol.notifications>li table.failures { + ol.notifications > li table.failures { opacity: 0.2; -webkit-transition: opacity 0.5s; } - ol.notifications>li:hover table.failures { + ol.notifications > li:hover table.failures { opacity: 1; } -ol.notifications>li ul.causes>li>ul.actions { +ol.notifications > li ul.causes > li > ul.actions { } - ol.notifications>li ul.causes>li>div.description { + ol.notifications > li ul.causes > li > div.description { padding: 0 10px 5px 0; display: -webkit-box; } - ol.notifications>li ul.causes>li>div.description>a { + ol.notifications > li ul.causes > li > div.description > a { padding: 5px 10px 5px 10px; margin: -5px 10px -2px 0; border-radius: 4px; display: inline-block; } - ol.notifications>li ul.causes>li:hover>div.description>a { + ol.notifications > li ul.causes > li:hover > div.description > a { background-color: #555; color: White; } - ol.notifications>li ul.causes>li:hover>div.description>a::after { + ol.notifications > li ul.causes > li:hover > div.description > a::after { content: ''; width: 0; height: 0; @@ -131,7 +126,7 @@ ol.notifications>li ul.causes>li>ul.actions { border-bottom: 5px solid White; } - ol.notifications>li ul.causes>li>div.description>span { + ol.notifications > li ul.causes > li > div.description > span { padding: 0 10px 0 0; display: block; cursor: default; @@ -139,42 +134,46 @@ ol.notifications>li ul.causes>li>ul.actions { -webkit-box-flex: 1; } - ol.notifications>li ul.causes>li>div.description>span>span.author { + ol.notifications > li ul.causes > li > div.description > span > span.author { padding: 0 0 0 5px; font-style: italic; } - ol.notifications>li ul.causes>li>div.description>span>span.reviewer { + ol.notifications > li ul.causes > li > div.description > span > span.reviewer { color: Gray; } - ol.notifications>li ul.causes>li>div.description>span>span.bugID::before { - content: 'bug '; + ol.notifications > li ul.causes > li > div.description > span > span.bugID::before { + content: '[bug '; padding-left: 8px; } - ol.notifications>li ul.causes>li>div.description>span>span.bugID>a { + ol.notifications > li ul.causes > li > div.description > span > span.bugID::after { + content: ']'; + } + + ol.notifications > li ul.causes > li > div.description > span > span.bugID > a { cursor: hand; pointer-events: auto; } - ol.notifications>li ul.causes>li>div.description>span>span.reviewer::before { + ol.notifications > li ul.causes > li > div.description > span > span.reviewer::before { content: ' ('; } - ol.notifications>li ul.causes>li>div.description>span>span.reviewer::after { + ol.notifications > li ul.causes > li > div.description > span > span.reviewer::after { content: ')'; } - ol.notifications>li ul.causes>li>ul.actions { + ol.notifications > li ul.causes > li > ul.actions { visibility: hidden; } - ol.notifications>li ul.causes>li:hover>ul.actions { + ol.notifications > li ul.causes > li:hover > ul.actions { visibility: visible; } - ol.notifications>li ul.causes>li li { + ol.notifications > li ul.causes > li li { padding: 10px 0 0 0; display: inline; } diff --git a/chromium/third_party/WebKit/Tools/GardeningServer/styles/onebar.css b/chromium/third_party/WebKit/Tools/GardeningServer/styles/onebar.css index 3165d2f5b5a..481195b450c 100644 --- a/chromium/third_party/WebKit/Tools/GardeningServer/styles/onebar.css +++ b/chromium/third_party/WebKit/Tools/GardeningServer/styles/onebar.css @@ -57,19 +57,21 @@ background: url(../images/partytime.gif) center center no-repeat; } -#chromium-gtests iframe { - border: 0; - height: 20px; -} - -#chromium-gtests { +#link-handling { position: absolute; top: 10px; - right: 5px; + right: 0; + padding-right: 4px; } -#gtest-label { - vertical-align: top; +/* This checkbox just overlaps the main content on smalls screens and doesn't +make a lot of sense as currently designed.*/ +@media only screen and (max-width: 400px) { + #link-handling { display: none; } +} + +#new-window-for-links { + vertical-align: text-bottom; } #onebar details { diff --git a/chromium/third_party/WebKit/Tools/GardeningServer/styles/results.css b/chromium/third_party/WebKit/Tools/GardeningServer/styles/results.css index f27b40765d9..12335e56d5e 100644 --- a/chromium/third_party/WebKit/Tools/GardeningServer/styles/results.css +++ b/chromium/third_party/WebKit/Tools/GardeningServer/styles/results.css @@ -23,6 +23,21 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ +.comparison { + display: flex; + flex-wrap: wrap; + width: 100%; +} + +.comparison > div { + flex: 1; + min-width: 300px; +} + +.results-container { + border: 1px solid gray; +} + .non-action-button, .results-view ul.actions, .ui-dialog ul.actions { float: right; margin: 0; @@ -154,6 +169,11 @@ html, body, #onebar, .results-view, .test-selector { } /*** status console ***/ +body.status-resizing { + cursor: ns-resize; + -webkit-user-select: none; +} + .status { position: fixed; bottom: 0; @@ -163,6 +183,25 @@ html, body, #onebar, .results-view, .test-selector { background-color: white; border-top: 1px solid gray; -webkit-box-shadow: 0px -2px 10px gray; + overflow: visible; +} + +.status > .dragger { + position: absolute; + top: -6px; + height: 6px; + left: 0; + right: 0; + background: transparent; + cursor: ns-resize; +} + +.status > .contents { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; overflow: auto; white-space: nowrap; padding: 4px; |