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

#3423 Robot Framework JSON output #3475

Open
wants to merge 23 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
cc8ee91
Added a --json option to rebot to outputting to a JSON format
Lemonlemmings Feb 3, 2020
2217475
Reworked how the JSON writer works so it's now in a logger format (si…
Lemonlemmings Feb 9, 2020
e81f5f7
Reworked how the JSON writer works so it's now in a logger format (si…
Lemonlemmings Feb 9, 2020
57f21e9
Removed unused parts of the jsonwriter
Lemonlemmings Feb 9, 2020
52b72ea
Updated rebot so it can now build the JSON it provides into an Execut…
Lemonlemmings Feb 10, 2020
0f8aa79
Updated so that there are some additional unit-tests and the failures…
Mar 30, 2020
478c6b0
Updated to more confidence in the JSON, and ensure that the JSON prod…
Lemonlemmings Jun 13, 2020
c6374bc
Fixed issues with help lines and trailing whitespace
Lemonlemmings Oct 2, 2020
50f67e7
Updated to fix unit tests failures and removal of criticality
Lemonlemmings Oct 9, 2020
94df3ef
Fixed keyword tagging, and assignments not being correct
Oct 14, 2020
d970ea2
Updated so that errors aren't incorrectly logged
Oct 15, 2020
7be930e
Undid error message write
Oct 15, 2020
d0d2eb6
Merged with upstream
Lemonlemmings Feb 22, 2021
b19dba9
Updated JSON
Lemonlemmings Feb 23, 2021
dca5dd2
Updated the JSON logging to allow for streaming into the file to save…
Lemonlemmings Feb 23, 2021
36a889e
Updated JSON element handlers to manage setup and teardown keywords
Lemonlemmings Feb 23, 2021
df224ff
Updated schema to accurately reflect possibilities, and updated to be…
Lemonlemmings Feb 23, 2021
44fa114
Resolved an issue with keyword teardowns causing multiple items in a …
Lemonlemmings Feb 23, 2021
3e2c880
Updated for keywords being able to have test teardowns
Lemonlemmings Feb 23, 2021
78d121f
Added more exceptions what objects the JSON will store
Lemonlemmings Feb 24, 2021
113f642
Added stats to the JSON output
Lemonlemmings Feb 24, 2021
f358104
Updated the schema to have the correct stats in
Lemonlemmings Feb 24, 2021
1acecfd
Updated settings for JSON flag.
Lemonlemmings Mar 8, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file modified atest/genrunner.py
100755 → 100644
Empty file.
4 changes: 2 additions & 2 deletions atest/resources/TestCheckerLibrary.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from robot import utils
from robot.api import logger
from robot.utils.asserts import assert_equal
from robot.result import (ExecutionResultBuilder, For, If, ForIteration, Keyword,
from robot.result import (XmlExecutionResultBuilder, For, If, ForIteration, Keyword,
Result, ResultVisitor, TestCase, TestSuite)
from robot.result.model import Body, ForIterations, IfBranches, IfBranch
from robot.libraries.BuiltIn import BuiltIn
Expand Down Expand Up @@ -71,7 +71,7 @@ def process_output(self, path):
try:
logger.info("Processing output '%s'." % path)
result = Result(root_suite=NoSlotsTestSuite())
ExecutionResultBuilder(path).build(result)
XmlExecutionResultBuilder(path).build(result)
except:
set_suite_variable('$SUITE', None)
msg, details = utils.get_error_details()
Expand Down
Empty file modified atest/robot/keywords/embedded_arguments_library_keywords.robot
100755 → 100644
Empty file.
Empty file modified atest/run.py
100755 → 100644
Empty file.
Empty file.
Empty file modified atest/testdata/keywords/resources/embedded_args_in_lk_1.py
100755 → 100644
Empty file.
Empty file modified atest/testdata/keywords/resources/embedded_args_in_lk_2.py
100755 → 100644
Empty file.
Empty file modified atest/testdata/running/stopping_with_signal/Library.py
100755 → 100644
Empty file.
Empty file.
Empty file modified atest/testdata/standard_libraries/process/files/script.py
100755 → 100644
Empty file.
Empty file modified atest/testdata/test_libraries/dynamic_libraries/EmbeddedArgs.py
100755 → 100644
Empty file.
Empty file modified atest/testresources/compile_java.sh
100755 → 100644
Empty file.
Empty file modified doc/api/generate.py
100755 → 100644
Empty file.
Empty file modified doc/libraries/extract_examples.py
100755 → 100644
Empty file.
247 changes: 247 additions & 0 deletions doc/schema/robot-10.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,247 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"suite": {
"type": "object",
"properties": {
"setup": {"$ref": "#/definitions/keyword"},
"teardown": {"$ref": "#/definitions/keyword"},
"suites": {
"type": "array",
"items": {"$ref": "#/definitions/suite"},
"minItems": 0
},
"tests": {
"type": "array",
"items": {"$ref": "#/definitions/test"},
"minItems": 0
},
"doc": {"type": "string"},
"metadata": {
"type": "object",
"additionalProperties": true
},
"status": {"$ref": "#/definitions/status"},
"name" : {
"type": "string"
},
"id": {
"type": "string"
},
"source":{
"type": "string"
}
},
"required": ["name", "status"],
"additionalProperties": true
},
"test": {
"type": "object",
"properties": {
"body": {"$ref": "#/definitions/body"},
"doc": {"type": "string"},
"tags": {
"type": "array",
"items": {"type": "string"},
"minItems": 0
},
"timeout": {"type": "string"},
"status": {"$ref": "#/definitions/status"},
"name" : {
"type": "string"
},
"id" : {
"type": "string"
}
},
"required": ["name", "status"],
"additionalProperties": true
},
"type": {
"type": "string",
"enum": ["kw", "setup", "teardown", "foritem", "for", "if", "elseif", "else"]
},
"keyword": {
"type": "object",
"properties": {
"body": {"$ref": "#/definitions/body"},
"msgs": {
"type": "array",
"items": {"$ref": "#/definitions/message"},
"minItems": 0
},
"doc": {"type": "string"},
"tags": {
"type": "array",
"items": {"type": "string"},
"minItems": 0
},
"timeout": {"type": "string"},
"args": {
"type": "array",
"items": {"type": "string"},
"minItems": 0
},
"lib": {"type": "string"},
"var": {
"type": "array",
"items": {"type": "string"},
"minItems": 0
},
"status": {"$ref": "#/definitions/status"},
"name" : {
"type": "string"
},
"sourcename" : {
"type": "string"
},
"type" : {"$ref": "#/definitions/type"}
},
"required": ["name", "status"],
"additionalProperties": true
},
"status": {
"type": "object",
"properties": {
"status": {"$ref": "#/definitions/status_enum"},
"endtime": {"type": "string"},
"starttime": {"type": "string"},
"elapsedtime": {"type": "string"},
"critical": {"type": "boolean"},
"msg": {"type": "string"}
},
"required": ["status"],
"additionalProperties": true
},
"message": {
"type": "object",
"properties": {
"msg": {"type": "string"},
"timestamp": {"type": "string"},
"level": {"$ref": "#/definitions/level_enum"},
"html": {"type": "boolean"}
},
"required": ["msg", "timestamp", "level"],
"additionalProperties": true
},
"metadata": {
"type": "object",
"properties": {
"name": {"type": "string"},
"value": {"type": "string"}
}
},
"for": {
"type": "object",
"properties": {
"flavor": {"type": "string"},
"var": {"type": "array",
"items": {"type": "string"}},
"value": {"type": "array",
"items": {"type": "string"}},
"status": {"$ref": "#/definitions/status"},
"doc": {"type": "string"},
"type" : {"$ref": "#/definitions/type"},
"iter": {"type": "array",
"items": {"$ref": "#/definitions/iter"}}
}
},
"itervar": {
"type": "object",
"properties": {
"name": {"type": "string"},
"value": {"type": "string"}
}
},
"iter": {
"type": "object",
"properties": {
"var": {"type": "array",
"items": {"$ref": "#/definitions/itervar"}},
"status": {"$ref": "#/definitions/status"},
"doc": {"type": "string"},
"body": {"$ref": "#/definitions/body"}
}
},
"if": {
"type": "object",
"properties": {
"doc": {"type": "string"},
"status": {"$ref": "#/definitions/status"},
"type" : {"$ref": "#/definitions/type"},
"branches": {"type": "array",
"items": {"$ref": "#/definitions/branch"}}
}
},
"branch": {
"type": "object",
"properties": {
"type": {"type": "string"},
"condition": {"type": "string"},
"doc": {"type": "string"},
"status": {"$ref": "#/definitions/status"},
"body": {"$ref": "#/definitions/body"}
}
},
"body": {
"type": "array",
"items": {"oneOf": [{"$ref": "#/definitions/keyword"},
{"$ref": "#/definitions/for"},
{"$ref": "#/definitions/if"},
{"$ref": "#/definitions/message"}]},
"minItems": 0
},
"statistics": {
"type": "object",
"properties": {
"total": {"$ref": "#/definitions/stats"},
"tag": {"$ref": "#/definitions/stats"},
"suite": {"$ref": "#/definitions/stats"}
},
"required": ["total", "tag", "suite"]
},
"stats": {
"type": "array",
"items": {"$ref": "#/definitions/stat"},
"minItems": 0
},
"stat": {
"type": "object",
"properties": {
"tag": {"type": "string"},
"fail": {"type": "number"},
"skip": {"type": "number"},
"critical": {"type": "boolean"},
"pass": {"type": "number"},
"info": {"type": "string"},
"doc": {"type": "string"},
"id": {"type": "string"},
"name": {"type": "string"}
},
"additionalProperties": true
},
"errors": {
"type": "array",
"items": {"$ref": "#/definitions/message"}
},
"status_enum": {
"type": "string",
"enum": ["PASS", "FAIL"]
},
"level_enum": {
"type": "string",
"enum": ["TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FAIL"]
}
},
"type": "object",
"properties": {
"generator": {"type": "string"},
"generated": {"type": "string"},
"rpa": {"type": "boolean"},
"suite": {"$ref": "#/definitions/suite"},
"statistics": {"$ref": "#/definitions/statistics"},
"errors": {"$ref": "#/definitions/errors"}
},
"required": ["suite"],
"additionalProperties": true
}
Empty file modified doc/userguide/ug2html.py
100755 → 100644
Empty file.
Empty file modified rundevel.py
100755 → 100644
Empty file.
Empty file modified setup.py
100755 → 100644
Empty file.
Empty file modified src/robot/__main__.py
100755 → 100644
Empty file.
15 changes: 14 additions & 1 deletion src/robot/conf/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class _BaseSettings(object):
'Log' : ('log', 'log.html'),
'Report' : ('report', 'report.html'),
'XUnit' : ('xunit', None),
'Json' : ('json', False),
'SplitLog' : ('splitlog', False),
'TimestampOutputs' : ('timestampoutputs', False),
'LogTitle' : ('logtitle', None),
Expand Down Expand Up @@ -203,7 +204,7 @@ def __getitem__(self, name):
def _get_output_file(self, option):
"""Returns path of the requested output file and creates needed dirs.

`option` can be 'Output', 'Log', 'Report', 'XUnit' or 'DebugFile'.
`option` can be 'Output', 'Log', 'Report', 'XUnit', or 'DebugFile'.
"""
name = self._opts[option]
if not name:
Expand All @@ -212,6 +213,8 @@ def _get_output_file(self, option):
self['Log'] = None
LOGGER.error('Log file is not created if output.xml is disabled.')
return None
if option == 'Output' and self.json is True and name == 'output.xml':
name = 'output.json'
name = self._process_output_name(option, name)
path = abspath(os.path.join(self['OutputDir'], name))
create_destination_directory(path, '%s file' % option.lower())
Expand Down Expand Up @@ -334,6 +337,10 @@ def report(self):
def xunit(self):
return self['XUnit']

