Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
3f078050
Commit
3f078050
authored
Mar 30, 2021
by
Scott Hampton
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Link to test file in test report widget
Add a link to the test case file in the test report MR widget modal.
parent
c84d9415
Changes
17
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
104 additions
and
41 deletions
+104
-41
app/assets/javascripts/reports/constants.js
app/assets/javascripts/reports/constants.js
+1
-1
app/assets/javascripts/reports/grouped_test_report/components/modal.vue
...ascripts/reports/grouped_test_report/components/modal.vue
+12
-9
app/assets/javascripts/reports/grouped_test_report/grouped_test_reports_app.vue
.../reports/grouped_test_report/grouped_test_reports_app.vue
+9
-2
app/assets/javascripts/reports/grouped_test_report/store/actions.js
.../javascripts/reports/grouped_test_report/store/actions.js
+1
-1
app/assets/javascripts/reports/grouped_test_report/store/mutation_types.js
...ripts/reports/grouped_test_report/store/mutation_types.js
+1
-1
app/assets/javascripts/reports/grouped_test_report/store/mutations.js
...avascripts/reports/grouped_test_report/store/mutations.js
+14
-5
app/assets/javascripts/reports/grouped_test_report/store/state.js
...ts/javascripts/reports/grouped_test_report/store/state.js
+7
-7
app/assets/javascripts/reports/grouped_test_report/store/utils.js
...ts/javascripts/reports/grouped_test_report/store/utils.js
+9
-0
app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue
...avascripts/vue_merge_request_widget/mr_widget_options.vue
+1
-0
changelogs/unreleased/22336-link-test-report-widget-to-file.yml
...logs/unreleased/22336-link-test-report-widget-to-file.yml
+5
-0
ee/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue
...avascripts/vue_merge_request_widget/mr_widget_options.vue
+1
-0
locale/gitlab.pot
locale/gitlab.pot
+3
-3
spec/frontend/reports/grouped_test_report/components/modal_spec.js
...tend/reports/grouped_test_report/components/modal_spec.js
+6
-3
spec/frontend/reports/grouped_test_report/grouped_test_reports_app_spec.js
...orts/grouped_test_report/grouped_test_reports_app_spec.js
+3
-1
spec/frontend/reports/grouped_test_report/store/actions_spec.js
...rontend/reports/grouped_test_report/store/actions_spec.js
+11
-6
spec/frontend/reports/grouped_test_report/store/mutations_spec.js
...ntend/reports/grouped_test_report/store/mutations_spec.js
+6
-2
spec/frontend/reports/grouped_test_report/store/utils_spec.js
.../frontend/reports/grouped_test_report/store/utils_spec.js
+14
-0
No files found.
app/assets/javascripts/reports/constants.js
View file @
3f078050
export
const
fieldTypes
=
{
export
const
fieldTypes
=
{
codeBock
:
'
codeBlock
'
,
codeB
l
ock
:
'
codeBlock
'
,
link
:
'
link
'
,
link
:
'
link
'
,
seconds
:
'
seconds
'
,
seconds
:
'
seconds
'
,
text
:
'
text
'
,
text
:
'
text
'
,
...
...
app/assets/javascripts/reports/grouped_test_report/components/modal.vue
View file @
3f078050
...
@@ -25,6 +25,14 @@ export default {
...
@@ -25,6 +25,14 @@ export default {
required
:
true
,
required
:
true
,
},
},
},
},
computed
:
{
filteredModalData
()
{
// Filter out the properties that don't have a value
return
Object
.
fromEntries
(
Object
.
entries
(
this
.
modalData
).
filter
((
data
)
=>
Boolean
(
data
[
1
].
value
)),
);
},
},
fieldTypes
,
fieldTypes
,
};
};
</
script
>
</
script
>
...
@@ -36,23 +44,18 @@ export default {
...
@@ -36,23 +44,18 @@ export default {
:hide-footer=
"true"
:hide-footer=
"true"
@
hide=
"$emit('hide')"
@
hide=
"$emit('hide')"
>
>
<div
<div
v-for=
"(field, key, index) in filteredModalData"
:key=
"index"
class=
"row gl-mt-3 gl-mb-3"
>
v-for=
"(field, key, index) in modalData"
v-if=
"field.value"
:key=
"index"
class=
"row gl-mt-3 gl-mb-3"
>
<strong
class=
"col-sm-3 text-right"
>
{{
field
.
text
}}
:
</strong>
<strong
class=
"col-sm-3 text-right"
>
{{
field
.
text
}}
:
</strong>
<div
class=
"col-sm-9 text-secondary"
>
<div
class=
"col-sm-9 text-secondary"
>
<code-block
v-if=
"field.type === $options.fieldTypes.codeBock"
:code=
"field.value"
/>
<code-block
v-if=
"field.type === $options.fieldTypes.codeB
l
ock"
:code=
"field.value"
/>
<gl-link
<gl-link
v-else-if=
"field.type === $options.fieldTypes.link"
v-else-if=
"field.type === $options.fieldTypes.link"
:href=
"field.value"
:href=
"field.value
.path
"
target=
"_blank"
target=
"_blank"
>
>
{{
field
.
value
}}
{{
field
.
value
.
text
}}
</gl-link>
</gl-link>
<gl-sprintf
<gl-sprintf
...
...
app/assets/javascripts/reports/grouped_test_report/grouped_test_reports_app.vue
View file @
3f078050
...
@@ -39,6 +39,10 @@ export default {
...
@@ -39,6 +39,10 @@ export default {
required
:
false
,
required
:
false
,
default
:
''
,
default
:
''
,
},
},
headBlobPath
:
{
type
:
String
,
required
:
true
,
},
},
},
componentNames
,
componentNames
,
computed
:
{
computed
:
{
...
@@ -73,12 +77,15 @@ export default {
...
@@ -73,12 +77,15 @@ export default {
},
},
},
},
created
()
{
created
()
{
this
.
setEndpoint
(
this
.
endpoint
);
this
.
setPaths
({
endpoint
:
this
.
endpoint
,
headBlobPath
:
this
.
headBlobPath
,
});
this
.
fetchReports
();
this
.
fetchReports
();
},
},
methods
:
{
methods
:
{
...
mapActions
([
'
set
Endpoint
'
,
'
fetchReports
'
,
'
closeModal
'
]),
...
mapActions
([
'
set
Paths
'
,
'
fetchReports
'
,
'
closeModal
'
]),
reportText
(
report
)
{
reportText
(
report
)
{
const
{
name
,
summary
}
=
report
||
{};
const
{
name
,
summary
}
=
report
||
{};
...
...
app/assets/javascripts/reports/grouped_test_report/store/actions.js
View file @
3f078050
...
@@ -4,7 +4,7 @@ import httpStatusCodes from '../../../lib/utils/http_status';
...
@@ -4,7 +4,7 @@ import httpStatusCodes from '../../../lib/utils/http_status';
import
Poll
from
'
../../../lib/utils/poll
'
;
import
Poll
from
'
../../../lib/utils/poll
'
;
import
*
as
types
from
'
./mutation_types
'
;
import
*
as
types
from
'
./mutation_types
'
;
export
const
set
Endpoint
=
({
commit
},
endpoint
)
=>
commit
(
types
.
SET_ENDPOINT
,
endpoint
);
export
const
set
Paths
=
({
commit
},
paths
)
=>
commit
(
types
.
SET_PATHS
,
paths
);
export
const
requestReports
=
({
commit
})
=>
commit
(
types
.
REQUEST_REPORTS
);
export
const
requestReports
=
({
commit
})
=>
commit
(
types
.
REQUEST_REPORTS
);
...
...
app/assets/javascripts/reports/grouped_test_report/store/mutation_types.js
View file @
3f078050
export
const
SET_
ENDPOINT
=
'
SET_ENDPOINT
'
;
export
const
SET_
PATHS
=
'
SET_PATHS
'
;
export
const
REQUEST_REPORTS
=
'
REQUEST_REPORTS
'
;
export
const
REQUEST_REPORTS
=
'
REQUEST_REPORTS
'
;
export
const
RECEIVE_REPORTS_SUCCESS
=
'
RECEIVE_REPORTS_SUCCESS
'
;
export
const
RECEIVE_REPORTS_SUCCESS
=
'
RECEIVE_REPORTS_SUCCESS
'
;
...
...
app/assets/javascripts/reports/grouped_test_report/store/mutations.js
View file @
3f078050
import
*
as
types
from
'
./mutation_types
'
;
import
*
as
types
from
'
./mutation_types
'
;
import
{
countRecentlyFailedTests
}
from
'
./utils
'
;
import
{
countRecentlyFailedTests
,
formatFilePath
}
from
'
./utils
'
;
export
default
{
export
default
{
[
types
.
SET_
ENDPOINT
](
state
,
endpoint
)
{
[
types
.
SET_
PATHS
](
state
,
{
endpoint
,
headBlobPath
}
)
{
state
.
endpoint
=
endpoint
;
state
.
endpoint
=
endpoint
;
state
.
headBlobPath
=
headBlobPath
;
},
},
[
types
.
REQUEST_REPORTS
](
state
)
{
[
types
.
REQUEST_REPORTS
](
state
)
{
state
.
isLoading
=
true
;
state
.
isLoading
=
true
;
...
@@ -42,17 +43,25 @@ export default {
...
@@ -42,17 +43,25 @@ export default {
state
.
status
=
null
;
state
.
status
=
null
;
},
},
[
types
.
SET_ISSUE_MODAL_DATA
](
state
,
payload
)
{
[
types
.
SET_ISSUE_MODAL_DATA
](
state
,
payload
)
{
state
.
modal
.
title
=
payload
.
issue
.
name
;
const
{
issue
}
=
payload
;
state
.
modal
.
title
=
issue
.
name
;
Object
.
keys
(
payload
.
issue
).
forEach
((
key
)
=>
{
Object
.
keys
(
issue
).
forEach
((
key
)
=>
{
if
(
Object
.
prototype
.
hasOwnProperty
.
call
(
state
.
modal
.
data
,
key
))
{
if
(
Object
.
prototype
.
hasOwnProperty
.
call
(
state
.
modal
.
data
,
key
))
{
state
.
modal
.
data
[
key
]
=
{
state
.
modal
.
data
[
key
]
=
{
...
state
.
modal
.
data
[
key
],
...
state
.
modal
.
data
[
key
],
value
:
payload
.
issue
[
key
],
value
:
issue
[
key
],
};
};
}
}
});
});
if
(
issue
.
file
)
{
state
.
modal
.
data
.
filename
.
value
=
{
text
:
issue
.
file
,
path
:
`
${
state
.
headBlobPath
}
/
${
formatFilePath
(
issue
.
file
)}
`
,
};
}
state
.
modal
.
open
=
true
;
state
.
modal
.
open
=
true
;
},
},
[
types
.
RESET_ISSUE_MODAL_DATA
](
state
)
{
[
types
.
RESET_ISSUE_MODAL_DATA
](
state
)
{
...
...
app/assets/javascripts/reports/grouped_test_report/store/state.js
View file @
3f078050
...
@@ -41,16 +41,16 @@ export default () => ({
...
@@ -41,16 +41,16 @@ export default () => ({
open
:
false
,
open
:
false
,
data
:
{
data
:
{
class
:
{
value
:
null
,
text
:
s__
(
'
Reports|Class
'
),
type
:
fieldTypes
.
link
,
},
classname
:
{
classname
:
{
value
:
null
,
value
:
null
,
text
:
s__
(
'
Reports|Classname
'
),
text
:
s__
(
'
Reports|Classname
'
),
type
:
fieldTypes
.
text
,
type
:
fieldTypes
.
text
,
},
},
filename
:
{
value
:
null
,
text
:
s__
(
'
Reports|Filename
'
),
type
:
fieldTypes
.
link
,
},
execution_time
:
{
execution_time
:
{
value
:
null
,
value
:
null
,
text
:
s__
(
'
Reports|Execution time
'
),
text
:
s__
(
'
Reports|Execution time
'
),
...
@@ -59,12 +59,12 @@ export default () => ({
...
@@ -59,12 +59,12 @@ export default () => ({
failure
:
{
failure
:
{
value
:
null
,
value
:
null
,
text
:
s__
(
'
Reports|Failure
'
),
text
:
s__
(
'
Reports|Failure
'
),
type
:
fieldTypes
.
codeBock
,
type
:
fieldTypes
.
codeB
l
ock
,
},
},
system_output
:
{
system_output
:
{
value
:
null
,
value
:
null
,
text
:
s__
(
'
Reports|System output
'
),
text
:
s__
(
'
Reports|System output
'
),
type
:
fieldTypes
.
codeBock
,
type
:
fieldTypes
.
codeB
l
ock
,
},
},
},
},
},
},
...
...
app/assets/javascripts/reports/grouped_test_report/store/utils.js
View file @
3f078050
...
@@ -100,3 +100,12 @@ export const statusIcon = (status) => {
...
@@ -100,3 +100,12 @@ export const statusIcon = (status) => {
return
ICON_NOTFOUND
;
return
ICON_NOTFOUND
;
};
};
/**
* Removes `./` from the beginning of a file path so it can be appended onto a blob path
* @param {String} file
* @returns {String} - formatted value
*/
export
const
formatFilePath
=
(
file
)
=>
{
return
file
.
replace
(
/^
\.?\/
*/
,
''
);
};
app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue
View file @
3f078050
...
@@ -480,6 +480,7 @@ export default {
...
@@ -480,6 +480,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"
:head-blob-path=
"mr.headBlobPath"
:pipeline-path=
"mr.pipeline.path"
:pipeline-path=
"mr.pipeline.path"
/>
/>
...
...
changelogs/unreleased/22336-link-test-report-widget-to-file.yml
0 → 100644
View file @
3f078050
---
title
:
Add link to test case file in the test report for merge requests
merge_request
:
57911
author
:
type
:
added
ee/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue
View file @
3f078050
...
@@ -380,6 +380,7 @@ export default {
...
@@ -380,6 +380,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"
:head-blob-path=
"mr.headBlobPath"
:pipeline-path=
"mr.pipeline.path"
:pipeline-path=
"mr.pipeline.path"
/>
/>
...
...
locale/gitlab.pot
View file @
3f078050
...
@@ -25837,9 +25837,6 @@ msgstr ""
...
@@ -25837,9 +25837,6 @@ msgstr ""
msgid "Reports|Base report parsing error:"
msgid "Reports|Base report parsing error:"
msgstr ""
msgstr ""
msgid "Reports|Class"
msgstr ""
msgid "Reports|Classname"
msgid "Reports|Classname"
msgstr ""
msgstr ""
...
@@ -25859,6 +25856,9 @@ msgstr[1] ""
...
@@ -25859,6 +25856,9 @@ msgstr[1] ""
msgid "Reports|Failure"
msgid "Reports|Failure"
msgstr ""
msgstr ""
msgid "Reports|Filename"
msgstr ""
msgid "Reports|Head report parsing error:"
msgid "Reports|Head report parsing error:"
msgstr ""
msgstr ""
...
...
spec/frontend/reports/grouped_test_report/components/modal_spec.js
View file @
3f078050
...
@@ -15,7 +15,10 @@ describe('Grouped Test Reports Modal', () => {
...
@@ -15,7 +15,10 @@ describe('Grouped Test Reports Modal', () => {
// populate data
// populate data
modalDataStructure
.
execution_time
.
value
=
0.009411
;
modalDataStructure
.
execution_time
.
value
=
0.009411
;
modalDataStructure
.
system_output
.
value
=
'
Failure/Error: is_expected.to eq(3)
\n\n
'
;
modalDataStructure
.
system_output
.
value
=
'
Failure/Error: is_expected.to eq(3)
\n\n
'
;
modalDataStructure
.
class
.
value
=
'
link
'
;
modalDataStructure
.
filename
.
value
=
{
text
:
'
link
'
,
path
:
'
/file/path
'
,
};
let
wrapper
;
let
wrapper
;
...
@@ -43,9 +46,9 @@ describe('Grouped Test Reports Modal', () => {
...
@@ -43,9 +46,9 @@ describe('Grouped Test Reports Modal', () => {
it
(
'
renders link
'
,
()
=>
{
it
(
'
renders link
'
,
()
=>
{
const
link
=
wrapper
.
findComponent
(
GlLink
);
const
link
=
wrapper
.
findComponent
(
GlLink
);
expect
(
link
.
attributes
().
href
).
toEqual
(
modalDataStructure
.
class
.
value
);
expect
(
link
.
attributes
().
href
).
toEqual
(
modalDataStructure
.
filename
.
value
.
path
);
expect
(
link
.
text
()).
toEqual
(
modalDataStructure
.
class
.
value
);
expect
(
link
.
text
()).
toEqual
(
modalDataStructure
.
filename
.
value
.
text
);
});
});
it
(
'
renders seconds
'
,
()
=>
{
it
(
'
renders seconds
'
,
()
=>
{
...
...
spec/frontend/reports/grouped_test_report/grouped_test_reports_app_spec.js
View file @
3f078050
...
@@ -17,6 +17,7 @@ localVue.use(Vuex);
...
@@ -17,6 +17,7 @@ localVue.use(Vuex);
describe
(
'
Grouped test reports app
'
,
()
=>
{
describe
(
'
Grouped test reports app
'
,
()
=>
{
const
endpoint
=
'
endpoint.json
'
;
const
endpoint
=
'
endpoint.json
'
;
const
headBlobPath
=
'
/blob/path
'
;
const
pipelinePath
=
'
/path/to/pipeline
'
;
const
pipelinePath
=
'
/path/to/pipeline
'
;
let
wrapper
;
let
wrapper
;
let
mockStore
;
let
mockStore
;
...
@@ -27,6 +28,7 @@ describe('Grouped test reports app', () => {
...
@@ -27,6 +28,7 @@ describe('Grouped test reports app', () => {
localVue
,
localVue
,
propsData
:
{
propsData
:
{
endpoint
,
endpoint
,
headBlobPath
,
pipelinePath
,
pipelinePath
,
...
props
,
...
props
,
},
},
...
@@ -56,7 +58,7 @@ describe('Grouped test reports app', () => {
...
@@ -56,7 +58,7 @@ describe('Grouped test reports app', () => {
...
getStoreConfig
(),
...
getStoreConfig
(),
actions
:
{
actions
:
{
fetchReports
:
()
=>
{},
fetchReports
:
()
=>
{},
set
Endpoint
:
()
=>
{},
set
Paths
:
()
=>
{},
},
},
});
});
mountComponent
();
mountComponent
();
...
...
spec/frontend/reports/grouped_test_report/store/actions_spec.js
View file @
3f078050
...
@@ -3,7 +3,7 @@ import { TEST_HOST } from 'helpers/test_constants';
...
@@ -3,7 +3,7 @@ import { TEST_HOST } from 'helpers/test_constants';
import
testAction
from
'
helpers/vuex_action_helper
'
;
import
testAction
from
'
helpers/vuex_action_helper
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
{
import
{
set
Endpoint
,
set
Paths
,
requestReports
,
requestReports
,
fetchReports
,
fetchReports
,
stopPolling
,
stopPolling
,
...
@@ -23,13 +23,18 @@ describe('Reports Store Actions', () => {
...
@@ -23,13 +23,18 @@ describe('Reports Store Actions', () => {
mockedState
=
state
();
mockedState
=
state
();
});
});
describe
(
'
set
Endpoint
'
,
()
=>
{
describe
(
'
set
Paths
'
,
()
=>
{
it
(
'
should commit SET_
ENDPOINT
mutation
'
,
(
done
)
=>
{
it
(
'
should commit SET_
PATHS
mutation
'
,
(
done
)
=>
{
testAction
(
testAction
(
set
Endpoint
,
set
Paths
,
'
endpoint.json
'
,
{
endpoint
:
'
endpoint.json
'
,
headBlobPath
:
'
/blob/path
'
}
,
mockedState
,
mockedState
,
[{
type
:
types
.
SET_ENDPOINT
,
payload
:
'
endpoint.json
'
}],
[
{
type
:
types
.
SET_PATHS
,
payload
:
{
endpoint
:
'
endpoint.json
'
,
headBlobPath
:
'
/blob/path
'
},
},
],
[],
[],
done
,
done
,
);
);
...
...
spec/frontend/reports/grouped_test_report/store/mutations_spec.js
View file @
3f078050
...
@@ -10,11 +10,15 @@ describe('Reports Store Mutations', () => {
...
@@ -10,11 +10,15 @@ describe('Reports Store Mutations', () => {
stateCopy
=
state
();
stateCopy
=
state
();
});
});
describe
(
'
SET_
ENDPOINT
'
,
()
=>
{
describe
(
'
SET_
PATHS
'
,
()
=>
{
it
(
'
should set endpoint
'
,
()
=>
{
it
(
'
should set endpoint
'
,
()
=>
{
mutations
[
types
.
SET_ENDPOINT
](
stateCopy
,
'
endpoint.json
'
);
mutations
[
types
.
SET_PATHS
](
stateCopy
,
{
endpoint
:
'
endpoint.json
'
,
headBlobPath
:
'
/blob/path
'
,
});
expect
(
stateCopy
.
endpoint
).
toEqual
(
'
endpoint.json
'
);
expect
(
stateCopy
.
endpoint
).
toEqual
(
'
endpoint.json
'
);
expect
(
stateCopy
.
headBlobPath
).
toEqual
(
'
/blob/path
'
);
});
});
});
});
...
...
spec/frontend/reports/grouped_test_report/store/utils_spec.js
View file @
3f078050
...
@@ -238,4 +238,18 @@ describe('Reports store utils', () => {
...
@@ -238,4 +238,18 @@ describe('Reports store utils', () => {
});
});
});
});
});
});
describe
(
'
formatFilePath
'
,
()
=>
{
it
.
each
`
file | expected
${
'
./test.js
'
}
|
${
'
test.js
'
}
${
'
/test.js
'
}
|
${
'
test.js
'
}
${
'
.//////////////test.js
'
}
|
${
'
test.js
'
}
${
'
test.js
'
}
|
${
'
test.js
'
}
${
'
mock/path./test.js
'
}
|
${
'
mock/path./test.js
'
}
${
'
./mock/path./test.js
'
}
|
${
'
mock/path./test.js
'
}
`
(
'
should format $file to be $expected
'
,
({
file
,
expected
})
=>
{
expect
(
utils
.
formatFilePath
(
file
)).
toBe
(
expected
);
});
});
});
});
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment