diff --git a/tcms/telemetry/api.py b/tcms/telemetry/api.py index ca462e90df..8eb4e4dba8 100644 --- a/tcms/telemetry/api.py +++ b/tcms/telemetry/api.py @@ -226,6 +226,22 @@ def test_case_health(query=None): return data +@http_basic_auth_login_required +@rpc_method(name="Testing.individual_test_case_health") +def individual_test_case_health_simple(query=None): + + if query is None: + query = {} + + res = ( + TestExecution.objects.filter(**query) + .values("run__plan", "case_id", "status__name", "status__weight") + .order_by("case", "run__plan", "status__weight") + ) + + return list(res) + + def _remove_all_excellent_executions(data): for key in dict.fromkeys(data): if data[key]["count"]["fail"] == 0: diff --git a/tcms/templates/include/tc_executions.html b/tcms/templates/include/tc_executions.html index 6c82856e5b..7fb08da9f6 100644 --- a/tcms/templates/include/tc_executions.html +++ b/tcms/templates/include/tc_executions.html @@ -23,10 +23,24 @@

-
+
+
+
{% trans 'Completion rate' %}: +
+
+
+
+
+
{% trans 'Failure rate' %}: +
+
+
+
+
+
diff --git a/tcms/testcases/static/testcases/js/get.js b/tcms/testcases/static/testcases/js/get.js index 5dbee3187b..57779b03bc 100644 --- a/tcms/testcases/static/testcases/js/get.js +++ b/tcms/testcases/static/testcases/js/get.js @@ -1,6 +1,6 @@ const plan_cache = {} -function addComponent (object_id, _input, to_table) { +function addComponent(object_id, _input, to_table) { const _name = _input.value if (_name.length > 0) { @@ -15,7 +15,7 @@ function addComponent (object_id, _input, to_table) { } } -function addTestPlanToTestCase (case_id, plans_table) { +function addTestPlanToTestCase(case_id, plans_table) { const plan_name = $('#input-add-plan')[0].value const plan = plan_cache[plan_name] @@ -31,7 +31,7 @@ function addTestPlanToTestCase (case_id, plans_table) { }) } -function initAddPlan (case_id, plans_table) { +function initAddPlan(case_id, plans_table) { // + button $('#btn-add-plan').click(function () { addTestPlanToTestCase(case_id, plans_table) @@ -210,6 +210,45 @@ $(document).ready(function () { }) }) + jsonRPC('Testing.individual_test_case_health', { case_id: case_id }, ress => { + + let res = {}; + let planId = 0; + ress.forEach(r => { + let positive = 0; + let negative = 0; + let allCount = 0; + if (r.status__weight > 0) { + positive++ + } else if (r.status__weight < 0) { + negative++ + } + allCount++ + + if (r.run__plan !== planId) { + planId = r.run__plan; + res[planId] = { + "completion_rate": allCount > 0 ? ((positive + negative) / allCount) : 0, + "failure_rate": allCount > 0 ? (negative / allCount) : 0, + } + positive = 0; + negative = 0; + allCount = 0; + } + }) + + Object.entries(res).forEach(([runId, data]) => { + const executionRow = $(`#execution-for-plan-${runId}`) + executionRow.find('.completion-rate').html(data.completion_rate) + executionRow.find('.completion-rate-container .progress-bar-danger').css('width', `${(1 - data.completion_rate) * 100}%`) + executionRow.find('.completion-rate-container .progress-bar-success').css('width', `${(data.completion_rate) * 100}%`) + + executionRow.find('.failure-rate').html(data.failure_rate) + executionRow.find('.failure-rate-container .progress-bar-danger').css('width', `${(data.failure_rate) * 100}%`) + executionRow.find('.failure-rate-container .progress-bar-success').css('width', `${(1 - data.failure_rate) * 100}%`) + }) + }) + // bind add TP to TC widget initAddPlan(case_id, plans_table)