Skip to content

Commit

Permalink
Use new status icons in get_details_case_run.html
Browse files Browse the repository at this point in the history
Refs kiwitcms#236
Closes kiwitcms#1261

Clean-up some of the java script in `testrun_actions.js`
Put up some TODO for future refactoring

Use the API to update the execution status

in favour of `updateRunStatus` function

Delete global variable `Nitrate.TestRuns.CaseRunStatus`

Delete `UpdateCaseRunStatusView`

because we will be using the API for updating execution statuses

Disable the button for the current execution status
,because we don't want to update the status of the execution, with the
same status

Also, add `opacity: 0.25` style to the disabled button, so that it is
visible to the user, that the button is disabled
  • Loading branch information
asankov committed Jan 25, 2020
1 parent c8bf257 commit fc0eaa8
Show file tree
Hide file tree
Showing 11 changed files with 121 additions and 179 deletions.
16 changes: 16 additions & 0 deletions tcms/.eslintrc.js
@@ -0,0 +1,16 @@
module.exports = {
"env": {
"browser": true,
"es6": true
},
"extends": "eslint:recommended",
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parserOptions": {
"ecmaVersion": 2018
},
"rules": {
}
};
1 change: 1 addition & 0 deletions tcms/rpc/api/forms/testrun.py
Expand Up @@ -90,4 +90,5 @@ def clean_status(self):

class UpdateExecutionForm(BaseCaseRunForm):
assignee = forms.ModelChoiceField(queryset=User.objects.all(), required=False)
tested_by = forms.ModelChoiceField(queryset=User.objects.all(), required=False)
build = forms.ModelChoiceField(queryset=Build.objects.all(), required=False)
3 changes: 3 additions & 0 deletions tcms/rpc/api/testexecution.py
Expand Up @@ -167,6 +167,9 @@ def update(case_run_id, values, **kwargs):
if form.cleaned_data['sortkey'] is not None:
tcr.sortkey = form.cleaned_data['sortkey']

if form.cleaned_data['tested_by']:
tcr.tested_by = form.cleaned_data['tested_by']

tcr.save()

else:
Expand Down
176 changes: 87 additions & 89 deletions tcms/static/js/testrun_actions.js
Expand Up @@ -3,6 +3,7 @@ Nitrate.TestRuns.Details = {};
Nitrate.TestRuns.Execute = {}
Nitrate.TestRuns.AssignCase = {}

let executionStatuses;

