From 12a777b2216f1887acd3dfc888e9bca775559222 Mon Sep 17 00:00:00 2001 From: Filipa Lacerda Date: Thu, 13 Jun 2019 13:21:44 +0100 Subject: [PATCH 1/2] Adds specs and changelog - squash --- .../javascripts/jobs/components/job_log.vue | 11 +++--- .../generate-spans-for-sections.yml | 5 +++ .../jobs/components/job_log_spec.js | 37 +++++++++++++++++++ spec/javascripts/jobs/mock_data.js | 15 ++++++++ 4 files changed, 62 insertions(+), 6 deletions(-) create mode 100644 changelogs/unreleased/generate-spans-for-sections.yml diff --git a/app/assets/javascripts/jobs/components/job_log.vue b/app/assets/javascripts/jobs/components/job_log.vue index 8e4557e2b6c..28d1490259d 100644 --- a/app/assets/javascripts/jobs/components/job_log.vue +++ b/app/assets/javascripts/jobs/components/job_log.vue @@ -49,12 +49,12 @@ export default { }, removeEventListener() { this.$el - .querySelector('.js-section-start') - .removeEventListener('click', this.handleSectionClick); + .querySelectorAll('.js-section-start') + .forEach(el => el.removeEventListener('click', this.handleSectionClick)); }, /** * The collapsible rows are sent in HTML from the backend - * We need to add a onclick handler for the divs that match `.js-section-start` + * We need tos add a onclick handler for the divs that match `.js-section-start` * */ handleCollapsibleRows() { @@ -68,13 +68,12 @@ export default { */ handleSectionClick(evt) { const clickedArrow = evt.currentTarget; - // toggle the arrow class clickedArrow.classList.toggle('fa-caret-right'); clickedArrow.classList.toggle('fa-caret-down'); - const dataSection = clickedArrow.getAttribute('data-section'); - const sibilings = this.$el.querySelectorAll(`.js-s_${dataSection}:not(.js-section-header)`); + const { section } = clickedArrow.dataset; + const sibilings = this.$el.querySelectorAll(`.js-s_${section}:not(.js-section-header)`); sibilings.forEach(row => row.classList.toggle('hidden')); }, diff --git a/changelogs/unreleased/generate-spans-for-sections.yml b/changelogs/unreleased/generate-spans-for-sections.yml new file mode 100644 index 00000000000..e167d66490f --- /dev/null +++ b/changelogs/unreleased/generate-spans-for-sections.yml @@ -0,0 +1,5 @@ +--- +title: Adds collapsible sections for job log +merge_request: 28642 +author: +type: added diff --git a/spec/javascripts/jobs/components/job_log_spec.js b/spec/javascripts/jobs/components/job_log_spec.js index dc0f77ceb80..4e94ae710c0 100644 --- a/spec/javascripts/jobs/components/job_log_spec.js +++ b/spec/javascripts/jobs/components/job_log_spec.js @@ -3,6 +3,7 @@ import component from '~/jobs/components/job_log.vue'; import createStore from '~/jobs/store'; import { mountComponentWithStore } from 'spec/helpers/vue_mount_component_helper'; import { resetStore } from '../store/helpers'; +import { logWithCollapsibleSections } from '../mock_data'; describe('Job Log', () => { const Component = Vue.extend(component); @@ -62,4 +63,40 @@ describe('Job Log', () => { expect(vm.$el.querySelector('.js-log-animation')).toBeNull(); }); }); + + describe('Collapsible sections', () => { + beforeEach(() => { + vm = mountComponentWithStore(Component, { + props: { + trace: logWithCollapsibleSections.html, + isComplete: true, + }, + store, + }); + }); + + it('renders open arrow', () => { + expect(vm.$el.querySelector('.fa-caret-down')).not.toBeNull(); + }); + + it('toggles hidden class to the sibilings rows when arrow is clicked', done => { + vm.$nextTick() + .then(() => { + const { section } = vm.$el.querySelector('.js-section-start').dataset; + vm.$el.querySelector('.js-section-start').click(); + + vm.$el.querySelectorAll(`.js-s_${section}:not(.js-section-header)`).forEach(el => { + expect(el.classList.contains('hidden')).toEqual(true); + }); + + vm.$el.querySelector('.js-section-start').click(); + + vm.$el.querySelectorAll(`.js-s_${section}:not(.js-section-header)`).forEach(el => { + expect(el.classList.contains('hidden')).toEqual(false); + }); + }) + .then(done) + .catch(done.fail); + }); + }); }); diff --git a/spec/javascripts/jobs/mock_data.js b/spec/javascripts/jobs/mock_data.js index 88b0bb206ee..0a6d6006adf 100644 --- a/spec/javascripts/jobs/mock_data.js +++ b/spec/javascripts/jobs/mock_data.js @@ -1190,3 +1190,18 @@ export const jobsInStage = { path: '/gitlab-org/gitlab-shell/pipelines/27#build', dropdown_path: '/gitlab-org/gitlab-shell/pipelines/27/stage.json?stage=build', }; + +export const logWithCollapsibleSections = { + append: false, + complete: true, + html: + '
Running after script...
$ date
Mon Jun 3 14:16:46 UTC 2019
Not uploading cache debian-stretch-ruby-2.6.3-node-10.x-3 due to policy
Uploading artifacts...
coverage/: found 5 matching files
knapsack/: found 4 matching files
rspec_flaky/: found 4 matching files
rspec_profiling/: found 1 matching files
WARNING: tmp/capybara/: no matching files
Uploading artifacts to coordinator... ok id=224162288 responseStatus=201 Created token=bBmyXJNW
Uploading artifacts...
junit_rspec.xml: found 1 matching files
Uploading artifacts to coordinator... ok id=224162288 responseStatus=201 Created token=bBmyXJNW
Job succeeded
', + id: 1385, + offset: 0, + size: 78815, + state: + 'eyJvZmZzZXQiOjc4ODE1LCJuX29wZW5fdGFncyI6MCwiZmdfY29sb3IiOm51bGwsImJnX2NvbG9yIjpudWxsLCJzdHlsZV9tYXNrIjowLCJzZWN0aW9ucyI6W10sImxpbmVub19pbl9zZWN0aW9uIjoxMX0=', + status: 'success', + total: 78815, + truncated: false, +}; From af55b429503a8596acb75dbb13d98f191cb3aa7d Mon Sep 17 00:00:00 2001 From: Filipa Lacerda Date: Fri, 14 Jun 2019 10:03:53 +0100 Subject: [PATCH 2/2] Update class names --- app/assets/javascripts/jobs/components/job_log.vue | 2 +- lib/gitlab/ci/ansi2html.rb | 2 +- spec/features/projects/jobs/user_browses_job_spec.rb | 4 ++-- spec/javascripts/jobs/components/job_log_spec.js | 4 ++-- spec/javascripts/jobs/mock_data.js | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/assets/javascripts/jobs/components/job_log.vue b/app/assets/javascripts/jobs/components/job_log.vue index 28d1490259d..d611b370ab9 100644 --- a/app/assets/javascripts/jobs/components/job_log.vue +++ b/app/assets/javascripts/jobs/components/job_log.vue @@ -73,7 +73,7 @@ export default { clickedArrow.classList.toggle('fa-caret-down'); const { section } = clickedArrow.dataset; - const sibilings = this.$el.querySelectorAll(`.js-s_${section}:not(.js-section-header)`); + const sibilings = this.$el.querySelectorAll(`.js-s-${section}:not(.js-section-header)`); sibilings.forEach(row => row.classList.toggle('hidden')); }, diff --git a/lib/gitlab/ci/ansi2html.rb b/lib/gitlab/ci/ansi2html.rb index 7f98cfa4f79..09caf165115 100644 --- a/lib/gitlab/ci/ansi2html.rb +++ b/lib/gitlab/ci/ansi2html.rb @@ -309,7 +309,7 @@ module Gitlab if @sections.any? css_classes << "section" css_classes << "js-section-header" if @lineno_in_section == 0 - css_classes += sections.map { |section| "js-s_#{section}" } + css_classes += sections.map { |section| "js-s-#{section}" } end @out << %{} diff --git a/spec/features/projects/jobs/user_browses_job_spec.rb b/spec/features/projects/jobs/user_browses_job_spec.rb index 1d6af95938f..07ebc2f4792 100644 --- a/spec/features/projects/jobs/user_browses_job_spec.rb +++ b/spec/features/projects/jobs/user_browses_job_spec.rb @@ -42,12 +42,12 @@ describe 'User browses a job', :js do text_to_hide = "Cloning into '/nolith/ci-tests'" expect(page).to have_content(text_to_hide) - expect(page).to have_css('.js-s_get-sources') + expect(page).to have_css('.js-s-get-sources') find('.js-section-start[data-section="get-sources"]').click expect(page).not_to have_content(text_to_hide) - expect(page).to have_no_css('.js-s_get-sources') + expect(page).to have_no_css('.js-s-get-sources') end end diff --git a/spec/javascripts/jobs/components/job_log_spec.js b/spec/javascripts/jobs/components/job_log_spec.js index 4e94ae710c0..7e2ec2ec3f7 100644 --- a/spec/javascripts/jobs/components/job_log_spec.js +++ b/spec/javascripts/jobs/components/job_log_spec.js @@ -85,13 +85,13 @@ describe('Job Log', () => { const { section } = vm.$el.querySelector('.js-section-start').dataset; vm.$el.querySelector('.js-section-start').click(); - vm.$el.querySelectorAll(`.js-s_${section}:not(.js-section-header)`).forEach(el => { + vm.$el.querySelectorAll(`.js-s-${section}:not(.js-section-header)`).forEach(el => { expect(el.classList.contains('hidden')).toEqual(true); }); vm.$el.querySelector('.js-section-start').click(); - vm.$el.querySelectorAll(`.js-s_${section}:not(.js-section-header)`).forEach(el => { + vm.$el.querySelectorAll(`.js-s-${section}:not(.js-section-header)`).forEach(el => { expect(el.classList.contains('hidden')).toEqual(false); }); }) diff --git a/spec/javascripts/jobs/mock_data.js b/spec/javascripts/jobs/mock_data.js index 0a6d6006adf..5d25d6b4ca2 100644 --- a/spec/javascripts/jobs/mock_data.js +++ b/spec/javascripts/jobs/mock_data.js @@ -1195,7 +1195,7 @@ export const logWithCollapsibleSections = { append: false, complete: true, html: - '
Running after script...
$ date
Mon Jun 3 14:16:46 UTC 2019
Not uploading cache debian-stretch-ruby-2.6.3-node-10.x-3 due to policy
Uploading artifacts...
coverage/: found 5 matching files
knapsack/: found 4 matching files
rspec_flaky/: found 4 matching files
rspec_profiling/: found 1 matching files
WARNING: tmp/capybara/: no matching files
Uploading artifacts to coordinator... ok id=224162288 responseStatus=201 Created token=bBmyXJNW
Uploading artifacts...
junit_rspec.xml: found 1 matching files
Uploading artifacts to coordinator... ok id=224162288 responseStatus=201 Created token=bBmyXJNW
Job succeeded
', + '
Running after script...
$ date
Mon Jun 3 14:16:46 UTC 2019
Not uploading cache debian-stretch-ruby-2.6.3-node-10.x-3 due to policy
Uploading artifacts...
coverage/: found 5 matching files
knapsack/: found 4 matching files
rspec_flaky/: found 4 matching files
rspec_profiling/: found 1 matching files
WARNING: tmp/capybara/: no matching files
Uploading artifacts to coordinator... ok id=224162288 responseStatus=201 Created token=bBmyXJNW
Uploading artifacts...
junit_rspec.xml: found 1 matching files
Uploading artifacts to coordinator... ok id=224162288 responseStatus=201 Created token=bBmyXJNW
Job succeeded
', id: 1385, offset: 0, size: 78815,