robotframework 6.1rc1__zip → 7.0a1__zip
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.
- {robotframework-6.1rc1/src/robotframework.egg-info → robotframework-7.0a1}/PKG-INFO +3 -6
- {robotframework-6.1rc1 → robotframework-7.0a1}/setup.py +2 -5
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/api/interfaces.py +36 -49
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/api/parsing.py +4 -2
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/conf/gatherfailed.py +2 -2
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/conf/languages.py +61 -25
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/conf/settings.py +8 -5
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/log.css +4 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/log.html +9 -1
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/model.js +2 -4
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/testdata.js +10 -3
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/template.py +3 -3
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/builder.py +0 -8
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/datatypes.py +9 -10
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/htmlutils.py +4 -7
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/jsonbuilder.py +14 -10
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/model.py +13 -25
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/robotbuilder.py +14 -4
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/xmlbuilder.py +8 -8
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/xmlwriter.py +12 -38
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/BuiltIn.py +215 -189
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/Collections.py +2 -9
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/DateTime.py +1 -1
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/OperatingSystem.py +4 -3
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/Process.py +26 -27
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/Remote.py +40 -36
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/String.py +4 -4
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/XML.py +7 -8
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/__init__.py +2 -2
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/dialogs_py.py +14 -2
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/__init__.py +4 -4
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/body.py +14 -6
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/configurer.py +19 -15
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/control.py +155 -85
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/filter.py +31 -25
- robotframework-7.0a1/src/robot/model/keyword.py +70 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/message.py +19 -10
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/modelobject.py +2 -8
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/modifier.py +1 -1
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/namepatterns.py +3 -25
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/stats.py +9 -15
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/tags.py +1 -1
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/testcase.py +12 -21
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/testsuite.py +43 -24
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/visitor.py +35 -8
- robotframework-7.0a1/src/robot/output/console/dotted.py +90 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/console/quiet.py +3 -2
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/console/verbose.py +60 -60
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/debugfile.py +36 -23
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/filelogger.py +16 -13
- robotframework-7.0a1/src/robot/output/listeners.py +586 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/logger.py +164 -77
- robotframework-7.0a1/src/robot/output/loggerapi.py +152 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/loggerhelper.py +23 -56
- robotframework-7.0a1/src/robot/output/output.py +158 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/stdoutlogsplitter.py +8 -5
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/xmllogger.py +163 -109
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/lexer/blocklexers.py +17 -13
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/lexer/context.py +12 -2
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/lexer/lexer.py +1 -1
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/lexer/settings.py +6 -3
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/lexer/statementlexers.py +39 -10
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/lexer/tokens.py +27 -29
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/model/blocks.py +19 -6
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/model/statements.py +184 -84
- robotframework-7.0a1/src/robot/parsing/model/visitor.py +102 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/reporting/expandkeywordmatcher.py +1 -1
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/reporting/jsbuildingcontext.py +8 -6
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/reporting/jsmodelbuilders.py +88 -61
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/reporting/stringcache.py +4 -3
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/reporting/xunitwriter.py +15 -21
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/__init__.py +3 -2
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/configurer.py +12 -9
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/flattenkeywordmatcher.py +8 -8
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/keywordremover.py +71 -54
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/merger.py +1 -1
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/model.py +400 -316
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/modeldeprecation.py +9 -3
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/resultbuilder.py +21 -23
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/xmlelementhandlers.py +76 -40
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/run.py +1 -1
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/__init__.py +1 -1
- robotframework-7.0a1/src/robot/running/arguments/argumentconverter.py +101 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/arguments/argumentmapper.py +16 -14
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/arguments/argumentparser.py +3 -1
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/arguments/argumentresolver.py +41 -33
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/arguments/argumentspec.py +24 -90
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/arguments/argumentvalidator.py +34 -27
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/arguments/customconverters.py +14 -11
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/arguments/embedded.py +23 -26
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/arguments/typeconverters.py +210 -220
- robotframework-7.0a1/src/robot/running/arguments/typeinfo.py +367 -0
- robotframework-7.0a1/src/robot/running/arguments/typevalidator.py +62 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/bodyrunner.py +83 -68
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/builder/builders.py +15 -25
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/builder/parsers.py +15 -10
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/builder/settings.py +9 -17
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/builder/transformers.py +166 -308
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/context.py +80 -25
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/handlers.py +11 -16
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/handlerstore.py +1 -1
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/librarykeywordrunner.py +9 -17
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/model.py +156 -36
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/namespace.py +18 -19
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/statusreporter.py +13 -12
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/suiterunner.py +18 -21
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/testlibraries.py +35 -39
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/usererrorhandler.py +8 -8
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/userkeyword.py +13 -8
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/userkeywordrunner.py +18 -21
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/testdoc.py +18 -13
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/__init__.py +50 -35
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/connectioncache.py +64 -59
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/encodingsniffer.py +9 -4
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/escaping.py +11 -9
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/markupwriters.py +20 -13
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/normalizing.py +9 -24
- robotframework-7.0a1/src/robot/utils/notset.py +33 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/platform.py +15 -5
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/robotpath.py +1 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/robottime.py +120 -88
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/robottypes.py +16 -31
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/setter.py +0 -5
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/text.py +7 -4
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/unic.py +2 -2
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/__init__.py +2 -2
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/assigner.py +17 -19
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/evaluation.py +20 -17
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/filesetter.py +80 -80
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/replacer.py +33 -36
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/scopes.py +3 -3
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/search.py +66 -41
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/store.py +14 -16
- robotframework-7.0a1/src/robot/variables/tablesetter.py +164 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/variables.py +1 -1
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/version.py +1 -1
- {robotframework-6.1rc1 → robotframework-7.0a1/src/robotframework.egg-info}/PKG-INFO +3 -6
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robotframework.egg-info/SOURCES.txt +3 -4
- {robotframework-6.1rc1 → robotframework-7.0a1}/tasks.py +6 -6
- robotframework-6.1rc1/src/robot/libraries/Reserved.py +0 -48
- robotframework-6.1rc1/src/robot/model/keyword.py +0 -173
- robotframework-6.1rc1/src/robot/output/console/dotted.py +0 -90
- robotframework-6.1rc1/src/robot/output/listenerarguments.py +0 -165
- robotframework-6.1rc1/src/robot/output/listenermethods.py +0 -113
- robotframework-6.1rc1/src/robot/output/listeners.py +0 -174
- robotframework-6.1rc1/src/robot/output/output.py +0 -95
- robotframework-6.1rc1/src/robot/parsing/model/visitor.py +0 -67
- robotframework-6.1rc1/src/robot/running/arguments/argumentconverter.py +0 -79
- robotframework-6.1rc1/src/robot/running/arguments/typevalidator.py +0 -56
- robotframework-6.1rc1/src/robot/running/modelcombiner.py +0 -32
- robotframework-6.1rc1/src/robot/variables/tablesetter.py +0 -156
- {robotframework-6.1rc1 → robotframework-7.0a1}/AUTHORS.rst +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/BUILD.rst +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/CONTRIBUTING.rst +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/COPYRIGHT.txt +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/INSTALL.rst +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/LICENSE.txt +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/MANIFEST.in +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/README.rst +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/setup.cfg +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/__main__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/api/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/api/deco.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/api/exceptions.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/api/logger.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/conf/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/errors.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/common/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/common/js_disabled.css +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/common/storage.js +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/htmlfilewriter.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/jsonwriter.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/lib/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/lib/jquery.highlight.min.js +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/lib/jquery.min.js +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/lib/jquery.tablesorter.min.js +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/lib/jquery.tmpl.min.js +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/lib/jsxcompressor.min.js +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/libdoc/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/libdoc/doc_formatting.css +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/libdoc/libdoc.css +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/libdoc/libdoc.html +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/libdoc/print.css +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/libdoc/pygments.css +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/common.css +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/doc_formatting.css +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/fileloading.js +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/log.js +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/print.css +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/report.css +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/report.html +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/util.js +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/view.js +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/testdoc/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/testdoc/testdoc.css +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/testdoc/testdoc.html +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdoc.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/consoleviewer.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/htmlwriter.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/jsonwriter.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/output.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/standardtypes.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/writer.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/Dialogs.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/Easter.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/Screenshot.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/Telnet.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/fixture.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/itemlist.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/metadata.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/statistics.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/suitestatistics.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/tagsetter.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/tagstatistics.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/totalstatistics.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/console/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/console/highlighting.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/librarylogger.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/pyloggingconf.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/lexer/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/lexer/tokenizer.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/model/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/parser/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/parser/blockparsers.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/parser/fileparser.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/parser/parser.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/suitestructure.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/pythonpathsetter.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/rebot.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/reporting/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/reporting/jsexecutionresult.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/reporting/jswriter.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/reporting/logreportwriters.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/reporting/outputwriter.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/reporting/resultwriter.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/executionerrors.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/executionresult.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/messagefilter.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/suiteteardownfailed.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/visitor.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/arguments/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/builder/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/dynamicmethods.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/importer.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/libraryscopes.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/outputcapture.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/randomizer.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/runkwregister.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/signalhandler.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/status.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/timeouts/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/timeouts/posix.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/timeouts/windows.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/application.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/argumentparser.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/asserts.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/charwidth.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/compress.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/dotdict.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/encoding.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/error.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/etreewrapper.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/filereader.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/frange.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/htmlformatters.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/importer.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/markuputils.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/match.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/misc.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/recommendations.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/restreader.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/robotenv.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/robotinspect.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/robotio.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/sortable.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/typehints.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/finders.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/notfound.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/resolvable.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robotframework.egg-info/dependency_links.txt +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robotframework.egg-info/entry_points.txt +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robotframework.egg-info/top_level.txt +0 -0
|
@@ -13,17 +13,19 @@
|
|
|
13
13
|
# See the License for the specific language governing permissions and
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
|
|
16
|
+
import re
|
|
17
|
+
|
|
16
18
|
from robot.output import LEVELS
|
|
19
|
+
from robot.result import Error, Keyword, Message, Return
|
|
17
20
|
|
|
18
21
|
from .jsbuildingcontext import JsBuildingContext
|
|
19
22
|
from .jsexecutionresult import JsExecutionResult
|
|
20
23
|
|
|
21
|
-
|
|
22
24
|
STATUSES = {'FAIL': 0, 'PASS': 1, 'SKIP': 2, 'NOT RUN': 3}
|
|
23
25
|
KEYWORD_TYPES = {'KEYWORD': 0, 'SETUP': 1, 'TEARDOWN': 2,
|
|
24
26
|
'FOR': 3, 'ITERATION': 4, 'IF': 5, 'ELSE IF': 6, 'ELSE': 7,
|
|
25
|
-
'RETURN': 8, '
|
|
26
|
-
'
|
|
27
|
+
'RETURN': 8, 'VAR': 9, 'TRY': 10, 'EXCEPT': 11, 'FINALLY': 12,
|
|
28
|
+
'WHILE': 13, 'CONTINUE': 14, 'BREAK': 15, 'ERROR': 16}
|
|
27
29
|
|
|
28
30
|
|
|
29
31
|
class JsModelBuilder:
|
|
@@ -47,49 +49,61 @@ class JsModelBuilder:
|
|
|
47
49
|
)
|
|
48
50
|
|
|
49
51
|
|
|
50
|
-
class
|
|
52
|
+
class Builder:
|
|
53
|
+
robot_note = re.compile('<span class="robot-note">(.*)</span>')
|
|
51
54
|
|
|
52
|
-
def __init__(self, context):
|
|
55
|
+
def __init__(self, context: JsBuildingContext):
|
|
53
56
|
self._context = context
|
|
54
57
|
self._string = self._context.string
|
|
55
58
|
self._html = self._context.html
|
|
56
59
|
self._timestamp = self._context.timestamp
|
|
57
60
|
|
|
58
|
-
def _get_status(self, item):
|
|
61
|
+
def _get_status(self, item, note_only=False):
|
|
59
62
|
model = (STATUSES[item.status],
|
|
60
|
-
self._timestamp(item.
|
|
61
|
-
item.
|
|
62
|
-
msg =
|
|
63
|
+
self._timestamp(item.start_time),
|
|
64
|
+
round(item.elapsed_time.total_seconds() * 1000))
|
|
65
|
+
msg = item.message
|
|
63
66
|
if not msg:
|
|
64
67
|
return model
|
|
65
|
-
|
|
66
|
-
|
|
68
|
+
if note_only:
|
|
69
|
+
if msg.startswith('*HTML*'):
|
|
70
|
+
match = self.robot_note.search(msg)
|
|
71
|
+
if match:
|
|
72
|
+
index = self._string(match.group(1))
|
|
73
|
+
return model + (index,)
|
|
74
|
+
return model
|
|
75
|
+
if msg.startswith('*HTML*'):
|
|
76
|
+
index = self._string(msg[6:].lstrip(), escape=False)
|
|
67
77
|
else:
|
|
68
|
-
|
|
69
|
-
return model + (
|
|
78
|
+
index = self._string(msg)
|
|
79
|
+
return model + (index,)
|
|
70
80
|
|
|
71
|
-
def
|
|
81
|
+
def _build_body(self, body, split=False):
|
|
72
82
|
splitting = self._context.start_splitting_if_needed(split)
|
|
73
|
-
# tuple([<listcomp
|
|
74
|
-
model = tuple([self.
|
|
83
|
+
# tuple([<listcomp>]) is faster than tuple(<genex>) with short lists.
|
|
84
|
+
model = tuple([self._build_body_item(item) for item in body])
|
|
75
85
|
return model if not splitting else self._context.end_splitting(model)
|
|
76
86
|
|
|
77
|
-
def
|
|
87
|
+
def _build_body_item(self, item):
|
|
78
88
|
raise NotImplementedError
|
|
79
89
|
|
|
80
90
|
|
|
81
|
-
class SuiteBuilder(
|
|
91
|
+
class SuiteBuilder(Builder):
|
|
82
92
|
|
|
83
93
|
def __init__(self, context):
|
|
84
|
-
|
|
94
|
+
super().__init__(context)
|
|
85
95
|
self._build_suite = self.build
|
|
86
96
|
self._build_test = TestBuilder(context).build
|
|
87
|
-
self.
|
|
97
|
+
self._build_body_item = BodyItemBuilder(context).build
|
|
88
98
|
|
|
89
99
|
def build(self, suite):
|
|
90
100
|
with self._context.prune_input(suite.tests, suite.suites):
|
|
91
101
|
stats = self._get_statistics(suite) # Must be done before pruning
|
|
92
|
-
|
|
102
|
+
fixture = []
|
|
103
|
+
if suite.has_setup:
|
|
104
|
+
fixture.append(suite.setup)
|
|
105
|
+
if suite.has_teardown:
|
|
106
|
+
fixture.append(suite.teardown)
|
|
93
107
|
return (self._string(suite.name, attr=True),
|
|
94
108
|
self._string(suite.source),
|
|
95
109
|
self._context.relative_source(suite.source),
|
|
@@ -98,7 +112,7 @@ class SuiteBuilder(_Builder):
|
|
|
98
112
|
self._get_status(suite),
|
|
99
113
|
tuple(self._build_suite(s) for s in suite.suites),
|
|
100
114
|
tuple(self._build_test(t) for t in suite.tests),
|
|
101
|
-
tuple(self.
|
|
115
|
+
tuple(self._build_body_item(kw, split=True) for kw in fixture),
|
|
102
116
|
stats)
|
|
103
117
|
|
|
104
118
|
def _yield_metadata(self, suite):
|
|
@@ -111,63 +125,76 @@ class SuiteBuilder(_Builder):
|
|
|
111
125
|
return (stats.total, stats.passed, stats.failed, stats.skipped)
|
|
112
126
|
|
|
113
127
|
|
|
114
|
-
class TestBuilder(
|
|
128
|
+
class TestBuilder(Builder):
|
|
115
129
|
|
|
116
130
|
def __init__(self, context):
|
|
117
|
-
|
|
118
|
-
self.
|
|
131
|
+
super().__init__(context)
|
|
132
|
+
self._build_body_item = BodyItemBuilder(context).build
|
|
119
133
|
|
|
120
134
|
def build(self, test):
|
|
121
|
-
|
|
135
|
+
body = self._get_body_items(test)
|
|
122
136
|
with self._context.prune_input(test.body):
|
|
123
137
|
return (self._string(test.name, attr=True),
|
|
124
138
|
self._string(test.timeout),
|
|
125
139
|
self._html(test.doc),
|
|
126
140
|
tuple(self._string(t) for t in test.tags),
|
|
127
141
|
self._get_status(test),
|
|
128
|
-
self.
|
|
142
|
+
self._build_body(body, split=True))
|
|
129
143
|
|
|
130
|
-
def
|
|
131
|
-
|
|
132
|
-
if test.
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
return kws
|
|
144
|
+
def _get_body_items(self, test):
|
|
145
|
+
body = test.body.flatten()
|
|
146
|
+
if test.has_setup:
|
|
147
|
+
body.insert(0, test.setup)
|
|
148
|
+
if test.has_teardown:
|
|
149
|
+
body.append(test.teardown)
|
|
150
|
+
return body
|
|
138
151
|
|
|
139
152
|
|
|
140
|
-
class
|
|
153
|
+
class BodyItemBuilder(Builder):
|
|
141
154
|
|
|
142
155
|
def __init__(self, context):
|
|
143
|
-
|
|
144
|
-
self.
|
|
156
|
+
super().__init__(context)
|
|
157
|
+
self._build_body_item = self.build
|
|
145
158
|
self._build_message = MessageBuilder(context).build
|
|
146
159
|
|
|
147
160
|
def build(self, item, split=False):
|
|
148
|
-
if item
|
|
161
|
+
if isinstance(item, Message):
|
|
149
162
|
return self._build_message(item)
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
163
|
+
with self._context.prune_input(item.body):
|
|
164
|
+
if isinstance (item, Keyword):
|
|
165
|
+
return self._build_keyword(item, split)
|
|
166
|
+
if isinstance(item, (Return, Error)):
|
|
167
|
+
return self._build(item, args=' '.join(item.values), split=split)
|
|
168
|
+
return self._build(item, item._log_name, split=split)
|
|
169
|
+
|
|
170
|
+
def _build_keyword(self, kw: Keyword, split):
|
|
153
171
|
self._context.check_expansion(kw)
|
|
154
|
-
|
|
155
|
-
if
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
172
|
+
body = kw.body.flatten()
|
|
173
|
+
if kw.has_setup:
|
|
174
|
+
body.insert(0, kw.setup)
|
|
175
|
+
if kw.has_teardown:
|
|
176
|
+
body.append(kw.teardown)
|
|
177
|
+
return self._build(kw, kw.name, kw.owner, kw.timeout, kw.doc,
|
|
178
|
+
' '.join(kw.args), ' '.join(kw.assign),
|
|
179
|
+
', '.join(kw.tags), body, split=split)
|
|
180
|
+
|
|
181
|
+
def _build(self, item, name='', owner='', timeout='', doc='', args='', assign='',
|
|
182
|
+
tags='', body=None, split=False):
|
|
183
|
+
if body is None:
|
|
184
|
+
body = item.body.flatten()
|
|
185
|
+
return (KEYWORD_TYPES[item.type],
|
|
186
|
+
self._string(name, attr=True),
|
|
187
|
+
self._string(owner, attr=True),
|
|
188
|
+
self._string(timeout),
|
|
189
|
+
self._html(doc),
|
|
190
|
+
self._string(args),
|
|
191
|
+
self._string(assign),
|
|
192
|
+
self._string(tags),
|
|
193
|
+
self._get_status(item, note_only=True),
|
|
194
|
+
self._build_body(body, split))
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
class MessageBuilder(Builder):
|
|
171
198
|
|
|
172
199
|
def build(self, msg):
|
|
173
200
|
if msg.level in ('WARN', 'ERROR'):
|
|
@@ -196,10 +223,10 @@ class StatisticsBuilder:
|
|
|
196
223
|
for stat in stats)
|
|
197
224
|
|
|
198
225
|
|
|
199
|
-
class ErrorsBuilder(
|
|
226
|
+
class ErrorsBuilder(Builder):
|
|
200
227
|
|
|
201
228
|
def __init__(self, context):
|
|
202
|
-
|
|
229
|
+
super().__init__(context)
|
|
203
230
|
self._build_message = ErrorMessageBuilder(context).build
|
|
204
231
|
|
|
205
232
|
def build(self, errors):
|
|
@@ -16,21 +16,22 @@
|
|
|
16
16
|
from robot.utils import compress_text, html_format
|
|
17
17
|
|
|
18
18
|
|
|
19
|
+
# TODO: can this be removed?
|
|
19
20
|
class StringIndex(int):
|
|
20
21
|
pass
|
|
21
22
|
|
|
22
23
|
|
|
23
24
|
class StringCache:
|
|
25
|
+
empty = StringIndex(0)
|
|
24
26
|
_compress_threshold = 80
|
|
25
27
|
_use_compressed_threshold = 1.1
|
|
26
|
-
_zero_index = StringIndex(0)
|
|
27
28
|
|
|
28
29
|
def __init__(self):
|
|
29
|
-
self._cache = {('', False): self.
|
|
30
|
+
self._cache = {('', False): self.empty}
|
|
30
31
|
|
|
31
32
|
def add(self, text, html=False):
|
|
32
33
|
if not text:
|
|
33
|
-
return self.
|
|
34
|
+
return self.empty
|
|
34
35
|
key = (text, html)
|
|
35
36
|
if key not in self._cache:
|
|
36
37
|
self._cache[key] = StringIndex(len(self._cache))
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
# See the License for the specific language governing permissions and
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
|
|
16
|
-
from robot.result import ResultVisitor
|
|
16
|
+
from robot.result import ResultVisitor, TestCase, TestSuite
|
|
17
17
|
from robot.utils import XmlWriter
|
|
18
18
|
|
|
19
19
|
|
|
@@ -38,32 +38,34 @@ class XUnitFileWriter(ResultVisitor):
|
|
|
38
38
|
def __init__(self, xml_writer):
|
|
39
39
|
self._writer = xml_writer
|
|
40
40
|
|
|
41
|
-
def start_suite(self, suite):
|
|
41
|
+
def start_suite(self, suite: TestSuite):
|
|
42
42
|
stats = suite.statistics # Accessing property only once.
|
|
43
43
|
attrs = {'name': suite.name,
|
|
44
|
-
'tests':
|
|
44
|
+
'tests': str(stats.total),
|
|
45
45
|
'errors': '0',
|
|
46
|
-
'failures':
|
|
47
|
-
'skipped':
|
|
48
|
-
'time':
|
|
49
|
-
'timestamp'
|
|
46
|
+
'failures': str(stats.failed),
|
|
47
|
+
'skipped': str(stats.skipped),
|
|
48
|
+
'time': format(suite.elapsed_time.total_seconds(), '.3f'),
|
|
49
|
+
'timestamp': suite.start_time.isoformat() if suite.start_time else None}
|
|
50
50
|
self._writer.start('testsuite', attrs)
|
|
51
51
|
|
|
52
|
-
def end_suite(self, suite):
|
|
52
|
+
def end_suite(self, suite: TestSuite):
|
|
53
53
|
if suite.metadata or suite.doc:
|
|
54
54
|
self._writer.start('properties')
|
|
55
55
|
if suite.doc:
|
|
56
|
-
self._writer.element('property', attrs={'name': 'Documentation',
|
|
56
|
+
self._writer.element('property', attrs={'name': 'Documentation',
|
|
57
|
+
'value': suite.doc})
|
|
57
58
|
for meta_name, meta_value in suite.metadata.items():
|
|
58
|
-
self._writer.element('property', attrs={'name': meta_name,
|
|
59
|
+
self._writer.element('property', attrs={'name': meta_name,
|
|
60
|
+
'value': meta_value})
|
|
59
61
|
self._writer.end('properties')
|
|
60
62
|
self._writer.end('testsuite')
|
|
61
63
|
|
|
62
|
-
def visit_test(self, test):
|
|
64
|
+
def visit_test(self, test: TestCase):
|
|
63
65
|
self._writer.start('testcase',
|
|
64
|
-
{'classname': test.parent.
|
|
66
|
+
{'classname': test.parent.full_name,
|
|
65
67
|
'name': test.name,
|
|
66
|
-
'time':
|
|
68
|
+
'time': format(test.elapsed_time.total_seconds(), '.3f')})
|
|
67
69
|
if test.failed:
|
|
68
70
|
self._writer.element('failure', attrs={'message': test.message,
|
|
69
71
|
'type': 'AssertionError'})
|
|
@@ -72,9 +74,6 @@ class XUnitFileWriter(ResultVisitor):
|
|
|
72
74
|
'type': 'SkipExecution'})
|
|
73
75
|
self._writer.end('testcase')
|
|
74
76
|
|
|
75
|
-
def _time_as_seconds(self, millis):
|
|
76
|
-
return format(millis / 1000, '.3f')
|
|
77
|
-
|
|
78
77
|
def visit_keyword(self, kw):
|
|
79
78
|
pass
|
|
80
79
|
|
|
@@ -86,8 +85,3 @@ class XUnitFileWriter(ResultVisitor):
|
|
|
86
85
|
|
|
87
86
|
def end_result(self, result):
|
|
88
87
|
self._writer.close()
|
|
89
|
-
|
|
90
|
-
def _starttime_to_isoformat(self, stime):
|
|
91
|
-
if not stime:
|
|
92
|
-
return None
|
|
93
|
-
return f'{stime[:4]}-{stime[4:6]}-{stime[6:8]}T{stime[9:22]}000'
|
|
@@ -38,7 +38,8 @@ __ http://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#
|
|
|
38
38
|
"""
|
|
39
39
|
|
|
40
40
|
from .executionresult import Result
|
|
41
|
-
from .model import (Break, Continue, Error, For, ForIteration, If, IfBranch, Keyword,
|
|
42
|
-
Return, TestCase, TestSuite, Try, TryBranch, While,
|
|
41
|
+
from .model import (Break, Continue, Error, For, ForIteration, If, IfBranch, Keyword,
|
|
42
|
+
Message, Return, TestCase, TestSuite, Try, TryBranch, Var, While,
|
|
43
|
+
WhileIteration)
|
|
43
44
|
from .resultbuilder import ExecutionResult, ExecutionResultBuilder
|
|
44
45
|
from .visitor import ResultVisitor
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
|
|
16
16
|
from robot import model
|
|
17
|
-
from robot.utils import is_string,
|
|
17
|
+
from robot.utils import is_string, parse_timestamp
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
class SuiteConfigurer(model.SuiteConfigurer):
|
|
@@ -32,11 +32,11 @@ class SuiteConfigurer(model.SuiteConfigurer):
|
|
|
32
32
|
|
|
33
33
|
def __init__(self, remove_keywords=None, log_level=None, start_time=None,
|
|
34
34
|
end_time=None, **base_config):
|
|
35
|
-
|
|
35
|
+
super().__init__(**base_config)
|
|
36
36
|
self.remove_keywords = self._get_remove_keywords(remove_keywords)
|
|
37
37
|
self.log_level = log_level
|
|
38
|
-
self.start_time = self.
|
|
39
|
-
self.end_time = self.
|
|
38
|
+
self.start_time = self._to_datetime(start_time)
|
|
39
|
+
self.end_time = self._to_datetime(end_time)
|
|
40
40
|
|
|
41
41
|
def _get_remove_keywords(self, value):
|
|
42
42
|
if value is None:
|
|
@@ -45,14 +45,13 @@ class SuiteConfigurer(model.SuiteConfigurer):
|
|
|
45
45
|
return [value]
|
|
46
46
|
return value
|
|
47
47
|
|
|
48
|
-
def
|
|
48
|
+
def _to_datetime(self, timestamp):
|
|
49
49
|
if not timestamp:
|
|
50
50
|
return None
|
|
51
51
|
try:
|
|
52
|
-
|
|
52
|
+
return parse_timestamp(timestamp)
|
|
53
53
|
except ValueError:
|
|
54
54
|
return None
|
|
55
|
-
return secs_to_timestamp(secs, millis=True)
|
|
56
55
|
|
|
57
56
|
def visit_suite(self, suite):
|
|
58
57
|
model.SuiteConfigurer.visit_suite(self, suite)
|
|
@@ -66,6 +65,10 @@ class SuiteConfigurer(model.SuiteConfigurer):
|
|
|
66
65
|
|
|
67
66
|
def _set_times(self, suite):
|
|
68
67
|
if self.start_time:
|
|
69
|
-
suite.
|
|
68
|
+
suite.end_time = suite.end_time # Preserve original value.
|
|
69
|
+
suite.elapsed_time = None # Force re-calculation.
|
|
70
|
+
suite.start_time = self.start_time
|
|
70
71
|
if self.end_time:
|
|
71
|
-
suite.
|
|
72
|
+
suite.start_time = suite.start_time
|
|
73
|
+
suite.elapsed_time = None
|
|
74
|
+
suite.end_time = self.end_time
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
|
|
16
16
|
from robot.errors import DataError
|
|
17
17
|
from robot.model import TagPatterns
|
|
18
|
-
from robot.utils import MultiMatcher
|
|
18
|
+
from robot.utils import MultiMatcher
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
def validate_flatten_keyword(options):
|
|
@@ -34,7 +34,7 @@ def validate_flatten_keyword(options):
|
|
|
34
34
|
class FlattenByTypeMatcher:
|
|
35
35
|
|
|
36
36
|
def __init__(self, flatten):
|
|
37
|
-
if
|
|
37
|
+
if isinstance(flatten, str):
|
|
38
38
|
flatten = [flatten]
|
|
39
39
|
flatten = [f.lower() for f in flatten]
|
|
40
40
|
self.types = set()
|
|
@@ -55,13 +55,13 @@ class FlattenByTypeMatcher:
|
|
|
55
55
|
class FlattenByNameMatcher:
|
|
56
56
|
|
|
57
57
|
def __init__(self, flatten):
|
|
58
|
-
if
|
|
58
|
+
if isinstance(flatten, str):
|
|
59
59
|
flatten = [flatten]
|
|
60
60
|
names = [n[5:] for n in flatten if n[:5].lower() == 'name:']
|
|
61
61
|
self._matcher = MultiMatcher(names)
|
|
62
62
|
|
|
63
|
-
def match(self,
|
|
64
|
-
name = '
|
|
63
|
+
def match(self, name, owner=None):
|
|
64
|
+
name = f'{owner}.{name}' if owner else name
|
|
65
65
|
return self._matcher.match(name)
|
|
66
66
|
|
|
67
67
|
def __bool__(self):
|
|
@@ -71,13 +71,13 @@ class FlattenByNameMatcher:
|
|
|
71
71
|
class FlattenByTagMatcher:
|
|
72
72
|
|
|
73
73
|
def __init__(self, flatten):
|
|
74
|
-
if
|
|
74
|
+
if isinstance(flatten, str):
|
|
75
75
|
flatten = [flatten]
|
|
76
76
|
patterns = [p[4:] for p in flatten if p[:4].lower() == 'tag:']
|
|
77
77
|
self._matcher = TagPatterns(patterns)
|
|
78
78
|
|
|
79
|
-
def match(self,
|
|
80
|
-
return self._matcher.match(
|
|
79
|
+
def match(self, tags):
|
|
80
|
+
return self._matcher.match(tags)
|
|
81
81
|
|
|
82
82
|
def __bool__(self):
|
|
83
83
|
return bool(self._matcher)
|
|
@@ -13,37 +13,40 @@
|
|
|
13
13
|
# See the License for the specific language governing permissions and
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
|
|
16
|
+
from abc import ABC
|
|
17
|
+
|
|
16
18
|
from robot.errors import DataError
|
|
17
19
|
from robot.model import SuiteVisitor, TagPattern
|
|
18
|
-
from robot.utils import Matcher, plural_or_not
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
def KeywordRemover(how):
|
|
22
|
-
upper = how.upper()
|
|
23
|
-
if upper.startswith('NAME:'):
|
|
24
|
-
return ByNameKeywordRemover(pattern=how[5:])
|
|
25
|
-
if upper.startswith('TAG:'):
|
|
26
|
-
return ByTagKeywordRemover(pattern=how[4:])
|
|
27
|
-
try:
|
|
28
|
-
return {'ALL': AllKeywordsRemover,
|
|
29
|
-
'PASSED': PassedKeywordRemover,
|
|
30
|
-
'FOR': ForLoopItemsRemover,
|
|
31
|
-
'WHILE': WhileLoopItemsRemover,
|
|
32
|
-
'WUKS': WaitUntilKeywordSucceedsRemover}[upper]()
|
|
33
|
-
except KeyError:
|
|
34
|
-
raise DataError(f"Expected 'ALL', 'PASSED', 'NAME:<pattern>', 'TAG:<pattern>', "
|
|
35
|
-
f"'FOR' or 'WUKS', got '{how}'.")
|
|
20
|
+
from robot.utils import html_escape, Matcher, plural_or_not
|
|
36
21
|
|
|
37
22
|
|
|
38
|
-
class
|
|
39
|
-
|
|
23
|
+
class KeywordRemover(SuiteVisitor, ABC):
|
|
24
|
+
message = 'Content removed using the --remove-keywords option.'
|
|
40
25
|
|
|
41
26
|
def __init__(self):
|
|
42
|
-
self.
|
|
27
|
+
self.removal_message = RemovalMessage(self.message)
|
|
28
|
+
|
|
29
|
+
@classmethod
|
|
30
|
+
def from_config(cls, conf):
|
|
31
|
+
upper = conf.upper()
|
|
32
|
+
if upper.startswith('NAME:'):
|
|
33
|
+
return ByNameKeywordRemover(pattern=conf[5:])
|
|
34
|
+
if upper.startswith('TAG:'):
|
|
35
|
+
return ByTagKeywordRemover(pattern=conf[4:])
|
|
36
|
+
try:
|
|
37
|
+
return {'ALL': AllKeywordsRemover,
|
|
38
|
+
'PASSED': PassedKeywordRemover,
|
|
39
|
+
'FOR': ForLoopItemsRemover,
|
|
40
|
+
'WHILE': WhileLoopItemsRemover,
|
|
41
|
+
'WUKS': WaitUntilKeywordSucceedsRemover}[upper]()
|
|
42
|
+
except KeyError:
|
|
43
|
+
raise DataError(f"Expected 'ALL', 'PASSED', 'NAME:<pattern>', "
|
|
44
|
+
f"'TAG:<pattern>', 'FOR' or 'WUKS', got '{conf}'.")
|
|
43
45
|
|
|
44
46
|
def _clear_content(self, item):
|
|
45
|
-
item.body
|
|
46
|
-
|
|
47
|
+
if item.body:
|
|
48
|
+
item.body.clear()
|
|
49
|
+
self.removal_message.set_to(item)
|
|
47
50
|
|
|
48
51
|
def _failed_or_warning_or_error(self, item):
|
|
49
52
|
return not item.passed or self._warning_or_error(item)
|
|
@@ -54,19 +57,25 @@ class _KeywordRemover(SuiteVisitor):
|
|
|
54
57
|
return finder.found
|
|
55
58
|
|
|
56
59
|
|
|
57
|
-
class AllKeywordsRemover(
|
|
60
|
+
class AllKeywordsRemover(KeywordRemover):
|
|
58
61
|
|
|
59
|
-
def
|
|
60
|
-
self._clear_content(
|
|
62
|
+
def start_body_item(self, item):
|
|
63
|
+
self._clear_content(item)
|
|
61
64
|
|
|
62
|
-
def
|
|
63
|
-
|
|
65
|
+
def start_if(self, item):
|
|
66
|
+
pass
|
|
64
67
|
|
|
65
|
-
def
|
|
66
|
-
self._clear_content(
|
|
68
|
+
def start_if_branch(self, item):
|
|
69
|
+
self._clear_content(item)
|
|
67
70
|
|
|
71
|
+
def start_try(self, item):
|
|
72
|
+
pass
|
|
73
|
+
|
|
74
|
+
def start_try_branch(self, item):
|
|
75
|
+
self._clear_content(item)
|
|
68
76
|
|
|
69
|
-
|
|
77
|
+
|
|
78
|
+
class PassedKeywordRemover(KeywordRemover):
|
|
70
79
|
|
|
71
80
|
def start_suite(self, suite):
|
|
72
81
|
if not suite.statistics.failed:
|
|
@@ -76,28 +85,28 @@ class PassedKeywordRemover(_KeywordRemover):
|
|
|
76
85
|
|
|
77
86
|
def visit_test(self, test):
|
|
78
87
|
if not self._failed_or_warning_or_error(test):
|
|
79
|
-
for
|
|
80
|
-
self._clear_content(
|
|
88
|
+
for item in test.body:
|
|
89
|
+
self._clear_content(item)
|
|
81
90
|
|
|
82
91
|
def visit_keyword(self, keyword):
|
|
83
92
|
pass
|
|
84
93
|
|
|
85
94
|
|
|
86
|
-
class ByNameKeywordRemover(
|
|
95
|
+
class ByNameKeywordRemover(KeywordRemover):
|
|
87
96
|
|
|
88
97
|
def __init__(self, pattern):
|
|
89
|
-
|
|
98
|
+
super().__init__()
|
|
90
99
|
self._matcher = Matcher(pattern, ignore='_')
|
|
91
100
|
|
|
92
101
|
def start_keyword(self, kw):
|
|
93
|
-
if self._matcher.match(kw.
|
|
102
|
+
if self._matcher.match(kw.full_name) and not self._warning_or_error(kw):
|
|
94
103
|
self._clear_content(kw)
|
|
95
104
|
|
|
96
105
|
|
|
97
|
-
class ByTagKeywordRemover(
|
|
106
|
+
class ByTagKeywordRemover(KeywordRemover):
|
|
98
107
|
|
|
99
108
|
def __init__(self, pattern):
|
|
100
|
-
|
|
109
|
+
super().__init__()
|
|
101
110
|
self._pattern = TagPattern.from_string(pattern)
|
|
102
111
|
|
|
103
112
|
def start_keyword(self, kw):
|
|
@@ -105,13 +114,13 @@ class ByTagKeywordRemover(_KeywordRemover):
|
|
|
105
114
|
self._clear_content(kw)
|
|
106
115
|
|
|
107
116
|
|
|
108
|
-
class
|
|
109
|
-
|
|
117
|
+
class LoopItemsRemover(KeywordRemover, ABC):
|
|
118
|
+
message = '{count} passing item{s} removed using the --remove-keywords option.'
|
|
110
119
|
|
|
111
120
|
def _remove_from_loop(self, loop):
|
|
112
121
|
before = len(loop.body)
|
|
113
122
|
self._remove_keywords(loop.body)
|
|
114
|
-
self.
|
|
123
|
+
self.removal_message.set_to_if_removed(loop, before)
|
|
115
124
|
|
|
116
125
|
def _remove_keywords(self, body):
|
|
117
126
|
iterations = body.filter(messages=False)
|
|
@@ -120,26 +129,26 @@ class _LoopItemsRemover(_KeywordRemover):
|
|
|
120
129
|
body.remove(it)
|
|
121
130
|
|
|
122
131
|
|
|
123
|
-
class ForLoopItemsRemover(
|
|
132
|
+
class ForLoopItemsRemover(LoopItemsRemover):
|
|
124
133
|
|
|
125
134
|
def start_for(self, for_):
|
|
126
135
|
self._remove_from_loop(for_)
|
|
127
136
|
|
|
128
137
|
|
|
129
|
-
class WhileLoopItemsRemover(
|
|
138
|
+
class WhileLoopItemsRemover(LoopItemsRemover):
|
|
130
139
|
|
|
131
140
|
def start_while(self, while_):
|
|
132
141
|
self._remove_from_loop(while_)
|
|
133
142
|
|
|
134
143
|
|
|
135
|
-
class WaitUntilKeywordSucceedsRemover(
|
|
136
|
-
|
|
144
|
+
class WaitUntilKeywordSucceedsRemover(KeywordRemover):
|
|
145
|
+
message = '{count} failing item{s} removed using the --remove-keywords option.'
|
|
137
146
|
|
|
138
147
|
def start_keyword(self, kw):
|
|
139
|
-
if kw.
|
|
148
|
+
if kw.owner == 'BuiltIn' and kw.name == 'Wait Until Keyword Succeeds':
|
|
140
149
|
before = len(kw.body)
|
|
141
150
|
self._remove_keywords(kw.body)
|
|
142
|
-
self.
|
|
151
|
+
self.removal_message.set_to_if_removed(kw, before)
|
|
143
152
|
|
|
144
153
|
def _remove_keywords(self, body):
|
|
145
154
|
keywords = body.filter(messages=False)
|
|
@@ -172,12 +181,20 @@ class WarningAndErrorFinder(SuiteVisitor):
|
|
|
172
181
|
class RemovalMessage:
|
|
173
182
|
|
|
174
183
|
def __init__(self, message):
|
|
175
|
-
self.
|
|
184
|
+
self.message = message
|
|
176
185
|
|
|
177
|
-
def
|
|
178
|
-
removed = len_before - len(
|
|
186
|
+
def set_to_if_removed(self, item, len_before):
|
|
187
|
+
removed = len_before - len(item.body)
|
|
179
188
|
if removed:
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
189
|
+
message = self.message.format(count=removed, s=plural_or_not(removed))
|
|
190
|
+
self.set_to(item, message)
|
|
191
|
+
|
|
192
|
+
def set_to(self, item, message=None):
|
|
193
|
+
if not item.message:
|
|
194
|
+
start = ''
|
|
195
|
+
elif item.message.startswith('*HTML*'):
|
|
196
|
+
start = item.message[6:].strip() + '<hr>'
|
|
197
|
+
else:
|
|
198
|
+
start = html_escape(item.message) + '<hr>'
|
|
199
|
+
message = message or self.message
|
|
200
|
+
item.message = f'*HTML* {start}<span class="robot-note">{message}</span>'
|