function toggleDiv(link, divId) {
var link = jQ(link);
Expand Down Expand Up @@ -60,15 +61,30 @@ Nitrate.TestRuns.Details.on_load = function() {
var toggle_case_run = function(e) {
var c = jQ(this).parent(); // Container
var c_container = c.next(); // Content Containers
var case_id = c.find('input[name="case"]')[0].value;
var case_run_id = c.find('input[name="case_run"]')[0].value;
var case_text_version = c.find('input[name="case_text_version"]')[0].value;
var type = 'case_run';
var caseId = c.find('input[name="case"]')[0].value;
var caseRunId = c.find('input[name="case_run"]')[0].value;
var caseTextVersion = c.find('input[name="case_text_version"]')[0].value;
var callback = function(t) {
// Observe the update case run stauts/comment form
c_container.parent().find('.update_form')
.unbind('submit').bind('submit', updateCaseRunStatus);

const caseId = c_container.find('input[name=case_id]').val()
const executionId = c_container.find('input[name=object_pk]').val()

const updateForm = c_container.find('.update_form')

updateForm.unbind('submit').bind('submit', event => {
event.stopPropagation();
event.preventDefault();

const comment = updateForm.find('td > textarea[name=comment]').val()
if (comment) {
addComment(executionId, caseId, comment)
}
});

const currentStatusId = parseInt(c_container.find('input[name=status_id]').val())
const submitButtons = c_container.find('.submit_button')
bindSubmitButtons(updateForm, currentStatusId, submitButtons, executionId, caseId)

var rc_callback = function(e) {
e.stopPropagation();
Expand All @@ -78,15 +94,12 @@ Nitrate.TestRuns.Details.on_load = function() {
}

const comment_id = $(this).find('input[name=comment_id]').val();
jsonRPC('TestExecution.remove_comment', [case_run_id, comment_id], function(data) {
constructCaseRunZone(c_container[0], c[0], case_id);
jsonRPC('TestExecution.remove_comment', [caseRunId, comment_id], function(data) {
constructCaseRunZone(c_container[0], c[0], caseId);
});
};
c_container.parent().find('.form_comment')
.unbind('submit').bind('submit', rc_callback);
c_container.find('.js-status-button').bind('click', function() {
this.form.value.value = jQ(this).data('formvalue');
});
c_container.find('.js-show-comments').bind('click', function() {
toggleDiv(this, jQ(this).data('param'));
});
Expand All @@ -111,9 +124,9 @@ Nitrate.TestRuns.Details.on_load = function() {

toggleTestExecutionPane({
'callback': callback,
'caseId': case_id,
'caserunId': case_run_id,
'caseTextVersion': case_text_version,
'caseId': caseId,
'caserunId': caseRunId,
'caseTextVersion': caseTextVersion,
'caserunRowContainer': c,
'expandPaneContainer': c_container
});
Expand Down Expand Up @@ -244,63 +257,44 @@ Nitrate.TestRuns.AssignCase.on_load = function() {
});
};

function updateExecutionStatus(updateForm, executionId, caseId, executionStatusPk) {

function updateRunStatus(object_pk, value, callback) {
jQ.ajax({
'url': '/runs/case-run-update-status/',
'type': 'POST',
'data': {'object_pk': object_pk, 'status_id': value },
'success': function (data, textStatus, jqXHR) {
callback();
},
'error': function (jqXHR, textStatus, errorThrown) {
json_failure(jqXHR);
}
});
}
const container = updateForm.parents().eq(3)
const parent = container.parent()
const title = parent.prev()
const link = title.find('.expandable')[0];

var updateCaseRunStatus = function(e) {
e.stopPropagation();
e.preventDefault();
var container = jQ(this).parents().eq(3);
var parent = container.parent();
var title = parent.prev();
var link = title.find('.expandable')[0];
var parameters = Nitrate.Utils.formSerialize(this);
var object_pk = parameters['object_pk'];
var value = parameters['value'];

// Callback when
var callback = function(t) {
// Update the contents
const value = parameters['value']
if (value != '') {
// Update the case run status icon
var crs = Nitrate.TestRuns.CaseRunStatus;
title.find('.execution_status_icon').each(function(index) {
for (i in crs) {
jQ(this).removeClass(crs[i].icon);
}
const execution = Nitrate.TestRuns.CaseRunStatus.find(tcs => tcs.pk === value);
jQ(this).addClass(execution.icon);
jQ(this).css('color', execution.color)
});
const comment = updateForm.find('textarea[name=comment]').val()
if (comment) {
addComment(executionId, caseId, comment)
}

// Update related people
var usr = Nitrate.User;
title.find('.link_tested_by').each(function(i) {
jQ(this).html(usr.username);
});
}
// Update the object when changing the status
jsonRPC('TestExecution.update', [executionId, {
'status': executionStatusPk,
'tested_by': Nitrate.User.pk
}], data => {

const executionStatusIcon = $(title.find('.execution_status_icon'))

// remove all the icon classes from the icon, so that we can add the proper class few lines below
executionStatuses.forEach(status => executionStatusIcon.removeClass(status.icon))

// update the icon in the table row
const executionStatus = executionStatuses.find(status => status.id === parseInt(executionStatusPk))
executionStatusIcon.addClass(executionStatus.icon)
executionStatusIcon.css('color', executionStatus.color)

// Update related people
title.find('.link_tested_by').html(data.tested_by);
// Mark the case run to mine
if (!title.is('.mine')) {
title.addClass('mine');
}

// Blind down next case
fireEvent(link, 'click');
if (jQ('#id_check_box_auto_blinddown').attr('checked') && parameters['value'] != '') {
if ($('#id_check_box_auto_blinddown')[0].checked && executionStatusPk) {
var next_title = parent.next();
if (!next_title.length) {
return false;
Expand All @@ -311,39 +305,33 @@ var updateCaseRunStatus = function(e) {
} else {
fireEvent(link, 'click');
}
};

// Add comment
if (parameters['comment'] != '') {
// Reset the content to loading
var ajax_loading = getAjaxLoading();
ajax_loading.id = 'id_loading_' + parameters['case_id'];
container.html(ajax_loading);
var c = jQ('<div>');

if (parameters['value'] != '') {
jsonRPC('TestExecution.add_comment', [object_pk, parameters['comment']], function(data){
updateCommentsCount(parameters['case_id'], true);
});
} else {
jsonRPC('TestExecution.add_comment', [object_pk, parameters['comment']], function(data){
updateCommentsCount(parameters['case_id'], true);
callback();
});
const submitButtons = updateForm.find('.submit_button')

bindSubmitButtons(updateForm, data.status_id, submitButtons, executionId, caseId)
});
};

function bindSubmitButtons(updateForm, currentStatusId, submitButtons, executionId, caseId) {
submitButtons.each((_index, b) => {
const submitButton = $(b)
const executionStatusId = parseInt(submitButton.attr('statusId'))

submitButton.unbind('click')

if (executionStatusId === currentStatusId) {
submitButton.css('opacity', '0.25')
} else {
submitButton.css('opacity', '1')
submitButton.bind('click', () => updateExecutionStatus(updateForm, executionId, caseId, executionStatusId))
}
}

// Update the object when changing the status
if (parameters['value'] != '') {
// Reset the content to loading
var ajax_loading = getAjaxLoading();
ajax_loading.id = 'id_loading_' + parameters['case_id'];
container.html(ajax_loading);
updateRunStatus([object_pk], value, callback);
}
};
})
}

function addComment(executionId, caseId, comment) {
jsonRPC('TestExecution.add_comment', [executionId, comment], () => updateCommentsCount(caseId, true));
}

function constructCaseRunZone(container, title_container, case_id) {
var link = jQ(title_container).find('.expandable')[0];
Expand Down Expand Up @@ -663,6 +651,9 @@ function showCommentForm() {
}

jQ(document).ready(function(){

jsonRPC('TestExecutionStatus.filter', {}, data => executionStatuses = data)

jQ('.btnBlueCaserun').mouseover(function() {
jQ(this).find('ul').show();
}).mouseout(function() {
Expand All @@ -681,7 +672,14 @@ jQ(document).ready(function(){
if (!window.confirm(default_messages.confirm.change_case_status)) {
return false;
}
updateRunStatus(object_pks, option, reloadWindow);
object_pks.forEach(executionId => {
jsonRPC('TestExecution.update', [executionId, {
'status': option,
'tested_by': Nitrate.User.pk
}], () => { }, true)
})

reloadWindow();
});
});

Expand Down
7 changes: 4 additions & 3 deletions tcms/templates/case/get_details_case_run.html
Expand Up @@ -29,11 +29,12 @@ <h4 style="padding-bottom:3px;">Comments</h4>
<input type="hidden" name="case_id" value="{{ execution.case_id }}" />
<input type="hidden" name="assignee" value="{{ execution.assignee_id }}" />
<input type="hidden" name="tested_by" value="{{ execution.tested_by_id }}" />
<input type="hidden" name="status_id" value="{{ execution.status_id }}" />
<input type="hidden" name="value" value="" />
{% if perms.testruns.change_testexecution %}
{% for status in execution_status %}
<input type="submit" class="btn btn_{{ status.name.lower }} btn_status js-status-button" title="{{ status.name }}" value="" crs_id="{{ status.pk }}" {% ifequal status.pk execution.status_id %}disabled="True"{% endifequal %} data-formvalue="{{ status.pk }}" />
{% endfor %}
{% for status in execution_status %}
<i class="submit_button {{ status.icon }} fa-2x" style="color: {{status.color}}" statusId="{{ status.pk }}" title="{{ status.name }}"></i>
{% endfor %}
{% endif %}
<input type="submit" class="submit-post" value="Submit">
</td>
Expand Down
9 changes: 0 additions & 9 deletions tcms/templates/run/get.html
Expand Up @@ -14,15 +14,6 @@
<script type="text/javascript" src="{% static 'js/testrun_actions.js' %}"></script>
<script type="text/javascript" src="{% static 'js/testcase_actions.js' %}"></script>
<script type="text/javascript">
{# Define the status array for all of case run status #}
Nitrate.TestRuns.CaseRunStatus = new Array();
{% for crs in test_status %}
Nitrate.TestRuns.CaseRunStatus.push({
"pk": "{{crs.pk}}",
"icon": "{{crs.icon}}",
"color": "{{crs.color}}"
});
{% endfor %}
Nitrate.Utils.after_page_load(Nitrate.TestRuns.Details.on_load);
</script>
<script type="text/javascript">
Expand Down
18 changes: 9 additions & 9 deletions tcms/testcases/tests/test_views.py
Expand Up @@ -8,8 +8,8 @@
from django.forms import ValidationError
from django.test import RequestFactory
from django.urls import reverse
from django.utils.translation import override
from django.utils.translation import gettext_lazy as _
from django.utils.translation import ugettext_lazy as _

from tcms.management.models import Priority, Tag
from tcms.testcases.fields import MultipleEmailField
Expand Down Expand Up @@ -55,14 +55,14 @@ def test_user_in_default_group_sees_comments(self):
'required rows="10">\n</textarea>',
html=True)

with override('en'):
for status in TestExecutionStatus.objects.all():
self.assertContains(
response,
"<input type=\"submit\" class=\"btn btn_%s btn_status js-status-button\" "
"title=\"%s\"" % (status.name.lower(), status.name),
html=False
)
for status in TestExecutionStatus.objects.all():
self.assertContains(
response,
'<i class="submit_button %s fa-2x" style="color: %s" \
statusId="%s" title="%s"></i>'
% (status.icon, status.color, status.pk, status.name),
html=True
)

def test_user_sees_bugs(self):
bug_1 = LinkReferenceFactory(execution=self.execution_1)
Expand Down
2 changes: 1 addition & 1 deletion tcms/testcases/views.py
Expand Up @@ -466,7 +466,7 @@ def get_context_data(self, **kwargs):
# Data of TestExecution
execution_comments = get_comments(execution)

execution_status = TestExecutionStatus.objects.values('pk', 'name').order_by('pk')
execution_status = TestExecutionStatus.objects.order_by('-weight', 'name')

data.update({
'test_case': case,
Expand Down

0 comments on commit fc0eaa8

Please sign in to comment.