@property
def json(self):
return self['Json']

@property
def log_level(self):
return self['LogLevel']
Expand Down Expand Up @@ -421,6 +428,7 @@ def get_rebot_settings(self):
for name in ['Name', 'Doc']:
settings._opts[name] = None
settings._opts['Output'] = None
settings._opts['Json'] = None
settings._opts['LogLevel'] = 'TRACE'
settings._opts['ProcessEmptySuite'] = self['RunEmptySuite']
settings._opts['ExpandKeywords'] = self['ExpandKeywords']
Expand Down Expand Up @@ -553,6 +561,11 @@ class RebotSettings(_BaseSettings):
'EndTime' : ('endtime', None),
'Merge' : ('merge', False)}

def __init__(self, options=None, **extra_options):
# When using rebot Json is an output argument, rather than a flag
self._output_opts.append('Json')
super(RebotSettings, self).__init__(options, **extra_options)

def _output_disabled(self):
return False

Expand Down
Empty file modified src/robot/htmldata/testdata/create_jsdata.py
100755 → 100644
Empty file.
Empty file modified src/robot/htmldata/testdata/create_libdoc_data.py
100755 → 100644
Empty file.
Empty file modified src/robot/htmldata/testdata/create_testdoc_data.py
100755 → 100644
Empty file.
Empty file modified src/robot/libdoc.py
100755 → 100644
Empty file.
Empty file modified src/robot/libdocpkg/consoleviewer.py
100755 → 100644
Empty file.
Loading