Commit 65a36f9d authored by Igor Drozdov's avatar Igor Drozdov

Merge branch '201840-link-testwidget' into 'master'

Link to test reports from MR Widget

Closes #201840

See merge request gitlab-org/gitlab!29729
parents 96106357 8717baed
...@@ -6,7 +6,9 @@ import ReportSection from './report_section.vue'; ...@@ -6,7 +6,9 @@ import ReportSection from './report_section.vue';
import SummaryRow from './summary_row.vue'; import SummaryRow from './summary_row.vue';
import IssuesList from './issues_list.vue'; import IssuesList from './issues_list.vue';
import Modal from './modal.vue'; import Modal from './modal.vue';
import { GlButton } from '@gitlab/ui';
import createStore from '../store'; import createStore from '../store';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { summaryTextBuilder, reportTextBuilder, statusIcon } from '../store/utils'; import { summaryTextBuilder, reportTextBuilder, statusIcon } from '../store/utils';
export default { export default {
...@@ -17,12 +19,19 @@ export default { ...@@ -17,12 +19,19 @@ export default {
SummaryRow, SummaryRow,
IssuesList, IssuesList,
Modal, Modal,
GlButton,
}, },
mixins: [glFeatureFlagsMixin()],
props: { props: {
endpoint: { endpoint: {
type: String, type: String,
required: true, required: true,
}, },
pipelinePath: {
type: String,
required: false,
default: '',
},
}, },
componentNames, componentNames,
computed: { computed: {
...@@ -43,6 +52,12 @@ export default { ...@@ -43,6 +52,12 @@ export default {
return summaryTextBuilder(s__('Reports|Test summary'), this.summary); return summaryTextBuilder(s__('Reports|Test summary'), this.summary);
}, },
testTabURL() {
return `${this.pipelinePath}/test_report`;
},
showViewFullReport() {
return Boolean(this.glFeatures.junitPipelineView) && this.pipelinePath.length;
},
}, },
created() { created() {
this.setEndpoint(this.endpoint); this.setEndpoint(this.endpoint);
...@@ -98,6 +113,11 @@ export default { ...@@ -98,6 +113,11 @@ export default {
:has-issues="reports.length > 0" :has-issues="reports.length > 0"
class="mr-widget-section grouped-security-reports mr-report" class="mr-widget-section grouped-security-reports mr-report"
> >
<template v-if="showViewFullReport" #actionButtons>
<gl-button :href="testTabURL" icon="external-link" data-testid="group-test-reports-full-link">
{{ s__('ciReport|View full report') }}
</gl-button>
</template>
<template #body> <template #body>
<div class="mr-widget-grouped-section report-block"> <div class="mr-widget-grouped-section report-block">
<template v-for="(report, i) in reports"> <template v-for="(report, i) in reports">
......
...@@ -384,6 +384,7 @@ export default { ...@@ -384,6 +384,7 @@ export default {
v-if="mr.testResultsPath" v-if="mr.testResultsPath"
class="js-reports-container" class="js-reports-container"
:endpoint="mr.testResultsPath" :endpoint="mr.testResultsPath"
:pipeline-path="mr.mergeRequestAddCiConfigPath"
/> />
<terraform-plan v-if="mr.terraformReportsPath" :endpoint="mr.terraformReportsPath" /> <terraform-plan v-if="mr.terraformReportsPath" :endpoint="mr.terraformReportsPath" />
......
...@@ -40,6 +40,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo ...@@ -40,6 +40,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
before_action do before_action do
push_frontend_feature_flag(:vue_issuable_sidebar, @project.group) push_frontend_feature_flag(:vue_issuable_sidebar, @project.group)
push_frontend_feature_flag(:junit_pipeline_view, @project.group)
end end
around_action :allow_gitaly_ref_name_caching, only: [:index, :show, :discussions] around_action :allow_gitaly_ref_name_caching, only: [:index, :show, :discussions]
......
---
title: Link to test reports from MR Widget
merge_request: 29729
author:
type: added
...@@ -367,6 +367,7 @@ export default { ...@@ -367,6 +367,7 @@ export default {
v-if="mr.testResultsPath" v-if="mr.testResultsPath"
class="js-reports-container" class="js-reports-container"
:endpoint="mr.testResultsPath" :endpoint="mr.testResultsPath"
:pipeline-path="mr.mergeRequestAddCiConfigPath"
/> />
<terraform-plan v-if="mr.terraformReportsPath" :endpoint="mr.terraformReportsPath" /> <terraform-plan v-if="mr.terraformReportsPath" :endpoint="mr.terraformReportsPath" />
......
...@@ -15,20 +15,29 @@ localVue.use(Vuex); ...@@ -15,20 +15,29 @@ localVue.use(Vuex);
describe('Grouped test reports app', () => { describe('Grouped test reports app', () => {
const endpoint = 'endpoint.json'; const endpoint = 'endpoint.json';
const pipelinePath = '/path/to/pipeline';
const Component = localVue.extend(GroupedTestReportsApp); const Component = localVue.extend(GroupedTestReportsApp);
let wrapper; let wrapper;
let mockStore; let mockStore;
const mountComponent = () => { const mountComponent = ({
glFeatures = { junitPipelineView: false },
props = { pipelinePath },
} = {}) => {
wrapper = mount(Component, { wrapper = mount(Component, {
store: mockStore, store: mockStore,
localVue, localVue,
propsData: { propsData: {
endpoint, endpoint,
pipelinePath,
...props,
}, },
methods: { methods: {
fetchReports: () => {}, fetchReports: () => {},
}, },
provide: {
glFeatures,
},
}); });
}; };
...@@ -39,6 +48,7 @@ describe('Grouped test reports app', () => { ...@@ -39,6 +48,7 @@ describe('Grouped test reports app', () => {
}; };
const findHeader = () => wrapper.find('[data-testid="report-section-code-text"]'); const findHeader = () => wrapper.find('[data-testid="report-section-code-text"]');
const findFullTestReportLink = () => wrapper.find('[data-testid="group-test-reports-full-link"]');
const findSummaryDescription = () => wrapper.find('[data-testid="test-summary-row-description"]'); const findSummaryDescription = () => wrapper.find('[data-testid="test-summary-row-description"]');
const findIssueDescription = () => wrapper.find('[data-testid="test-issue-body-description"]'); const findIssueDescription = () => wrapper.find('[data-testid="test-issue-body-description"]');
const findAllIssueDescriptions = () => const findAllIssueDescriptions = () =>
...@@ -67,6 +77,38 @@ describe('Grouped test reports app', () => { ...@@ -67,6 +77,38 @@ describe('Grouped test reports app', () => {
}); });
}); });
describe('`View full report` button', () => {
it('should not render the full test report link', () => {
expect(findFullTestReportLink().exists()).toBe(false);
});
describe('With junitPipelineView feature flag enabled', () => {
beforeEach(() => {
mountComponent({ glFeatures: { junitPipelineView: true } });
});
it('should render the full test report link', () => {
const fullTestReportLink = findFullTestReportLink();
expect(fullTestReportLink.exists()).toBe(true);
expect(fullTestReportLink.attributes('href')).toBe(`${pipelinePath}/test_report`);
});
});
describe('Without a pipelinePath', () => {
beforeEach(() => {
mountComponent({
glFeatures: { junitPipelineView: true },
props: { pipelinePath: '' },
});
});
it('should not render the full test report link', () => {
expect(findFullTestReportLink().exists()).toBe(false);
});
});
});
describe('with new failed result', () => { describe('with new failed result', () => {
beforeEach(() => { beforeEach(() => {
setReports(newFailedTestReports); setReports(newFailedTestReports);
......
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