robotframework 6.1rc1__zip → 7.0__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 → robotframework-7.0}/INSTALL.rst +25 -25
- {robotframework-6.1rc1 → robotframework-7.0}/PKG-INFO +6 -8
- {robotframework-6.1rc1 → robotframework-7.0}/README.rst +3 -2
- {robotframework-6.1rc1 → robotframework-7.0}/setup.py +3 -6
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/api/__init__.py +4 -1
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/api/deco.py +60 -14
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/api/exceptions.py +6 -6
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/api/interfaces.py +403 -68
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/api/logger.py +27 -20
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/api/parsing.py +4 -2
- robotframework-7.0/src/robot/api/py.typed +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/conf/gatherfailed.py +2 -2
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/conf/languages.py +61 -25
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/conf/settings.py +21 -14
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/common/storage.js +11 -6
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/htmlfilewriter.py +1 -1
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/libdoc/libdoc.css +10 -2
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/libdoc/libdoc.html +10 -0
- robotframework-7.0/src/robot/htmldata/rebot/common.css +362 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/doc_formatting.css +13 -7
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/log.css +51 -10
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/log.html +14 -23
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/model.js +2 -4
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/report.css +83 -19
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/report.html +22 -7
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/testdata.js +10 -3
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/view.js +84 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/template.py +3 -3
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/builder.py +0 -8
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/datatypes.py +9 -10
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/htmlutils.py +4 -7
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/jsonbuilder.py +38 -20
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/model.py +21 -28
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/robotbuilder.py +50 -31
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/standardtypes.py +9 -1
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/xmlbuilder.py +35 -20
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/xmlwriter.py +18 -38
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/BuiltIn.py +255 -205
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/Collections.py +384 -240
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/DateTime.py +73 -60
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/OperatingSystem.py +6 -5
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/Process.py +26 -27
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/Remote.py +40 -36
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/String.py +66 -76
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/XML.py +66 -59
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/__init__.py +2 -2
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/dialogs_py.py +14 -2
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/__init__.py +5 -5
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/body.py +44 -13
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/configurer.py +19 -15
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/control.py +230 -88
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/filter.py +31 -25
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/itemlist.py +9 -8
- robotframework-7.0/src/robot/model/keyword.py +77 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/message.py +19 -10
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/modelobject.py +27 -15
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/modifier.py +1 -1
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/namepatterns.py +3 -25
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/stats.py +9 -15
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/tags.py +1 -1
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/testcase.py +15 -27
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/testsuite.py +44 -28
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/visitor.py +35 -8
- robotframework-7.0/src/robot/output/console/dotted.py +90 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/console/quiet.py +3 -2
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/console/verbose.py +61 -61
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/debugfile.py +39 -24
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/filelogger.py +18 -15
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/librarylogger.py +3 -2
- robotframework-7.0/src/robot/output/listeners.py +753 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/logger.py +216 -80
- robotframework-7.0/src/robot/output/loggerapi.py +215 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/loggerhelper.py +23 -56
- robotframework-7.0/src/robot/output/output.py +185 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/stdoutlogsplitter.py +8 -5
- robotframework-7.0/src/robot/output/xmllogger.py +459 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/blocklexers.py +17 -13
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/context.py +12 -2
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/lexer.py +1 -1
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/settings.py +6 -3
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/statementlexers.py +39 -10
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/tokens.py +27 -29
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/model/blocks.py +19 -6
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/model/statements.py +193 -94
- robotframework-7.0/src/robot/parsing/model/visitor.py +100 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/rebot.py +2 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/expandkeywordmatcher.py +1 -1
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/jsbuildingcontext.py +8 -6
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/jsmodelbuilders.py +88 -61
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/logreportwriters.py +16 -10
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/outputwriter.py +18 -2
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/resultwriter.py +4 -4
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/stringcache.py +3 -3
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/xunitwriter.py +15 -21
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/__init__.py +3 -2
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/configurer.py +12 -9
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/executionresult.py +56 -8
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/flattenkeywordmatcher.py +48 -9
- robotframework-7.0/src/robot/result/keywordremover.py +207 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/merger.py +1 -1
- robotframework-7.0/src/robot/result/model.py +1185 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/modeldeprecation.py +9 -3
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/resultbuilder.py +46 -36
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/xmlelementhandlers.py +83 -43
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/run.py +3 -1
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/__init__.py +14 -4
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/arguments/__init__.py +2 -1
- robotframework-7.0/src/robot/running/arguments/argumentconverter.py +100 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/arguments/argumentmapper.py +26 -24
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/arguments/argumentparser.py +85 -61
- robotframework-7.0/src/robot/running/arguments/argumentresolver.py +158 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/arguments/argumentspec.py +83 -116
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/arguments/argumentvalidator.py +33 -27
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/arguments/customconverters.py +15 -12
- robotframework-7.0/src/robot/running/arguments/embedded.py +145 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/arguments/typeconverters.py +268 -220
- robotframework-7.0/src/robot/running/arguments/typeinfo.py +317 -0
- robotframework-7.0/src/robot/running/arguments/typeinfoparser.py +219 -0
- robotframework-7.0/src/robot/running/arguments/typevalidator.py +60 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/bodyrunner.py +147 -129
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/builder/builders.py +17 -26
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/builder/parsers.py +17 -11
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/builder/settings.py +9 -17
- robotframework-7.0/src/robot/running/builder/transformers.py +535 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/context.py +113 -31
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/dynamicmethods.py +62 -34
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/importer.py +27 -49
- robotframework-7.0/src/robot/running/invalidkeyword.py +67 -0
- robotframework-7.0/src/robot/running/keywordfinder.py +91 -0
- robotframework-7.0/src/robot/running/keywordimplementation.py +164 -0
- robotframework-7.0/src/robot/running/librarykeyword.py +392 -0
- robotframework-7.0/src/robot/running/librarykeywordrunner.py +250 -0
- robotframework-7.0/src/robot/running/libraryscopes.py +115 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/model.py +198 -337
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/namespace.py +124 -137
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/outputcapture.py +20 -12
- robotframework-7.0/src/robot/running/resourcemodel.py +448 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/statusreporter.py +16 -13
- robotframework-7.0/src/robot/running/suiterunner.py +265 -0
- robotframework-7.0/src/robot/running/testlibraries.py +500 -0
- robotframework-7.0/src/robot/running/userkeywordrunner.py +260 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/testdoc.py +18 -13
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/__init__.py +53 -35
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/connectioncache.py +64 -59
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/dotdict.py +3 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/encodingsniffer.py +9 -4
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/escaping.py +19 -19
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/importer.py +2 -2
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/markupwriters.py +23 -15
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/misc.py +1 -2
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/normalizing.py +9 -24
- robotframework-7.0/src/robot/utils/notset.py +33 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/platform.py +15 -5
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/robotio.py +9 -9
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/robotpath.py +1 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/robottime.py +122 -90
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/robottypes.py +21 -31
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/setter.py +0 -5
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/text.py +7 -4
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/unic.py +2 -2
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/__init__.py +2 -2
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/assigner.py +17 -19
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/evaluation.py +20 -17
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/filesetter.py +80 -80
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/replacer.py +33 -36
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/scopes.py +17 -12
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/search.py +66 -41
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/store.py +14 -16
- robotframework-7.0/src/robot/variables/tablesetter.py +164 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/variables.py +1 -1
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/version.py +1 -1
- {robotframework-6.1rc1 → robotframework-7.0}/src/robotframework.egg-info/PKG-INFO +6 -8
- {robotframework-6.1rc1 → robotframework-7.0}/src/robotframework.egg-info/SOURCES.txt +10 -8
- {robotframework-6.1rc1 → robotframework-7.0}/tasks.py +6 -6
- robotframework-6.1rc1/src/robot/htmldata/rebot/common.css +0 -239
- 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/output/xmllogger.py +0 -354
- robotframework-6.1rc1/src/robot/parsing/model/visitor.py +0 -67
- robotframework-6.1rc1/src/robot/result/keywordremover.py +0 -183
- robotframework-6.1rc1/src/robot/result/model.py +0 -957
- robotframework-6.1rc1/src/robot/running/arguments/argumentconverter.py +0 -79
- robotframework-6.1rc1/src/robot/running/arguments/argumentresolver.py +0 -131
- robotframework-6.1rc1/src/robot/running/arguments/embedded.py +0 -146
- robotframework-6.1rc1/src/robot/running/arguments/typevalidator.py +0 -56
- robotframework-6.1rc1/src/robot/running/builder/transformers.py +0 -642
- robotframework-6.1rc1/src/robot/running/handlers.py +0 -321
- robotframework-6.1rc1/src/robot/running/handlerstore.py +0 -66
- robotframework-6.1rc1/src/robot/running/librarykeywordrunner.py +0 -238
- robotframework-6.1rc1/src/robot/running/libraryscopes.py +0 -97
- robotframework-6.1rc1/src/robot/running/modelcombiner.py +0 -32
- robotframework-6.1rc1/src/robot/running/suiterunner.py +0 -249
- robotframework-6.1rc1/src/robot/running/testlibraries.py +0 -420
- robotframework-6.1rc1/src/robot/running/usererrorhandler.py +0 -75
- robotframework-6.1rc1/src/robot/running/userkeyword.py +0 -111
- robotframework-6.1rc1/src/robot/running/userkeywordrunner.py +0 -274
- robotframework-6.1rc1/src/robot/variables/tablesetter.py +0 -156
- {robotframework-6.1rc1 → robotframework-7.0}/AUTHORS.rst +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/BUILD.rst +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/CONTRIBUTING.rst +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/COPYRIGHT.txt +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/LICENSE.txt +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/MANIFEST.in +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/setup.cfg +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/__main__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/conf/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/errors.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/common/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/common/js_disabled.css +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/jsonwriter.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/lib/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.highlight.min.js +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.min.js +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.tablesorter.min.js +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.tmpl.min.js +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/lib/jsxcompressor.min.js +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/libdoc/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/libdoc/doc_formatting.css +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/libdoc/print.css +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/libdoc/pygments.css +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/fileloading.js +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/log.js +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/print.css +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/util.js +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/testdoc/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/testdoc/testdoc.css +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/testdoc/testdoc.html +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdoc.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/consoleviewer.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/htmlwriter.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/jsonwriter.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/output.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/writer.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/Dialogs.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/Easter.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/Screenshot.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/Telnet.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/fixture.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/metadata.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/statistics.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/suitestatistics.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/tagsetter.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/tagstatistics.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/totalstatistics.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/console/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/console/highlighting.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/pyloggingconf.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/tokenizer.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/model/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/parser/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/parser/blockparsers.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/parser/fileparser.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/parser/parser.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/suitestructure.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/pythonpathsetter.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/jsexecutionresult.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/jswriter.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/executionerrors.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/messagefilter.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/suiteteardownfailed.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/visitor.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/builder/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/randomizer.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/runkwregister.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/signalhandler.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/status.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/timeouts/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/timeouts/posix.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/timeouts/windows.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/application.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/argumentparser.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/asserts.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/charwidth.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/compress.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/encoding.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/error.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/etreewrapper.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/filereader.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/frange.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/htmlformatters.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/markuputils.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/match.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/recommendations.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/restreader.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/robotenv.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/robotinspect.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/sortable.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/typehints.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/finders.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/notfound.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/resolvable.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robotframework.egg-info/dependency_links.txt +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robotframework.egg-info/entry_points.txt +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robotframework.egg-info/top_level.txt +0 -0
|
@@ -13,28 +13,34 @@
|
|
|
13
13
|
# See the License for the specific language governing permissions and
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
|
|
16
|
+
import warnings
|
|
17
|
+
|
|
16
18
|
from robot.model import Tags
|
|
17
19
|
|
|
18
20
|
|
|
19
21
|
def deprecated(method):
|
|
20
22
|
def wrapper(self, *args, **kws):
|
|
21
23
|
"""Deprecated."""
|
|
24
|
+
warnings.warn(f"'robot.result.{type(self).__name__}.{method.__name__}' is "
|
|
25
|
+
f"deprecated and will be removed in Robot Framework 8.0.",
|
|
26
|
+
stacklevel=1)
|
|
22
27
|
return method(self, *args, **kws)
|
|
23
28
|
return wrapper
|
|
24
29
|
|
|
25
30
|
|
|
26
31
|
class DeprecatedAttributesMixin:
|
|
27
32
|
__slots__ = []
|
|
33
|
+
_log_name = ''
|
|
28
34
|
|
|
29
35
|
@property
|
|
30
36
|
@deprecated
|
|
31
37
|
def name(self):
|
|
32
|
-
return
|
|
38
|
+
return self._log_name
|
|
33
39
|
|
|
34
40
|
@property
|
|
35
41
|
@deprecated
|
|
36
42
|
def kwname(self):
|
|
37
|
-
return self.
|
|
43
|
+
return self._log_name
|
|
38
44
|
|
|
39
45
|
@property
|
|
40
46
|
@deprecated
|
|
@@ -63,5 +69,5 @@ class DeprecatedAttributesMixin:
|
|
|
63
69
|
|
|
64
70
|
@property
|
|
65
71
|
@deprecated
|
|
66
|
-
def
|
|
72
|
+
def doc(self):
|
|
67
73
|
return ''
|
|
@@ -13,35 +13,43 @@
|
|
|
13
13
|
# See the License for the specific language governing permissions and
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
|
|
16
|
+
from pathlib import Path
|
|
17
|
+
|
|
16
18
|
from robot.errors import DataError
|
|
17
19
|
from robot.model import SuiteVisitor
|
|
18
20
|
from robot.utils import ET, ETSource, get_error_message
|
|
19
21
|
|
|
20
|
-
from .executionresult import
|
|
21
|
-
from .flattenkeywordmatcher import (
|
|
22
|
-
|
|
22
|
+
from .executionresult import CombinedResult, is_json_source, Result
|
|
23
|
+
from .flattenkeywordmatcher import (create_flatten_message, FlattenByNameMatcher,
|
|
24
|
+
FlattenByTypeMatcher, FlattenByTags)
|
|
23
25
|
from .merger import Merger
|
|
26
|
+
from .model import TestSuite
|
|
24
27
|
from .xmlelementhandlers import XmlElementHandler
|
|
25
28
|
|
|
26
29
|
|
|
27
30
|
def ExecutionResult(*sources, **options):
|
|
28
31
|
"""Factory method to constructs :class:`~.executionresult.Result` objects.
|
|
29
32
|
|
|
30
|
-
:param sources: XML source(s) containing execution results.
|
|
31
|
-
Can be specified as paths
|
|
32
|
-
|
|
33
|
+
:param sources: XML or JSON source(s) containing execution results.
|
|
34
|
+
Can be specified as paths (``pathlib.Path`` or ``str``), opened file
|
|
35
|
+
objects, or strings/bytes containing XML/JSON directly.
|
|
33
36
|
:param options: Configuration options.
|
|
34
37
|
Using ``merge=True`` causes multiple results to be combined so that
|
|
35
38
|
tests in the latter results replace the ones in the original.
|
|
36
39
|
Setting ``rpa`` either to ``True`` (RPA mode) or ``False`` (test
|
|
37
|
-
automation) sets execution mode explicitly. By default it is got
|
|
40
|
+
automation) sets execution mode explicitly. By default, it is got
|
|
38
41
|
from processed output files and conflicting modes cause an error.
|
|
39
42
|
Other options are passed directly to the
|
|
40
43
|
:class:`ExecutionResultBuilder` object used internally.
|
|
41
44
|
:returns: :class:`~.executionresult.Result` instance.
|
|
42
45
|
|
|
43
|
-
|
|
44
|
-
|
|
46
|
+
A source is considered to be JSON in these cases:
|
|
47
|
+
- It is a path with a ``.json`` suffix.
|
|
48
|
+
- It is an open file that has a ``name`` attribute with a ``.json`` suffix.
|
|
49
|
+
- It is string or bytes starting with ``{`` and ending with ``}``.
|
|
50
|
+
|
|
51
|
+
This method should be imported by external code via the :mod:`robot.api`
|
|
52
|
+
package. See the :mod:`robot.result` package for a usage example.
|
|
45
53
|
"""
|
|
46
54
|
if not sources:
|
|
47
55
|
raise DataError('One or more data source needed.')
|
|
@@ -66,13 +74,27 @@ def _combine_results(sources, options):
|
|
|
66
74
|
|
|
67
75
|
|
|
68
76
|
def _single_result(source, options):
|
|
77
|
+
if is_json_source(source):
|
|
78
|
+
return _json_result(source, options)
|
|
79
|
+
return _xml_result(source, options)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def _json_result(source, options):
|
|
83
|
+
try:
|
|
84
|
+
suite = TestSuite.from_json(source)
|
|
85
|
+
except Exception:
|
|
86
|
+
raise DataError(f"Reading JSON source '{source}' failed: {get_error_message()}")
|
|
87
|
+
return Result(source, suite, rpa=options.pop('rpa', None))
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def _xml_result(source, options):
|
|
69
91
|
ets = ETSource(source)
|
|
70
92
|
result = Result(source, rpa=options.pop('rpa', None))
|
|
71
93
|
try:
|
|
72
94
|
return ExecutionResultBuilder(ets, **options).build(result)
|
|
73
95
|
except IOError as err:
|
|
74
96
|
error = err.strerror
|
|
75
|
-
except:
|
|
97
|
+
except Exception:
|
|
76
98
|
error = get_error_message()
|
|
77
99
|
raise DataError(f"Reading XML source '{ets}' failed: {error}")
|
|
78
100
|
|
|
@@ -106,6 +128,10 @@ class ExecutionResultBuilder:
|
|
|
106
128
|
with self._source as source:
|
|
107
129
|
self._parse(source, handler.start, handler.end)
|
|
108
130
|
result.handle_suite_teardown_failures()
|
|
131
|
+
if self._flattened_keywords:
|
|
132
|
+
# Tags are nowadays written after keyword content, so we cannot
|
|
133
|
+
# flatten based on them when parsing output.xml.
|
|
134
|
+
result.suite.visit(FlattenByTags(self._flattened_keywords))
|
|
109
135
|
if not self._include_keywords:
|
|
110
136
|
result.suite.visit(RemoveKeywords())
|
|
111
137
|
return result
|
|
@@ -143,49 +169,33 @@ class ExecutionResultBuilder:
|
|
|
143
169
|
# Performance optimized. Do not change without profiling!
|
|
144
170
|
name_match, by_name = self._get_matcher(FlattenByNameMatcher, flattened)
|
|
145
171
|
type_match, by_type = self._get_matcher(FlattenByTypeMatcher, flattened)
|
|
146
|
-
|
|
147
|
-
started = -1 # if 0 or more, we are flattening
|
|
172
|
+
started = -1 # if 0 or more, we are flattening
|
|
148
173
|
tags = []
|
|
149
174
|
containers = {'kw', 'for', 'while', 'iter', 'if', 'try'}
|
|
150
|
-
|
|
151
|
-
seen_doc = False
|
|
175
|
+
inside = 0 # to make sure we don't read tags from a test
|
|
152
176
|
for event, elem in context:
|
|
153
177
|
tag = elem.tag
|
|
154
|
-
|
|
155
|
-
end = not start
|
|
156
|
-
if start:
|
|
178
|
+
if event == 'start':
|
|
157
179
|
if tag in containers:
|
|
158
|
-
|
|
180
|
+
inside += 1
|
|
159
181
|
if started >= 0:
|
|
160
182
|
started += 1
|
|
161
|
-
elif by_name and name_match(elem.get('name', ''), elem.get('
|
|
183
|
+
elif by_name and name_match(elem.get('name', ''), elem.get('owner')
|
|
184
|
+
or elem.get('library')):
|
|
162
185
|
started = 0
|
|
163
|
-
seen_doc = False
|
|
164
186
|
elif by_type and type_match(tag):
|
|
165
187
|
started = 0
|
|
166
|
-
seen_doc = False
|
|
167
188
|
tags = []
|
|
168
189
|
else:
|
|
169
190
|
if tag in containers:
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
doc.text = '_*Content flattened.*_'
|
|
174
|
-
yield 'start', doc
|
|
175
|
-
yield 'end', doc
|
|
176
|
-
elif by_tags and inside_kw and started < 0 and tag == 'tag':
|
|
177
|
-
tags.append(elem.text or '')
|
|
178
|
-
if tags_match(tags):
|
|
179
|
-
started = 0
|
|
180
|
-
seen_doc = False
|
|
181
|
-
elif started == 0 and tag == 'doc':
|
|
182
|
-
seen_doc = True
|
|
183
|
-
elem.text = f"{elem.text or ''}\n\n_*Content flattened.*_".strip()
|
|
191
|
+
inside -= 1
|
|
192
|
+
elif started == 0 and tag == 'status':
|
|
193
|
+
elem.text = create_flatten_message(elem.text)
|
|
184
194
|
if started <= 0 or tag == 'msg':
|
|
185
195
|
yield event, elem
|
|
186
196
|
else:
|
|
187
197
|
elem.clear()
|
|
188
|
-
if started >= 0 and end and tag in containers:
|
|
198
|
+
if started >= 0 and event == 'end' and tag in containers:
|
|
189
199
|
started -= 1
|
|
190
200
|
|
|
191
201
|
def _get_matcher(self, matcher_class, flattened):
|
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
# See the License for the specific language governing permissions and
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
|
|
16
|
+
from datetime import datetime
|
|
17
|
+
|
|
16
18
|
from robot.errors import DataError
|
|
17
19
|
|
|
18
20
|
|
|
@@ -47,8 +49,6 @@ class ElementHandler:
|
|
|
47
49
|
|
|
48
50
|
def get_child_handler(self, tag):
|
|
49
51
|
if tag not in self.children:
|
|
50
|
-
if not self.tag:
|
|
51
|
-
raise DataError(f"Incompatible root element '{tag}'.")
|
|
52
52
|
raise DataError(f"Incompatible child element '{tag}' for '{self.tag}'.")
|
|
53
53
|
return self.element_handlers[tag]
|
|
54
54
|
|
|
@@ -58,13 +58,23 @@ class ElementHandler:
|
|
|
58
58
|
def end(self, elem, result):
|
|
59
59
|
pass
|
|
60
60
|
|
|
61
|
-
def
|
|
62
|
-
|
|
63
|
-
|
|
61
|
+
def _legacy_timestamp(self, elem, attr_name):
|
|
62
|
+
ts = elem.get(attr_name)
|
|
63
|
+
if ts == 'N/A' or not ts:
|
|
64
|
+
return None
|
|
65
|
+
ts = ts.ljust(24, '0')
|
|
66
|
+
return datetime(int(ts[:4]), int(ts[4:6]), int(ts[6:8]),
|
|
67
|
+
int(ts[9:11]), int(ts[12:14]), int(ts[15:17]), int(ts[18:24]))
|
|
64
68
|
|
|
65
69
|
|
|
66
70
|
class RootHandler(ElementHandler):
|
|
67
|
-
children = frozenset(('robot',))
|
|
71
|
+
children = frozenset(('robot', 'suite'))
|
|
72
|
+
|
|
73
|
+
def get_child_handler(self, tag):
|
|
74
|
+
try:
|
|
75
|
+
return super().get_child_handler(tag)
|
|
76
|
+
except DataError:
|
|
77
|
+
raise DataError(f"Incompatible root element '{tag}'.")
|
|
68
78
|
|
|
69
79
|
|
|
70
80
|
@ElementHandler.register
|
|
@@ -106,7 +116,8 @@ class TestHandler(ElementHandler):
|
|
|
106
116
|
tag = 'test'
|
|
107
117
|
# 'tags' is for RF < 4 compatibility.
|
|
108
118
|
children = frozenset(('doc', 'tags', 'tag', 'timeout', 'status', 'kw', 'if', 'for',
|
|
109
|
-
'try', 'while', '
|
|
119
|
+
'try', 'while', 'variable', 'return', 'break', 'continue',
|
|
120
|
+
'error', 'msg'))
|
|
110
121
|
|
|
111
122
|
def start(self, elem, result):
|
|
112
123
|
lineno = elem.get('line')
|
|
@@ -121,7 +132,7 @@ class KeywordHandler(ElementHandler):
|
|
|
121
132
|
# 'arguments', 'assign' and 'tags' are for RF < 4 compatibility.
|
|
122
133
|
children = frozenset(('doc', 'arguments', 'arg', 'assign', 'var', 'tags', 'tag',
|
|
123
134
|
'timeout', 'status', 'msg', 'kw', 'if', 'for', 'try',
|
|
124
|
-
'while', 'return', 'break', 'continue', 'error'))
|
|
135
|
+
'while', 'variable', 'return', 'break', 'continue', 'error'))
|
|
125
136
|
|
|
126
137
|
def start(self, elem, result):
|
|
127
138
|
elem_type = elem.get('type')
|
|
@@ -136,9 +147,15 @@ class KeywordHandler(ElementHandler):
|
|
|
136
147
|
body = result.body
|
|
137
148
|
except AttributeError:
|
|
138
149
|
body = self._get_body_for_suite_level_keyword(result)
|
|
139
|
-
return body.create_keyword(
|
|
140
|
-
|
|
141
|
-
|
|
150
|
+
return body.create_keyword(**self._get_keyword_attrs(elem))
|
|
151
|
+
|
|
152
|
+
def _get_keyword_attrs(self, elem):
|
|
153
|
+
# 'library' and 'sourcename' are RF < 7 compatibility.
|
|
154
|
+
return {
|
|
155
|
+
'name': elem.get('name', ''),
|
|
156
|
+
'owner': elem.get('owner') or elem.get('library'),
|
|
157
|
+
'source_name': elem.get('source_name') or elem.get('sourcename')
|
|
158
|
+
}
|
|
142
159
|
|
|
143
160
|
def _get_body_for_suite_level_keyword(self, result):
|
|
144
161
|
# Someone, most likely a listener, has created a `<kw>` element on suite level.
|
|
@@ -149,24 +166,22 @@ class KeywordHandler(ElementHandler):
|
|
|
149
166
|
kw_type = 'teardown' if result.tests or result.suites else 'setup'
|
|
150
167
|
keyword = getattr(result, kw_type)
|
|
151
168
|
if not keyword:
|
|
152
|
-
keyword.config(
|
|
169
|
+
keyword.config(name=f'Implicit {kw_type}', status=keyword.PASS)
|
|
153
170
|
return keyword.body
|
|
154
171
|
|
|
155
172
|
def _create_setup(self, elem, result):
|
|
156
|
-
return result.setup.config(
|
|
157
|
-
libname=elem.get('library'))
|
|
173
|
+
return result.setup.config(**self._get_keyword_attrs(elem))
|
|
158
174
|
|
|
159
175
|
def _create_teardown(self, elem, result):
|
|
160
|
-
return result.teardown.config(
|
|
161
|
-
libname=elem.get('library'))
|
|
176
|
+
return result.teardown.config(**self._get_keyword_attrs(elem))
|
|
162
177
|
|
|
163
178
|
# RF < 4 compatibility.
|
|
164
179
|
|
|
165
180
|
def _create_for(self, elem, result):
|
|
166
|
-
return result.body.create_keyword(
|
|
181
|
+
return result.body.create_keyword(name=elem.get('name'), type='FOR')
|
|
167
182
|
|
|
168
183
|
def _create_foritem(self, elem, result):
|
|
169
|
-
return result.body.create_keyword(
|
|
184
|
+
return result.body.create_keyword(name=elem.get('name'), type='ITERATION')
|
|
170
185
|
|
|
171
186
|
_create_iteration = _create_foritem
|
|
172
187
|
|
|
@@ -201,7 +216,7 @@ class WhileHandler(ElementHandler):
|
|
|
201
216
|
class IterationHandler(ElementHandler):
|
|
202
217
|
tag = 'iter'
|
|
203
218
|
children = frozenset(('var', 'doc', 'status', 'kw', 'if', 'for', 'msg', 'try',
|
|
204
|
-
'while', 'return', 'break', 'continue', 'error'))
|
|
219
|
+
'while', 'variable', 'return', 'break', 'continue', 'error'))
|
|
205
220
|
|
|
206
221
|
def start(self, elem, result):
|
|
207
222
|
return result.body.create_iteration()
|
|
@@ -220,9 +235,11 @@ class IfHandler(ElementHandler):
|
|
|
220
235
|
class BranchHandler(ElementHandler):
|
|
221
236
|
tag = 'branch'
|
|
222
237
|
children = frozenset(('status', 'kw', 'if', 'for', 'try', 'while', 'msg', 'doc',
|
|
223
|
-
'return', 'pattern', 'break', 'continue', 'error'))
|
|
238
|
+
'variable', 'return', 'pattern', 'break', 'continue', 'error'))
|
|
224
239
|
|
|
225
240
|
def start(self, elem, result):
|
|
241
|
+
if 'variable' in elem.attrib: # RF < 7.0 compatibility.
|
|
242
|
+
elem.attrib['assign'] = elem.attrib.pop('variable')
|
|
226
243
|
return result.body.create_branch(**elem.attrib)
|
|
227
244
|
|
|
228
245
|
|
|
@@ -244,10 +261,21 @@ class PatternHandler(ElementHandler):
|
|
|
244
261
|
result.patterns += (elem.text or '',)
|
|
245
262
|
|
|
246
263
|
|
|
264
|
+
@ElementHandler.register
|
|
265
|
+
class VariableHandler(ElementHandler):
|
|
266
|
+
tag = 'variable'
|
|
267
|
+
children = frozenset(('var', 'status', 'msg', 'kw'))
|
|
268
|
+
|
|
269
|
+
def start(self, elem, result):
|
|
270
|
+
return result.body.create_var(name=elem.get('name', ''),
|
|
271
|
+
scope=elem.get('scope'),
|
|
272
|
+
separator=elem.get('separator'))
|
|
273
|
+
|
|
274
|
+
|
|
247
275
|
@ElementHandler.register
|
|
248
276
|
class ReturnHandler(ElementHandler):
|
|
249
277
|
tag = 'return'
|
|
250
|
-
children = frozenset(('
|
|
278
|
+
children = frozenset(('value', 'status', 'msg', 'kw'))
|
|
251
279
|
|
|
252
280
|
def start(self, elem, result):
|
|
253
281
|
return result.body.create_return()
|
|
@@ -285,11 +313,23 @@ class MessageHandler(ElementHandler):
|
|
|
285
313
|
tag = 'msg'
|
|
286
314
|
|
|
287
315
|
def end(self, elem, result):
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
316
|
+
self._create_message(elem, result.body.create_message)
|
|
317
|
+
|
|
318
|
+
def _create_message(self, elem, creator):
|
|
319
|
+
if 'time' in elem.attrib: # RF >= 7
|
|
320
|
+
timestamp = elem.attrib['time']
|
|
321
|
+
else: # RF < 7
|
|
322
|
+
timestamp = self._legacy_timestamp(elem, 'timestamp')
|
|
323
|
+
creator(elem.text or '',
|
|
324
|
+
elem.get('level', 'INFO'),
|
|
325
|
+
elem.get('html') in ('true', 'yes'), # 'yes' is RF < 4 compatibility
|
|
326
|
+
timestamp)
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
class ErrorMessageHandler(MessageHandler):
|
|
330
|
+
|
|
331
|
+
def end(self, elem, result):
|
|
332
|
+
self._create_message(elem, result.messages.create)
|
|
293
333
|
|
|
294
334
|
|
|
295
335
|
@ElementHandler.register
|
|
@@ -302,8 +342,12 @@ class StatusHandler(ElementHandler):
|
|
|
302
342
|
def end(self, elem, result):
|
|
303
343
|
if self.set_status:
|
|
304
344
|
result.status = elem.get('status', 'FAIL')
|
|
305
|
-
|
|
306
|
-
|
|
345
|
+
if 'start' in elem.attrib: # RF >= 7
|
|
346
|
+
result.start_time = elem.attrib['start']
|
|
347
|
+
result.elapsed_time = float(elem.attrib['elapsed'])
|
|
348
|
+
else: # RF < 7
|
|
349
|
+
result.start_time = self._legacy_timestamp(elem, 'starttime')
|
|
350
|
+
result.end_time = self._legacy_timestamp(elem, 'endtime')
|
|
307
351
|
if elem.text:
|
|
308
352
|
result.message = elem.text
|
|
309
353
|
|
|
@@ -313,7 +357,13 @@ class DocHandler(ElementHandler):
|
|
|
313
357
|
tag = 'doc'
|
|
314
358
|
|
|
315
359
|
def end(self, elem, result):
|
|
316
|
-
|
|
360
|
+
try:
|
|
361
|
+
result.doc = elem.text or ''
|
|
362
|
+
except AttributeError:
|
|
363
|
+
# With RF < 7 control structures can have `<doc>` containing information
|
|
364
|
+
# about flattening or removing date. Nowadays, they don't have `doc`
|
|
365
|
+
# attribute at all and `message` is used for this information.
|
|
366
|
+
result.message = elem.text or ''
|
|
317
367
|
|
|
318
368
|
|
|
319
369
|
@ElementHandler.register
|
|
@@ -372,12 +422,12 @@ class VarHandler(ElementHandler):
|
|
|
372
422
|
|
|
373
423
|
def end(self, elem, result):
|
|
374
424
|
value = elem.text or ''
|
|
375
|
-
if result.type
|
|
425
|
+
if result.type in (result.KEYWORD, result.FOR):
|
|
376
426
|
result.assign += (value,)
|
|
377
|
-
elif result.type == result.FOR:
|
|
378
|
-
result.variables += (value,)
|
|
379
427
|
elif result.type == result.ITERATION:
|
|
380
|
-
result.
|
|
428
|
+
result.assign[elem.get('name')] = value
|
|
429
|
+
elif result.type == result.VAR:
|
|
430
|
+
result.value += (value,)
|
|
381
431
|
else:
|
|
382
432
|
raise DataError(f"Invalid element '{elem}' for result '{result!r}'.")
|
|
383
433
|
|
|
@@ -415,16 +465,6 @@ class ErrorsHandler(ElementHandler):
|
|
|
415
465
|
return ErrorMessageHandler()
|
|
416
466
|
|
|
417
467
|
|
|
418
|
-
class ErrorMessageHandler(ElementHandler):
|
|
419
|
-
|
|
420
|
-
def end(self, elem, result):
|
|
421
|
-
html_true = ('true', 'yes') # 'yes' is compatibility for RF < 4.
|
|
422
|
-
result.messages.create(elem.text or '',
|
|
423
|
-
elem.get('level', 'INFO'),
|
|
424
|
-
elem.get('html') in html_true,
|
|
425
|
-
self._timestamp(elem, 'timestamp'))
|
|
426
|
-
|
|
427
|
-
|
|
428
468
|
@ElementHandler.register
|
|
429
469
|
class StatisticsHandler(ElementHandler):
|
|
430
470
|
tag = 'statistics'
|
|
@@ -176,6 +176,8 @@ Options
|
|
|
176
176
|
can also be further processed with Rebot tool. Can be
|
|
177
177
|
disabled by giving a special value `NONE`.
|
|
178
178
|
Default: output.xml
|
|
179
|
+
--legacyoutput Create XML output file in format compatible with
|
|
180
|
+
Robot Framework 6.x and earlier.
|
|
179
181
|
-l --log file HTML log file. Can be disabled by giving a special
|
|
180
182
|
value `NONE`. Default: log.html
|
|
181
183
|
Examples: `--log mylog.html`, `-l NONE`
|
|
@@ -444,11 +446,11 @@ class RobotFramework(Application):
|
|
|
444
446
|
lang=settings.languages,
|
|
445
447
|
allow_empty_suite=settings.run_empty_suite)
|
|
446
448
|
suite = builder.build(*datasources)
|
|
447
|
-
settings.rpa = suite.rpa
|
|
448
449
|
if settings.pre_run_modifiers:
|
|
449
450
|
suite.visit(ModelModifier(settings.pre_run_modifiers,
|
|
450
451
|
settings.run_empty_suite, LOGGER))
|
|
451
452
|
suite.configure(**settings.suite_config)
|
|
453
|
+
settings.rpa = suite.validate_execution_mode()
|
|
452
454
|
with pyloggingconf.robot_handler_enabled(settings.log_level):
|
|
453
455
|
old_max_error_lines = text.MAX_ERROR_LINES
|
|
454
456
|
old_max_assign_length = text.MAX_ASSIGN_LENGTH
|
|
@@ -32,6 +32,12 @@ The public API of this module consists of the following objects:
|
|
|
32
32
|
:mod:`robot.running.model` module. These classes are typically only needed
|
|
33
33
|
in type hints.
|
|
34
34
|
|
|
35
|
+
* Keyword implementation related classes :class:`~robot.running.resourcemodel.UserKeyword`,
|
|
36
|
+
:class:`~robot.running.librarykeyword.LibraryKeyword`,
|
|
37
|
+
:class:`~robot.running.invalidkeyword.InvalidKeyword` and their common base class
|
|
38
|
+
:class:`~robot.running.keywordimplementation.KeywordImplementation`. Also these
|
|
39
|
+
classes are mainly needed in type hints.
|
|
40
|
+
|
|
35
41
|
* :class:`~robot.running.builder.settings.TestDefaults` that is part of the
|
|
36
42
|
`external parsing API`__ and also typically needed only in type hints.
|
|
37
43
|
|
|
@@ -43,6 +49,7 @@ the :mod:`robot.api` package.
|
|
|
43
49
|
|
|
44
50
|
.. note:: Prior to Robot Framework 6.1, only some classes in
|
|
45
51
|
:mod:`robot.running.model` were exposed via :mod:`robot.running`.
|
|
52
|
+
Keyword implementation related classes are new in Robot Framework 7.0.
|
|
46
53
|
|
|
47
54
|
Examples
|
|
48
55
|
--------
|
|
@@ -110,9 +117,12 @@ the results is possible using the
|
|
|
110
117
|
from .arguments import ArgInfo, ArgumentSpec, TypeConverter, TypeInfo
|
|
111
118
|
from .builder import ResourceFileBuilder, TestDefaults, TestSuiteBuilder
|
|
112
119
|
from .context import EXECUTION_CONTEXTS
|
|
113
|
-
from .
|
|
114
|
-
|
|
120
|
+
from .keywordimplementation import KeywordImplementation
|
|
121
|
+
from .invalidkeyword import InvalidKeyword
|
|
122
|
+
from .librarykeyword import LibraryKeyword
|
|
123
|
+
from .model import (Break, Continue, Error, For, ForIteration, If, IfBranch, Keyword,
|
|
124
|
+
Return, TestCase, TestSuite, Try, TryBranch, Var, While,
|
|
125
|
+
WhileIteration)
|
|
126
|
+
from .resourcemodel import ResourceFile, UserKeyword
|
|
115
127
|
from .runkwregister import RUN_KW_REGISTER
|
|
116
128
|
from .testlibraries import TestLibrary
|
|
117
|
-
from .usererrorhandler import UserErrorHandler
|
|
118
|
-
from .userkeyword import UserLibrary
|
|
@@ -16,7 +16,8 @@
|
|
|
16
16
|
from .argumentmapper import DefaultValue
|
|
17
17
|
from .argumentparser import (DynamicArgumentParser, PythonArgumentParser,
|
|
18
18
|
UserKeywordArgumentParser)
|
|
19
|
-
from .argumentspec import ArgInfo, ArgumentSpec
|
|
19
|
+
from .argumentspec import ArgInfo, ArgumentSpec
|
|
20
20
|
from .embedded import EmbeddedArguments
|
|
21
21
|
from .customconverters import CustomArgumentConverters
|
|
22
22
|
from .typeconverters import TypeConverter
|
|
23
|
+
from .typeinfo import TypeInfo
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Copyright 2008-2015 Nokia Networks
|
|
2
|
+
# Copyright 2016- Robot Framework Foundation
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
from typing import TYPE_CHECKING
|
|
17
|
+
|
|
18
|
+
from robot.variables import contains_variable
|
|
19
|
+
|
|
20
|
+
from .typeinfo import TypeInfo
|
|
21
|
+
|
|
22
|
+
if TYPE_CHECKING:
|
|
23
|
+
from robot.conf import LanguagesLike
|
|
24
|
+
|
|
25
|
+
from .argumentspec import ArgumentSpec
|
|
26
|
+
from .customconverters import CustomArgumentConverters
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class ArgumentConverter:
|
|
30
|
+
|
|
31
|
+
def __init__(self, arg_spec: 'ArgumentSpec',
|
|
32
|
+
custom_converters: 'CustomArgumentConverters',
|
|
33
|
+
dry_run: bool = False,
|
|
34
|
+
languages: 'LanguagesLike' = None):
|
|
35
|
+
self.spec = arg_spec
|
|
36
|
+
self.custom_converters = custom_converters
|
|
37
|
+
self.dry_run = dry_run
|
|
38
|
+
self.languages = languages
|
|
39
|
+
|
|
40
|
+
def convert(self, positional, named):
|
|
41
|
+
return self._convert_positional(positional), self._convert_named(named)
|
|
42
|
+
|
|
43
|
+
def _convert_positional(self, positional):
|
|
44
|
+
names = self.spec.positional
|
|
45
|
+
converted = [self._convert(name, value)
|
|
46
|
+
for name, value in zip(names, positional)]
|
|
47
|
+
if self.spec.var_positional:
|
|
48
|
+
converted.extend(self._convert(self.spec.var_positional, value)
|
|
49
|
+
for value in positional[len(names):])
|
|
50
|
+
return converted
|
|
51
|
+
|
|
52
|
+
def _convert_named(self, named):
|
|
53
|
+
names = set(self.spec.positional) | set(self.spec.named_only)
|
|
54
|
+
var_named = self.spec.var_named
|
|
55
|
+
return [(name, self._convert(name if name in names else var_named, value))
|
|
56
|
+
for name, value in named]
|
|
57
|
+
|
|
58
|
+
def _convert(self, name, value):
|
|
59
|
+
spec = self.spec
|
|
60
|
+
if (spec.types is None
|
|
61
|
+
or self.dry_run and contains_variable(value, identifiers='$@&%')):
|
|
62
|
+
return value
|
|
63
|
+
conversion_error = None
|
|
64
|
+
# Don't convert None if argument has None as a default value.
|
|
65
|
+
# Python < 3.11 adds None to type hints automatically when using None as
|
|
66
|
+
# a default value which preserves None automatically. This code keeps
|
|
67
|
+
# the same behavior also with newer Python versions. We can consider
|
|
68
|
+
# changing this once Python 3.11 is our minimum supported version.
|
|
69
|
+
if value is None and name in spec.defaults and spec.defaults[name] is None:
|
|
70
|
+
return value
|
|
71
|
+
# Primarily convert arguments based on type hints.
|
|
72
|
+
if name in spec.types:
|
|
73
|
+
info: TypeInfo = spec.types[name]
|
|
74
|
+
try:
|
|
75
|
+
return info.convert(value, name, self.custom_converters, self.languages)
|
|
76
|
+
except ValueError as err:
|
|
77
|
+
conversion_error = err
|
|
78
|
+
except TypeError:
|
|
79
|
+
pass
|
|
80
|
+
# Try conversion also based on the default value type. We probably should
|
|
81
|
+
# do this only if there is no explicit type hint, but Python < 3.11
|
|
82
|
+
# handling `arg: type = None` differently than newer versions would mean
|
|
83
|
+
# that conversion behavior depends on the Python version. Once Python 3.11
|
|
84
|
+
# is our minimum supported version, we can consider reopening
|
|
85
|
+
# https://github.com/robotframework/robotframework/issues/4881
|
|
86
|
+
if name in spec.defaults:
|
|
87
|
+
typ = type(spec.defaults[name])
|
|
88
|
+
if typ == str: # Don't convert arguments to strings.
|
|
89
|
+
info = TypeInfo()
|
|
90
|
+
elif typ == int: # Try also conversion to float.
|
|
91
|
+
info = TypeInfo.from_sequence([int, float])
|
|
92
|
+
else:
|
|
93
|
+
info = TypeInfo.from_type(typ)
|
|
94
|
+
try:
|
|
95
|
+
return info.convert(value, name, languages=self.languages)
|
|
96
|
+
except (ValueError, TypeError):
|
|
97
|
+
pass
|
|
98
|
+
if conversion_error:
|
|
99
|
+
raise conversion_error
|
|
100
|
+
return value
|