From ac7efb29164e0f30e88be713c07672df3f54e3e6 Mon Sep 17 00:00:00 2001 From: Luke Bennett Date: Thu, 8 Sep 2016 16:50:36 +0100 Subject: Removed inline JS and added new affix declaration Tidied up UX Corrected naming convention issues with removing inline JS @deckar01 saves the day! Simplified `toggleSidebar` and `hideSidebar` Review changes Merge conflicts and update autoscroll button --- app/assets/javascripts/build.js | 83 +++++++++++++++++--------------- app/assets/javascripts/dispatcher.js.es6 | 3 ++ app/assets/stylesheets/pages/builds.scss | 22 +++------ app/helpers/builds_helper.rb | 10 ++++ app/views/projects/builds/show.html.haml | 28 +++++------ 5 files changed, 74 insertions(+), 72 deletions(-) diff --git a/app/assets/javascripts/build.js b/app/assets/javascripts/build.js index 12e653f4122..54fed3dd573 100644 --- a/app/assets/javascripts/build.js +++ b/app/assets/javascripts/build.js @@ -8,41 +8,44 @@ Build.state = null; function Build(options) { - this.page_url = options.page_url; - this.build_url = options.build_url; - this.build_status = options.build_status; + options = options || $('.js-build-options').data(); + this.pageUrl = options.pageUrl; + this.buildUrl = options.buildUrl; + this.buildStatus = options.buildStatus; this.state = options.state1; - this.build_stage = options.build_stage; - this.hideSidebar = bind(this.hideSidebar, this); - this.toggleSidebar = bind(this.toggleSidebar, this); + this.buildStage = options.buildStage; this.updateDropdown = bind(this.updateDropdown, this); this.$document = $(document); clearInterval(Build.interval); // Init breakpoint checker this.bp = Breakpoints.get(); + this.initSidebar(); + this.$buildScroll = $('#js-build-scroll'); - this.populateJobs(this.build_stage); - this.updateStageDropdownText(this.build_stage); + this.populateJobs(this.buildStage); + this.updateStageDropdownText(this.buildStage); + this.sidebarOnResize(); - $(window).off('resize.build').on('resize.build', this.hideSidebar); + 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); - $('#js-build-scroll > a').off('click').on('click', 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.initScrollButtons(); + this.initScrollButtonAffix(); } - if (this.build_status === "running" || this.build_status === "pending") { + if (this.buildStatus === "running" || this.buildStatus === "pending") { $('#autoscroll-button').on('click', function() { var state; state = $(this).data("state"); if ("enabled" === state) { $(this).data("state", "disabled"); - return $(this).text("enable autoscroll"); + return $(this).text("Enable autoscroll"); } else { $(this).data("state", "enabled"); - return $(this).text("disable autoscroll"); + return $(this).text("Disable autoscroll"); } // // Bind autoscroll button to follow build output @@ -50,7 +53,7 @@ }); Build.interval = setInterval((function(_this) { return function() { - if (window.location.href.split("#").first() === _this.page_url) { + if (window.location.href.split("#").first() === _this.pageUrl) { return _this.getBuildTrace(); } }; @@ -72,7 +75,6 @@ top: this.sidebarTranslationLimits.max }); this.$sidebar.niceScroll(); - this.hideSidebar(); this.$document.off('click', '.js-sidebar-build-toggle').on('click', '.js-sidebar-build-toggle', this.toggleSidebar); this.$document.off('scroll.translateSidebar').on('scroll.translateSidebar', this.translateSidebar.bind(this)); }; @@ -81,11 +83,11 @@ var removeRefreshStatuses = ['success', 'failed', 'canceled', 'skipped'] return $.ajax({ - url: this.build_url, + url: this.buildUrl, dataType: 'json', - success: function(build_data) { - $('.js-build-output').html(build_data.trace_html); - if (removeRefreshStatuses.indexOf(build_data.status) >= 0) { + success: function(buildData) { + $('.js-build-output').html(buildData.trace_html); + if (removeRefreshStatuses.indexOf(buildData.status) >= 0) { return $('.js-build-refresh').remove(); } } @@ -94,7 +96,7 @@ Build.prototype.getBuildTrace = function() { return $.ajax({ - url: this.page_url + "/trace.json?state=" + (encodeURIComponent(this.state)), + url: this.pageUrl + "/trace.json?state=" + (encodeURIComponent(this.state)), dataType: "json", success: (function(_this) { return function(log) { @@ -108,8 +110,8 @@ $('.js-build-output').html(log.html); } return _this.checkAutoscroll(); - } else if (log.status !== _this.build_status) { - return Turbolinks.visit(_this.page_url); + } else if (log.status !== _this.buildStatus) { + return Turbolinks.visit(_this.pageUrl); } }; })(this) @@ -122,12 +124,11 @@ } }; - Build.prototype.initScrollButtons = function() { - var $body, $buildScroll, $buildTrace; - $buildScroll = $('#js-build-scroll'); + Build.prototype.initScrollButtonAffix = function() { + var $body, $buildTrace; $body = $('body'); $buildTrace = $('#build-trace'); - return $buildScroll.affix({ + return this.$buildScroll.affix({ offset: { bottom: function() { return $body.outerHeight() - ($buildTrace.outerHeight() + $buildTrace.offset().top); @@ -136,18 +137,12 @@ }); }; - Build.prototype.shouldHideSidebar = function() { + Build.prototype.shouldHideSidebarForViewport = function() { var bootstrapBreakpoint; bootstrapBreakpoint = this.bp.getBreakpointSize(); return bootstrapBreakpoint === 'xs' || bootstrapBreakpoint === 'sm'; }; - Build.prototype.toggleSidebar = function() { - if (this.shouldHideSidebar()) { - return this.$sidebar.toggleClass('right-sidebar-expanded right-sidebar-collapsed'); - } - }; - Build.prototype.translateSidebar = function(e) { var newPosition = this.sidebarTranslationLimits.max - (document.body.scrollTop || document.documentElement.scrollTop); if (newPosition < this.sidebarTranslationLimits.min) newPosition = this.sidebarTranslationLimits.min; @@ -156,12 +151,20 @@ }); }; - Build.prototype.hideSidebar = function() { - if (this.shouldHideSidebar()) { - return this.$sidebar.removeClass('right-sidebar-expanded').addClass('right-sidebar-collapsed'); - } else { - return this.$sidebar.removeClass('right-sidebar-collapsed').addClass('right-sidebar-expanded'); - } + Build.prototype.toggleSidebar = function(shouldHide) { + var shouldShow = typeof shouldHide === 'boolean' ? !shouldHide : undefined; + this.$buildScroll.toggleClass('sidebar-expanded', shouldShow) + .toggleClass('sidebar-collapsed', shouldHide); + this.$sidebar.toggleClass('right-sidebar-expanded', shouldShow) + .toggleClass('right-sidebar-collapsed', shouldHide); + }; + + Build.prototype.sidebarOnResize = function() { + this.toggleSidebar(this.shouldHideSidebarForViewport()); + }; + + Build.prototype.sidebarOnClick = function() { + if (this.shouldHideSidebarForViewport()) this.toggleSidebar(); }; Build.prototype.updateArtifactRemoveDate = function() { diff --git a/app/assets/javascripts/dispatcher.js.es6 b/app/assets/javascripts/dispatcher.js.es6 index 8e4fd1f19ba..756a24cc0fc 100644 --- a/app/assets/javascripts/dispatcher.js.es6 +++ b/app/assets/javascripts/dispatcher.js.es6 @@ -29,6 +29,9 @@ case 'projects:boards:index': shortcut_handler = new ShortcutsNavigation(); break; + case 'projects:builds:show': + new Build(); + break; case 'projects:merge_requests:index': case 'projects:issues:index': Issuable.init(); diff --git a/app/assets/stylesheets/pages/builds.scss b/app/assets/stylesheets/pages/builds.scss index 6300ac9662f..f1d311cabbe 100644 --- a/app/assets/stylesheets/pages/builds.scss +++ b/app/assets/stylesheets/pages/builds.scss @@ -14,18 +14,10 @@ } } - .autoscroll-container { - position: fixed; - bottom: 20px; - right: 20px; - z-index: 100; - } - .scroll-controls { - &.affix-top { - position: absolute; - top: 10px; - right: 25px; + .scroll-step { + width: 31px; + margin: 0 0 0 auto; } &.affix-bottom { @@ -34,13 +26,13 @@ } &.affix { - right: 30px; + right: 25px; bottom: 15px; z-index: 1; + } - @media (min-width: $screen-md-min) { - right: 26%; - } + &.sidebar-expanded { + right: #{$gutter_width + ($gl-padding * 2)}; } a { diff --git a/app/helpers/builds_helper.rb b/app/helpers/builds_helper.rb index f3aaff9140d..fde297c588e 100644 --- a/app/helpers/builds_helper.rb +++ b/app/helpers/builds_helper.rb @@ -5,4 +5,14 @@ module BuildsHelper build_class += ' retried' if build.retried? build_class end + + def javascript_build_options + { + page_url: namespace_project_build_url(@project.namespace, @project, @build), + build_url: namespace_project_build_url(@project.namespace, @project, @build, :json), + build_status: @build.status, + build_stage: @build.stage, + state1: @build.trace_with_state[:state] + } + end end diff --git a/app/views/projects/builds/show.html.haml b/app/views/projects/builds/show.html.haml index b5e8b0bf6eb..ae7a7ecb392 100644 --- a/app/views/projects/builds/show.html.haml +++ b/app/views/projects/builds/show.html.haml @@ -1,6 +1,5 @@ - @no_container = true - page_title "#{@build.name} (##{@build.id})", "Builds" -- trace_with_state = @build.trace_with_state - header_title project_title(@project, "Builds", project_builds_path(@project)) = render "projects/pipelines/head", build_subnav: true @@ -28,32 +27,27 @@ Runners page .prepend-top-default - - if @build.active? - .autoscroll-container - %button.btn.btn-success.btn-sm#autoscroll-button{:type => "button", :data => {:state => 'disabled'}} enable autoscroll - if @build.erased? .erased.alert.alert-warning - erased_by = "by #{link_to @build.erased_by.name, user_path(@build.erased_by)}" if @build.erased_by Build has been erased #{erased_by.html_safe} #{time_ago_with_tooltip(@build.erased_at)} - else #js-build-scroll.scroll-controls - = link_to '#build-trace', class: 'btn' do - %i.fa.fa-angle-up - = link_to '#down-build-trace', class: 'btn' do - %i.fa.fa-angle-down + .scroll-step + = link_to '#build-trace', class: 'btn' do + %i.fa.fa-angle-up + = link_to '#down-build-trace', class: 'btn' do + %i.fa.fa-angle-down + - if @build.active? + .autoscroll-container + %button.btn.btn-sm#autoscroll-button{:type => "button", :data => {:state => 'disabled'}} + Enable autoscroll %pre.build-trace#build-trace %code.bash.js-build-output = icon("refresh spin", class: "js-build-refresh") - #down-build-trace + #down-build-trace = render "sidebar" - :javascript - new Build({ - page_url: "#{namespace_project_build_url(@project.namespace, @project, @build)}", - build_url: "#{namespace_project_build_url(@project.namespace, @project, @build, :json)}", - build_status: "#{@build.status}", - build_stage: "#{@build.stage}", - state1: "#{trace_with_state[:state]}" - }) +.js-build-options{ data: javascript_build_options } -- cgit v1.2.1 From dd45c5e11eb2b315d89779abf6103e2531e1cc08 Mon Sep 17 00:00:00 2001 From: Jared Deckard Date: Tue, 20 Sep 2016 10:50:32 -0500 Subject: Add javascript unit tests for Build Move comments to the correct location Remove array extension usage Move build options to fixture to match view --- app/assets/javascripts/build.js | 16 +-- spec/javascripts/build_spec.js.es6 | 174 ++++++++++++++++++++++++++++++ spec/javascripts/fixtures/build.html.haml | 57 ++++++++++ 3 files changed, 239 insertions(+), 8 deletions(-) create mode 100644 spec/javascripts/build_spec.js.es6 create mode 100644 spec/javascripts/fixtures/build.html.haml diff --git a/app/assets/javascripts/build.js b/app/assets/javascripts/build.js index 54fed3dd573..3d284e5846f 100644 --- a/app/assets/javascripts/build.js +++ b/app/assets/javascripts/build.js @@ -37,6 +37,7 @@ this.initScrollButtonAffix(); } if (this.buildStatus === "running" || this.buildStatus === "pending") { + // Bind autoscroll button to follow build output $('#autoscroll-button').on('click', function() { var state; state = $(this).data("state"); @@ -47,20 +48,15 @@ $(this).data("state", "enabled"); return $(this).text("Disable autoscroll"); } - // - // Bind autoscroll button to follow build output - // }); Build.interval = setInterval((function(_this) { + // Check for new build output if user still watching build page + // Only valid for runnig build when output changes during time return function() { - if (window.location.href.split("#").first() === _this.pageUrl) { + if (_this.location() === _this.pageUrl) { return _this.getBuildTrace(); } }; - // - // Check for new build output if user still watching build page - // Only valid for runnig build when output changes during time - // })(this), 4000); } } @@ -79,6 +75,10 @@ this.$document.off('scroll.translateSidebar').on('scroll.translateSidebar', this.translateSidebar.bind(this)); }; + Build.prototype.location = function() { + return window.location.href.split("#")[0]; + }; + Build.prototype.getInitialBuildTrace = function() { var removeRefreshStatuses = ['success', 'failed', 'canceled', 'skipped'] diff --git a/spec/javascripts/build_spec.js.es6 b/spec/javascripts/build_spec.js.es6 new file mode 100644 index 00000000000..44485c7745c --- /dev/null +++ b/spec/javascripts/build_spec.js.es6 @@ -0,0 +1,174 @@ +/* eslint-disable */ +//= require build +//= require breakpoints +//= require jquery.nicescroll +//= require turbolinks + +(() => { + describe('Build', () => { + fixture.preload('build.html'); + + beforeEach(function() { + fixture.load('build.html'); + spyOn($, 'ajax'); + }); + + describe('constructor', () => { + beforeEach(function() { + jasmine.clock().install(); + }); + + afterEach(() => { + jasmine.clock().uninstall(); + }); + + describe('setup', function() { + beforeEach(function() { + this.build = new Build(); + }); + + it('copies build options', function() { + expect(this.build.pageUrl).toBe('http://example.com/root/test-build/builds/2'); + expect(this.build.buildUrl).toBe('http://example.com/root/test-build/builds/2.json'); + expect(this.build.buildStatus).toBe('passed'); + expect(this.build.buildStage).toBe('test'); + expect(this.build.state).toBe('buildstate'); + }); + + it('only shows the jobs matching the current stage', function() { + expect($('.build-job[data-stage="build"]').is(':visible')).toBe(false); + expect($('.build-job[data-stage="test"]').is(':visible')).toBe(true); + expect($('.build-job[data-stage="deploy"]').is(':visible')).toBe(false); + }); + + it('selects the current stage in the build dropdown menu', function() { + expect($('.stage-selection').text()).toBe('test'); + }); + + it('updates the jobs when the build dropdown changes', function() { + $('.stage-item:contains("build")').click(); + + expect($('.stage-selection').text()).toBe('build'); + expect($('.build-job[data-stage="build"]').is(':visible')).toBe(true); + expect($('.build-job[data-stage="test"]').is(':visible')).toBe(false); + expect($('.build-job[data-stage="deploy"]').is(':visible')).toBe(false); + }); + }); + + describe('initial build trace', function() { + beforeEach(function() { + new Build(); + }); + + it('displays the initial build trace', function() { + expect($.ajax.calls.count()).toBe(1); + const [{url, dataType, success, context}] = $.ajax.calls.argsFor(0); + expect(url).toBe('http://example.com/root/test-build/builds/2.json'); + expect(dataType).toBe('json'); + expect(success).toEqual(jasmine.any(Function)); + + success.call(context, {trace_html: 'Example', status: 'running'}); + + expect($('#build-trace .js-build-output').text()).toMatch(/Example/); + }); + + it('removes the spinner', function() { + const [{success, context}] = $.ajax.calls.argsFor(0); + success.call(context, {trace_html: 'Example', status: 'success'}); + + expect($('.js-build-refresh').length).toBe(0); + }); + }); + + describe('running build', function() { + beforeEach(function() { + $('.js-build-options').data('buildStatus', 'running'); + this.build = new Build(); + spyOn(this.build, 'location') + .and.returnValue('http://example.com/root/test-build/builds/2'); + }); + + it('updates the build trace on an interval', function() { + jasmine.clock().tick(4001); + + expect($.ajax.calls.count()).toBe(2); + let [{url, dataType, success, context}] = $.ajax.calls.argsFor(1); + expect(url).toBe( + 'http://example.com/root/test-build/builds/2/trace.json?state=buildstate' + ); + expect(dataType).toBe('json'); + expect(success).toEqual(jasmine.any(Function)); + + success.call(context, { + html: 'Update', + status: 'running', + state: 'newstate', + append: true + }); + + expect($('#build-trace .js-build-output').text()).toMatch(/Update/); + expect(this.build.state).toBe('newstate'); + + jasmine.clock().tick(4001); + + expect($.ajax.calls.count()).toBe(3); + [{url, dataType, success, context}] = $.ajax.calls.argsFor(2); + expect(url).toBe( + 'http://example.com/root/test-build/builds/2/trace.json?state=newstate' + ); + expect(dataType).toBe('json'); + expect(success).toEqual(jasmine.any(Function)); + + success.call(context, { + html: 'More', + status: 'running', + state: 'finalstate', + append: true + }); + + expect($('#build-trace .js-build-output').text()).toMatch(/UpdateMore/); + expect(this.build.state).toBe('finalstate'); + }); + + it('replaces the entire build trace', function() { + jasmine.clock().tick(4001); + let [{success, context}] = $.ajax.calls.argsFor(1); + success.call(context, { + html: 'Update', + status: 'running', + append: true + }); + + expect($('#build-trace .js-build-output').text()).toMatch(/Update/); + + jasmine.clock().tick(4001); + [{success, context}] = $.ajax.calls.argsFor(2); + success.call(context, { + html: 'Different', + status: 'running', + append: false + }); + + expect($('#build-trace .js-build-output').text()).not.toMatch(/Update/); + expect($('#build-trace .js-build-output').text()).toMatch(/Different/); + }); + + it('reloads the page when the build is done', function() { + spyOn(Turbolinks, 'visit'); + + jasmine.clock().tick(4001); + let [{success, context}] = $.ajax.calls.argsFor(1); + success.call(context, { + html: 'Final', + status: 'passed', + append: true + }); + + expect(Turbolinks.visit).toHaveBeenCalledWith( + 'http://example.com/root/test-build/builds/2' + ); + }); + }); + }); + }); +})(); diff --git a/spec/javascripts/fixtures/build.html.haml b/spec/javascripts/fixtures/build.html.haml new file mode 100644 index 00000000000..a2bc81c6be7 --- /dev/null +++ b/spec/javascripts/fixtures/build.html.haml @@ -0,0 +1,57 @@ +.build-page + .prepend-top-default + .autoscroll-container + %button.btn.btn-success.btn-sm#autoscroll-button{:type => "button", :data => {:state => 'disabled'}} enable autoscroll + #js-build-scroll.scroll-controls + %a.btn{href: '#build-trace'} + %i.fa.fa-angle-up + %a.btn{href: '#down-build-trace'} + %i.fa.fa-angle-down + %pre.build-trace#build-trace + %code.bash.js-build-output + %i.fa.fa-refresh.fa-spin.js-build-refresh + +%aside.right-sidebar.right-sidebar-expanded.build-sidebar.js-build-sidebar + .block.build-sidebar-header.visible-xs-block.visible-sm-block.append-bottom-default + Build + %strong #1 + %a.gutter-toggle.pull-right.js-sidebar-build-toggle{ href: "#" } + %i.fa.fa-angle-double-right + .blocks-container + .dropdown.build-dropdown + .title Stage + %button.dropdown-menu-toggle{type: 'button', 'data-toggle' => 'dropdown'} + %span.stage-selection More + %i.fa.fa-caret-down + %ul.dropdown-menu + %li + %a.stage-item build + %li + %a.stage-item test + %li + %a.stage-item deploy + .builds-container + .build-job{data: {stage: 'build'}} + %a{href: 'http://example.com/root/test-build/builds/1'} + %i.fa.fa-check + %i.fa.fa-check-circle-o + %span + Setup + .build-job{data: {stage: 'test'}} + %a{href: 'http://example.com/root/test-build/builds/2'} + %i.fa.fa-check + %i.fa.fa-check-circle-o + %span + Tests + .build-job{data: {stage: 'deploy'}} + %a{href: 'http://example.com/root/test-build/builds/3'} + %i.fa.fa-check + %i.fa.fa-check-circle-o + %span + Deploy + +.js-build-options{ data: { page_url: 'http://example.com/root/test-build/builds/2', + build_url: 'http://example.com/root/test-build/builds/2.json', + build_status: 'passed', + build_stage: 'test', + state1: 'buildstate' }} -- cgit v1.2.1 From 4f377364ad2b073e59e8edde86f270c80cdb317a Mon Sep 17 00:00:00 2001 From: "Luke \"Jared\" Bennett" Date: Mon, 31 Oct 2016 14:56:55 +0000 Subject: Added new .eslintrc for jasmine tests and corrected build_spec --- package.json | 1 + spec/javascripts/.eslintrc | 11 +++++++ spec/javascripts/build_spec.js.es6 | 65 +++++++++++++++++++------------------- 3 files changed, 45 insertions(+), 32 deletions(-) create mode 100644 spec/javascripts/.eslintrc diff --git a/package.json b/package.json index a303c9c1eac..e75e070451b 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "eslint-config-airbnb": "^12.0.0", "eslint-plugin-filenames": "^1.1.0", "eslint-plugin-import": "^2.0.1", + "eslint-plugin-jasmine": "^1.8.1", "eslint-plugin-jsx-a11y": "^2.2.3", "eslint-plugin-react": "^6.4.1" } diff --git a/spec/javascripts/.eslintrc b/spec/javascripts/.eslintrc new file mode 100644 index 00000000000..90388929612 --- /dev/null +++ b/spec/javascripts/.eslintrc @@ -0,0 +1,11 @@ +{ + "plugins": ["jasmine"], + "env": { + "jasmine": true + }, + "extends": "plugin:jasmine/recommended", + "rules": { + "prefer-arrow-callback": 0, + "func-names": 0 + } +} diff --git a/spec/javascripts/build_spec.js.es6 b/spec/javascripts/build_spec.js.es6 index 44485c7745c..370944b6a8c 100644 --- a/spec/javascripts/build_spec.js.es6 +++ b/spec/javascripts/build_spec.js.es6 @@ -1,4 +1,5 @@ -/* eslint-disable */ +/* global Build */ +/* eslint-disable no-new */ //= require build //= require breakpoints //= require jquery.nicescroll @@ -8,13 +9,13 @@ describe('Build', () => { fixture.preload('build.html'); - beforeEach(function() { + beforeEach(function () { fixture.load('build.html'); spyOn($, 'ajax'); }); describe('constructor', () => { - beforeEach(function() { + beforeEach(function () { jasmine.clock().install(); }); @@ -22,12 +23,12 @@ jasmine.clock().uninstall(); }); - describe('setup', function() { - beforeEach(function() { + describe('setup', function () { + beforeEach(function () { this.build = new Build(); }); - it('copies build options', function() { + it('copies build options', function () { expect(this.build.pageUrl).toBe('http://example.com/root/test-build/builds/2'); expect(this.build.buildUrl).toBe('http://example.com/root/test-build/builds/2.json'); expect(this.build.buildStatus).toBe('passed'); @@ -35,17 +36,17 @@ expect(this.build.state).toBe('buildstate'); }); - it('only shows the jobs matching the current stage', function() { + it('only shows the jobs matching the current stage', function () { expect($('.build-job[data-stage="build"]').is(':visible')).toBe(false); expect($('.build-job[data-stage="test"]').is(':visible')).toBe(true); expect($('.build-job[data-stage="deploy"]').is(':visible')).toBe(false); }); - it('selects the current stage in the build dropdown menu', function() { + it('selects the current stage in the build dropdown menu', function () { expect($('.stage-selection').text()).toBe('test'); }); - it('updates the jobs when the build dropdown changes', function() { + it('updates the jobs when the build dropdown changes', function () { $('.stage-item:contains("build")').click(); expect($('.stage-selection').text()).toBe('build'); @@ -55,44 +56,44 @@ }); }); - describe('initial build trace', function() { - beforeEach(function() { + describe('initial build trace', function () { + beforeEach(function () { new Build(); }); - it('displays the initial build trace', function() { + it('displays the initial build trace', function () { expect($.ajax.calls.count()).toBe(1); - const [{url, dataType, success, context}] = $.ajax.calls.argsFor(0); + const [{ url, dataType, success, context }] = $.ajax.calls.argsFor(0); expect(url).toBe('http://example.com/root/test-build/builds/2.json'); expect(dataType).toBe('json'); expect(success).toEqual(jasmine.any(Function)); - success.call(context, {trace_html: 'Example', status: 'running'}); + success.call(context, { trace_html: 'Example', status: 'running' }); expect($('#build-trace .js-build-output').text()).toMatch(/Example/); }); - it('removes the spinner', function() { - const [{success, context}] = $.ajax.calls.argsFor(0); - success.call(context, {trace_html: 'Example', status: 'success'}); + it('removes the spinner', function () { + const [{ success, context }] = $.ajax.calls.argsFor(0); + success.call(context, { trace_html: 'Example', status: 'success' }); expect($('.js-build-refresh').length).toBe(0); }); }); - describe('running build', function() { - beforeEach(function() { + describe('running build', function () { + beforeEach(function () { $('.js-build-options').data('buildStatus', 'running'); this.build = new Build(); spyOn(this.build, 'location') .and.returnValue('http://example.com/root/test-build/builds/2'); }); - it('updates the build trace on an interval', function() { + it('updates the build trace on an interval', function () { jasmine.clock().tick(4001); expect($.ajax.calls.count()).toBe(2); - let [{url, dataType, success, context}] = $.ajax.calls.argsFor(1); + let [{ url, dataType, success, context }] = $.ajax.calls.argsFor(1); expect(url).toBe( 'http://example.com/root/test-build/builds/2/trace.json?state=buildstate' ); @@ -103,7 +104,7 @@ html: 'Update', status: 'running', state: 'newstate', - append: true + append: true, }); expect($('#build-trace .js-build-output').text()).toMatch(/Update/); @@ -112,7 +113,7 @@ jasmine.clock().tick(4001); expect($.ajax.calls.count()).toBe(3); - [{url, dataType, success, context}] = $.ajax.calls.argsFor(2); + [{ url, dataType, success, context }] = $.ajax.calls.argsFor(2); expect(url).toBe( 'http://example.com/root/test-build/builds/2/trace.json?state=newstate' ); @@ -123,45 +124,45 @@ html: 'More', status: 'running', state: 'finalstate', - append: true + append: true, }); expect($('#build-trace .js-build-output').text()).toMatch(/UpdateMore/); expect(this.build.state).toBe('finalstate'); }); - it('replaces the entire build trace', function() { + it('replaces the entire build trace', function () { jasmine.clock().tick(4001); - let [{success, context}] = $.ajax.calls.argsFor(1); + let [{ success, context }] = $.ajax.calls.argsFor(1); success.call(context, { html: 'Update', status: 'running', - append: true + append: true, }); expect($('#build-trace .js-build-output').text()).toMatch(/Update/); jasmine.clock().tick(4001); - [{success, context}] = $.ajax.calls.argsFor(2); + [{ success, context }] = $.ajax.calls.argsFor(2); success.call(context, { html: 'Different', status: 'running', - append: false + append: false, }); expect($('#build-trace .js-build-output').text()).not.toMatch(/Update/); expect($('#build-trace .js-build-output').text()).toMatch(/Different/); }); - it('reloads the page when the build is done', function() { + it('reloads the page when the build is done', function () { spyOn(Turbolinks, 'visit'); jasmine.clock().tick(4001); - let [{success, context}] = $.ajax.calls.argsFor(1); + const [{ success, context }] = $.ajax.calls.argsFor(1); success.call(context, { html: 'Final', status: 'passed', - append: true + append: true, }); expect(Turbolinks.visit).toHaveBeenCalledWith( -- cgit v1.2.1