@teambit/defender.ui.test-page 0.0.57 → 0.0.59
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/tests-page.js
CHANGED
|
@@ -40,7 +40,117 @@ const lanes_hooks_use_viewed_lane_from_url_1 = require("@teambit/lanes.hooks.use
|
|
|
40
40
|
const classnames_1 = __importDefault(require("classnames"));
|
|
41
41
|
const react_1 = __importStar(require("react"));
|
|
42
42
|
const defender_ui_test_table_1 = require("@teambit/defender.ui.test-table");
|
|
43
|
+
const design_content_table_1 = require("@teambit/design.content.table");
|
|
44
|
+
const base_react_navigation_link_1 = require("@teambit/base-react.navigation.link");
|
|
43
45
|
const tests_page_module_scss_1 = __importDefault(require("./tests-page.module.scss"));
|
|
46
|
+
/**
|
|
47
|
+
* Displays the total row with color-coded values
|
|
48
|
+
* 0-25 - red
|
|
49
|
+
* 26-50 - orange
|
|
50
|
+
* 51-75 - yellow
|
|
51
|
+
* 76-100 - green
|
|
52
|
+
*/
|
|
53
|
+
const getColor = (pct) => {
|
|
54
|
+
if (pct < 25)
|
|
55
|
+
return 'var(--negative-color)';
|
|
56
|
+
if (pct < 50)
|
|
57
|
+
return 'var(--warning-color)';
|
|
58
|
+
if (pct < 75)
|
|
59
|
+
return '#EEB90F';
|
|
60
|
+
return 'var(--positive-color)';
|
|
61
|
+
};
|
|
62
|
+
const StyledRow = ({ row, type, displayValue }) => {
|
|
63
|
+
if (!row)
|
|
64
|
+
return null;
|
|
65
|
+
const data = row.data[type];
|
|
66
|
+
if (!data) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
return (react_1.default.createElement("span", { style: { color: getColor(data.pct) } }, displayValue(data)));
|
|
70
|
+
};
|
|
71
|
+
const StyledTotalRow = (props) => (react_1.default.createElement(StyledRow, Object.assign({}, props, { displayValue: data => `${data.covered}/${data.total}` })));
|
|
72
|
+
const StyledPctRow = (props) => (react_1.default.createElement(StyledRow, Object.assign({}, props, { displayValue: data => `${data.pct}%` })));
|
|
73
|
+
const createColumn = (id, header, type) => [
|
|
74
|
+
{
|
|
75
|
+
id: `${id}_pct`,
|
|
76
|
+
header: '%',
|
|
77
|
+
cell: ({ row }) => (row ? react_1.default.createElement(StyledPctRow, { row: row, type: type }) : null),
|
|
78
|
+
value: (row) => { var _a; return (_a = row === null || row === void 0 ? void 0 : row.data[type].pct) !== null && _a !== void 0 ? _a : 0; },
|
|
79
|
+
className: {
|
|
80
|
+
td: tests_page_module_scss_1.default.coverage_column,
|
|
81
|
+
th: tests_page_module_scss_1.default.coverage_column,
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
id: `${id}_total`,
|
|
86
|
+
header: 'Total',
|
|
87
|
+
cell: ({ row }) => (row ? react_1.default.createElement(StyledTotalRow, { row: row, type: type }) : null),
|
|
88
|
+
value: (row) => { var _a; return (_a = row === null || row === void 0 ? void 0 : row.data[type].covered) !== null && _a !== void 0 ? _a : 0; },
|
|
89
|
+
className: {
|
|
90
|
+
td: tests_page_module_scss_1.default.coverage_column,
|
|
91
|
+
th: tests_page_module_scss_1.default.coverage_column,
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
];
|
|
95
|
+
const calculatePercentage = (data) => {
|
|
96
|
+
const covered = data.lines.covered
|
|
97
|
+
+ data.branches.covered
|
|
98
|
+
+ data.functions.covered
|
|
99
|
+
+ data.statements.covered;
|
|
100
|
+
const total = data.lines.total
|
|
101
|
+
+ data.branches.total
|
|
102
|
+
+ data.functions.total
|
|
103
|
+
+ data.statements.total;
|
|
104
|
+
return (covered / total) * 100;
|
|
105
|
+
};
|
|
106
|
+
const columns = [
|
|
107
|
+
{
|
|
108
|
+
id: 'path',
|
|
109
|
+
header: 'File',
|
|
110
|
+
cell: ({ row }) => (react_1.default.createElement("div", { className: tests_page_module_scss_1.default.filePath },
|
|
111
|
+
react_1.default.createElement(base_react_navigation_link_1.Link, { href: `../~code/${row === null || row === void 0 ? void 0 : row.path}${document.location.search}` }, row === null || row === void 0 ? void 0 : row.path)))
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
id: 'progress',
|
|
115
|
+
header: 'Overall',
|
|
116
|
+
cell: ({ row }) => {
|
|
117
|
+
if (!row) {
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
const coveredPercentage = calculatePercentage(row === null || row === void 0 ? void 0 : row.data);
|
|
121
|
+
return (react_1.default.createElement("div", { className: tests_page_module_scss_1.default.summaryProgressBar },
|
|
122
|
+
react_1.default.createElement("div", { className: tests_page_module_scss_1.default.progressBarFill, style: {
|
|
123
|
+
width: `${coveredPercentage}%`,
|
|
124
|
+
backgroundColor: getColor(coveredPercentage)
|
|
125
|
+
} })));
|
|
126
|
+
},
|
|
127
|
+
value: (file) => { var _a; return (_a = file === null || file === void 0 ? void 0 : file.data.lines.pct) !== null && _a !== void 0 ? _a : 0; },
|
|
128
|
+
className: {
|
|
129
|
+
td: tests_page_module_scss_1.default.coverage_column,
|
|
130
|
+
th: tests_page_module_scss_1.default.coverage_column,
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
id: 'lines',
|
|
135
|
+
header: 'Lines',
|
|
136
|
+
columns: createColumn('lines', 'Lines', 'lines')
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
id: 'functions',
|
|
140
|
+
header: 'Functions',
|
|
141
|
+
columns: createColumn('functions', 'Functions', 'functions')
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
id: 'statements',
|
|
145
|
+
header: 'Statements',
|
|
146
|
+
columns: createColumn('statements', 'Statements', 'statements')
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
id: 'branches',
|
|
150
|
+
header: 'Branches',
|
|
151
|
+
columns: createColumn('branches', 'Branches', 'branches')
|
|
152
|
+
},
|
|
153
|
+
];
|
|
44
154
|
const TESTS_SUBSCRIPTION_CHANGED = (0, client_1.gql) `
|
|
45
155
|
subscription OnTestsChanged($id: String!) {
|
|
46
156
|
testsChanged(id: $id) {
|
|
@@ -86,13 +196,87 @@ const GET_COMPONENT = (0, client_1.gql) `
|
|
|
86
196
|
error
|
|
87
197
|
}
|
|
88
198
|
}
|
|
199
|
+
coverage {
|
|
200
|
+
total {
|
|
201
|
+
lines {
|
|
202
|
+
total
|
|
203
|
+
covered
|
|
204
|
+
pct
|
|
205
|
+
}
|
|
206
|
+
functions {
|
|
207
|
+
total
|
|
208
|
+
covered
|
|
209
|
+
pct
|
|
210
|
+
}
|
|
211
|
+
statements {
|
|
212
|
+
total
|
|
213
|
+
covered
|
|
214
|
+
pct
|
|
215
|
+
}
|
|
216
|
+
branches {
|
|
217
|
+
total
|
|
218
|
+
covered
|
|
219
|
+
pct
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
files {
|
|
223
|
+
path
|
|
224
|
+
data {
|
|
225
|
+
lines {
|
|
226
|
+
total
|
|
227
|
+
covered
|
|
228
|
+
pct
|
|
229
|
+
}
|
|
230
|
+
functions {
|
|
231
|
+
total
|
|
232
|
+
covered
|
|
233
|
+
pct
|
|
234
|
+
}
|
|
235
|
+
statements {
|
|
236
|
+
total
|
|
237
|
+
covered
|
|
238
|
+
pct
|
|
239
|
+
}
|
|
240
|
+
branches {
|
|
241
|
+
total
|
|
242
|
+
covered
|
|
243
|
+
pct
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
89
248
|
}
|
|
90
249
|
}
|
|
91
250
|
}
|
|
92
251
|
}
|
|
93
252
|
`;
|
|
253
|
+
const TotalCoverageSummary = ({ coverageResult }) => {
|
|
254
|
+
const { lines, statements, functions, branches } = coverageResult.total;
|
|
255
|
+
const data = [
|
|
256
|
+
{ label: "Statements", value: `${statements.covered}/${statements.total}`, pct: statements.pct },
|
|
257
|
+
{ label: "Branches", value: `${branches.covered}/${branches.total}`, pct: branches.pct },
|
|
258
|
+
{ label: "Functions", value: `${functions.covered}/${functions.total}`, pct: functions.pct },
|
|
259
|
+
{ label: "Lines", value: `${lines.covered}/${lines.total}`, pct: lines.pct },
|
|
260
|
+
];
|
|
261
|
+
const totalCovered = lines.covered + branches.covered + functions.covered + statements.covered;
|
|
262
|
+
const totalLines = lines.total + branches.total + functions.total + statements.total;
|
|
263
|
+
return (react_1.default.createElement("div", { style: { display: "flex", flexDirection: "column", marginBottom: "20px" } },
|
|
264
|
+
react_1.default.createElement("div", { className: tests_page_module_scss_1.default.container }, data.map((item) => (react_1.default.createElement("div", { key: item.label, className: tests_page_module_scss_1.default.item },
|
|
265
|
+
react_1.default.createElement("span", { className: tests_page_module_scss_1.default.percentage, style: {
|
|
266
|
+
color: getColor(item.pct)
|
|
267
|
+
} },
|
|
268
|
+
item.pct,
|
|
269
|
+
"%"),
|
|
270
|
+
react_1.default.createElement("span", { className: tests_page_module_scss_1.default.label }, item.label),
|
|
271
|
+
react_1.default.createElement("span", { className: tests_page_module_scss_1.default.badge }, item.value))))),
|
|
272
|
+
react_1.default.createElement("div", { className: tests_page_module_scss_1.default.summaryProgressBar },
|
|
273
|
+
react_1.default.createElement("div", { className: tests_page_module_scss_1.default.progressBarFill, style: {
|
|
274
|
+
width: `${totalCovered / totalLines * 100}%`,
|
|
275
|
+
backgroundColor: getColor(totalCovered / totalLines * 100)
|
|
276
|
+
} }))));
|
|
277
|
+
};
|
|
94
278
|
function TestsPage({ className, emptyState }) {
|
|
95
|
-
var _a, _b, _c, _d;
|
|
279
|
+
var _a, _b, _c, _d, _e;
|
|
96
280
|
const query = (0, ui_foundation_ui_react_router_use_query_1.useQuery)();
|
|
97
281
|
const component = (0, react_1.useContext)(component_1.ComponentContext);
|
|
98
282
|
const viewedLaneFromUrl = (0, lanes_hooks_use_viewed_lane_from_url_1.useViewedLaneFromUrl)();
|
|
@@ -103,15 +287,16 @@ function TestsPage({ className, emptyState }) {
|
|
|
103
287
|
const onTestsChanged = (0, client_1.useSubscription)(TESTS_SUBSCRIPTION_CHANGED, {
|
|
104
288
|
variables: { id },
|
|
105
289
|
});
|
|
106
|
-
const { data } = (0, client_1.useQuery)(GET_COMPONENT, {
|
|
290
|
+
const { data, loading } = (0, client_1.useQuery)(GET_COMPONENT, {
|
|
107
291
|
variables: { id },
|
|
108
292
|
});
|
|
109
293
|
const testData = ((_a = onTestsChanged.data) === null || _a === void 0 ? void 0 : _a.testsChanged) || ((_b = data === null || data === void 0 ? void 0 : data.getHost) === null || _b === void 0 ? void 0 : _b.getTests);
|
|
110
294
|
const testResults = (_c = testData === null || testData === void 0 ? void 0 : testData.testsResults) === null || _c === void 0 ? void 0 : _c.testFiles;
|
|
295
|
+
const testCoverage = (_d = testData === null || testData === void 0 ? void 0 : testData.testsResults) === null || _d === void 0 ? void 0 : _d.coverage;
|
|
111
296
|
// TODO: change loading EmptyBox
|
|
112
|
-
if (testData === null || testData === void 0 ? void 0 : testData.loading)
|
|
297
|
+
if (loading || (testData === null || testData === void 0 ? void 0 : testData.loading))
|
|
113
298
|
return react_1.default.createElement(defender_ui_test_loader_1.TestLoader, null);
|
|
114
|
-
const env = (
|
|
299
|
+
const env = (_e = component.environment) === null || _e === void 0 ? void 0 : _e.id;
|
|
115
300
|
const EmptyStateTemplate = emptyState.get(env || '');
|
|
116
301
|
if ((testResults === null || (testData === null || testData === void 0 ? void 0 : testData.testsResults) === null) &&
|
|
117
302
|
component.host === 'teambit.workspace/workspace' &&
|
|
@@ -132,6 +317,14 @@ function TestsPage({ className, emptyState }) {
|
|
|
132
317
|
react_1.default.createElement("div", null,
|
|
133
318
|
react_1.default.createElement(documenter_ui_heading_1.H1, { className: tests_page_module_scss_1.default.title }, "Tests"),
|
|
134
319
|
react_1.default.createElement(design_ui_separator_1.Separator, { isPresentational: true, className: tests_page_module_scss_1.default.separator }),
|
|
135
|
-
react_1.default.createElement(
|
|
320
|
+
react_1.default.createElement(documenter_ui_heading_1.H2, { className: tests_page_module_scss_1.default.subtitle }, "Tests Results"),
|
|
321
|
+
react_1.default.createElement(defender_ui_test_table_1.TestTable, { testResults: testResults, className: tests_page_module_scss_1.default.testBlock }),
|
|
322
|
+
testCoverage && testCoverage.files.length > 0 && (react_1.default.createElement(react_1.default.Fragment, null,
|
|
323
|
+
react_1.default.createElement(design_ui_separator_1.Separator, { isPresentational: true, className: tests_page_module_scss_1.default.separator }),
|
|
324
|
+
react_1.default.createElement(documenter_ui_heading_1.H2, { className: tests_page_module_scss_1.default.subtitle }, "Coverage Report"),
|
|
325
|
+
react_1.default.createElement(TotalCoverageSummary, { coverageResult: testCoverage }),
|
|
326
|
+
react_1.default.createElement(design_content_table_1.Table, { data: testCoverage.files, columns: columns, sorting: {
|
|
327
|
+
enable: true,
|
|
328
|
+
} }))))));
|
|
136
329
|
}
|
|
137
330
|
//# sourceMappingURL=tests-page.js.map
|
package/dist/tests-page.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tests-page.js","sourceRoot":"","sources":["../tests-page.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"tests-page.js","sourceRoot":"","sources":["../tests-page.tsx"],"names":[],"mappings":"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"}
|
|
@@ -10,6 +10,10 @@
|
|
|
10
10
|
margin-bottom: 24px;
|
|
11
11
|
font-size: var(--bit-h-xs, 26px);
|
|
12
12
|
}
|
|
13
|
+
.subtitle {
|
|
14
|
+
margin-bottom: 24px;
|
|
15
|
+
font-size: var(--bit-h-xxs, 18px);
|
|
16
|
+
}
|
|
13
17
|
.separator {
|
|
14
18
|
margin-bottom: 41px;
|
|
15
19
|
}
|
|
@@ -18,3 +22,74 @@
|
|
|
18
22
|
.testBlock {
|
|
19
23
|
margin-bottom: 50px;
|
|
20
24
|
}
|
|
25
|
+
|
|
26
|
+
th {
|
|
27
|
+
font-weight: bold;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.container {
|
|
31
|
+
display: flex;
|
|
32
|
+
gap: 20px;
|
|
33
|
+
margin-bottom: 30px;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.item {
|
|
37
|
+
display: flex;
|
|
38
|
+
align-items: center;
|
|
39
|
+
gap: 6px;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.percentage {
|
|
43
|
+
font-weight: bolder;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.label {
|
|
47
|
+
color: #666;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.badge {
|
|
51
|
+
background-color: var(--surface-neutral-active-color, #eeeff2);
|
|
52
|
+
color: #666;
|
|
53
|
+
padding: 2px 6px;
|
|
54
|
+
border-radius: 12px;
|
|
55
|
+
font-size: 0.85em;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.coverage_column {
|
|
59
|
+
width: 75px;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.filePath {
|
|
63
|
+
font-family: monospace;
|
|
64
|
+
display: flex;
|
|
65
|
+
align-items: center;
|
|
66
|
+
justify-items: center;
|
|
67
|
+
gap: 4px;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.progressBar {
|
|
71
|
+
width: 150px;
|
|
72
|
+
border-radius: 50px;
|
|
73
|
+
height: 6px;
|
|
74
|
+
display: inline-block;
|
|
75
|
+
margin-left: 10px;
|
|
76
|
+
background-color: lightgray;
|
|
77
|
+
overflow: hidden;
|
|
78
|
+
position: relative;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.progressBarFill {
|
|
82
|
+
height: 100%;
|
|
83
|
+
border-radius: 50px;
|
|
84
|
+
width: 0;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.summaryProgressBar {
|
|
88
|
+
width: 100%;
|
|
89
|
+
border-radius: 50px;
|
|
90
|
+
height: 6px;
|
|
91
|
+
display: inline-block;
|
|
92
|
+
background-color: lightgray;
|
|
93
|
+
overflow: hidden;
|
|
94
|
+
position: relative;
|
|
95
|
+
}
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@teambit/defender.ui.test-page",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.59",
|
|
4
4
|
"homepage": "https://bit.cloud/teambit/defender/ui/test-page",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"componentId": {
|
|
7
7
|
"scope": "teambit.defender",
|
|
8
8
|
"name": "ui/test-page",
|
|
9
|
-
"version": "0.0.
|
|
9
|
+
"version": "0.0.59"
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"classnames": "2.2.6",
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
"@teambit/design.ui.empty-box": "0.0.363",
|
|
18
18
|
"@teambit/design.ui.separator": "0.0.354",
|
|
19
19
|
"@teambit/documenter.ui.heading": "4.1.1",
|
|
20
|
+
"@teambit/design.content.table": "0.0.2",
|
|
20
21
|
"@teambit/mdx.ui.mdx-layout": "1.0.11",
|
|
21
22
|
"@teambit/ui-foundation.ui.react-router.use-query": "0.0.505",
|
|
22
23
|
"@teambit/lanes.hooks.use-viewed-lane-from-url": "0.0.237"
|
|
@@ -34,7 +35,8 @@
|
|
|
34
35
|
"peerDependencies": {
|
|
35
36
|
"@apollo/client": "^3.6.0",
|
|
36
37
|
"react": "^16.8.0 || ^17.0.0",
|
|
37
|
-
"react-dom": "^16.8.0 || ^17.0.0"
|
|
38
|
+
"react-dom": "^16.8.0 || ^17.0.0",
|
|
39
|
+
"@teambit/base-react.navigation.link": "2.0.32"
|
|
38
40
|
},
|
|
39
41
|
"license": "Apache-2.0",
|
|
40
42
|
"optionalDependencies": {},
|
package/tests-page.module.scss
CHANGED
|
@@ -10,6 +10,10 @@
|
|
|
10
10
|
margin-bottom: 24px;
|
|
11
11
|
font-size: var(--bit-h-xs, 26px);
|
|
12
12
|
}
|
|
13
|
+
.subtitle {
|
|
14
|
+
margin-bottom: 24px;
|
|
15
|
+
font-size: var(--bit-h-xxs, 18px);
|
|
16
|
+
}
|
|
13
17
|
.separator {
|
|
14
18
|
margin-bottom: 41px;
|
|
15
19
|
}
|
|
@@ -18,3 +22,74 @@
|
|
|
18
22
|
.testBlock {
|
|
19
23
|
margin-bottom: 50px;
|
|
20
24
|
}
|
|
25
|
+
|
|
26
|
+
th {
|
|
27
|
+
font-weight: bold;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.container {
|
|
31
|
+
display: flex;
|
|
32
|
+
gap: 20px;
|
|
33
|
+
margin-bottom: 30px;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.item {
|
|
37
|
+
display: flex;
|
|
38
|
+
align-items: center;
|
|
39
|
+
gap: 6px;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.percentage {
|
|
43
|
+
font-weight: bolder;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.label {
|
|
47
|
+
color: #666;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.badge {
|
|
51
|
+
background-color: var(--surface-neutral-active-color, #eeeff2);
|
|
52
|
+
color: #666;
|
|
53
|
+
padding: 2px 6px;
|
|
54
|
+
border-radius: 12px;
|
|
55
|
+
font-size: 0.85em;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.coverage_column {
|
|
59
|
+
width: 75px;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.filePath {
|
|
63
|
+
font-family: monospace;
|
|
64
|
+
display: flex;
|
|
65
|
+
align-items: center;
|
|
66
|
+
justify-items: center;
|
|
67
|
+
gap: 4px;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.progressBar {
|
|
71
|
+
width: 150px;
|
|
72
|
+
border-radius: 50px;
|
|
73
|
+
height: 6px;
|
|
74
|
+
display: inline-block;
|
|
75
|
+
margin-left: 10px;
|
|
76
|
+
background-color: lightgray;
|
|
77
|
+
overflow: hidden;
|
|
78
|
+
position: relative;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.progressBarFill {
|
|
82
|
+
height: 100%;
|
|
83
|
+
border-radius: 50px;
|
|
84
|
+
width: 0;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.summaryProgressBar {
|
|
88
|
+
width: 100%;
|
|
89
|
+
border-radius: 50px;
|
|
90
|
+
height: 6px;
|
|
91
|
+
display: inline-block;
|
|
92
|
+
background-color: lightgray;
|
|
93
|
+
overflow: hidden;
|
|
94
|
+
position: relative;
|
|
95
|
+
}
|
package/tests-page.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useQuery, useSubscription, gql } from '@apollo/client';
|
|
2
2
|
import { ComponentContext } from '@teambit/component';
|
|
3
3
|
import { useQuery as useRouterQuery } from '@teambit/ui-foundation.ui.react-router.use-query';
|
|
4
|
-
import { H1 } from '@teambit/documenter.ui.heading';
|
|
4
|
+
import { H1, H2 } from '@teambit/documenter.ui.heading';
|
|
5
5
|
import { Separator } from '@teambit/design.ui.separator';
|
|
6
6
|
import { EmptyBox } from '@teambit/design.ui.empty-box';
|
|
7
7
|
import { MDXLayout } from '@teambit/mdx.ui.mdx-layout';
|
|
@@ -12,8 +12,176 @@ import { useViewedLaneFromUrl } from '@teambit/lanes.hooks.use-viewed-lane-from-
|
|
|
12
12
|
import classNames from 'classnames';
|
|
13
13
|
import React, { HTMLAttributes, useContext } from 'react';
|
|
14
14
|
import { TestTable } from '@teambit/defender.ui.test-table';
|
|
15
|
+
import { Table, type ColumnProps, type CellFunctionProps } from '@teambit/design.content.table';
|
|
16
|
+
import { Link } from '@teambit/base-react.navigation.link';
|
|
15
17
|
import styles from './tests-page.module.scss';
|
|
16
18
|
|
|
19
|
+
type CoverageResults = {
|
|
20
|
+
files: CoverageFile[]
|
|
21
|
+
total: CoverageData
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
type CoverageStats = {
|
|
25
|
+
pct: number
|
|
26
|
+
total: number
|
|
27
|
+
covered: number
|
|
28
|
+
skipped: number
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
type CoverageFile = {
|
|
32
|
+
path: string
|
|
33
|
+
data: CoverageData
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
type CoverageData = {
|
|
37
|
+
lines: CoverageStats
|
|
38
|
+
statements: CoverageStats
|
|
39
|
+
functions: CoverageStats
|
|
40
|
+
branches: CoverageStats
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Displays the total row with color-coded values
|
|
45
|
+
* 0-25 - red
|
|
46
|
+
* 26-50 - orange
|
|
47
|
+
* 51-75 - yellow
|
|
48
|
+
* 76-100 - green
|
|
49
|
+
*/
|
|
50
|
+
const getColor = (pct: number) => {
|
|
51
|
+
if (pct < 25) return 'var(--negative-color)';
|
|
52
|
+
if (pct < 50) return 'var(--warning-color)';
|
|
53
|
+
if (pct < 75) return '#EEB90F';
|
|
54
|
+
return 'var(--positive-color)';
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const StyledRow: React.FC<{
|
|
58
|
+
row: CoverageFile | undefined | null,
|
|
59
|
+
type: keyof CoverageFile['data'],
|
|
60
|
+
displayValue: (data: CoverageFile['data'][keyof CoverageFile['data']]) => string
|
|
61
|
+
}> = ({ row, type, displayValue }) => {
|
|
62
|
+
if (!row) return null;
|
|
63
|
+
|
|
64
|
+
const data = row.data[type];
|
|
65
|
+
|
|
66
|
+
if (!data) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return (
|
|
71
|
+
<span style={{ color: getColor(data.pct) }}>
|
|
72
|
+
{displayValue(data)}
|
|
73
|
+
</span>
|
|
74
|
+
)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const StyledTotalRow = (props: { row: CoverageFile | undefined | null, type: keyof CoverageFile['data'] }) => (
|
|
78
|
+
<StyledRow {...props} displayValue={data => `${data.covered}/${data.total}`} />
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
const StyledPctRow = (props: { row: CoverageFile | undefined | null, type: keyof CoverageFile['data'] }) => (
|
|
82
|
+
<StyledRow {...props} displayValue={data => `${data.pct}%`} />
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
const createColumn = (id: string, header: string, type: keyof CoverageFile['data']) => [
|
|
86
|
+
{
|
|
87
|
+
id: `${id}_pct`,
|
|
88
|
+
header: '%',
|
|
89
|
+
cell: ({ row }: CellFunctionProps<CoverageFile>) => (
|
|
90
|
+
row ? <StyledPctRow row={row} type={type} /> : null
|
|
91
|
+
),
|
|
92
|
+
value: (row?: CoverageFile) => row?.data[type].pct ?? 0,
|
|
93
|
+
className: {
|
|
94
|
+
td: styles.coverage_column,
|
|
95
|
+
th: styles.coverage_column,
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
id: `${id}_total`,
|
|
100
|
+
header: 'Total',
|
|
101
|
+
cell: ({ row }: CellFunctionProps<CoverageFile>) => (
|
|
102
|
+
row ? <StyledTotalRow row={row} type={type} /> : null
|
|
103
|
+
),
|
|
104
|
+
value: (row?: CoverageFile) => row?.data[type].covered ?? 0,
|
|
105
|
+
className: {
|
|
106
|
+
td: styles.coverage_column,
|
|
107
|
+
th: styles.coverage_column,
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
];
|
|
111
|
+
|
|
112
|
+
const calculatePercentage = (data: CoverageData) => {
|
|
113
|
+
const covered = data.lines.covered
|
|
114
|
+
+ data.branches.covered
|
|
115
|
+
+ data.functions.covered
|
|
116
|
+
+ data.statements.covered;
|
|
117
|
+
|
|
118
|
+
const total = data.lines.total
|
|
119
|
+
+ data.branches.total
|
|
120
|
+
+ data.functions.total
|
|
121
|
+
+ data.statements.total;
|
|
122
|
+
return (covered / total) * 100;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const columns: ColumnProps<CoverageFile>[] = [
|
|
126
|
+
{
|
|
127
|
+
id: 'path',
|
|
128
|
+
header: 'File',
|
|
129
|
+
cell: ({ row }) => (
|
|
130
|
+
<div className={styles.filePath}>
|
|
131
|
+
<Link href={`../~code/${row?.path}${document.location.search}`}>
|
|
132
|
+
{row?.path}
|
|
133
|
+
</Link>
|
|
134
|
+
</div>
|
|
135
|
+
)
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
id: 'progress',
|
|
139
|
+
header: 'Overall',
|
|
140
|
+
cell: ({ row }) => {
|
|
141
|
+
if (!row) {
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const coveredPercentage = calculatePercentage(row?.data);
|
|
146
|
+
|
|
147
|
+
return (
|
|
148
|
+
<div className={styles.summaryProgressBar}>
|
|
149
|
+
<div className={styles.progressBarFill} style={{
|
|
150
|
+
width: `${coveredPercentage}%`,
|
|
151
|
+
backgroundColor: getColor(coveredPercentage)
|
|
152
|
+
}}
|
|
153
|
+
/>
|
|
154
|
+
</div>
|
|
155
|
+
)
|
|
156
|
+
},
|
|
157
|
+
value: (file) => file?.data.lines.pct ?? 0,
|
|
158
|
+
className: {
|
|
159
|
+
td: styles.coverage_column,
|
|
160
|
+
th: styles.coverage_column,
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
id: 'lines',
|
|
165
|
+
header: 'Lines',
|
|
166
|
+
columns: createColumn('lines', 'Lines', 'lines')
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
id: 'functions',
|
|
170
|
+
header: 'Functions',
|
|
171
|
+
columns: createColumn('functions', 'Functions', 'functions')
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
id: 'statements',
|
|
175
|
+
header: 'Statements',
|
|
176
|
+
columns: createColumn('statements', 'Statements', 'statements')
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
id: 'branches',
|
|
180
|
+
header: 'Branches',
|
|
181
|
+
columns: createColumn('branches', 'Branches', 'branches')
|
|
182
|
+
},
|
|
183
|
+
];
|
|
184
|
+
|
|
17
185
|
const TESTS_SUBSCRIPTION_CHANGED = gql`
|
|
18
186
|
subscription OnTestsChanged($id: String!) {
|
|
19
187
|
testsChanged(id: $id) {
|
|
@@ -60,12 +228,111 @@ const GET_COMPONENT = gql`
|
|
|
60
228
|
error
|
|
61
229
|
}
|
|
62
230
|
}
|
|
231
|
+
coverage {
|
|
232
|
+
total {
|
|
233
|
+
lines {
|
|
234
|
+
total
|
|
235
|
+
covered
|
|
236
|
+
pct
|
|
237
|
+
}
|
|
238
|
+
functions {
|
|
239
|
+
total
|
|
240
|
+
covered
|
|
241
|
+
pct
|
|
242
|
+
}
|
|
243
|
+
statements {
|
|
244
|
+
total
|
|
245
|
+
covered
|
|
246
|
+
pct
|
|
247
|
+
}
|
|
248
|
+
branches {
|
|
249
|
+
total
|
|
250
|
+
covered
|
|
251
|
+
pct
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
files {
|
|
255
|
+
path
|
|
256
|
+
data {
|
|
257
|
+
lines {
|
|
258
|
+
total
|
|
259
|
+
covered
|
|
260
|
+
pct
|
|
261
|
+
}
|
|
262
|
+
functions {
|
|
263
|
+
total
|
|
264
|
+
covered
|
|
265
|
+
pct
|
|
266
|
+
}
|
|
267
|
+
statements {
|
|
268
|
+
total
|
|
269
|
+
covered
|
|
270
|
+
pct
|
|
271
|
+
}
|
|
272
|
+
branches {
|
|
273
|
+
total
|
|
274
|
+
covered
|
|
275
|
+
pct
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
63
280
|
}
|
|
64
281
|
}
|
|
65
282
|
}
|
|
66
283
|
}
|
|
67
284
|
`;
|
|
68
285
|
|
|
286
|
+
type TotalCoverageSummaryProps = {
|
|
287
|
+
coverageResult: CoverageResults;
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
const TotalCoverageSummary: React.FC<TotalCoverageSummaryProps> = ({ coverageResult }) => {
|
|
291
|
+
const { lines, statements, functions, branches } = coverageResult.total
|
|
292
|
+
|
|
293
|
+
const data = [
|
|
294
|
+
{ label: "Statements", value: `${statements.covered}/${statements.total}`, pct: statements.pct },
|
|
295
|
+
{ label: "Branches", value: `${branches.covered}/${branches.total}`, pct: branches.pct },
|
|
296
|
+
{ label: "Functions", value: `${functions.covered}/${functions.total}`, pct: functions.pct },
|
|
297
|
+
{ label: "Lines", value: `${lines.covered}/${lines.total}`, pct: lines.pct },
|
|
298
|
+
]
|
|
299
|
+
|
|
300
|
+
const totalCovered = lines.covered + branches.covered + functions.covered + statements.covered;
|
|
301
|
+
const totalLines = lines.total + branches.total + functions.total + statements.total;
|
|
302
|
+
|
|
303
|
+
return (
|
|
304
|
+
<div style={{ display: "flex", flexDirection: "column", marginBottom: "20px" }}>
|
|
305
|
+
<div className={styles.container}>
|
|
306
|
+
{data.map((item) => (
|
|
307
|
+
<div key={item.label} className={styles.item}>
|
|
308
|
+
<span className={styles.percentage}
|
|
309
|
+
style={{
|
|
310
|
+
color: getColor(item.pct)
|
|
311
|
+
}}
|
|
312
|
+
>
|
|
313
|
+
{item.pct}%
|
|
314
|
+
</span>
|
|
315
|
+
<span className={styles.label}>
|
|
316
|
+
{item.label}
|
|
317
|
+
</span>
|
|
318
|
+
<span className={styles.badge}>
|
|
319
|
+
{item.value}
|
|
320
|
+
</span>
|
|
321
|
+
</div>
|
|
322
|
+
))}
|
|
323
|
+
</div>
|
|
324
|
+
{/** Display a progress bar for the total */}
|
|
325
|
+
<div className={styles.summaryProgressBar}>
|
|
326
|
+
<div className={styles.progressBarFill} style={{
|
|
327
|
+
width: `${totalCovered / totalLines * 100}%`,
|
|
328
|
+
backgroundColor: getColor(totalCovered / totalLines * 100)
|
|
329
|
+
}}
|
|
330
|
+
/>
|
|
331
|
+
</div>
|
|
332
|
+
</div>
|
|
333
|
+
)
|
|
334
|
+
}
|
|
335
|
+
|
|
69
336
|
type TestsPageProps = {
|
|
70
337
|
emptyState: EmptyStateSlot;
|
|
71
338
|
} & HTMLAttributes<HTMLDivElement>;
|
|
@@ -86,15 +353,16 @@ export function TestsPage({ className, emptyState }: TestsPageProps) {
|
|
|
86
353
|
variables: { id },
|
|
87
354
|
});
|
|
88
355
|
|
|
89
|
-
const { data } = useQuery(GET_COMPONENT, {
|
|
356
|
+
const { data, loading } = useQuery(GET_COMPONENT, {
|
|
90
357
|
variables: { id },
|
|
91
358
|
});
|
|
92
359
|
|
|
93
360
|
const testData = onTestsChanged.data?.testsChanged || data?.getHost?.getTests;
|
|
94
361
|
const testResults = testData?.testsResults?.testFiles;
|
|
362
|
+
const testCoverage = testData?.testsResults?.coverage as CoverageResults;
|
|
95
363
|
|
|
96
364
|
// TODO: change loading EmptyBox
|
|
97
|
-
if (testData?.loading) return <TestLoader />;
|
|
365
|
+
if (loading || testData?.loading) return <TestLoader />;
|
|
98
366
|
|
|
99
367
|
const env = component.environment?.id;
|
|
100
368
|
const EmptyStateTemplate = emptyState.get(env || '');
|
|
@@ -139,7 +407,22 @@ export function TestsPage({ className, emptyState }: TestsPageProps) {
|
|
|
139
407
|
<div>
|
|
140
408
|
<H1 className={styles.title}>Tests</H1>
|
|
141
409
|
<Separator isPresentational className={styles.separator} />
|
|
410
|
+
<H2 className={styles.subtitle}>Tests Results</H2>
|
|
142
411
|
<TestTable testResults={testResults} className={styles.testBlock} />
|
|
412
|
+
{testCoverage && testCoverage.files.length > 0 && (
|
|
413
|
+
<>
|
|
414
|
+
<Separator isPresentational className={styles.separator} />
|
|
415
|
+
<H2 className={styles.subtitle}>Coverage Report</H2>
|
|
416
|
+
<TotalCoverageSummary coverageResult={testCoverage} />
|
|
417
|
+
<Table<CoverageFile>
|
|
418
|
+
data={testCoverage.files}
|
|
419
|
+
columns={columns}
|
|
420
|
+
sorting={{
|
|
421
|
+
enable: true,
|
|
422
|
+
}}
|
|
423
|
+
/>
|
|
424
|
+
</>
|
|
425
|
+
)}
|
|
143
426
|
</div>
|
|
144
427
|
</div>
|
|
145
428
|
);
|
|
File without changes
|