Commit 5e1a7415 authored by Scott Hampton's avatar Scott Hampton

Move test case trace to modal

Move the test case system output from the
table to be in a modal. This will help the table
be more uniform and easier to digest.
parent 9aae3376
<script>
import { GlModal } from '@gitlab/ui';
import { __ } from '~/locale';
import CodeBlock from '~/vue_shared/components/code_block.vue';
export default {
name: 'TestCaseDetails',
components: {
CodeBlock,
GlModal,
},
props: {
modalId: {
type: String,
required: true,
},
testCase: {
type: Object,
required: true,
validator: ({ classname, formattedTime, name }) =>
Boolean(classname) && Boolean(formattedTime) && Boolean(name),
},
},
text: {
name: __('Name'),
duration: __('Execution time'),
trace: __('System output'),
},
modalCloseButton: {
text: __('Close'),
attributes: [{ variant: 'info' }],
},
};
</script>
<template>
<gl-modal
:modal-id="modalId"
:title="testCase.classname"
:action-primary="$options.modalCloseButton"
>
<div class="gl-display-flex gl-flex-wrap gl-mx-n4 gl-my-3">
<strong class="gl-text-right col-sm-3">{{ $options.text.name }}</strong>
<div class="col-sm-9" data-testid="test-case-name">
{{ testCase.name }}
</div>
</div>
<div class="gl-display-flex gl-flex-wrap gl-mx-n4 gl-my-3">
<strong class="gl-text-right col-sm-3">{{ $options.text.duration }}</strong>
<div class="col-sm-9" data-testid="test-case-duration">
{{ testCase.formattedTime }}
</div>
</div>
<div v-if="testCase.system_output" class="gl-display-flex gl-flex-wrap gl-mx-n4 gl-my-3">
<strong class="gl-text-right col-sm-3">{{ $options.text.trace }}</strong>
<div class="col-sm-9" data-testid="test-case-trace">
<code-block :code="testCase.system_output" />
</div>
</div>
</gl-modal>
</template>
......@@ -61,7 +61,7 @@ export default {
<div
v-else-if="!isLoading && showTests"
ref="container"
class="tests-detail position-relative"
class="position-relative"
data-testid="tests-detail"
>
<transition
......@@ -69,13 +69,13 @@ export default {
@before-enter="beforeEnterTransition"
@after-leave="afterLeaveTransition"
>
<div v-if="showSuite" key="detail" class="w-100 position-absolute slide-enter-to-element">
<div v-if="showSuite" key="detail" class="w-100 slide-enter-to-element">
<test-summary :report="getSelectedSuite" show-back @on-back-click="summaryBackClick" />
<test-suite-table />
</div>
<div v-else key="summary" class="w-100 position-absolute slide-enter-from-element">
<div v-else key="summary" class="w-100 slide-enter-from-element">
<test-summary :report="testReports" />
<test-summary-table @row-click="summaryTableRowClick" />
......
<script>
import { mapGetters } from 'vuex';
import { GlTooltipDirective, GlFriendlyWrap, GlIcon, GlButton } from '@gitlab/ui';
import { GlModalDirective, GlTooltipDirective, GlFriendlyWrap, GlIcon, GlButton } from '@gitlab/ui';
import { __ } from '~/locale';
import TestCaseDetails from './test_case_details.vue';
export default {
name: 'TestsSuiteTable',
......@@ -9,9 +10,11 @@ export default {
GlIcon,
GlFriendlyWrap,
GlButton,
TestCaseDetails,
},
directives: {
GlTooltip: GlTooltipDirective,
GlModalDirective,
},
props: {
heading: {
......@@ -43,7 +46,7 @@ export default {
<div role="rowheader" class="table-section section-20">
{{ __('Suite') }}
</div>
<div role="rowheader" class="table-section section-20">
<div role="rowheader" class="table-section section-40">
{{ __('Name') }}
</div>
<div role="rowheader" class="table-section section-10">
......@@ -52,12 +55,12 @@ export default {
<div role="rowheader" class="table-section section-10 text-center">
{{ __('Status') }}
</div>
<div role="rowheader" class="table-section flex-grow-1">
{{ __('Trace'), }}
</div>
<div role="rowheader" class="table-section section-10 text-right">
<div role="rowheader" class="table-section section-10">
{{ __('Duration') }}
</div>
<div role="rowheader" class="table-section section-10">
{{ __('Details'), }}
</div>
</div>
<div
......@@ -72,7 +75,7 @@ export default {
</div>
</div>
<div class="table-section section-20 section-wrap">
<div class="table-section section-40 section-wrap">
<div role="rowheader" class="table-mobile-header">{{ __('Name') }}</div>
<div class="table-mobile-content gl-md-pr-2 gl-overflow-wrap-break">
<gl-friendly-wrap :symbols="$options.wrapSymbols" :text="testCase.name" />
......@@ -107,24 +110,24 @@ export default {
</div>
</div>
<div class="table-section flex-grow-1">
<div role="rowheader" class="table-mobile-header">{{ __('Trace'), }}</div>
<div class="table-mobile-content">
<pre
v-if="testCase.system_output"
class="build-trace build-trace-rounded text-left"
><code class="bash p-0">{{testCase.system_output}}</code></pre>
</div>
</div>
<div class="table-section section-10 section-wrap">
<div role="rowheader" class="table-mobile-header">
{{ __('Duration') }}
</div>
<div class="table-mobile-content text-right pr-sm-1">
<div class="table-mobile-content pr-sm-1">
{{ testCase.formattedTime }}
</div>
</div>
<div class="table-section section-10 section-wrap">
<div role="rowheader" class="table-mobile-header">{{ __('Details'), }}</div>
<div class="table-mobile-content">
<gl-button v-gl-modal-directive="`test-case-details-${index}`">{{
__('View details')
}}</gl-button>
<test-case-details :modal-id="`test-case-details-${index}`" :test-case="testCase" />
</div>
</div>
</div>
</div>
......
---
title: Move test report system output to modal
merge_request: 45575
author:
type: changed
......@@ -10652,6 +10652,9 @@ msgstr ""
msgid "Excluding merge commits. Limited to 6,000 commits."
msgstr ""
msgid "Execution time"
msgstr ""
msgid "Existing branch name, tag, or commit SHA"
msgstr ""
......@@ -25418,6 +25421,9 @@ msgstr ""
msgid "System metrics (Kubernetes)"
msgstr ""
msgid "System output"
msgstr ""
msgid "Table of Contents"
msgstr ""
......@@ -27508,9 +27514,6 @@ msgstr ""
msgid "TotalRefCountIndicator|1000+"
msgstr ""
msgid "Trace"
msgstr ""
msgid "Tracing"
msgstr ""
......
import { shallowMount, createLocalVue } from '@vue/test-utils';
import { GlModal } from '@gitlab/ui';
import TestCaseDetails from '~/pipelines/components/test_reports/test_case_details.vue';
import CodeBlock from '~/vue_shared/components/code_block.vue';
const localVue = createLocalVue();
describe('Test case details', () => {
let wrapper;
const defaultTestCase = {
classname: 'spec.test_spec',
name: 'Test#something cool',
formattedTime: '10.04ms',
system_output: 'Line 42 is broken',
};
const findModal = () => wrapper.find(GlModal);
const findName = () => wrapper.find('[data-testid="test-case-name"]');
const findDuration = () => wrapper.find('[data-testid="test-case-duration"]');
const findSystemOutput = () => wrapper.find('[data-testid="test-case-trace"]');
const createComponent = (testCase = {}) => {
wrapper = shallowMount(TestCaseDetails, {
localVue,
propsData: {
modalId: 'my-modal',
testCase: {
...defaultTestCase,
...testCase,
},
},
stubs: { CodeBlock, GlModal },
});
};
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
describe('required details', () => {
beforeEach(() => {
createComponent();
});
it('renders the test case classname as modal title', () => {
expect(findModal().attributes('title')).toBe(defaultTestCase.classname);
});
it('renders the test case name', () => {
expect(findName().text()).toBe(defaultTestCase.name);
});
it('renders the test case duration', () => {
expect(findDuration().text()).toBe(defaultTestCase.formattedTime);
});
});
describe('when test case has system output', () => {
it('renders the test case system output', () => {
createComponent();
expect(findSystemOutput().text()).toBe(defaultTestCase.system_output);
});
});
describe('when test case does not have system output', () => {
it('does not render the test case system output', () => {
createComponent({ system_output: null });
expect(findSystemOutput().exists()).toBe(false);
});
});
});
import Vuex from 'vuex';
import { shallowMount, createLocalVue } from '@vue/test-utils';
import { getJSONFixture } from 'helpers/fixtures';
import { GlButton } from '@gitlab/ui';
import { GlButton, GlFriendlyWrap } from '@gitlab/ui';
import SuiteTable from '~/pipelines/components/test_reports/test_suite_table.vue';
import * as getters from '~/pipelines/stores/test_reports/getters';
import { TestStatus } from '~/pipelines/constants';
......@@ -40,6 +40,7 @@ describe('Test reports suite table', () => {
wrapper = shallowMount(SuiteTable, {
store,
localVue,
stubs: { GlFriendlyWrap },
});
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment