FE: Resolve "Performance issues when processing large build traces with Ansi2html"
This commit is contained in:
parent
9216f59a3f
commit
8ca5afdf27
4 changed files with 239 additions and 174 deletions
|
@ -1,24 +1,28 @@
|
|||
/* eslint-disable func-names, space-before-function-paren, no-var, prefer-rest-params, wrap-iife, no-use-before-define, no-param-reassign, quotes, yoda, no-else-return, consistent-return, comma-dangle, object-shorthand, prefer-template, one-var, one-var-declaration-per-line, no-unused-vars, max-len, vars-on-top */
|
||||
/* eslint-disable func-names, wrap-iife, no-use-before-define,
|
||||
consistent-return, prefer-rest-params */
|
||||
/* global Breakpoints */
|
||||
|
||||
var bind = function(fn, me) { return function() { return fn.apply(me, arguments); }; };
|
||||
var AUTO_SCROLL_OFFSET = 75;
|
||||
var DOWN_BUILD_TRACE = '#down-build-trace';
|
||||
const bind = function (fn, me) { return function () { return fn.apply(me, arguments); }; };
|
||||
const AUTO_SCROLL_OFFSET = 75;
|
||||
const DOWN_BUILD_TRACE = '#down-build-trace';
|
||||
|
||||
window.Build = (function() {
|
||||
window.Build = (function () {
|
||||
Build.timeout = null;
|
||||
|
||||
Build.state = null;
|
||||
|
||||
function Build(options) {
|
||||
options = options || $('.js-build-options').data();
|
||||
this.pageUrl = options.pageUrl;
|
||||
this.buildUrl = options.buildUrl;
|
||||
this.buildStatus = options.buildStatus;
|
||||
this.state = options.logState;
|
||||
this.buildStage = options.buildStage;
|
||||
this.updateDropdown = bind(this.updateDropdown, this);
|
||||
this.options = options || $('.js-build-options').data();
|
||||
|
||||
this.pageUrl = this.options.pageUrl;
|
||||
this.buildUrl = this.options.buildUrl;
|
||||
this.buildStatus = this.options.buildStatus;
|
||||
this.state = this.options.logState;
|
||||
this.buildStage = this.options.buildStage;
|
||||
this.$document = $(document);
|
||||
|
||||
this.updateDropdown = bind(this.updateDropdown, this);
|
||||
|
||||
this.$body = $('body');
|
||||
this.$buildTrace = $('#build-trace');
|
||||
this.$autoScrollContainer = $('.autoscroll-container');
|
||||
|
@ -29,112 +33,110 @@ window.Build = (function() {
|
|||
this.$scrollTopBtn = $('#scroll-top');
|
||||
this.$scrollBottomBtn = $('#scroll-bottom');
|
||||
this.$buildRefreshAnimation = $('.js-build-refresh');
|
||||
this.$buildScroll = $('#js-build-scroll');
|
||||
this.$truncatedInfo = $('.js-truncated-info');
|
||||
|
||||
clearTimeout(Build.timeout);
|
||||
// Init breakpoint checker
|
||||
this.bp = Breakpoints.get();
|
||||
|
||||
this.initSidebar();
|
||||
this.$buildScroll = $('#js-build-scroll');
|
||||
|
||||
this.populateJobs(this.buildStage);
|
||||
this.updateStageDropdownText(this.buildStage);
|
||||
this.sidebarOnResize();
|
||||
|
||||
this.$document.off('click', '.js-sidebar-build-toggle').on('click', '.js-sidebar-build-toggle', this.sidebarOnClick.bind(this));
|
||||
this.$document.off('click', '.stage-item').on('click', '.stage-item', this.updateDropdown);
|
||||
this.$document
|
||||
.off('click', '.js-sidebar-build-toggle')
|
||||
.on('click', '.js-sidebar-build-toggle', this.sidebarOnClick.bind(this));
|
||||
|
||||
this.$document
|
||||
.off('click', '.stage-item')
|
||||
.on('click', '.stage-item', this.updateDropdown);
|
||||
|
||||
this.$document.on('scroll', this.initScrollMonitor.bind(this));
|
||||
$(window).off('resize.build').on('resize.build', this.sidebarOnResize.bind(this));
|
||||
$('a', this.$buildScroll).off('click.stepTrace').on('click.stepTrace', this.stepTrace);
|
||||
|
||||
$(window)
|
||||
.off('resize.build')
|
||||
.on('resize.build', this.sidebarOnResize.bind(this));
|
||||
|
||||
$('a', this.$buildScroll)
|
||||
.off('click.stepTrace')
|
||||
.on('click.stepTrace', this.stepTrace);
|
||||
|
||||
this.updateArtifactRemoveDate();
|
||||
if ($('#build-trace').length) {
|
||||
this.getInitialBuildTrace();
|
||||
this.initScrollButtonAffix();
|
||||
}
|
||||
this.initScrollButtonAffix();
|
||||
this.invokeBuildTrace();
|
||||
}
|
||||
|
||||
Build.prototype.initSidebar = function() {
|
||||
Build.prototype.initSidebar = function () {
|
||||
this.$sidebar = $('.js-build-sidebar');
|
||||
this.$sidebar.niceScroll();
|
||||
this.$document.off('click', '.js-sidebar-build-toggle').on('click', '.js-sidebar-build-toggle', this.toggleSidebar);
|
||||
this.$document
|
||||
.off('click', '.js-sidebar-build-toggle')
|
||||
.on('click', '.js-sidebar-build-toggle', this.toggleSidebar);
|
||||
};
|
||||
|
||||
Build.prototype.location = function() {
|
||||
return window.location.href.split("#")[0];
|
||||
Build.prototype.invokeBuildTrace = function () {
|
||||
return this.getBuildTrace();
|
||||
};
|
||||
|
||||
Build.prototype.invokeBuildTrace = function() {
|
||||
var continueRefreshStatuses = ['running', 'pending'];
|
||||
// Continue to update build trace when build is running or pending
|
||||
if (continueRefreshStatuses.indexOf(this.buildStatus) !== -1) {
|
||||
// Check for new build output if user still watching build page
|
||||
// Only valid for runnig build when output changes during time
|
||||
Build.timeout = setTimeout((function(_this) {
|
||||
return function() {
|
||||
if (_this.location() === _this.pageUrl) {
|
||||
return _this.getBuildTrace();
|
||||
}
|
||||
};
|
||||
})(this), 4000);
|
||||
}
|
||||
};
|
||||
|
||||
Build.prototype.getInitialBuildTrace = function() {
|
||||
var removeRefreshStatuses = ['success', 'failed', 'canceled', 'skipped'];
|
||||
|
||||
Build.prototype.getBuildTrace = function () {
|
||||
return $.ajax({
|
||||
url: this.pageUrl + "/trace.json",
|
||||
url: `${this.pageUrl}/trace.json`,
|
||||
dataType: 'json',
|
||||
success: function(buildData) {
|
||||
$('.js-build-output').html(buildData.html);
|
||||
gl.utils.setCiStatusFavicon(`${this.pageUrl}/status.json`);
|
||||
if (window.location.hash === DOWN_BUILD_TRACE) {
|
||||
$("html,body").scrollTop(this.$buildTrace.height());
|
||||
data: {
|
||||
state: this.state,
|
||||
},
|
||||
success: ((log) => {
|
||||
const $buildContainer = $('.js-build-output');
|
||||
|
||||
if (log.state) {
|
||||
this.state = log.state;
|
||||
}
|
||||
if (removeRefreshStatuses.indexOf(buildData.status) !== -1) {
|
||||
|
||||
if (log.append) {
|
||||
$buildContainer.append(log.html);
|
||||
} else {
|
||||
$buildContainer.html(log.html);
|
||||
if (log.truncated) {
|
||||
$('.js-truncated-info-size').html(` ${log.size} `);
|
||||
this.$truncatedInfo.removeClass('hidden');
|
||||
this.initAffixTruncatedInfo();
|
||||
} else {
|
||||
this.$truncatedInfo.addClass('hidden');
|
||||
}
|
||||
}
|
||||
|
||||
this.checkAutoscroll();
|
||||
|
||||
if (!log.complete) {
|
||||
Build.timeout = setTimeout(() => {
|
||||
this.invokeBuildTrace();
|
||||
}, 4000);
|
||||
} else {
|
||||
this.$buildRefreshAnimation.remove();
|
||||
return this.initScrollMonitor();
|
||||
}
|
||||
}.bind(this)
|
||||
|
||||
if (log.status !== this.buildStatus) {
|
||||
let pageUrl = this.pageUrl;
|
||||
|
||||
if (this.$autoScrollStatus.data('state') === 'enabled') {
|
||||
pageUrl += DOWN_BUILD_TRACE;
|
||||
}
|
||||
|
||||
gl.utils.visitUrl(pageUrl);
|
||||
}
|
||||
}),
|
||||
error: () => {
|
||||
this.$buildRefreshAnimation.remove();
|
||||
return this.initScrollMonitor();
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
Build.prototype.getBuildTrace = function() {
|
||||
return $.ajax({
|
||||
url: this.pageUrl + "/trace.json?state=" + (encodeURIComponent(this.state)),
|
||||
dataType: "json",
|
||||
success: (function(_this) {
|
||||
return function(log) {
|
||||
var pageUrl;
|
||||
|
||||
if (log.state) {
|
||||
_this.state = log.state;
|
||||
}
|
||||
_this.invokeBuildTrace();
|
||||
if (log.status === "running") {
|
||||
if (log.append) {
|
||||
$('.js-build-output').append(log.html);
|
||||
} else {
|
||||
$('.js-build-output').html(log.html);
|
||||
}
|
||||
return _this.checkAutoscroll();
|
||||
} else if (log.status !== _this.buildStatus) {
|
||||
pageUrl = _this.pageUrl;
|
||||
if (_this.$autoScrollStatus.data('state') === 'enabled') {
|
||||
pageUrl += DOWN_BUILD_TRACE;
|
||||
}
|
||||
|
||||
return gl.utils.visitUrl(pageUrl);
|
||||
}
|
||||
};
|
||||
})(this)
|
||||
});
|
||||
};
|
||||
|
||||
Build.prototype.checkAutoscroll = function() {
|
||||
if (this.$autoScrollStatus.data("state") === "enabled") {
|
||||
return $("html,body").scrollTop(this.$buildTrace.height());
|
||||
Build.prototype.checkAutoscroll = function () {
|
||||
if (this.$autoScrollStatus.data('state') === 'enabled') {
|
||||
return $('html,body').scrollTop(this.$buildTrace.height());
|
||||
}
|
||||
|
||||
// Handle a situation where user started new build
|
||||
|
@ -146,7 +148,7 @@ window.Build = (function() {
|
|||
}
|
||||
};
|
||||
|
||||
Build.prototype.initScrollButtonAffix = function() {
|
||||
Build.prototype.initScrollButtonAffix = function () {
|
||||
// Hide everything initially
|
||||
this.$scrollTopBtn.hide();
|
||||
this.$scrollBottomBtn.hide();
|
||||
|
@ -167,15 +169,17 @@ window.Build = (function() {
|
|||
// - Show Top Arrow button
|
||||
// - Show Bottom Arrow button
|
||||
// - Disable Autoscroll and hide indicator (when build is running)
|
||||
Build.prototype.initScrollMonitor = function() {
|
||||
if (!gl.utils.isInViewport(this.$upBuildTrace.get(0)) && !gl.utils.isInViewport(this.$downBuildTrace.get(0))) {
|
||||
Build.prototype.initScrollMonitor = function () {
|
||||
if (!gl.utils.isInViewport(this.$upBuildTrace.get(0)) &&
|
||||
!gl.utils.isInViewport(this.$downBuildTrace.get(0))) {
|
||||
// User is somewhere in middle of Build Log
|
||||
|
||||
this.$scrollTopBtn.show();
|
||||
|
||||
if (this.buildStatus === 'success' || this.buildStatus === 'failed') { // Check if Build is completed
|
||||
this.$scrollBottomBtn.show();
|
||||
} else if (this.$buildRefreshAnimation.is(':visible') && !gl.utils.isInViewport(this.$buildRefreshAnimation.get(0))) {
|
||||
} else if (this.$buildRefreshAnimation.is(':visible') &&
|
||||
!gl.utils.isInViewport(this.$buildRefreshAnimation.get(0))) {
|
||||
this.$scrollBottomBtn.show();
|
||||
} else {
|
||||
this.$scrollBottomBtn.hide();
|
||||
|
@ -186,10 +190,13 @@ window.Build = (function() {
|
|||
this.$autoScrollContainer.hide();
|
||||
this.$autoScrollStatusText.removeClass('animate');
|
||||
} else {
|
||||
this.$autoScrollContainer.css({ top: this.$body.outerHeight() - AUTO_SCROLL_OFFSET }).show();
|
||||
this.$autoScrollContainer.css({
|
||||
top: this.$body.outerHeight() - AUTO_SCROLL_OFFSET,
|
||||
}).show();
|
||||
this.$autoScrollStatusText.addClass('animate');
|
||||
}
|
||||
} else if (gl.utils.isInViewport(this.$upBuildTrace.get(0)) && !gl.utils.isInViewport(this.$downBuildTrace.get(0))) {
|
||||
} else if (gl.utils.isInViewport(this.$upBuildTrace.get(0)) &&
|
||||
!gl.utils.isInViewport(this.$downBuildTrace.get(0))) {
|
||||
// User is at Top of Build Log
|
||||
|
||||
this.$scrollTopBtn.hide();
|
||||
|
@ -197,17 +204,22 @@ window.Build = (function() {
|
|||
|
||||
this.$autoScrollContainer.hide();
|
||||
this.$autoScrollStatusText.removeClass('animate');
|
||||
} else if ((!gl.utils.isInViewport(this.$upBuildTrace.get(0)) && gl.utils.isInViewport(this.$downBuildTrace.get(0))) ||
|
||||
(this.$buildRefreshAnimation.is(':visible') && gl.utils.isInViewport(this.$buildRefreshAnimation.get(0)))) {
|
||||
} else if ((!gl.utils.isInViewport(this.$upBuildTrace.get(0)) &&
|
||||
gl.utils.isInViewport(this.$downBuildTrace.get(0))) ||
|
||||
(this.$buildRefreshAnimation.is(':visible') &&
|
||||
gl.utils.isInViewport(this.$buildRefreshAnimation.get(0)))) {
|
||||
// User is at Bottom of Build Log
|
||||
|
||||
this.$scrollTopBtn.show();
|
||||
this.$scrollBottomBtn.hide();
|
||||
|
||||
// Show and Reposition Autoscroll Status Indicator
|
||||
this.$autoScrollContainer.css({ top: this.$body.outerHeight() - AUTO_SCROLL_OFFSET }).show();
|
||||
this.$autoScrollContainer.css({
|
||||
top: this.$body.outerHeight() - AUTO_SCROLL_OFFSET,
|
||||
}).show();
|
||||
this.$autoScrollStatusText.addClass('animate');
|
||||
} else if (gl.utils.isInViewport(this.$upBuildTrace.get(0)) && gl.utils.isInViewport(this.$downBuildTrace.get(0))) {
|
||||
} else if (gl.utils.isInViewport(this.$upBuildTrace.get(0)) &&
|
||||
gl.utils.isInViewport(this.$downBuildTrace.get(0))) {
|
||||
// Build Log height is small
|
||||
|
||||
this.$scrollTopBtn.hide();
|
||||
|
@ -218,65 +230,81 @@ window.Build = (function() {
|
|||
this.$autoScrollStatusText.removeClass('animate');
|
||||
}
|
||||
|
||||
if (this.buildStatus === "running" || this.buildStatus === "pending") {
|
||||
if (this.buildStatus === 'running' || this.buildStatus === 'pending') {
|
||||
// Check if Refresh Animation is in Viewport and enable Autoscroll, disable otherwise.
|
||||
this.$autoScrollStatus.data("state", gl.utils.isInViewport(this.$buildRefreshAnimation.get(0)) ? 'enabled' : 'disabled');
|
||||
this.$autoScrollStatus.data(
|
||||
'state',
|
||||
gl.utils.isInViewport(this.$buildRefreshAnimation.get(0)) ? 'enabled' : 'disabled',
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
Build.prototype.shouldHideSidebarForViewport = function() {
|
||||
var bootstrapBreakpoint;
|
||||
bootstrapBreakpoint = this.bp.getBreakpointSize();
|
||||
Build.prototype.shouldHideSidebarForViewport = function () {
|
||||
const bootstrapBreakpoint = this.bp.getBreakpointSize();
|
||||
return bootstrapBreakpoint === 'xs' || bootstrapBreakpoint === 'sm';
|
||||
};
|
||||
|
||||
Build.prototype.toggleSidebar = function(shouldHide) {
|
||||
var shouldShow = typeof shouldHide === 'boolean' ? !shouldHide : undefined;
|
||||
Build.prototype.toggleSidebar = function (shouldHide) {
|
||||
const shouldShow = typeof shouldHide === 'boolean' ? !shouldHide : undefined;
|
||||
|
||||
this.$buildScroll.toggleClass('sidebar-expanded', shouldShow)
|
||||
.toggleClass('sidebar-collapsed', shouldHide);
|
||||
this.$truncatedInfo.toggleClass('sidebar-expanded', shouldShow)
|
||||
.toggleClass('sidebar-collapsed', shouldHide);
|
||||
this.$sidebar.toggleClass('right-sidebar-expanded', shouldShow)
|
||||
.toggleClass('right-sidebar-collapsed', shouldHide);
|
||||
};
|
||||
|
||||
Build.prototype.sidebarOnResize = function() {
|
||||
Build.prototype.sidebarOnResize = function () {
|
||||
this.toggleSidebar(this.shouldHideSidebarForViewport());
|
||||
};
|
||||
|
||||
Build.prototype.sidebarOnClick = function() {
|
||||
Build.prototype.sidebarOnClick = function () {
|
||||
if (this.shouldHideSidebarForViewport()) this.toggleSidebar();
|
||||
};
|
||||
|
||||
Build.prototype.updateArtifactRemoveDate = function() {
|
||||
var $date, date;
|
||||
$date = $('.js-artifacts-remove');
|
||||
Build.prototype.updateArtifactRemoveDate = function () {
|
||||
const $date = $('.js-artifacts-remove');
|
||||
if ($date.length) {
|
||||
date = $date.text();
|
||||
return $date.text(gl.utils.timeFor(new Date(date.replace(/([0-9]+)-([0-9]+)-([0-9]+)/g, '$1/$2/$3')), ' '));
|
||||
const date = $date.text();
|
||||
return $date.text(
|
||||
gl.utils.timeFor(new Date(date.replace(/([0-9]+)-([0-9]+)-([0-9]+)/g, '$1/$2/$3')), ' '),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
Build.prototype.populateJobs = function(stage) {
|
||||
Build.prototype.populateJobs = function (stage) {
|
||||
$('.build-job').hide();
|
||||
$('.build-job[data-stage="' + stage + '"]').show();
|
||||
$(`.build-job[data-stage="${stage}"]`).show();
|
||||
};
|
||||
|
||||
Build.prototype.updateStageDropdownText = function(stage) {
|
||||
Build.prototype.updateStageDropdownText = function (stage) {
|
||||
$('.stage-selection').text(stage);
|
||||
};
|
||||
|
||||
Build.prototype.updateDropdown = function(e) {
|
||||
Build.prototype.updateDropdown = function (e) {
|
||||
e.preventDefault();
|
||||
var stage = e.currentTarget.text;
|
||||
const stage = e.currentTarget.text;
|
||||
this.updateStageDropdownText(stage);
|
||||
this.populateJobs(stage);
|
||||
};
|
||||
|
||||
Build.prototype.stepTrace = function(e) {
|
||||
var $currentTarget;
|
||||
Build.prototype.stepTrace = function (e) {
|
||||
e.preventDefault();
|
||||
$currentTarget = $(e.currentTarget);
|
||||
|
||||
const $currentTarget = $(e.currentTarget);
|
||||
$.scrollTo($currentTarget.attr('href'), {
|
||||
offset: 0
|
||||
offset: 0,
|
||||
});
|
||||
};
|
||||
|
||||
Build.prototype.initAffixTruncatedInfo = function () {
|
||||
const offsetTop = this.$buildTrace.offset().top;
|
||||
|
||||
this.$truncatedInfo.affix({
|
||||
offset: {
|
||||
top: offsetTop,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -57,6 +57,37 @@
|
|||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.truncated-info {
|
||||
text-align: center;
|
||||
border-bottom: 1px solid;
|
||||
background-color: $black-transparent;
|
||||
height: 45px;
|
||||
|
||||
&.affix {
|
||||
top: 0;
|
||||
}
|
||||
|
||||
// with sidebar
|
||||
&.affix.sidebar-expanded {
|
||||
right: 312px;
|
||||
left: 22px;
|
||||
}
|
||||
|
||||
// without sidebar
|
||||
&.affix.sidebar-collapsed {
|
||||
right: 20px;
|
||||
left: 20px;
|
||||
}
|
||||
|
||||
&.affix-top {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
margin: 0 auto;
|
||||
right: 5px;
|
||||
left: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.scroll-controls {
|
||||
|
@ -186,6 +217,7 @@
|
|||
white-space: pre;
|
||||
overflow-x: auto;
|
||||
font-size: 12px;
|
||||
position: relative;
|
||||
|
||||
.fa-refresh {
|
||||
font-size: 24px;
|
||||
|
|
|
@ -71,6 +71,11 @@
|
|||
= custom_icon('scroll_down_hover_active')
|
||||
#up-build-trace
|
||||
%pre.build-trace#build-trace
|
||||
.js-truncated-info.truncated-info.hidden
|
||||
%span<
|
||||
Showing last
|
||||
%span.js-truncated-info-size><
|
||||
KiB of log
|
||||
%code.bash.js-build-output
|
||||
.build-loader-animation.js-build-refresh
|
||||
|
||||
|
|
|
@ -64,58 +64,33 @@ describe('Build', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('initial build trace', () => {
|
||||
beforeEach(() => {
|
||||
new Build();
|
||||
});
|
||||
|
||||
it('displays the initial build trace', () => {
|
||||
expect($.ajax.calls.count()).toBe(1);
|
||||
const [{ url, dataType, success, context }] = $.ajax.calls.argsFor(0);
|
||||
expect(url).toBe(
|
||||
`${BUILD_URL}/trace.json`,
|
||||
);
|
||||
expect(dataType).toBe('json');
|
||||
expect(success).toEqual(jasmine.any(Function));
|
||||
spyOn(gl.utils, 'setCiStatusFavicon').and.callFake(() => {});
|
||||
|
||||
success.call(context, { html: '<span>Example</span>', status: 'running' });
|
||||
|
||||
expect($('#build-trace .js-build-output').text()).toMatch(/Example/);
|
||||
});
|
||||
|
||||
it('removes the spinner', () => {
|
||||
const [{ success, context }] = $.ajax.calls.argsFor(0);
|
||||
spyOn(gl.utils, 'setCiStatusFavicon').and.callFake(() => {});
|
||||
success.call(context, { trace_html: '<span>Example</span>', status: 'success' });
|
||||
|
||||
expect($('.js-build-refresh').length).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('running build', () => {
|
||||
beforeEach(function () {
|
||||
$('.js-build-options').data('buildStatus', 'running');
|
||||
this.build = new Build();
|
||||
spyOn(this.build, 'location').and.returnValue(BUILD_URL);
|
||||
});
|
||||
|
||||
it('updates the build trace on an interval', function () {
|
||||
spyOn(gl.utils, 'visitUrl');
|
||||
|
||||
jasmine.clock().tick(4001);
|
||||
|
||||
expect($.ajax.calls.count()).toBe(2);
|
||||
let [{ url, dataType, success, context }] = $.ajax.calls.argsFor(1);
|
||||
expect(url).toBe(
|
||||
`${BUILD_URL}/trace.json?state=`,
|
||||
);
|
||||
expect(dataType).toBe('json');
|
||||
expect(success).toEqual(jasmine.any(Function));
|
||||
expect($.ajax.calls.count()).toBe(1);
|
||||
|
||||
success.call(context, {
|
||||
// We have to do it this way to prevent Webpack to fail to compile
|
||||
// when destructuring assignments and reusing
|
||||
// the same variables names inside the same scope
|
||||
let args = $.ajax.calls.argsFor(0)[0];
|
||||
|
||||
expect(args.url).toBe(`${BUILD_URL}/trace.json`);
|
||||
expect(args.dataType).toBe('json');
|
||||
expect(args.success).toEqual(jasmine.any(Function));
|
||||
|
||||
args.success.call($, {
|
||||
html: '<span>Update<span>',
|
||||
status: 'running',
|
||||
state: 'newstate',
|
||||
append: true,
|
||||
complete: false,
|
||||
});
|
||||
|
||||
expect($('#build-trace .js-build-output').text()).toMatch(/Update/);
|
||||
|
@ -123,17 +98,20 @@ describe('Build', () => {
|
|||
|
||||
jasmine.clock().tick(4001);
|
||||
|
||||
expect($.ajax.calls.count()).toBe(3);
|
||||
[{ url, dataType, success, context }] = $.ajax.calls.argsFor(2);
|
||||
expect(url).toBe(`${BUILD_URL}/trace.json?state=newstate`);
|
||||
expect(dataType).toBe('json');
|
||||
expect(success).toEqual(jasmine.any(Function));
|
||||
expect($.ajax.calls.count()).toBe(2);
|
||||
|
||||
success.call(context, {
|
||||
args = $.ajax.calls.argsFor(1)[0];
|
||||
expect(args.url).toBe(`${BUILD_URL}/trace.json`);
|
||||
expect(args.dataType).toBe('json');
|
||||
expect(args.data.state).toBe('newstate');
|
||||
expect(args.success).toEqual(jasmine.any(Function));
|
||||
|
||||
args.success.call($, {
|
||||
html: '<span>More</span>',
|
||||
status: 'running',
|
||||
state: 'finalstate',
|
||||
append: true,
|
||||
complete: true,
|
||||
});
|
||||
|
||||
expect($('#build-trace .js-build-output').text()).toMatch(/UpdateMore/);
|
||||
|
@ -141,19 +119,22 @@ describe('Build', () => {
|
|||
});
|
||||
|
||||
it('replaces the entire build trace', () => {
|
||||
spyOn(gl.utils, 'visitUrl');
|
||||
|
||||
jasmine.clock().tick(4001);
|
||||
let [{ success, context }] = $.ajax.calls.argsFor(1);
|
||||
success.call(context, {
|
||||
let args = $.ajax.calls.argsFor(0)[0];
|
||||
args.success.call($, {
|
||||
html: '<span>Update</span>',
|
||||
status: 'running',
|
||||
append: true,
|
||||
append: false,
|
||||
complete: false,
|
||||
});
|
||||
|
||||
expect($('#build-trace .js-build-output').text()).toMatch(/Update/);
|
||||
|
||||
jasmine.clock().tick(4001);
|
||||
[{ success, context }] = $.ajax.calls.argsFor(2);
|
||||
success.call(context, {
|
||||
args = $.ajax.calls.argsFor(1)[0];
|
||||
args.success.call($, {
|
||||
html: '<span>Different</span>',
|
||||
status: 'running',
|
||||
append: false,
|
||||
|
@ -163,15 +144,34 @@ describe('Build', () => {
|
|||
expect($('#build-trace .js-build-output').text()).toMatch(/Different/);
|
||||
});
|
||||
|
||||
it('shows information about truncated log', () => {
|
||||
jasmine.clock().tick(4001);
|
||||
const [{ success }] = $.ajax.calls.argsFor(0);
|
||||
|
||||
success.call($, {
|
||||
html: '<span>Update</span>',
|
||||
status: 'success',
|
||||
append: false,
|
||||
truncated: true,
|
||||
size: '50',
|
||||
});
|
||||
|
||||
expect(
|
||||
$('#build-trace .js-truncated-info').text().trim(),
|
||||
).toContain('Showing last 50 KiB of log');
|
||||
expect($('#build-trace .js-truncated-info-size').text()).toMatch('50');
|
||||
});
|
||||
|
||||
it('reloads the page when the build is done', () => {
|
||||
spyOn(gl.utils, 'visitUrl');
|
||||
|
||||
jasmine.clock().tick(4001);
|
||||
const [{ success, context }] = $.ajax.calls.argsFor(1);
|
||||
success.call(context, {
|
||||
const [{ success }] = $.ajax.calls.argsFor(0);
|
||||
success.call($, {
|
||||
html: '<span>Final</span>',
|
||||
status: 'passed',
|
||||
append: true,
|
||||
complete: true,
|
||||
});
|
||||
|
||||
expect(gl.utils.visitUrl).toHaveBeenCalledWith(BUILD_URL);
|
||||
|
|
Loading…
Reference in a new issue