robotframework 6.1.1__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.1.1 → robotframework-7.0}/INSTALL.rst +25 -25
- {robotframework-6.1.1 → robotframework-7.0}/PKG-INFO +6 -8
- {robotframework-6.1.1 → robotframework-7.0}/README.rst +3 -2
- {robotframework-6.1.1 → robotframework-7.0}/setup.py +3 -6
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/api/__init__.py +4 -1
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/api/deco.py +60 -14
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/api/exceptions.py +6 -6
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/api/interfaces.py +402 -67
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/api/logger.py +27 -20
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/api/parsing.py +4 -2
- robotframework-7.0/src/robot/api/py.typed +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/conf/gatherfailed.py +2 -2
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/conf/languages.py +0 -9
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/conf/settings.py +21 -14
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/common/storage.js +11 -6
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/htmlfilewriter.py +1 -1
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/libdoc/libdoc.css +10 -2
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/libdoc/libdoc.html +10 -0
- robotframework-7.0/src/robot/htmldata/rebot/common.css +362 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/doc_formatting.css +13 -7
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/log.css +51 -10
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/log.html +14 -23
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/model.js +2 -4
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/report.css +83 -19
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/report.html +22 -7
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/testdata.js +10 -3
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/view.js +84 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/template.py +3 -3
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/builder.py +0 -8
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/datatypes.py +9 -10
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/htmlutils.py +4 -7
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/jsonbuilder.py +38 -20
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/model.py +21 -28
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/robotbuilder.py +50 -31
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/standardtypes.py +9 -1
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/xmlbuilder.py +35 -20
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/xmlwriter.py +18 -38
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/BuiltIn.py +255 -205
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/Collections.py +384 -240
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/DateTime.py +73 -60
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/OperatingSystem.py +6 -5
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/Process.py +26 -27
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/Remote.py +40 -36
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/String.py +66 -76
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/XML.py +66 -59
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/__init__.py +2 -2
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/__init__.py +5 -5
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/body.py +44 -13
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/configurer.py +15 -11
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/control.py +226 -84
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/filter.py +31 -25
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/itemlist.py +9 -8
- robotframework-7.0/src/robot/model/keyword.py +77 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/message.py +19 -10
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/modelobject.py +25 -7
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/namepatterns.py +3 -25
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/stats.py +9 -15
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/tags.py +1 -1
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/testcase.py +15 -27
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/testsuite.py +17 -26
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/visitor.py +35 -8
- robotframework-7.0/src/robot/output/console/dotted.py +90 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/console/quiet.py +3 -2
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/console/verbose.py +61 -61
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/debugfile.py +39 -24
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/filelogger.py +18 -15
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/librarylogger.py +3 -2
- robotframework-7.0/src/robot/output/listeners.py +753 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/logger.py +216 -80
- robotframework-7.0/src/robot/output/loggerapi.py +215 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/loggerhelper.py +23 -56
- robotframework-7.0/src/robot/output/output.py +185 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/stdoutlogsplitter.py +8 -5
- robotframework-7.0/src/robot/output/xmllogger.py +459 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/blocklexers.py +17 -13
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/context.py +12 -2
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/lexer.py +1 -1
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/settings.py +6 -3
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/statementlexers.py +39 -10
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/tokens.py +27 -29
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/model/blocks.py +19 -6
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/model/statements.py +193 -94
- robotframework-7.0/src/robot/parsing/model/visitor.py +100 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/rebot.py +2 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/expandkeywordmatcher.py +1 -1
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/jsbuildingcontext.py +8 -6
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/jsmodelbuilders.py +88 -61
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/logreportwriters.py +16 -10
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/outputwriter.py +18 -2
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/resultwriter.py +4 -4
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/stringcache.py +3 -3
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/xunitwriter.py +15 -21
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/__init__.py +3 -2
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/configurer.py +12 -9
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/executionresult.py +56 -8
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/flattenkeywordmatcher.py +48 -9
- robotframework-7.0/src/robot/result/keywordremover.py +207 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/merger.py +1 -1
- robotframework-7.0/src/robot/result/model.py +1185 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/modeldeprecation.py +9 -3
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/resultbuilder.py +46 -36
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/xmlelementhandlers.py +83 -43
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/run.py +2 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/__init__.py +14 -4
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/arguments/__init__.py +2 -1
- robotframework-7.0/src/robot/running/arguments/argumentconverter.py +100 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/arguments/argumentmapper.py +26 -24
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/arguments/argumentparser.py +82 -60
- robotframework-7.0/src/robot/running/arguments/argumentresolver.py +158 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/arguments/argumentspec.py +83 -116
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/arguments/argumentvalidator.py +33 -27
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/arguments/customconverters.py +15 -12
- robotframework-7.0/src/robot/running/arguments/embedded.py +145 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/arguments/typeconverters.py +233 -213
- 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.1.1 → robotframework-7.0}/src/robot/running/bodyrunner.py +147 -129
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/builder/builders.py +2 -1
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/builder/parsers.py +10 -11
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/builder/settings.py +9 -17
- robotframework-7.0/src/robot/running/builder/transformers.py +535 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/context.py +113 -31
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/dynamicmethods.py +62 -34
- {robotframework-6.1.1 → 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.1.1 → robotframework-7.0}/src/robot/running/model.py +195 -377
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/namespace.py +124 -137
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/outputcapture.py +20 -12
- robotframework-7.0/src/robot/running/resourcemodel.py +448 -0
- {robotframework-6.1.1 → 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.1.1 → robotframework-7.0}/src/robot/testdoc.py +18 -13
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/__init__.py +53 -35
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/connectioncache.py +64 -59
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/dotdict.py +3 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/encodingsniffer.py +1 -1
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/escaping.py +19 -19
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/importer.py +2 -2
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/markupwriters.py +23 -15
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/misc.py +1 -2
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/normalizing.py +9 -24
- robotframework-7.0/src/robot/utils/notset.py +33 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/platform.py +15 -5
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/robotio.py +9 -9
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/robotpath.py +1 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/robottime.py +122 -90
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/robottypes.py +21 -31
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/setter.py +0 -5
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/text.py +7 -4
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/unic.py +2 -2
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/__init__.py +2 -2
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/assigner.py +17 -19
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/evaluation.py +20 -17
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/filesetter.py +80 -80
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/replacer.py +33 -36
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/scopes.py +17 -12
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/search.py +66 -41
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/store.py +14 -16
- robotframework-7.0/src/robot/variables/tablesetter.py +164 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/variables.py +1 -1
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/version.py +1 -1
- {robotframework-6.1.1 → robotframework-7.0}/src/robotframework.egg-info/PKG-INFO +6 -8
- {robotframework-6.1.1 → robotframework-7.0}/src/robotframework.egg-info/SOURCES.txt +10 -8
- {robotframework-6.1.1 → robotframework-7.0}/tasks.py +6 -6
- robotframework-6.1.1/src/robot/htmldata/rebot/common.css +0 -239
- robotframework-6.1.1/src/robot/libraries/Reserved.py +0 -48
- robotframework-6.1.1/src/robot/model/keyword.py +0 -173
- robotframework-6.1.1/src/robot/output/console/dotted.py +0 -90
- robotframework-6.1.1/src/robot/output/listenerarguments.py +0 -165
- robotframework-6.1.1/src/robot/output/listenermethods.py +0 -113
- robotframework-6.1.1/src/robot/output/listeners.py +0 -174
- robotframework-6.1.1/src/robot/output/output.py +0 -95
- robotframework-6.1.1/src/robot/output/xmllogger.py +0 -354
- robotframework-6.1.1/src/robot/parsing/model/visitor.py +0 -67
- robotframework-6.1.1/src/robot/result/keywordremover.py +0 -183
- robotframework-6.1.1/src/robot/result/model.py +0 -957
- robotframework-6.1.1/src/robot/running/arguments/argumentconverter.py +0 -79
- robotframework-6.1.1/src/robot/running/arguments/argumentresolver.py +0 -131
- robotframework-6.1.1/src/robot/running/arguments/embedded.py +0 -146
- robotframework-6.1.1/src/robot/running/arguments/typevalidator.py +0 -56
- robotframework-6.1.1/src/robot/running/builder/transformers.py +0 -642
- robotframework-6.1.1/src/robot/running/handlers.py +0 -321
- robotframework-6.1.1/src/robot/running/handlerstore.py +0 -66
- robotframework-6.1.1/src/robot/running/librarykeywordrunner.py +0 -238
- robotframework-6.1.1/src/robot/running/libraryscopes.py +0 -97
- robotframework-6.1.1/src/robot/running/modelcombiner.py +0 -32
- robotframework-6.1.1/src/robot/running/suiterunner.py +0 -248
- robotframework-6.1.1/src/robot/running/testlibraries.py +0 -423
- robotframework-6.1.1/src/robot/running/usererrorhandler.py +0 -75
- robotframework-6.1.1/src/robot/running/userkeyword.py +0 -111
- robotframework-6.1.1/src/robot/running/userkeywordrunner.py +0 -274
- robotframework-6.1.1/src/robot/variables/tablesetter.py +0 -156
- {robotframework-6.1.1 → robotframework-7.0}/AUTHORS.rst +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/BUILD.rst +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/CONTRIBUTING.rst +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/COPYRIGHT.txt +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/LICENSE.txt +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/MANIFEST.in +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/setup.cfg +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/__main__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/conf/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/errors.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/common/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/common/js_disabled.css +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/jsonwriter.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/lib/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.highlight.min.js +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.min.js +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.tablesorter.min.js +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.tmpl.min.js +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/lib/jsxcompressor.min.js +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/libdoc/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/libdoc/doc_formatting.css +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/libdoc/print.css +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/libdoc/pygments.css +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/fileloading.js +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/log.js +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/print.css +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/util.js +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/testdoc/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/testdoc/testdoc.css +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/testdoc/testdoc.html +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdoc.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/consoleviewer.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/htmlwriter.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/jsonwriter.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/output.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/writer.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/Dialogs.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/Easter.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/Screenshot.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/Telnet.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/dialogs_py.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/fixture.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/metadata.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/modifier.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/statistics.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/suitestatistics.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/tagsetter.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/tagstatistics.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/totalstatistics.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/console/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/console/highlighting.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/pyloggingconf.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/tokenizer.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/model/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/parser/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/parser/blockparsers.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/parser/fileparser.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/parser/parser.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/suitestructure.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/pythonpathsetter.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/jsexecutionresult.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/jswriter.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/executionerrors.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/messagefilter.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/suiteteardownfailed.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/visitor.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/builder/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/randomizer.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/runkwregister.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/signalhandler.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/status.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/timeouts/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/timeouts/posix.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/timeouts/windows.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/application.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/argumentparser.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/asserts.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/charwidth.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/compress.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/encoding.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/error.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/etreewrapper.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/filereader.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/frange.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/htmlformatters.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/markuputils.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/match.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/recommendations.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/restreader.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/robotenv.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/robotinspect.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/sortable.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/typehints.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/finders.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/notfound.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/resolvable.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robotframework.egg-info/dependency_links.txt +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robotframework.egg-info/entry_points.txt +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robotframework.egg-info/top_level.txt +0 -0
|
@@ -13,12 +13,18 @@
|
|
|
13
13
|
# See the License for the specific language governing permissions and
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
|
|
16
|
-
from
|
|
16
|
+
from datetime import datetime
|
|
17
|
+
from typing import Literal
|
|
18
|
+
|
|
19
|
+
from robot.utils import html_escape, setter
|
|
17
20
|
|
|
18
21
|
from .body import BodyItem
|
|
19
22
|
from .itemlist import ItemList
|
|
20
23
|
|
|
21
24
|
|
|
25
|
+
MessageLevel = Literal['TRACE', 'DEBUG', 'INFO', 'WARN', 'ERROR', 'FAIL', 'SKIP']
|
|
26
|
+
|
|
27
|
+
|
|
22
28
|
class Message(BodyItem):
|
|
23
29
|
"""A message created during the test execution.
|
|
24
30
|
|
|
@@ -27,22 +33,25 @@ class Message(BodyItem):
|
|
|
27
33
|
"""
|
|
28
34
|
type = BodyItem.MESSAGE
|
|
29
35
|
repr_args = ('message', 'level')
|
|
30
|
-
__slots__ = ['message', 'level', 'html', '
|
|
36
|
+
__slots__ = ['message', 'level', 'html', '_timestamp']
|
|
31
37
|
|
|
32
|
-
def __init__(self, message=
|
|
33
|
-
|
|
38
|
+
def __init__(self, message: str = '',
|
|
39
|
+
level: MessageLevel = 'INFO',
|
|
40
|
+
html: bool = False,
|
|
41
|
+
timestamp: 'datetime|str|None' = None,
|
|
42
|
+
parent: 'BodyItem|None' = None):
|
|
34
43
|
self.message = message
|
|
35
|
-
#: Severity of the message. Either ``TRACE``, ``DEBUG``, ``INFO``,
|
|
36
|
-
#: ``WARN``, ``ERROR``, ``FAIL`` or ``SKIP`. The last two are only used
|
|
37
|
-
#: with keyword failure messages.
|
|
38
44
|
self.level = level
|
|
39
|
-
#: ``True`` if the content is in HTML, ``False`` otherwise.
|
|
40
45
|
self.html = html
|
|
41
|
-
#: Timestamp in format ``%Y%m%d %H:%M:%S.%f``.
|
|
42
46
|
self.timestamp = timestamp
|
|
43
|
-
#: The object this message was triggered by.
|
|
44
47
|
self.parent = parent
|
|
45
48
|
|
|
49
|
+
@setter
|
|
50
|
+
def timestamp(self, timestamp: 'datetime|str|None') -> 'datetime|None':
|
|
51
|
+
if isinstance(timestamp, str):
|
|
52
|
+
return datetime.fromisoformat(timestamp)
|
|
53
|
+
return timestamp
|
|
54
|
+
|
|
46
55
|
@property
|
|
47
56
|
def html_message(self):
|
|
48
57
|
"""Returns the message content as HTML."""
|
|
@@ -35,6 +35,9 @@ class ModelObject(metaclass=SetterAwareType):
|
|
|
35
35
|
"""Create this object based on data in a dictionary.
|
|
36
36
|
|
|
37
37
|
Data can be got from the :meth:`to_dict` method or created externally.
|
|
38
|
+
|
|
39
|
+
With ``robot.running`` model objects new in Robot Framework 6.1,
|
|
40
|
+
with ``robot.result`` new in Robot Framework 7.0.
|
|
38
41
|
"""
|
|
39
42
|
try:
|
|
40
43
|
return cls().config(**data)
|
|
@@ -49,7 +52,7 @@ class ModelObject(metaclass=SetterAwareType):
|
|
|
49
52
|
The data is given as the ``source`` parameter. It can be:
|
|
50
53
|
|
|
51
54
|
- a string (or bytes) containing the data directly,
|
|
52
|
-
- an open file object where to read the data, or
|
|
55
|
+
- an open file object where to read the data from, or
|
|
53
56
|
- a path (``pathlib.Path`` or string) to a UTF-8 encoded file to read.
|
|
54
57
|
|
|
55
58
|
The JSON data is first converted to a Python dictionary and the object
|
|
@@ -58,6 +61,9 @@ class ModelObject(metaclass=SetterAwareType):
|
|
|
58
61
|
Notice that the ``source`` is considered to be JSON data if it is
|
|
59
62
|
a string and contains ``{``. If you need to use ``{`` in a file system
|
|
60
63
|
path, pass it in as a ``pathlib.Path`` instance.
|
|
64
|
+
|
|
65
|
+
With ``robot.running`` model objects new in Robot Framework 6.1,
|
|
66
|
+
with ``robot.result`` new in Robot Framework 7.0.
|
|
61
67
|
"""
|
|
62
68
|
try:
|
|
63
69
|
data = JsonLoader().load(source)
|
|
@@ -69,6 +75,9 @@ class ModelObject(metaclass=SetterAwareType):
|
|
|
69
75
|
"""Serialize this object into a dictionary.
|
|
70
76
|
|
|
71
77
|
The object can be later restored by using the :meth:`from_dict` method.
|
|
78
|
+
|
|
79
|
+
With ``robot.running`` model objects new in Robot Framework 6.1,
|
|
80
|
+
with ``robot.result`` new in Robot Framework 7.0.
|
|
72
81
|
"""
|
|
73
82
|
raise NotImplementedError
|
|
74
83
|
|
|
@@ -84,7 +93,7 @@ class ModelObject(metaclass=SetterAwareType):
|
|
|
84
93
|
|
|
85
94
|
def to_json(self, file: 'None|TextIO|Path|str' = None, *,
|
|
86
95
|
ensure_ascii: bool = False, indent: int = 0,
|
|
87
|
-
separators: 'tuple[str, str]' = (',', ':')) -> 'None
|
|
96
|
+
separators: 'tuple[str, str]' = (',', ':')) -> 'str|None':
|
|
88
97
|
"""Serialize this object into JSON.
|
|
89
98
|
|
|
90
99
|
The object is first converted to a Python dictionary using the
|
|
@@ -94,7 +103,7 @@ class ModelObject(metaclass=SetterAwareType):
|
|
|
94
103
|
It can be:
|
|
95
104
|
|
|
96
105
|
- ``None`` (default) to return the data as a string,
|
|
97
|
-
- an open file object where to write the data, or
|
|
106
|
+
- an open file object where to write the data to, or
|
|
98
107
|
- a path (``pathlib.Path`` or string) to a file where to write
|
|
99
108
|
the data using UTF-8 encoding.
|
|
100
109
|
|
|
@@ -102,6 +111,9 @@ class ModelObject(metaclass=SetterAwareType):
|
|
|
102
111
|
are passed directly to the underlying json__ module. Notice that
|
|
103
112
|
the defaults differ from what ``json`` uses.
|
|
104
113
|
|
|
114
|
+
With ``robot.running`` model objects new in Robot Framework 6.1,
|
|
115
|
+
with ``robot.result`` new in Robot Framework 7.0.
|
|
116
|
+
|
|
105
117
|
__ https://docs.python.org/3/library/json.html
|
|
106
118
|
"""
|
|
107
119
|
return JsonDumper(ensure_ascii=ensure_ascii, indent=indent,
|
|
@@ -167,14 +179,20 @@ class ModelObject(metaclass=SetterAwareType):
|
|
|
167
179
|
return copy.deepcopy(self).config(**attributes)
|
|
168
180
|
|
|
169
181
|
def __repr__(self) -> str:
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
182
|
+
args = []
|
|
183
|
+
for name in self.repr_args:
|
|
184
|
+
value = getattr(self, name)
|
|
185
|
+
if self._include_in_repr(name, value):
|
|
186
|
+
value = self._repr_format(name, value)
|
|
187
|
+
args.append(f'{name}={value}')
|
|
188
|
+
return f"{full_name(self)}({', '.join(args)})"
|
|
174
189
|
|
|
175
190
|
def _include_in_repr(self, name: str, value: Any) -> bool:
|
|
176
191
|
return True
|
|
177
192
|
|
|
193
|
+
def _repr_format(self, name: str, value: Any) -> str:
|
|
194
|
+
return repr(value)
|
|
195
|
+
|
|
178
196
|
|
|
179
197
|
def full_name(obj_or_cls):
|
|
180
198
|
cls = type(obj_or_cls) if not isinstance(obj_or_cls, type) else obj_or_cls
|
|
@@ -23,15 +23,9 @@ class NamePatterns(Iterable[str]):
|
|
|
23
23
|
def __init__(self, patterns: Sequence[str] = (), ignore: Sequence[str] = '_'):
|
|
24
24
|
self.matcher = MultiMatcher(patterns, ignore)
|
|
25
25
|
|
|
26
|
-
def match(self, name: str,
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
def _match(self, name: str) -> bool:
|
|
31
|
-
return self.matcher.match(name)
|
|
32
|
-
|
|
33
|
-
def _match_longname(self, name: str) -> bool:
|
|
34
|
-
raise NotImplementedError
|
|
26
|
+
def match(self, name: str, full_name: 'str|None' = None) -> bool:
|
|
27
|
+
match = self.matcher.match
|
|
28
|
+
return bool(match(name) or full_name and match(full_name))
|
|
35
29
|
|
|
36
30
|
def __bool__(self) -> bool:
|
|
37
31
|
return bool(self.matcher)
|
|
@@ -39,19 +33,3 @@ class NamePatterns(Iterable[str]):
|
|
|
39
33
|
def __iter__(self) -> Iterator[str]:
|
|
40
34
|
for matcher in self.matcher:
|
|
41
35
|
yield matcher.pattern
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
class SuiteNamePatterns(NamePatterns):
|
|
45
|
-
|
|
46
|
-
def _match_longname(self, name):
|
|
47
|
-
while '.' in name:
|
|
48
|
-
if self._match(name):
|
|
49
|
-
return True
|
|
50
|
-
name = name.split('.', 1)[1]
|
|
51
|
-
return False
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
class TestNamePatterns(NamePatterns):
|
|
55
|
-
|
|
56
|
-
def _match_longname(self, name):
|
|
57
|
-
return self._match(name)
|
|
@@ -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 timedelta
|
|
17
|
+
|
|
16
18
|
from robot.utils import (Sortable, elapsed_time_to_string, html_escape,
|
|
17
19
|
is_string, normalize)
|
|
18
20
|
|
|
@@ -31,14 +33,10 @@ class Stat(Sortable):
|
|
|
31
33
|
#: or name of the tag for
|
|
32
34
|
#: :class:`~robot.model.tagstatistics.TagStatistics`
|
|
33
35
|
self.name = name
|
|
34
|
-
#: Number of passed tests.
|
|
35
36
|
self.passed = 0
|
|
36
|
-
#: Number of failed tests.
|
|
37
37
|
self.failed = 0
|
|
38
|
-
#: Number of skipped tests.
|
|
39
38
|
self.skipped = 0
|
|
40
|
-
|
|
41
|
-
self.elapsed = 0
|
|
39
|
+
self.elapsed = timedelta()
|
|
42
40
|
self._norm_name = normalize(name, ignore='_')
|
|
43
41
|
|
|
44
42
|
def get_attributes(self, include_label=False, include_elapsed=False,
|
|
@@ -49,8 +47,7 @@ class Stat(Sortable):
|
|
|
49
47
|
if include_label:
|
|
50
48
|
attrs['label'] = self.name
|
|
51
49
|
if include_elapsed:
|
|
52
|
-
attrs['elapsed'] = elapsed_time_to_string(self.elapsed,
|
|
53
|
-
include_millis=False)
|
|
50
|
+
attrs['elapsed'] = elapsed_time_to_string(self.elapsed, include_millis=False)
|
|
54
51
|
if exclude_empty:
|
|
55
52
|
attrs = dict((k, v) for k, v in attrs.items() if v not in ('', None))
|
|
56
53
|
if values_as_strings:
|
|
@@ -83,7 +80,7 @@ class Stat(Sortable):
|
|
|
83
80
|
self.failed += 1
|
|
84
81
|
|
|
85
82
|
def _update_elapsed(self, test):
|
|
86
|
-
self.elapsed += test.
|
|
83
|
+
self.elapsed += test.elapsed_time
|
|
87
84
|
|
|
88
85
|
@property
|
|
89
86
|
def _sort_key(self):
|
|
@@ -106,12 +103,9 @@ class SuiteStat(Stat):
|
|
|
106
103
|
type = 'suite'
|
|
107
104
|
|
|
108
105
|
def __init__(self, suite):
|
|
109
|
-
|
|
110
|
-
#: Identifier of the suite, e.g. `s1-s2`.
|
|
106
|
+
super().__init__(suite.full_name)
|
|
111
107
|
self.id = suite.id
|
|
112
|
-
|
|
113
|
-
#: including sub-suites.
|
|
114
|
-
self.elapsed = suite.elapsedtime
|
|
108
|
+
self.elapsed = suite.elapsed_time
|
|
115
109
|
self._name = suite.name
|
|
116
110
|
|
|
117
111
|
def _get_custom_attrs(self):
|
|
@@ -131,7 +125,7 @@ class TagStat(Stat):
|
|
|
131
125
|
type = 'tag'
|
|
132
126
|
|
|
133
127
|
def __init__(self, name, doc='', links=None, combined=None):
|
|
134
|
-
|
|
128
|
+
super().__init__(name)
|
|
135
129
|
#: Documentation of tag as a string.
|
|
136
130
|
self.doc = doc
|
|
137
131
|
#: List of tuples in which the first value is the link URL and
|
|
@@ -164,7 +158,7 @@ class TagStat(Stat):
|
|
|
164
158
|
class CombinedTagStat(TagStat):
|
|
165
159
|
|
|
166
160
|
def __init__(self, pattern, name=None, doc='', links=None):
|
|
167
|
-
|
|
161
|
+
super().__init__(name or pattern, doc, links, combined=pattern)
|
|
168
162
|
self.pattern = TagPattern.from_string(pattern)
|
|
169
163
|
|
|
170
164
|
def match(self, tags):
|
|
@@ -105,7 +105,7 @@ class Tags(Sequence[str]):
|
|
|
105
105
|
|
|
106
106
|
class TagPatterns(Sequence['TagPattern']):
|
|
107
107
|
|
|
108
|
-
def __init__(self, patterns: Iterable[str]):
|
|
108
|
+
def __init__(self, patterns: Iterable[str] = ()):
|
|
109
109
|
self._patterns = tuple(TagPattern.from_string(p) for p in Tags(patterns))
|
|
110
110
|
|
|
111
111
|
def match(self, tags: Iterable[str]) -> bool:
|
|
@@ -13,7 +13,6 @@
|
|
|
13
13
|
# See the License for the specific language governing permissions and
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
|
|
16
|
-
import sys
|
|
17
16
|
from pathlib import Path
|
|
18
17
|
from typing import Any, Generic, Sequence, Type, TYPE_CHECKING, TypeVar
|
|
19
18
|
|
|
@@ -22,7 +21,7 @@ from robot.utils import setter
|
|
|
22
21
|
from .body import Body, BodyItem
|
|
23
22
|
from .fixture import create_fixture
|
|
24
23
|
from .itemlist import ItemList
|
|
25
|
-
from .keyword import Keyword
|
|
24
|
+
from .keyword import Keyword
|
|
26
25
|
from .modelobject import DataDict, ModelObject
|
|
27
26
|
from .tags import Tags
|
|
28
27
|
|
|
@@ -35,7 +34,7 @@ TC = TypeVar('TC', bound='TestCase')
|
|
|
35
34
|
KW = TypeVar('KW', bound='Keyword', covariant=True)
|
|
36
35
|
|
|
37
36
|
|
|
38
|
-
class TestCase(ModelObject, Generic[KW]
|
|
37
|
+
class TestCase(ModelObject, Generic[KW]):
|
|
39
38
|
"""Base model for a single test case.
|
|
40
39
|
|
|
41
40
|
Extended by :class:`robot.running.model.TestCase` and
|
|
@@ -43,16 +42,16 @@ class TestCase(ModelObject, Generic[KW] if sys.version_info >= (3, 7) else objec
|
|
|
43
42
|
"""
|
|
44
43
|
body_class = Body
|
|
45
44
|
# See model.TestSuite on removing the type ignore directive
|
|
46
|
-
fixture_class: Type[KW] = Keyword
|
|
45
|
+
fixture_class: Type[KW] = Keyword # type: ignore
|
|
47
46
|
repr_args = ('name',)
|
|
48
47
|
__slots__ = ['parent', 'name', 'doc', 'timeout', 'lineno', '_setup', '_teardown']
|
|
49
48
|
|
|
50
49
|
def __init__(self, name: str = '',
|
|
51
50
|
doc: str = '',
|
|
52
|
-
tags: Sequence[str] = (),
|
|
51
|
+
tags: 'Tags|Sequence[str]' = (),
|
|
53
52
|
timeout: 'str|None' = None,
|
|
54
53
|
lineno: 'int|None' = None,
|
|
55
|
-
parent: 'TestSuite|None' = None):
|
|
54
|
+
parent: 'TestSuite[KW, TestCase[KW]]|None' = None):
|
|
56
55
|
self.name = name
|
|
57
56
|
self.doc = doc
|
|
58
57
|
self.tags = tags
|
|
@@ -69,7 +68,7 @@ class TestCase(ModelObject, Generic[KW] if sys.version_info >= (3, 7) else objec
|
|
|
69
68
|
return self.body_class(self, body)
|
|
70
69
|
|
|
71
70
|
@setter
|
|
72
|
-
def tags(self, tags: Sequence[str]) -> Tags:
|
|
71
|
+
def tags(self, tags: 'Tags|Sequence[str]') -> Tags:
|
|
73
72
|
"""Test tags as a :class:`~.model.tags.Tags` object."""
|
|
74
73
|
return Tags(tags)
|
|
75
74
|
|
|
@@ -121,7 +120,7 @@ class TestCase(ModelObject, Generic[KW] if sys.version_info >= (3, 7) else objec
|
|
|
121
120
|
return bool(self._setup)
|
|
122
121
|
|
|
123
122
|
@property
|
|
124
|
-
def teardown(self) ->
|
|
123
|
+
def teardown(self) -> KW:
|
|
125
124
|
"""Test teardown as a :class:`~.model.keyword.Keyword` object.
|
|
126
125
|
|
|
127
126
|
See :attr:`setup` for more information.
|
|
@@ -144,19 +143,6 @@ class TestCase(ModelObject, Generic[KW] if sys.version_info >= (3, 7) else objec
|
|
|
144
143
|
"""
|
|
145
144
|
return bool(self._teardown)
|
|
146
145
|
|
|
147
|
-
@property
|
|
148
|
-
def keywords(self) -> Keywords:
|
|
149
|
-
"""Deprecated since Robot Framework 4.0
|
|
150
|
-
|
|
151
|
-
Use :attr:`body`, :attr:`setup` or :attr:`teardown` instead.
|
|
152
|
-
"""
|
|
153
|
-
keywords = [self.setup] + list(self.body) + [self.teardown]
|
|
154
|
-
return Keywords(self, [kw for kw in keywords if kw])
|
|
155
|
-
|
|
156
|
-
@keywords.setter
|
|
157
|
-
def keywords(self, keywords):
|
|
158
|
-
Keywords.raise_deprecation_error()
|
|
159
|
-
|
|
160
146
|
@property
|
|
161
147
|
def id(self) -> str:
|
|
162
148
|
"""Test case id in format like ``s1-t3``.
|
|
@@ -171,11 +157,16 @@ class TestCase(ModelObject, Generic[KW] if sys.version_info >= (3, 7) else objec
|
|
|
171
157
|
return f'{self.parent.id}-t{index + 1}'
|
|
172
158
|
|
|
173
159
|
@property
|
|
174
|
-
def
|
|
175
|
-
"""Test name prefixed with the
|
|
160
|
+
def full_name(self) -> str:
|
|
161
|
+
"""Test name prefixed with the full name of the parent suite."""
|
|
176
162
|
if not self.parent:
|
|
177
163
|
return self.name
|
|
178
|
-
return f'{self.parent.
|
|
164
|
+
return f'{self.parent.full_name}.{self.name}'
|
|
165
|
+
|
|
166
|
+
@property
|
|
167
|
+
def longname(self) -> str:
|
|
168
|
+
"""Deprecated since Robot Framework 7.0. Use :attr:`full_name` instead."""
|
|
169
|
+
return self.full_name
|
|
179
170
|
|
|
180
171
|
@property
|
|
181
172
|
def source(self) -> 'Path|None':
|
|
@@ -185,9 +176,6 @@ class TestCase(ModelObject, Generic[KW] if sys.version_info >= (3, 7) else objec
|
|
|
185
176
|
""":mod:`Visitor interface <robot.model.visitor>` entry-point."""
|
|
186
177
|
visitor.visit_test(self)
|
|
187
178
|
|
|
188
|
-
def __str__(self) -> str:
|
|
189
|
-
return self.name
|
|
190
|
-
|
|
191
179
|
def to_dict(self) -> 'dict[str, Any]':
|
|
192
180
|
data: 'dict[str, Any]' = {'name': self.name}
|
|
193
181
|
if self.doc:
|
|
@@ -13,7 +13,6 @@
|
|
|
13
13
|
# See the License for the specific language governing permissions and
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
|
|
16
|
-
import sys
|
|
17
16
|
from collections.abc import Mapping
|
|
18
17
|
from pathlib import Path
|
|
19
18
|
from typing import Any, Generic, Iterator, Sequence, Type, TypeVar
|
|
@@ -25,7 +24,7 @@ from .configurer import SuiteConfigurer
|
|
|
25
24
|
from .filter import Filter, EmptySuiteRemover
|
|
26
25
|
from .fixture import create_fixture
|
|
27
26
|
from .itemlist import ItemList
|
|
28
|
-
from .keyword import Keyword
|
|
27
|
+
from .keyword import Keyword
|
|
29
28
|
from .metadata import Metadata
|
|
30
29
|
from .modelobject import DataDict, ModelObject
|
|
31
30
|
from .tagsetter import TagSetter
|
|
@@ -37,14 +36,14 @@ KW = TypeVar('KW', bound=Keyword, covariant=True)
|
|
|
37
36
|
TC = TypeVar('TC', bound=TestCase, covariant=True)
|
|
38
37
|
|
|
39
38
|
|
|
40
|
-
class TestSuite(ModelObject, Generic[KW, TC]
|
|
39
|
+
class TestSuite(ModelObject, Generic[KW, TC]):
|
|
41
40
|
"""Base model for single suite.
|
|
42
41
|
|
|
43
42
|
Extended by :class:`robot.running.model.TestSuite` and
|
|
44
43
|
:class:`robot.result.model.TestSuite`.
|
|
45
44
|
"""
|
|
46
45
|
# FIXME: Type Ignore declarations: Typevars only accept subclasses of the bound class
|
|
47
|
-
#
|
|
46
|
+
# assigning `Type[KW]` to `Keyword` results in an error. In RF 7 the class should be
|
|
48
47
|
# made impossible to instantiate directly, and the assignments can be replaced with
|
|
49
48
|
# KnownAtRuntime
|
|
50
49
|
fixture_class: Type[KW] = Keyword # type: ignore
|
|
@@ -58,7 +57,7 @@ class TestSuite(ModelObject, Generic[KW, TC] if sys.version_info >= (3, 7) else
|
|
|
58
57
|
metadata: 'Mapping[str, str]|None' = None,
|
|
59
58
|
source: 'Path|str|None' = None,
|
|
60
59
|
rpa: 'bool|None' = False,
|
|
61
|
-
parent: 'TestSuite|None' = None):
|
|
60
|
+
parent: 'TestSuite[KW, TC]|None' = None):
|
|
62
61
|
self._name = name
|
|
63
62
|
self.doc = doc
|
|
64
63
|
self.metadata = metadata
|
|
@@ -192,11 +191,19 @@ class TestSuite(ModelObject, Generic[KW, TC] if sys.version_info >= (3, 7) else
|
|
|
192
191
|
suite.adjust_source(relative_to, root)
|
|
193
192
|
|
|
194
193
|
@property
|
|
195
|
-
def
|
|
196
|
-
"""Suite name prefixed with the
|
|
194
|
+
def full_name(self) -> str:
|
|
195
|
+
"""Suite name prefixed with the full name of the possible parent suite.
|
|
196
|
+
|
|
197
|
+
Just :attr:`name` of the suite if it has no :attr:`parent`.
|
|
198
|
+
"""
|
|
197
199
|
if not self.parent:
|
|
198
200
|
return self.name
|
|
199
|
-
return f'{self.parent.
|
|
201
|
+
return f'{self.parent.full_name}.{self.name}'
|
|
202
|
+
|
|
203
|
+
@property
|
|
204
|
+
def longname(self) -> str:
|
|
205
|
+
"""Deprecated since Robot Framework 7.0. Use :attr:`full_name` instead."""
|
|
206
|
+
return self.full_name
|
|
200
207
|
|
|
201
208
|
@setter
|
|
202
209
|
def metadata(self, metadata: 'Mapping[str, str]|None') -> Metadata:
|
|
@@ -217,12 +224,12 @@ class TestSuite(ModelObject, Generic[KW, TC] if sys.version_info >= (3, 7) else
|
|
|
217
224
|
suite.validate_execution_mode()
|
|
218
225
|
if rpa is None:
|
|
219
226
|
rpa = suite.rpa
|
|
220
|
-
name = suite.
|
|
227
|
+
name = suite.full_name
|
|
221
228
|
elif rpa is not suite.rpa:
|
|
222
229
|
mode1, mode2 = ('tasks', 'tests') if rpa else ('tests', 'tasks')
|
|
223
230
|
raise DataError(
|
|
224
231
|
f"Conflicting execution modes: Suite '{name}' has {mode1} but "
|
|
225
|
-
f"suite '{suite.
|
|
232
|
+
f"suite '{suite.full_name}' has {mode2}. Resolve the conflict "
|
|
226
233
|
f"or use '--rpa' or '--norpa' options to set the execution "
|
|
227
234
|
f"mode explicitly."
|
|
228
235
|
)
|
|
@@ -309,19 +316,6 @@ class TestSuite(ModelObject, Generic[KW, TC] if sys.version_info >= (3, 7) else
|
|
|
309
316
|
"""
|
|
310
317
|
return bool(self._teardown)
|
|
311
318
|
|
|
312
|
-
@property
|
|
313
|
-
def keywords(self) -> Keywords:
|
|
314
|
-
"""Deprecated since Robot Framework 4.0.
|
|
315
|
-
|
|
316
|
-
Use :attr:`setup` or :attr:`teardown` instead.
|
|
317
|
-
"""
|
|
318
|
-
keywords = [self.setup, self.teardown]
|
|
319
|
-
return Keywords(self, [kw for kw in keywords if kw])
|
|
320
|
-
|
|
321
|
-
@keywords.setter
|
|
322
|
-
def keywords(self, keywords):
|
|
323
|
-
Keywords.raise_deprecation_error()
|
|
324
|
-
|
|
325
319
|
@property
|
|
326
320
|
def id(self) -> str:
|
|
327
321
|
"""An automatically generated unique id.
|
|
@@ -425,9 +419,6 @@ class TestSuite(ModelObject, Generic[KW, TC] if sys.version_info >= (3, 7) else
|
|
|
425
419
|
""":mod:`Visitor interface <robot.model.visitor>` entry-point."""
|
|
426
420
|
visitor.visit_suite(self)
|
|
427
421
|
|
|
428
|
-
def __str__(self) -> str:
|
|
429
|
-
return self.name
|
|
430
|
-
|
|
431
422
|
def to_dict(self) -> 'dict[str, Any]':
|
|
432
423
|
data: 'dict[str, Any]' = {'name': self.name}
|
|
433
424
|
if self.doc:
|
|
@@ -21,7 +21,7 @@ and the :mod:`result model <robot.result.model>`, but the objects passed to
|
|
|
21
21
|
the visitor methods are slightly different depending on the model they are
|
|
22
22
|
used with. The main differences are that on the execution side keywords do
|
|
23
23
|
not have child keywords nor messages, and that only the result objects have
|
|
24
|
-
status related attributes like :attr:`status` and :attr:`
|
|
24
|
+
status related attributes like :attr:`status` and :attr:`start_time`.
|
|
25
25
|
|
|
26
26
|
This module contains :class:`SuiteVisitor` that implements the core logic to
|
|
27
27
|
visit a test suite structure, and the :mod:`~robot.result` package contains
|
|
@@ -80,19 +80,19 @@ Type hints
|
|
|
80
80
|
|
|
81
81
|
Visitor methods have type hints to give more information about the model objects
|
|
82
82
|
they receive to editors. Because visitors can be used with both running and result
|
|
83
|
-
models, the types that are used are base classes from the
|
|
84
|
-
module. Actual
|
|
85
|
-
:mod:`robot.running
|
|
86
|
-
For example, this
|
|
83
|
+
models, the types that are used as type hints are base classes from the
|
|
84
|
+
:mod:`robot.model` module. Actual visitor implementations can import appropriate
|
|
85
|
+
types from the :mod:`robot.running` or the :mod:`robot.result` module instead.
|
|
86
|
+
For example, this visitor uses the result side model objects::
|
|
87
87
|
|
|
88
88
|
from robot.api import SuiteVisitor
|
|
89
|
-
from robot.result
|
|
89
|
+
from robot.result import TestCase, TestSuite
|
|
90
90
|
|
|
91
91
|
|
|
92
92
|
class FailurePrinter(SuiteVisitor):
|
|
93
93
|
|
|
94
94
|
def start_suite(self, suite: TestSuite):
|
|
95
|
-
print(f"{suite.
|
|
95
|
+
print(f"{suite.full_name}: {suite.statistics.failed} failed")
|
|
96
96
|
|
|
97
97
|
def visit_test(self, test: TestCase):
|
|
98
98
|
if test.failed:
|
|
@@ -107,7 +107,7 @@ from typing import TYPE_CHECKING
|
|
|
107
107
|
if TYPE_CHECKING:
|
|
108
108
|
from robot.model import (Break, BodyItem, Continue, Error, For, If, IfBranch,
|
|
109
109
|
Keyword, Message, Return, TestCase, TestSuite, Try,
|
|
110
|
-
TryBranch, While)
|
|
110
|
+
TryBranch, Var, While)
|
|
111
111
|
from robot.result import ForIteration, WhileIteration
|
|
112
112
|
|
|
113
113
|
|
|
@@ -178,10 +178,15 @@ class SuiteVisitor:
|
|
|
178
178
|
the body of the keyword
|
|
179
179
|
"""
|
|
180
180
|
if self.start_keyword(keyword) is not False:
|
|
181
|
+
self._possible_setup(keyword)
|
|
181
182
|
self._possible_body(keyword)
|
|
182
183
|
self._possible_teardown(keyword)
|
|
183
184
|
self.end_keyword(keyword)
|
|
184
185
|
|
|
186
|
+
def _possible_setup(self, item: 'BodyItem'):
|
|
187
|
+
if getattr(item, 'has_setup', False):
|
|
188
|
+
item.setup.visit(self) # type: ignore
|
|
189
|
+
|
|
185
190
|
def _possible_body(self, item: 'BodyItem'):
|
|
186
191
|
if hasattr(item, 'body'):
|
|
187
192
|
item.body.visit(self) # type: ignore
|
|
@@ -422,6 +427,28 @@ class SuiteVisitor:
|
|
|
422
427
|
"""
|
|
423
428
|
self.end_body_item(iteration)
|
|
424
429
|
|
|
430
|
+
def visit_var(self, var: 'Var'):
|
|
431
|
+
"""Visits a VAR elements."""
|
|
432
|
+
if self.start_var(var) is not False:
|
|
433
|
+
self._possible_body(var)
|
|
434
|
+
self.end_var(var)
|
|
435
|
+
|
|
436
|
+
def start_var(self, var: 'Var') -> 'bool|None':
|
|
437
|
+
"""Called when a VAR element starts.
|
|
438
|
+
|
|
439
|
+
By default, calls :meth:`start_body_item` which, by default, does nothing.
|
|
440
|
+
|
|
441
|
+
Can return explicit ``False`` to stop visiting.
|
|
442
|
+
"""
|
|
443
|
+
return self.start_body_item(var)
|
|
444
|
+
|
|
445
|
+
def end_var(self, var: 'Var'):
|
|
446
|
+
"""Called when a VAR element ends.
|
|
447
|
+
|
|
448
|
+
By default, calls :meth:`end_body_item` which, by default, does nothing.
|
|
449
|
+
"""
|
|
450
|
+
self.end_body_item(var)
|
|
451
|
+
|
|
425
452
|
def visit_return(self, return_: 'Return'):
|
|
426
453
|
"""Visits a RETURN elements."""
|
|
427
454
|
if self.start_return(return_) is not False:
|
|
@@ -0,0 +1,90 @@
|
|
|
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
|
+
import sys
|
|
17
|
+
|
|
18
|
+
from robot.model import SuiteVisitor
|
|
19
|
+
from robot.result import TestCase, TestSuite
|
|
20
|
+
from robot.utils import plural_or_not as s, secs_to_timestr
|
|
21
|
+
|
|
22
|
+
from .highlighting import HighlightingStream
|
|
23
|
+
from ..loggerapi import LoggerApi
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class DottedOutput(LoggerApi):
|
|
27
|
+
|
|
28
|
+
def __init__(self, width=78, colors='AUTO', stdout=None, stderr=None):
|
|
29
|
+
self.width = width
|
|
30
|
+
self.stdout = HighlightingStream(stdout or sys.__stdout__, colors)
|
|
31
|
+
self.stderr = HighlightingStream(stderr or sys.__stderr__, colors)
|
|
32
|
+
self.markers_on_row = 0
|
|
33
|
+
|
|
34
|
+
def start_suite(self, data, result):
|
|
35
|
+
if not data.parent:
|
|
36
|
+
count = data.test_count
|
|
37
|
+
ts = ('test' if not data.rpa else 'task') + s(count)
|
|
38
|
+
self.stdout.write(f"Running suite '{result.name}' with {count} {ts}.\n")
|
|
39
|
+
self.stdout.write('=' * self.width + '\n')
|
|
40
|
+
|
|
41
|
+
def end_test(self, data, result):
|
|
42
|
+
if self.markers_on_row == self.width:
|
|
43
|
+
self.stdout.write('\n')
|
|
44
|
+
self.markers_on_row = 0
|
|
45
|
+
self.markers_on_row += 1
|
|
46
|
+
if result.passed:
|
|
47
|
+
self.stdout.write('.')
|
|
48
|
+
elif result.skipped:
|
|
49
|
+
self.stdout.highlight('s', 'SKIP')
|
|
50
|
+
elif result.tags.robot('exit'):
|
|
51
|
+
self.stdout.write('x')
|
|
52
|
+
else:
|
|
53
|
+
self.stdout.highlight('F', 'FAIL')
|
|
54
|
+
|
|
55
|
+
def end_suite(self, data, result):
|
|
56
|
+
if not data.parent:
|
|
57
|
+
self.stdout.write('\n')
|
|
58
|
+
StatusReporter(self.stdout, self.width).report(result)
|
|
59
|
+
self.stdout.write('\n')
|
|
60
|
+
|
|
61
|
+
def message(self, msg):
|
|
62
|
+
if msg.level in ('WARN', 'ERROR'):
|
|
63
|
+
self.stderr.error(msg.message, msg.level)
|
|
64
|
+
|
|
65
|
+
def result_file(self, kind, path):
|
|
66
|
+
self.stdout.write(f"{kind+':':8} {path}\n")
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class StatusReporter(SuiteVisitor):
|
|
70
|
+
|
|
71
|
+
def __init__(self, stream, width):
|
|
72
|
+
self.stream = stream
|
|
73
|
+
self.width = width
|
|
74
|
+
|
|
75
|
+
def report(self, suite: TestSuite):
|
|
76
|
+
suite.visit(self)
|
|
77
|
+
stats = suite.statistics
|
|
78
|
+
ts = ('test' if not suite.rpa else 'task') + s(stats.total)
|
|
79
|
+
elapsed = secs_to_timestr(suite.elapsed_time)
|
|
80
|
+
self.stream.write(f"{'=' * self.width}\nRun suite '{suite.name}' with "
|
|
81
|
+
f"{stats.total} {ts} in {elapsed}.\n\n")
|
|
82
|
+
ed = 'ED' if suite.status != 'SKIP' else 'PED'
|
|
83
|
+
self.stream.highlight(suite.status + ed, suite.status)
|
|
84
|
+
self.stream.write(f'\n{stats.message}\n')
|
|
85
|
+
|
|
86
|
+
def visit_test(self, test: TestCase):
|
|
87
|
+
if test.failed and not test.tags.robot('exit'):
|
|
88
|
+
self.stream.write('-' * self.width + '\n')
|
|
89
|
+
self.stream.highlight('FAIL')
|
|
90
|
+
self.stream.write(f': {test.full_name}\n{test.message.strip()}\n')
|