robotframework 6.1rc1__zip → 7.0a1__zip
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {robotframework-6.1rc1/src/robotframework.egg-info → robotframework-7.0a1}/PKG-INFO +3 -6
- {robotframework-6.1rc1 → robotframework-7.0a1}/setup.py +2 -5
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/api/interfaces.py +36 -49
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/api/parsing.py +4 -2
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/conf/gatherfailed.py +2 -2
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/conf/languages.py +61 -25
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/conf/settings.py +8 -5
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/log.css +4 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/log.html +9 -1
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/model.js +2 -4
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/testdata.js +10 -3
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/template.py +3 -3
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/builder.py +0 -8
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/datatypes.py +9 -10
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/htmlutils.py +4 -7
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/jsonbuilder.py +14 -10
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/model.py +13 -25
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/robotbuilder.py +14 -4
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/xmlbuilder.py +8 -8
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/xmlwriter.py +12 -38
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/BuiltIn.py +215 -189
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/Collections.py +2 -9
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/DateTime.py +1 -1
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/OperatingSystem.py +4 -3
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/Process.py +26 -27
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/Remote.py +40 -36
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/String.py +4 -4
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/XML.py +7 -8
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/__init__.py +2 -2
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/dialogs_py.py +14 -2
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/__init__.py +4 -4
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/body.py +14 -6
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/configurer.py +19 -15
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/control.py +155 -85
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/filter.py +31 -25
- robotframework-7.0a1/src/robot/model/keyword.py +70 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/message.py +19 -10
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/modelobject.py +2 -8
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/modifier.py +1 -1
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/namepatterns.py +3 -25
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/stats.py +9 -15
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/tags.py +1 -1
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/testcase.py +12 -21
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/testsuite.py +43 -24
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/visitor.py +35 -8
- robotframework-7.0a1/src/robot/output/console/dotted.py +90 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/console/quiet.py +3 -2
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/console/verbose.py +60 -60
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/debugfile.py +36 -23
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/filelogger.py +16 -13
- robotframework-7.0a1/src/robot/output/listeners.py +586 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/logger.py +164 -77
- robotframework-7.0a1/src/robot/output/loggerapi.py +152 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/loggerhelper.py +23 -56
- robotframework-7.0a1/src/robot/output/output.py +158 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/stdoutlogsplitter.py +8 -5
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/xmllogger.py +163 -109
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/lexer/blocklexers.py +17 -13
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/lexer/context.py +12 -2
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/lexer/lexer.py +1 -1
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/lexer/settings.py +6 -3
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/lexer/statementlexers.py +39 -10
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/lexer/tokens.py +27 -29
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/model/blocks.py +19 -6
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/model/statements.py +184 -84
- robotframework-7.0a1/src/robot/parsing/model/visitor.py +102 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/reporting/expandkeywordmatcher.py +1 -1
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/reporting/jsbuildingcontext.py +8 -6
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/reporting/jsmodelbuilders.py +88 -61
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/reporting/stringcache.py +4 -3
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/reporting/xunitwriter.py +15 -21
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/__init__.py +3 -2
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/configurer.py +12 -9
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/flattenkeywordmatcher.py +8 -8
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/keywordremover.py +71 -54
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/merger.py +1 -1
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/model.py +400 -316
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/modeldeprecation.py +9 -3
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/resultbuilder.py +21 -23
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/xmlelementhandlers.py +76 -40
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/run.py +1 -1
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/__init__.py +1 -1
- robotframework-7.0a1/src/robot/running/arguments/argumentconverter.py +101 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/arguments/argumentmapper.py +16 -14
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/arguments/argumentparser.py +3 -1
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/arguments/argumentresolver.py +41 -33
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/arguments/argumentspec.py +24 -90
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/arguments/argumentvalidator.py +34 -27
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/arguments/customconverters.py +14 -11
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/arguments/embedded.py +23 -26
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/arguments/typeconverters.py +210 -220
- robotframework-7.0a1/src/robot/running/arguments/typeinfo.py +367 -0
- robotframework-7.0a1/src/robot/running/arguments/typevalidator.py +62 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/bodyrunner.py +83 -68
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/builder/builders.py +15 -25
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/builder/parsers.py +15 -10
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/builder/settings.py +9 -17
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/builder/transformers.py +166 -308
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/context.py +80 -25
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/handlers.py +11 -16
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/handlerstore.py +1 -1
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/librarykeywordrunner.py +9 -17
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/model.py +156 -36
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/namespace.py +18 -19
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/statusreporter.py +13 -12
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/suiterunner.py +18 -21
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/testlibraries.py +35 -39
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/usererrorhandler.py +8 -8
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/userkeyword.py +13 -8
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/userkeywordrunner.py +18 -21
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/testdoc.py +18 -13
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/__init__.py +50 -35
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/connectioncache.py +64 -59
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/encodingsniffer.py +9 -4
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/escaping.py +11 -9
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/markupwriters.py +20 -13
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/normalizing.py +9 -24
- robotframework-7.0a1/src/robot/utils/notset.py +33 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/platform.py +15 -5
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/robotpath.py +1 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/robottime.py +120 -88
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/robottypes.py +16 -31
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/setter.py +0 -5
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/text.py +7 -4
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/unic.py +2 -2
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/__init__.py +2 -2
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/assigner.py +17 -19
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/evaluation.py +20 -17
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/filesetter.py +80 -80
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/replacer.py +33 -36
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/scopes.py +3 -3
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/search.py +66 -41
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/store.py +14 -16
- robotframework-7.0a1/src/robot/variables/tablesetter.py +164 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/variables.py +1 -1
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/version.py +1 -1
- {robotframework-6.1rc1 → robotframework-7.0a1/src/robotframework.egg-info}/PKG-INFO +3 -6
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robotframework.egg-info/SOURCES.txt +3 -4
- {robotframework-6.1rc1 → robotframework-7.0a1}/tasks.py +6 -6
- robotframework-6.1rc1/src/robot/libraries/Reserved.py +0 -48
- robotframework-6.1rc1/src/robot/model/keyword.py +0 -173
- robotframework-6.1rc1/src/robot/output/console/dotted.py +0 -90
- robotframework-6.1rc1/src/robot/output/listenerarguments.py +0 -165
- robotframework-6.1rc1/src/robot/output/listenermethods.py +0 -113
- robotframework-6.1rc1/src/robot/output/listeners.py +0 -174
- robotframework-6.1rc1/src/robot/output/output.py +0 -95
- robotframework-6.1rc1/src/robot/parsing/model/visitor.py +0 -67
- robotframework-6.1rc1/src/robot/running/arguments/argumentconverter.py +0 -79
- robotframework-6.1rc1/src/robot/running/arguments/typevalidator.py +0 -56
- robotframework-6.1rc1/src/robot/running/modelcombiner.py +0 -32
- robotframework-6.1rc1/src/robot/variables/tablesetter.py +0 -156
- {robotframework-6.1rc1 → robotframework-7.0a1}/AUTHORS.rst +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/BUILD.rst +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/CONTRIBUTING.rst +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/COPYRIGHT.txt +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/INSTALL.rst +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/LICENSE.txt +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/MANIFEST.in +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/README.rst +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/setup.cfg +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/__main__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/api/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/api/deco.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/api/exceptions.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/api/logger.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/conf/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/errors.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/common/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/common/js_disabled.css +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/common/storage.js +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/htmlfilewriter.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/jsonwriter.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/lib/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/lib/jquery.highlight.min.js +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/lib/jquery.min.js +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/lib/jquery.tablesorter.min.js +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/lib/jquery.tmpl.min.js +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/lib/jsxcompressor.min.js +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/libdoc/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/libdoc/doc_formatting.css +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/libdoc/libdoc.css +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/libdoc/libdoc.html +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/libdoc/print.css +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/libdoc/pygments.css +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/common.css +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/doc_formatting.css +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/fileloading.js +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/log.js +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/print.css +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/report.css +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/report.html +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/util.js +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/view.js +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/testdoc/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/testdoc/testdoc.css +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/testdoc/testdoc.html +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdoc.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/consoleviewer.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/htmlwriter.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/jsonwriter.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/output.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/standardtypes.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/writer.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/Dialogs.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/Easter.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/Screenshot.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/Telnet.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/fixture.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/itemlist.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/metadata.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/statistics.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/suitestatistics.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/tagsetter.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/tagstatistics.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/totalstatistics.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/console/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/console/highlighting.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/librarylogger.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/pyloggingconf.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/lexer/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/lexer/tokenizer.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/model/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/parser/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/parser/blockparsers.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/parser/fileparser.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/parser/parser.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/suitestructure.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/pythonpathsetter.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/rebot.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/reporting/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/reporting/jsexecutionresult.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/reporting/jswriter.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/reporting/logreportwriters.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/reporting/outputwriter.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/reporting/resultwriter.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/executionerrors.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/executionresult.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/messagefilter.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/suiteteardownfailed.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/visitor.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/arguments/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/builder/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/dynamicmethods.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/importer.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/libraryscopes.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/outputcapture.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/randomizer.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/runkwregister.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/signalhandler.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/status.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/timeouts/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/timeouts/posix.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/timeouts/windows.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/application.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/argumentparser.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/asserts.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/charwidth.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/compress.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/dotdict.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/encoding.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/error.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/etreewrapper.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/filereader.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/frange.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/htmlformatters.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/importer.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/markuputils.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/match.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/misc.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/recommendations.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/restreader.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/robotenv.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/robotinspect.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/robotio.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/sortable.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/typehints.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/finders.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/notfound.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/resolvable.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robotframework.egg-info/dependency_links.txt +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robotframework.egg-info/entry_points.txt +0 -0
- {robotframework-6.1rc1 → robotframework-7.0a1}/src/robotframework.egg-info/top_level.txt +0 -0
|
@@ -35,7 +35,7 @@ class ModelModifier(SuiteVisitor):
|
|
|
35
35
|
message, details = get_error_details()
|
|
36
36
|
self._log_error(f"Executing model modifier '{type_name(visitor)}' "
|
|
37
37
|
f"failed: {message}\n{details}")
|
|
38
|
-
if not (suite.
|
|
38
|
+
if not (suite.has_tests or self._empty_suite_ok):
|
|
39
39
|
raise DataError(f"Suite '{suite.name}' contains no tests after "
|
|
40
40
|
f"model modifiers.")
|
|
41
41
|
|
|
@@ -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,7 +42,7 @@ 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
|
|
|
@@ -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':
|
|
@@ -13,18 +13,18 @@
|
|
|
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
|
|
20
19
|
|
|
20
|
+
from robot.errors import DataError
|
|
21
21
|
from robot.utils import seq2str, setter
|
|
22
22
|
|
|
23
23
|
from .configurer import SuiteConfigurer
|
|
24
24
|
from .filter import Filter, EmptySuiteRemover
|
|
25
25
|
from .fixture import create_fixture
|
|
26
26
|
from .itemlist import ItemList
|
|
27
|
-
from .keyword import Keyword
|
|
27
|
+
from .keyword import Keyword
|
|
28
28
|
from .metadata import Metadata
|
|
29
29
|
from .modelobject import DataDict, ModelObject
|
|
30
30
|
from .tagsetter import TagSetter
|
|
@@ -36,14 +36,14 @@ KW = TypeVar('KW', bound=Keyword, covariant=True)
|
|
|
36
36
|
TC = TypeVar('TC', bound=TestCase, covariant=True)
|
|
37
37
|
|
|
38
38
|
|
|
39
|
-
class TestSuite(ModelObject, Generic[KW, TC]
|
|
39
|
+
class TestSuite(ModelObject, Generic[KW, TC]):
|
|
40
40
|
"""Base model for single suite.
|
|
41
41
|
|
|
42
42
|
Extended by :class:`robot.running.model.TestSuite` and
|
|
43
43
|
:class:`robot.result.model.TestSuite`.
|
|
44
44
|
"""
|
|
45
45
|
# FIXME: Type Ignore declarations: Typevars only accept subclasses of the bound class
|
|
46
|
-
#
|
|
46
|
+
# assigning `Type[KW]` to `Keyword` results in an error. In RF 7 the class should be
|
|
47
47
|
# made impossible to instantiate directly, and the assignments can be replaced with
|
|
48
48
|
# KnownAtRuntime
|
|
49
49
|
fixture_class: Type[KW] = Keyword # type: ignore
|
|
@@ -56,7 +56,7 @@ class TestSuite(ModelObject, Generic[KW, TC] if sys.version_info >= (3, 7) else
|
|
|
56
56
|
doc: str = '',
|
|
57
57
|
metadata: 'Mapping[str, str]|None' = None,
|
|
58
58
|
source: 'Path|str|None' = None,
|
|
59
|
-
rpa: 'bool|None' =
|
|
59
|
+
rpa: 'bool|None' = False,
|
|
60
60
|
parent: 'TestSuite|None' = None):
|
|
61
61
|
self._name = name
|
|
62
62
|
self.doc = doc
|
|
@@ -191,17 +191,51 @@ class TestSuite(ModelObject, Generic[KW, TC] if sys.version_info >= (3, 7) else
|
|
|
191
191
|
suite.adjust_source(relative_to, root)
|
|
192
192
|
|
|
193
193
|
@property
|
|
194
|
-
def
|
|
195
|
-
"""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
|
+
"""
|
|
196
199
|
if not self.parent:
|
|
197
200
|
return self.name
|
|
198
|
-
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
|
|
199
207
|
|
|
200
208
|
@setter
|
|
201
209
|
def metadata(self, metadata: 'Mapping[str, str]|None') -> Metadata:
|
|
202
210
|
"""Free suite metadata as a :class:`~.metadata.Metadata` object."""
|
|
203
211
|
return Metadata(metadata)
|
|
204
212
|
|
|
213
|
+
def validate_execution_mode(self) -> 'bool|None':
|
|
214
|
+
"""Validate that suite execution mode is set consistently.
|
|
215
|
+
|
|
216
|
+
Raise an exception if the execution mode is not set (i.e. the :attr:`rpa`
|
|
217
|
+
attribute is ``None``) and child suites have conflicting execution modes.
|
|
218
|
+
|
|
219
|
+
The execution mode is returned. New in RF 6.1.1.
|
|
220
|
+
"""
|
|
221
|
+
if self.rpa is None:
|
|
222
|
+
rpa = name = None
|
|
223
|
+
for suite in self.suites:
|
|
224
|
+
suite.validate_execution_mode()
|
|
225
|
+
if rpa is None:
|
|
226
|
+
rpa = suite.rpa
|
|
227
|
+
name = suite.full_name
|
|
228
|
+
elif rpa is not suite.rpa:
|
|
229
|
+
mode1, mode2 = ('tasks', 'tests') if rpa else ('tests', 'tasks')
|
|
230
|
+
raise DataError(
|
|
231
|
+
f"Conflicting execution modes: Suite '{name}' has {mode1} but "
|
|
232
|
+
f"suite '{suite.full_name}' has {mode2}. Resolve the conflict "
|
|
233
|
+
f"or use '--rpa' or '--norpa' options to set the execution "
|
|
234
|
+
f"mode explicitly."
|
|
235
|
+
)
|
|
236
|
+
self.rpa = rpa
|
|
237
|
+
return self.rpa
|
|
238
|
+
|
|
205
239
|
@setter
|
|
206
240
|
def suites(self, suites: 'Sequence[TestSuite|DataDict]') -> 'TestSuites[TestSuite[KW, TC]]':
|
|
207
241
|
return TestSuites['TestSuite'](self.__class__, self, suites)
|
|
@@ -282,19 +316,6 @@ class TestSuite(ModelObject, Generic[KW, TC] if sys.version_info >= (3, 7) else
|
|
|
282
316
|
"""
|
|
283
317
|
return bool(self._teardown)
|
|
284
318
|
|
|
285
|
-
@property
|
|
286
|
-
def keywords(self) -> Keywords:
|
|
287
|
-
"""Deprecated since Robot Framework 4.0.
|
|
288
|
-
|
|
289
|
-
Use :attr:`setup` or :attr:`teardown` instead.
|
|
290
|
-
"""
|
|
291
|
-
keywords = [self.setup, self.teardown]
|
|
292
|
-
return Keywords(self, [kw for kw in keywords if kw])
|
|
293
|
-
|
|
294
|
-
@keywords.setter
|
|
295
|
-
def keywords(self, keywords):
|
|
296
|
-
Keywords.raise_deprecation_error()
|
|
297
|
-
|
|
298
319
|
@property
|
|
299
320
|
def id(self) -> str:
|
|
300
321
|
"""An automatically generated unique id.
|
|
@@ -331,9 +352,7 @@ class TestSuite(ModelObject, Generic[KW, TC] if sys.version_info >= (3, 7) else
|
|
|
331
352
|
|
|
332
353
|
@property
|
|
333
354
|
def has_tests(self) -> bool:
|
|
334
|
-
|
|
335
|
-
return True
|
|
336
|
-
return any(s.has_tests for s in self.suites)
|
|
355
|
+
return bool(self.tests) or any(s.has_tests for s in self.suites)
|
|
337
356
|
|
|
338
357
|
def set_tags(self, add: Sequence[str] = (), remove: Sequence[str] = (),
|
|
339
358
|
persist: bool = False):
|
|
@@ -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 output_file(self, name, path):
|
|
66
|
+
self.stdout.write(f"{name+':':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')
|
|
@@ -16,9 +16,10 @@
|
|
|
16
16
|
import sys
|
|
17
17
|
|
|
18
18
|
from .highlighting import HighlightingStream
|
|
19
|
+
from ..loggerapi import LoggerApi
|
|
19
20
|
|
|
20
21
|
|
|
21
|
-
class QuietOutput:
|
|
22
|
+
class QuietOutput(LoggerApi):
|
|
22
23
|
|
|
23
24
|
def __init__(self, colors='AUTO', stderr=None):
|
|
24
25
|
self._stderr = HighlightingStream(stderr or sys.__stderr__, colors)
|
|
@@ -28,5 +29,5 @@ class QuietOutput:
|
|
|
28
29
|
self._stderr.error(msg.message, msg.level)
|
|
29
30
|
|
|
30
31
|
|
|
31
|
-
class NoOutput:
|
|
32
|
+
class NoOutput(LoggerApi):
|
|
32
33
|
pass
|