Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support custom statuses #3869

Open
wants to merge 9 commits into
base: master
Choose a base branch
from

Conversation

mihaiparvu
Copy link
Contributor

PR for #3625

Added the possibility to set custom status from command line option --addstatus. The new status is set based on tags and displayed both in console output and log.html. The color can be customized but only in the log file, in console it maintains the old colors.

mparvu and others added 8 commits February 23, 2021 14:31
…work into issue_3625

# Conflicts:
#	src/robot/htmldata/rebot/testdata.js
#	src/robot/reporting/jsmodelbuilders.py
#	src/robot/result/model.py
#	src/robot/result/suiteteardownfailed.py
#	src/robot/result/xmlelementhandlers.py
#	src/robot/running/statusreporter.py
@codecov-io
Copy link

codecov-io commented Mar 2, 2021

Codecov Report

Merging #3869 (f17e11a) into master (0fabf9f) will decrease coverage by 0.12%.
The diff coverage is 48.94%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #3869      +/-   ##
==========================================
- Coverage   75.27%   75.16%   -0.11%     
==========================================
  Files         222      222              
  Lines       18716    18753      +37     
  Branches     3036     3045       +9     
==========================================
+ Hits        14087    14094       +7     
- Misses       4096     4120      +24     
- Partials      533      539       +6     
Impacted Files Coverage Δ
src/robot/run.py 80.40% <ø> (ø)
src/robot/running/suiterunner.py 74.36% <ø> (ø)
src/robot/running/status.py 69.46% <33.34%> (-2.35%) ⬇️
src/robot/conf/settings.py 70.77% <42.86%> (-1.51%) ⬇️
src/robot/running/statusreporter.py 82.09% <60.00%> (+0.28%) ⬆️
src/robot/output/console/highlighting.py 75.94% <100.00%> (+0.75%) ⬆️
src/robot/reporting/jsmodelbuilders.py 98.24% <100.00%> (-0.01%) ⬇️
src/robot/utils/robotinspect.py 47.62% <0.00%> (-19.04%) ⬇️
src/robot/version.py 55.56% <0.00%> (-11.11%) ⬇️
src/robot/libdocpkg/datatypes.py 94.57% <0.00%> (-1.08%) ⬇️
... and 1 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 0fabf9f...f17e11a. Read the comment docs.

Copy link
Member

@pekkaklarck pekkaklarck left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good start but the core logic how custom statuses are set to objects need to be changed to something less fragile. Let's discuss about better alternative separately.

There were also some other issues explained in individual comments. In addition to them, I noticed these problems when testing the code locally:

  • Statistics aren't collected for the custom statuses. There probably should be new status columns in both log and report statics, but needed to test how that works if there are multiple custom statuses. Should also show custom statuses in status graphs.

    Right now also collecting "normal" statistics is broken. I tested creating a new status based on PASS, and those tests were considered failed in all statistics.

  • Dark status colors make reading the black status text hard in the log file. We preferably should automatically decide should the status text be black or white depending on the specified status color. Alternatively we could require giving that as well but it would make the usage a bit more complicated.

@@ -136,7 +136,7 @@ def _check_test_status(self, test, status=None, message=None):
test.exp_status = status
if message is not None:
test.exp_message = message
if test.exp_status != test.status:
if test.exp_status != test.status and test.status in ['PASS', 'FAIL', 'SKIP']:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change looks risky. Doesn't it mean that custom statuses aren't validated at all?

@@ -1322,7 +1322,6 @@
var idCounter = 0;
var _statistics = null;
var LEVELS = ['TRACE', 'DEBUG', 'INFO', 'WARN', 'ERROR', 'FAIL', 'SKIP'];
var STATUSES = ['FAIL', 'PASS', 'NOT_RUN', 'SKIP'];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to change examples under doc at all. These changes just add distraction to the PR.

@@ -273,6 +282,13 @@ def _process_tag_stat_link(self, value):
raise DataError("Invalid format for option '--tagstatlink'. "
"Expected 'tag:link:title' but got '%s'." % value)

def _process_custom_statuses(self, value):
tokens = value.split(':')
if len(tokens) == 4 and tokens[1] in ['PASS', 'FAIL', 'SKIP']:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should support also lower case values.

for (let status of Object.keys(statuses)) {
css.append(".label.".concat(status.toLowerCase()).concat("{ background-color:").concat(statuses[status]).concat("}"));
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't it possible to just modify CSS directly and not inject <style> like this? If styles are injected, we could probably do that when writing the log file itself.

@@ -38,7 +37,7 @@ window.testdata = function () {
}

function parseStatus(stats) {
return STATUSES[stats[0]];
return stats[0];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Statuses should be written to log.html as integers like earlier. That takes less space and lists containing only integers are faster to process by browsers than lists containing integers and strings. The hard coded STATUSES list mapping integers to actual statuses should just be replaced with a list containing also the custom statuses. It probably could be written to the config section along with custom title, background color, etc.

# reset custom statuses
StatusMixin.PASS = 'PASS'
StatusMixin.FAIL = 'FAIL'
StatusMixin.SKIP = 'SKIP'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks really strange. Do I get the logic right that code elsewhere sets custom values for StatusMixin.XXX constants and they are reset here? If yes, that's not a very good approach. It only works if code is executed in certain order and doesn't work at all if you programmatically check results.

@@ -60,7 +59,7 @@ def __init__(self, context):
def _get_status(self, item):
# Branch status with IF/ELSE, "normal" status with others.
status = getattr(item, 'branch_status', item.status)
model = (STATUSES[status],
model = (status,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I already commented the related JS code on log.html side, statuses should still be integers in log.html. Should somehow be able to map also custom statuses to integers here. Probably the mapping could be passed to JsModelBuilder but also the processes result object could have that info.

Examples:
--addstatus KNOWN_ISSUE:FAIL:bug-id-*:purple
--addstatus NON-CRITICAL:SKIP:non-critical:pink
New in RF 4.x
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for|foritem looks like a copy-paste error.

Also rebot.py would need this option.

StatusMixin.FAIL = custom_status[0]
else:
StatusMixin.SKIP = custom_status[0]
break
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I commented the code on the highlighter, the logic to here modify constants and then elsewhere resetting them isn't a valid approach. It's too fragile because it requires code to be run in certain exact order and doesn't work at all if analyzing/modifying results programmatically. I'm not exactly sure what's the best way to handle this core logic, but I write some ideas as general comments.

@pekkaklarck
Copy link
Member

The hard part with this issue is designing how to store information about custom statuses internally. For example, should the status attribute tests have get these custom statuses or should it always be one of the base statuses PASS/FAIL/SKIP? The former initially feels better, but it would require changes in all code looking for statuses. In the latter case test could/should have a separate attribute that returns possible custom status based on configs and test base status and tags. We could consider renaming the current status to e.g. base_status and using status with the new attribute, though.

We also need to design how to pass the custom status information to tests. Most likely it could be given to the top level result suite where tests could query it. We used similar approach with criticality information earlier.

We can discuss all this further here or on Slack. It seems pretty clear that there's so much work still to be done that it's nevertheless best to move this issue from RF 4.1 to RF 5.0 scope.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants