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
696dd434
Commit
696dd434
authored
Mar 15, 2022
by
Heinrich Lee Yu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Revert "Merge branch '338285-test-summary-mr-report-widget' into 'master'"
This reverts merge request !82376
parent
319b201a
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
4 additions
and
355 deletions
+4
-355
app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue
...s/vue_merge_request_widget/components/extensions/base.vue
+1
-1
app/assets/javascripts/vue_merge_request_widget/extensions/test_report/constants.js
..._merge_request_widget/extensions/test_report/constants.js
+0
-39
app/assets/javascripts/vue_merge_request_widget/extensions/test_report/index.js
.../vue_merge_request_widget/extensions/test_report/index.js
+0
-82
app/assets/javascripts/vue_merge_request_widget/extensions/test_report/utils.js
.../vue_merge_request_widget/extensions/test_report/utils.js
+0
-55
app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue
...avascripts/vue_merge_request_widget/mr_widget_options.vue
+1
-15
locale/gitlab.pot
locale/gitlab.pot
+0
-12
spec/frontend/vue_mr_widget/extensions/test_report/index_spec.js
...ontend/vue_mr_widget/extensions/test_report/index_spec.js
+0
-149
spec/frontend/vue_mr_widget/mr_widget_options_spec.js
spec/frontend/vue_mr_widget/mr_widget_options_spec.js
+2
-2
No files found.
app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue
View file @
696dd434
...
@@ -86,7 +86,7 @@ export default {
...
@@ -86,7 +86,7 @@ export default {
);
);
},
},
statusIconName
()
{
statusIconName
()
{
if
(
this
.
hasFetchError
)
return
EXTENSION_ICONS
.
failed
;
if
(
this
.
hasFetchError
)
return
EXTENSION_ICONS
.
error
;
if
(
this
.
isLoadingSummary
)
return
null
;
if
(
this
.
isLoadingSummary
)
return
null
;
return
this
.
statusIcon
(
this
.
collapsedData
);
return
this
.
statusIcon
(
this
.
collapsedData
);
...
...
app/assets/javascripts/vue_merge_request_widget/extensions/test_report/constants.js
deleted
100644 → 0
View file @
319b201a
import
{
__
,
n__
,
s__
,
sprintf
}
from
'
~/locale
'
;
const
digitText
=
(
bold
=
false
)
=>
(
bold
?
'
%{strong_start}%d%{strong_end}
'
:
'
%d
'
);
const
noText
=
(
bold
=
false
)
=>
(
bold
?
'
%{strong_start}no%{strong_end}
'
:
'
no
'
);
export
const
TESTS_FAILED_STATUS
=
'
failed
'
;
export
const
ERROR_STATUS
=
'
error
'
;
export
const
i18n
=
{
label
:
s__
(
'
Reports|Test summary
'
),
loading
:
s__
(
'
Reports|Test summary results are loading
'
),
error
:
s__
(
'
Reports|Test summary failed to load results
'
),
fullReport
:
s__
(
'
Reports|Full report
'
),
noChanges
:
(
bold
)
=>
s__
(
`Reports|
${
noText
(
bold
)}
changed test results`
),
resultsString
:
(
combinedString
,
resolvedString
)
=>
sprintf
(
s__
(
'
Reports|%{combinedString} and %{resolvedString}
'
),
{
combinedString
,
resolvedString
,
}),
summaryText
:
(
name
,
resultsString
)
=>
sprintf
(
__
(
'
%{name}: %{resultsString}
'
),
{
name
,
resultsString
}),
failedClause
:
(
failed
,
bold
)
=>
n__
(
`
${
digitText
(
bold
)}
failed`
,
`
${
digitText
(
bold
)}
failed`
,
failed
),
erroredClause
:
(
errored
,
bold
)
=>
n__
(
`
${
digitText
(
bold
)}
error`
,
`
${
digitText
(
bold
)}
errors`
,
errored
),
resolvedClause
:
(
resolved
,
bold
)
=>
n__
(
`
${
digitText
(
bold
)}
fixed test result`
,
`
${
digitText
(
bold
)}
fixed test results`
,
resolved
),
totalClause
:
(
total
,
bold
)
=>
n__
(
`
${
digitText
(
bold
)}
total test`
,
`
${
digitText
(
bold
)}
total tests`
,
total
),
reportError
:
s__
(
'
Reports|An error occurred while loading report
'
),
reportErrorWithName
:
(
name
)
=>
sprintf
(
s__
(
'
Reports|An error occurred while loading %{name} results
'
),
{
name
}),
headReportParsingError
:
s__
(
'
Reports|Head report parsing error:
'
),
baseReportParsingError
:
s__
(
'
Reports|Base report parsing error:
'
),
};
app/assets/javascripts/vue_merge_request_widget/extensions/test_report/index.js
deleted
100644 → 0
View file @
319b201a
import
{
uniqueId
}
from
'
lodash
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
{
EXTENSION_ICONS
}
from
'
../../constants
'
;
import
{
summaryTextBuilder
,
reportTextBuilder
,
reportSubTextBuilder
}
from
'
./utils
'
;
import
{
i18n
,
TESTS_FAILED_STATUS
,
ERROR_STATUS
}
from
'
./constants
'
;
export
default
{
name
:
'
WidgetTestSummary
'
,
enablePolling
:
true
,
i18n
,
expandEvent
:
'
i_testing_summary_widget_total
'
,
props
:
[
'
testResultsPath
'
,
'
headBlobPath
'
,
'
pipeline
'
],
computed
:
{
summary
(
data
)
{
if
(
data
.
parsingInProgress
)
{
return
this
.
$options
.
i18n
.
loading
;
}
if
(
data
.
hasSuiteError
)
{
return
this
.
$options
.
i18n
.
error
;
}
return
summaryTextBuilder
(
this
.
$options
.
i18n
.
label
,
data
.
summary
);
},
statusIcon
(
data
)
{
if
(
data
.
parsingInProgress
)
{
return
null
;
}
if
(
data
.
status
===
TESTS_FAILED_STATUS
)
{
return
EXTENSION_ICONS
.
warning
;
}
if
(
data
.
hasSuiteError
)
{
return
EXTENSION_ICONS
.
failed
;
}
return
EXTENSION_ICONS
.
success
;
},
tertiaryButtons
()
{
return
[
{
text
:
this
.
$options
.
i18n
.
fullReport
,
href
:
`
${
this
.
pipeline
.
path
}
/test_report`
,
target
:
'
_blank
'
,
},
];
},
},
methods
:
{
fetchCollapsedData
()
{
return
axios
.
get
(
this
.
testResultsPath
).
then
(({
data
=
{},
status
})
=>
{
return
{
data
:
{
hasSuiteError
:
data
.
suites
?.
some
((
suite
)
=>
suite
.
status
===
ERROR_STATUS
),
parsingInProgress
:
status
===
204
,
...
data
,
},
};
});
},
fetchFullData
()
{
return
Promise
.
resolve
(
this
.
prepareReports
());
},
suiteIcon
(
suite
)
{
if
(
suite
.
status
===
ERROR_STATUS
)
{
return
EXTENSION_ICONS
.
error
;
}
if
(
suite
.
status
===
TESTS_FAILED_STATUS
)
{
return
EXTENSION_ICONS
.
failed
;
}
return
EXTENSION_ICONS
.
success
;
},
prepareReports
()
{
return
this
.
collapsedData
.
suites
.
map
((
suite
)
=>
{
return
{
id
:
uniqueId
(
'
suite-
'
),
text
:
reportTextBuilder
(
suite
),
subtext
:
reportSubTextBuilder
(
suite
),
icon
:
{
name
:
this
.
suiteIcon
(
suite
),
},
};
});
},
},
};
app/assets/javascripts/vue_merge_request_widget/extensions/test_report/utils.js
deleted
100644 → 0
View file @
319b201a
import
{
i18n
}
from
'
./constants
'
;
const
textBuilder
=
(
results
,
boldNumbers
=
false
)
=>
{
const
{
failed
,
errored
,
resolved
,
total
}
=
results
;
const
failedOrErrored
=
(
failed
||
0
)
+
(
errored
||
0
);
const
failedString
=
failed
?
i18n
.
failedClause
(
failed
,
boldNumbers
)
:
null
;
const
erroredString
=
errored
?
i18n
.
erroredClause
(
errored
,
boldNumbers
)
:
null
;
const
combinedString
=
failed
&&
errored
?
`
${
failedString
}
,
${
erroredString
}
`
:
failedString
||
erroredString
;
const
resolvedString
=
resolved
?
i18n
.
resolvedClause
(
resolved
,
boldNumbers
)
:
null
;
const
totalString
=
total
?
i18n
.
totalClause
(
total
,
boldNumbers
)
:
null
;
let
resultsString
=
i18n
.
noChanges
(
boldNumbers
);
if
(
failedOrErrored
)
{
if
(
resolved
)
{
resultsString
=
i18n
.
resultsString
(
combinedString
,
resolvedString
);
}
else
{
resultsString
=
combinedString
;
}
}
else
if
(
resolved
)
{
resultsString
=
resolvedString
;
}
return
`
${
resultsString
}
,
${
totalString
}
`
;
};
export
const
summaryTextBuilder
=
(
name
=
''
,
results
=
{})
=>
{
const
resultsString
=
textBuilder
(
results
,
true
);
return
i18n
.
summaryText
(
name
,
resultsString
);
};
export
const
reportTextBuilder
=
({
name
=
''
,
summary
=
{},
status
})
=>
{
if
(
!
name
)
{
return
i18n
.
reportError
;
}
if
(
status
===
'
error
'
)
{
return
i18n
.
reportErrorWithName
(
name
);
}
const
resultsString
=
textBuilder
(
summary
);
return
i18n
.
summaryText
(
name
,
resultsString
);
};
export
const
reportSubTextBuilder
=
({
suite_errors
})
=>
{
const
errors
=
[];
if
(
suite_errors
?.
head
)
{
errors
.
push
(
`
${
i18n
.
headReportParsingError
}
${
suite_errors
.
head
}
`
);
}
if
(
suite_errors
?.
base
)
{
errors
.
push
(
`
${
i18n
.
baseReportParsingError
}
${
suite_errors
.
base
}
`
);
}
return
errors
.
join
(
'
<br />
'
);
};
app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue
View file @
696dd434
...
@@ -46,7 +46,6 @@ import mergeRequestQueryVariablesMixin from './mixins/merge_request_query_variab
...
@@ -46,7 +46,6 @@ import mergeRequestQueryVariablesMixin from './mixins/merge_request_query_variab
import
getStateQuery
from
'
./queries/get_state.query.graphql
'
;
import
getStateQuery
from
'
./queries/get_state.query.graphql
'
;
import
terraformExtension
from
'
./extensions/terraform
'
;
import
terraformExtension
from
'
./extensions/terraform
'
;
import
accessibilityExtension
from
'
./extensions/accessibility
'
;
import
accessibilityExtension
from
'
./extensions/accessibility
'
;
import
testReportExtension
from
'
./extensions/test_report
'
;
export
default
{
export
default
{
// False positive i18n lint: https://gitlab.com/gitlab-org/frontend/eslint-plugin-i18n/issues/25
// False positive i18n lint: https://gitlab.com/gitlab-org/frontend/eslint-plugin-i18n/issues/25
...
@@ -191,9 +190,6 @@ export default {
...
@@ -191,9 +190,6 @@ export default {
shouldRenderTerraformPlans
()
{
shouldRenderTerraformPlans
()
{
return
Boolean
(
this
.
mr
?.
terraformReportsPath
);
return
Boolean
(
this
.
mr
?.
terraformReportsPath
);
},
},
shouldRenderTestReport
()
{
return
Boolean
(
this
.
mr
?.
testResultsPath
);
},
mergeError
()
{
mergeError
()
{
let
{
mergeError
}
=
this
.
mr
;
let
{
mergeError
}
=
this
.
mr
;
...
@@ -250,11 +246,6 @@ export default {
...
@@ -250,11 +246,6 @@ export default {
this
.
registerAccessibilityExtension
();
this
.
registerAccessibilityExtension
();
}
}
},
},
shouldRenderTestReport
(
newVal
)
{
if
(
newVal
)
{
this
.
registerTestReportExtension
();
}
},
},
},
mounted
()
{
mounted
()
{
MRWidgetService
.
fetchInitialData
()
MRWidgetService
.
fetchInitialData
()
...
@@ -500,11 +491,6 @@ export default {
...
@@ -500,11 +491,6 @@ export default {
registerExtension
(
accessibilityExtension
);
registerExtension
(
accessibilityExtension
);
}
}
},
},
registerTestReportExtension
()
{
if
(
this
.
shouldRenderTestReport
&&
this
.
shouldShowExtension
)
{
registerExtension
(
testReportExtension
);
}
},
},
},
};
};
</
script
>
</
script
>
...
@@ -577,7 +563,7 @@ export default {
...
@@ -577,7 +563,7 @@ export default {
/>
/>
<grouped-test-reports-app
<grouped-test-reports-app
v-if=
"mr.testResultsPath
&& !shouldShowExtension
"
v-if=
"mr.testResultsPath"
class=
"js-reports-container"
class=
"js-reports-container"
:endpoint=
"mr.testResultsPath"
:endpoint=
"mr.testResultsPath"
:head-blob-path=
"mr.headBlobPath"
:head-blob-path=
"mr.headBlobPath"
...
...
locale/gitlab.pot
View file @
696dd434
...
@@ -847,9 +847,6 @@ msgstr ""
...
@@ -847,9 +847,6 @@ msgstr ""
msgid "%{name}, confirm your email address now!"
msgid "%{name}, confirm your email address now!"
msgstr ""
msgstr ""
msgid "%{name}: %{resultsString}"
msgstr ""
msgid "%{no_of_days} day"
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
msgstr[0] ""
...
@@ -30953,9 +30950,6 @@ msgstr ""
...
@@ -30953,9 +30950,6 @@ msgstr ""
msgid "Reports|Filename"
msgid "Reports|Filename"
msgstr ""
msgstr ""
msgid "Reports|Full report"
msgstr ""
msgid "Reports|Head report parsing error:"
msgid "Reports|Head report parsing error:"
msgstr ""
msgstr ""
...
@@ -30998,15 +30992,9 @@ msgstr ""
...
@@ -30998,15 +30992,9 @@ msgstr ""
msgid "Reports|Test summary failed loading results"
msgid "Reports|Test summary failed loading results"
msgstr ""
msgstr ""
msgid "Reports|Test summary failed to load results"
msgstr ""
msgid "Reports|Test summary results are being parsed"
msgid "Reports|Test summary results are being parsed"
msgstr ""
msgstr ""
msgid "Reports|Test summary results are loading"
msgstr ""
msgid "Reports|Tool"
msgid "Reports|Tool"
msgstr ""
msgstr ""
...
...
spec/frontend/vue_mr_widget/extensions/test_report/index_spec.js
deleted
100644 → 0
View file @
319b201a
import
{
GlButton
}
from
'
@gitlab/ui
'
;
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
testReportExtension
from
'
~/vue_merge_request_widget/extensions/test_report
'
;
import
{
i18n
}
from
'
~/vue_merge_request_widget/extensions/test_report/constants
'
;
import
{
mountExtended
}
from
'
helpers/vue_test_utils_helper
'
;
import
{
trimText
}
from
'
helpers/text_helper
'
;
import
waitForPromises
from
'
helpers/wait_for_promises
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
extensionsContainer
from
'
~/vue_merge_request_widget/components/extensions/container
'
;
import
{
registerExtension
}
from
'
~/vue_merge_request_widget/components/extensions
'
;
import
httpStatusCodes
from
'
~/lib/utils/http_status
'
;
import
{
failedReport
}
from
'
../../../reports/mock_data/mock_data
'
;
import
mixedResultsTestReports
from
'
../../../reports/mock_data/new_and_fixed_failures_report.json
'
;
import
newErrorsTestReports
from
'
../../../reports/mock_data/new_errors_report.json
'
;
import
newFailedTestReports
from
'
../../../reports/mock_data/new_failures_report.json
'
;
import
successTestReports
from
'
../../../reports/mock_data/no_failures_report.json
'
;
import
resolvedFailures
from
'
../../../reports/mock_data/resolved_failures.json
'
;
const
reportWithParsingErrors
=
failedReport
;
reportWithParsingErrors
.
suites
[
0
].
suite_errors
=
{
head
:
'
JUnit XML parsing failed: 2:24: FATAL: attributes construct error
'
,
base
:
'
JUnit data parsing failed: string not matched
'
,
};
describe
(
'
Test report extension
'
,
()
=>
{
let
wrapper
;
let
mock
;
registerExtension
(
testReportExtension
);
const
endpoint
=
'
/root/repo/-/merge_requests/4/test_reports.json
'
;
const
mockApi
=
(
statusCode
,
data
=
mixedResultsTestReports
)
=>
{
mock
.
onGet
(
endpoint
).
reply
(
statusCode
,
data
);
};
const
findToggleCollapsedButton
=
()
=>
wrapper
.
findByTestId
(
'
toggle-button
'
);
const
findTertiaryButton
=
()
=>
wrapper
.
find
(
GlButton
);
const
findAllExtensionListItems
=
()
=>
wrapper
.
findAllByTestId
(
'
extension-list-item
'
);
const
createComponent
=
()
=>
{
wrapper
=
mountExtended
(
extensionsContainer
,
{
propsData
:
{
mr
:
{
testResultsPath
:
endpoint
,
headBlobPath
:
'
head/blob/path
'
,
pipeline
:
{
path
:
'
pipeline/path
'
},
},
},
});
};
const
createExpandedWidgetWithData
=
async
(
data
=
mixedResultsTestReports
)
=>
{
mockApi
(
httpStatusCodes
.
OK
,
data
);
createComponent
();
await
waitForPromises
();
findToggleCollapsedButton
().
trigger
(
'
click
'
);
await
waitForPromises
();
};
beforeEach
(()
=>
{
mock
=
new
MockAdapter
(
axios
);
});
afterEach
(()
=>
{
wrapper
.
destroy
();
mock
.
restore
();
});
describe
(
'
summary
'
,
()
=>
{
it
(
'
displays loading text
'
,
()
=>
{
mockApi
(
httpStatusCodes
.
OK
);
createComponent
();
expect
(
wrapper
.
text
()).
toContain
(
i18n
.
loading
);
});
it
(
'
displays failed loading text
'
,
async
()
=>
{
mockApi
(
httpStatusCodes
.
INTERNAL_SERVER_ERROR
);
createComponent
();
await
waitForPromises
();
expect
(
wrapper
.
text
()).
toContain
(
i18n
.
error
);
});
it
.
each
`
description | mockData | expectedResult
${
'
mixed test results
'
}
|
${
mixedResultsTestReports
}
|
${
'
Test summary: 2 failed and 2 fixed test results, 11 total tests
'
}
${
'
unchanged test results
'
}
|
${
successTestReports
}
|
${
'
Test summary: no changed test results, 11 total tests
'
}
${
'
tests with errors
'
}
|
${
newErrorsTestReports
}
|
${
'
Test summary: 2 errors, 11 total tests
'
}
${
'
failed test results
'
}
|
${
newFailedTestReports
}
|
${
'
Test summary: 2 failed, 11 total tests
'
}
${
'
resolved failures
'
}
|
${
resolvedFailures
}
|
${
'
Test summary: 4 fixed test results, 11 total tests
'
}
`
(
'
displays summary text for $description
'
,
async
({
mockData
,
expectedResult
})
=>
{
mockApi
(
httpStatusCodes
.
OK
,
mockData
);
createComponent
();
await
waitForPromises
();
expect
(
wrapper
.
text
()).
toContain
(
expectedResult
);
});
it
(
'
displays a link to the full report
'
,
async
()
=>
{
mockApi
(
httpStatusCodes
.
OK
);
createComponent
();
await
waitForPromises
();
expect
(
findTertiaryButton
().
text
()).
toBe
(
'
Full report
'
);
expect
(
findTertiaryButton
().
attributes
(
'
href
'
)).
toBe
(
'
pipeline/path/test_report
'
);
});
it
(
'
shows an error when a suite has a parsing error
'
,
async
()
=>
{
mockApi
(
httpStatusCodes
.
OK
,
reportWithParsingErrors
);
createComponent
();
await
waitForPromises
();
expect
(
wrapper
.
text
()).
toContain
(
i18n
.
error
);
});
});
describe
(
'
expanded data
'
,
()
=>
{
it
(
'
displays summary for each suite
'
,
async
()
=>
{
await
createExpandedWidgetWithData
();
expect
(
trimText
(
findAllExtensionListItems
().
at
(
0
).
text
())).
toBe
(
'
rspec:pg: 1 failed and 2 fixed test results, 8 total tests
'
,
);
expect
(
trimText
(
findAllExtensionListItems
().
at
(
1
).
text
())).
toBe
(
'
java ant: 1 failed, 3 total tests
'
,
);
});
it
(
'
displays suite parsing errors
'
,
async
()
=>
{
await
createExpandedWidgetWithData
(
reportWithParsingErrors
);
const
suiteText
=
trimText
(
findAllExtensionListItems
().
at
(
0
).
text
());
expect
(
suiteText
).
toContain
(
'
Head report parsing error: JUnit XML parsing failed: 2:24: FATAL: attributes construct error
'
,
);
expect
(
suiteText
).
toContain
(
'
Base report parsing error: JUnit data parsing failed: string not matched
'
,
);
});
});
});
spec/frontend/vue_mr_widget/mr_widget_options_spec.js
View file @
696dd434
...
@@ -1025,7 +1025,7 @@ describe('MrWidgetOptions', () => {
...
@@ -1025,7 +1025,7 @@ describe('MrWidgetOptions', () => {
it
(
'
captures sentry error and displays error when poll has failed
'
,
()
=>
{
it
(
'
captures sentry error and displays error when poll has failed
'
,
()
=>
{
expect
(
captureException
).
toHaveBeenCalledTimes
(
1
);
expect
(
captureException
).
toHaveBeenCalledTimes
(
1
);
expect
(
captureException
).
toHaveBeenCalledWith
(
new
Error
(
'
Fetch error
'
));
expect
(
captureException
).
toHaveBeenCalledWith
(
new
Error
(
'
Fetch error
'
));
expect
(
wrapper
.
findComponent
(
StatusIcon
).
props
(
'
iconName
'
)).
toBe
(
'
failed
'
);
expect
(
wrapper
.
findComponent
(
StatusIcon
).
props
(
'
iconName
'
)).
toBe
(
'
error
'
);
});
});
});
});
});
});
...
@@ -1036,7 +1036,7 @@ describe('MrWidgetOptions', () => {
...
@@ -1036,7 +1036,7 @@ describe('MrWidgetOptions', () => {
const
itHandlesTheException
=
()
=>
{
const
itHandlesTheException
=
()
=>
{
expect
(
captureException
).
toHaveBeenCalledTimes
(
1
);
expect
(
captureException
).
toHaveBeenCalledTimes
(
1
);
expect
(
captureException
).
toHaveBeenCalledWith
(
new
Error
(
'
Fetch error
'
));
expect
(
captureException
).
toHaveBeenCalledWith
(
new
Error
(
'
Fetch error
'
));
expect
(
wrapper
.
findComponent
(
StatusIcon
).
props
(
'
iconName
'
)).
toBe
(
'
failed
'
);
expect
(
wrapper
.
findComponent
(
StatusIcon
).
props
(
'
iconName
'
)).
toBe
(
'
error
'
);
};
};
beforeEach
(()
=>
{
beforeEach
(()
=>
{
...
...
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