robotframework 7.1.1__zip → 7.2b1__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-7.1.1 → robotframework-7.2b1}/BUILD.rst +2 -2
- {robotframework-7.1.1 → robotframework-7.2b1}/PKG-INFO +2 -2
- {robotframework-7.1.1 → robotframework-7.2b1}/setup.py +1 -1
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/api/__init__.py +33 -9
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/api/deco.py +8 -6
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/api/interfaces.py +21 -4
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/api/parsing.py +72 -68
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/conf/languages.py +4 -3
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/conf/settings.py +11 -10
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/errors.py +3 -1
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/htmlfilewriter.py +3 -0
- robotframework-7.2b1/src/robot/htmldata/libdoc/libdoc.html +408 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/rebot/log.html +1 -1
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/rebot/report.html +1 -1
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/rebot/testdata.js +1 -1
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libdoc.py +19 -11
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libdocpkg/htmlwriter.py +7 -4
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libdocpkg/model.py +7 -5
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libdocpkg/writer.py +2 -2
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libraries/BuiltIn.py +109 -32
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libraries/Collections.py +18 -4
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/model/__init__.py +3 -3
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/model/body.py +48 -57
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/model/control.py +35 -4
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/model/message.py +13 -8
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/model/modelobject.py +26 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/model/statistics.py +13 -9
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/model/stats.py +12 -14
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/model/suitestatistics.py +8 -9
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/model/tags.py +10 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/model/tagstatistics.py +7 -8
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/model/testcase.py +1 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/model/testsuite.py +1 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/model/totalstatistics.py +14 -21
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/model/visitor.py +29 -3
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/output/__init__.py +3 -2
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/output/console/dotted.py +6 -3
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/output/debugfile.py +3 -3
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/output/filelogger.py +7 -3
- robotframework-7.2b1/src/robot/output/jsonlogger.py +338 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/output/librarylogger.py +12 -11
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/output/listeners.py +49 -47
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/output/logger.py +33 -20
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/output/loggerapi.py +6 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/output/loggerhelper.py +26 -55
- robotframework-7.2b1/src/robot/output/loglevel.py +54 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/output/output.py +21 -17
- robotframework-7.2b1/src/robot/output/outputfile.py +174 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/output/pyloggingconf.py +2 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/output/xmllogger.py +40 -169
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/parsing/lexer/blocklexers.py +25 -12
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/parsing/lexer/statementlexers.py +16 -7
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/parsing/lexer/tokens.py +2 -1
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/parsing/model/__init__.py +1 -1
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/parsing/model/blocks.py +34 -2
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/parsing/model/statements.py +32 -2
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/parsing/parser/blockparsers.py +7 -2
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/rebot.py +10 -2
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/reporting/jsmodelbuilders.py +1 -1
- robotframework-7.2b1/src/robot/reporting/outputwriter.py +30 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/result/__init__.py +1 -1
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/result/executionerrors.py +9 -9
- robotframework-7.2b1/src/robot/result/executionresult.py +331 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/result/messagefilter.py +14 -10
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/result/model.py +90 -18
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/result/resultbuilder.py +2 -5
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/result/xmlelementhandlers.py +20 -9
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/run.py +18 -6
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/__init__.py +1 -1
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/arguments/embedded.py +7 -6
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/arguments/typeconverters.py +14 -2
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/arguments/typeinfo.py +22 -2
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/bodyrunner.py +41 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/builder/settings.py +2 -1
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/builder/transformers.py +46 -20
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/context.py +22 -11
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/librarykeyword.py +1 -1
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/librarykeywordrunner.py +29 -23
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/model.py +31 -4
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/status.py +42 -35
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/statusreporter.py +1 -1
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/suiterunner.py +22 -15
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/importer.py +39 -23
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/unic.py +7 -8
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/variables/evaluation.py +21 -2
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/variables/replacer.py +20 -24
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/variables/scopes.py +17 -8
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/variables/variables.py +4 -1
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/version.py +1 -1
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robotframework.egg-info/PKG-INFO +2 -2
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robotframework.egg-info/SOURCES.txt +3 -4
- robotframework-7.1.1/src/robot/htmldata/libdoc/doc_formatting.css +0 -74
- robotframework-7.1.1/src/robot/htmldata/libdoc/libdoc.css +0 -747
- robotframework-7.1.1/src/robot/htmldata/libdoc/libdoc.html +0 -702
- robotframework-7.1.1/src/robot/htmldata/libdoc/print.css +0 -11
- robotframework-7.1.1/src/robot/htmldata/libdoc/pygments.css +0 -162
- robotframework-7.1.1/src/robot/reporting/outputwriter.py +0 -48
- robotframework-7.1.1/src/robot/result/executionresult.py +0 -201
- {robotframework-7.1.1 → robotframework-7.2b1}/AUTHORS.rst +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/CONTRIBUTING.rst +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/COPYRIGHT.txt +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/INSTALL.rst +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/LICENSE.txt +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/MANIFEST.in +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/README.rst +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/setup.cfg +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/__init__.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/__main__.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/api/exceptions.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/api/logger.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/api/py.typed +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/conf/__init__.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/conf/gatherfailed.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/__init__.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/common/__init__.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/common/js_disabled.css +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/common/storage.js +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/jsonwriter.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/lib/__init__.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/lib/jquery.highlight.min.js +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/lib/jquery.min.js +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/lib/jquery.tablesorter.min.js +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/lib/jquery.tmpl.min.js +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/lib/jsxcompressor.min.js +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/libdoc/__init__.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/rebot/__init__.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/rebot/common.css +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/rebot/doc_formatting.css +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/rebot/fileloading.js +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/rebot/log.css +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/rebot/log.js +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/rebot/model.js +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/rebot/print.css +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/rebot/report.css +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/rebot/util.js +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/rebot/view.js +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/template.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/testdoc/__init__.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/testdoc/testdoc.css +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/testdoc/testdoc.html +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libdocpkg/__init__.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libdocpkg/builder.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libdocpkg/consoleviewer.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libdocpkg/datatypes.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libdocpkg/htmlutils.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libdocpkg/jsonbuilder.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libdocpkg/jsonwriter.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libdocpkg/output.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libdocpkg/robotbuilder.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libdocpkg/standardtypes.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libdocpkg/xmlbuilder.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libdocpkg/xmlwriter.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libraries/DateTime.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libraries/Dialogs.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libraries/Easter.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libraries/OperatingSystem.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libraries/Process.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libraries/Remote.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libraries/Screenshot.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libraries/String.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libraries/Telnet.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libraries/XML.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libraries/__init__.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libraries/dialogs_py.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/model/configurer.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/model/filter.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/model/fixture.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/model/itemlist.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/model/keyword.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/model/metadata.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/model/modifier.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/model/namepatterns.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/model/tagsetter.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/output/console/__init__.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/output/console/highlighting.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/output/console/quiet.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/output/console/verbose.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/output/stdoutlogsplitter.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/parsing/__init__.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/parsing/lexer/__init__.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/parsing/lexer/context.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/parsing/lexer/lexer.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/parsing/lexer/settings.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/parsing/lexer/tokenizer.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/parsing/model/visitor.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/parsing/parser/__init__.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/parsing/parser/fileparser.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/parsing/parser/parser.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/parsing/suitestructure.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/pythonpathsetter.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/reporting/__init__.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/reporting/expandkeywordmatcher.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/reporting/jsbuildingcontext.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/reporting/jsexecutionresult.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/reporting/jswriter.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/reporting/logreportwriters.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/reporting/resultwriter.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/reporting/stringcache.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/reporting/xunitwriter.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/result/configurer.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/result/flattenkeywordmatcher.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/result/keywordremover.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/result/merger.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/result/modeldeprecation.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/result/suiteteardownfailed.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/result/visitor.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/arguments/__init__.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/arguments/argumentconverter.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/arguments/argumentmapper.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/arguments/argumentparser.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/arguments/argumentresolver.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/arguments/argumentspec.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/arguments/argumentvalidator.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/arguments/customconverters.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/arguments/typeinfoparser.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/arguments/typevalidator.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/builder/__init__.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/builder/builders.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/builder/parsers.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/dynamicmethods.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/importer.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/invalidkeyword.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/keywordfinder.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/keywordimplementation.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/libraryscopes.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/namespace.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/outputcapture.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/randomizer.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/resourcemodel.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/runkwregister.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/signalhandler.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/testlibraries.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/timeouts/__init__.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/timeouts/nosupport.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/timeouts/posix.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/timeouts/windows.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/userkeywordrunner.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/testdoc.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/__init__.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/application.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/argumentparser.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/asserts.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/charwidth.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/compress.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/connectioncache.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/dotdict.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/encoding.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/encodingsniffer.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/error.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/escaping.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/etreewrapper.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/filereader.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/frange.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/htmlformatters.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/markuputils.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/markupwriters.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/match.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/misc.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/normalizing.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/notset.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/platform.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/recommendations.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/restreader.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/robotenv.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/robotinspect.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/robotio.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/robotpath.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/robottime.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/robottypes.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/setter.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/sortable.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/text.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/typehints.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/variables/__init__.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/variables/assigner.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/variables/filesetter.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/variables/finders.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/variables/notfound.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/variables/resolvable.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/variables/search.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/variables/store.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/variables/tablesetter.py +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robotframework.egg-info/dependency_links.txt +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robotframework.egg-info/entry_points.txt +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/src/robotframework.egg-info/top_level.txt +0 -0
- {robotframework-7.1.1 → robotframework-7.2b1}/tasks.py +0 -0
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
import os.path
|
|
17
17
|
from abc import ABC
|
|
18
18
|
from pathlib import Path
|
|
19
|
+
from typing import Any, Iterable
|
|
19
20
|
|
|
20
21
|
from robot.errors import DataError, TimeoutError
|
|
21
22
|
from robot.model import BodyItem
|
|
@@ -23,15 +24,17 @@ from robot.utils import (get_error_details, Importer, safe_str,
|
|
|
23
24
|
split_args_from_name_or_path, type_name)
|
|
24
25
|
|
|
25
26
|
from .loggerapi import LoggerApi
|
|
26
|
-
from .loggerhelper import IsLogged
|
|
27
27
|
from .logger import LOGGER
|
|
28
|
+
from .loglevel import LogLevel
|
|
28
29
|
|
|
29
30
|
|
|
30
31
|
class Listeners:
|
|
31
32
|
_listeners: 'list[ListenerFacade]'
|
|
32
33
|
|
|
33
|
-
def __init__(self, listeners=(),
|
|
34
|
-
|
|
34
|
+
def __init__(self, listeners: Iterable['str|Any'] = (),
|
|
35
|
+
log_level: 'LogLevel|str' = 'INFO'):
|
|
36
|
+
self._log_level = log_level \
|
|
37
|
+
if isinstance(log_level, LogLevel) else LogLevel(log_level)
|
|
35
38
|
self._listeners = self._import_listeners(listeners)
|
|
36
39
|
|
|
37
40
|
# Must be property to allow LibraryListeners to override it.
|
|
@@ -67,8 +70,8 @@ class Listeners:
|
|
|
67
70
|
# Modules have `__name__`, with others better to use `type_name`.
|
|
68
71
|
name = getattr(listener, '__name__', None) or type_name(listener)
|
|
69
72
|
if self._get_version(listener) == 2:
|
|
70
|
-
return ListenerV2Facade(listener, name, self.
|
|
71
|
-
return ListenerV3Facade(listener, name, self.
|
|
73
|
+
return ListenerV2Facade(listener, name, self._log_level, library)
|
|
74
|
+
return ListenerV3Facade(listener, name, self._log_level, library)
|
|
72
75
|
|
|
73
76
|
def _get_version(self, listener):
|
|
74
77
|
version = getattr(listener, 'ROBOT_LISTENER_API_VERSION', 3)
|
|
@@ -80,9 +83,6 @@ class Listeners:
|
|
|
80
83
|
raise DataError(f"Unsupported API version '{version}'.")
|
|
81
84
|
return version
|
|
82
85
|
|
|
83
|
-
def set_log_level(self, level):
|
|
84
|
-
self._is_logged.set_level(level)
|
|
85
|
-
|
|
86
86
|
def __iter__(self):
|
|
87
87
|
return iter(self.listeners)
|
|
88
88
|
|
|
@@ -93,7 +93,7 @@ class Listeners:
|
|
|
93
93
|
class LibraryListeners(Listeners):
|
|
94
94
|
_listeners: 'list[list[ListenerFacade]]'
|
|
95
95
|
|
|
96
|
-
def __init__(self, log_level='INFO'):
|
|
96
|
+
def __init__(self, log_level: 'LogLevel|str' = 'INFO'):
|
|
97
97
|
super().__init__(log_level=log_level)
|
|
98
98
|
|
|
99
99
|
@property
|
|
@@ -122,10 +122,10 @@ class LibraryListeners(Listeners):
|
|
|
122
122
|
|
|
123
123
|
class ListenerFacade(LoggerApi, ABC):
|
|
124
124
|
|
|
125
|
-
def __init__(self, listener, name,
|
|
125
|
+
def __init__(self, listener, name, log_level, library=None):
|
|
126
126
|
self.listener = listener
|
|
127
127
|
self.name = name
|
|
128
|
-
self._is_logged = is_logged
|
|
128
|
+
self._is_logged = log_level.is_logged
|
|
129
129
|
self.library = library
|
|
130
130
|
self.priority = self._get_priority(listener)
|
|
131
131
|
|
|
@@ -141,7 +141,7 @@ class ListenerFacade(LoggerApi, ABC):
|
|
|
141
141
|
method = getattr(self.listener, method_name, None)
|
|
142
142
|
if method:
|
|
143
143
|
return ListenerMethod(method, self.name)
|
|
144
|
-
return ListenerMethod(None, self.name)
|
|
144
|
+
return fallback or ListenerMethod(None, self.name)
|
|
145
145
|
|
|
146
146
|
def _get_method_names(self, name):
|
|
147
147
|
names = [name, self._to_camelCase(name)] if '_' in name else [name]
|
|
@@ -156,8 +156,8 @@ class ListenerFacade(LoggerApi, ABC):
|
|
|
156
156
|
|
|
157
157
|
class ListenerV3Facade(ListenerFacade):
|
|
158
158
|
|
|
159
|
-
def __init__(self, listener, name,
|
|
160
|
-
super().__init__(listener, name,
|
|
159
|
+
def __init__(self, listener, name, log_level, library=None):
|
|
160
|
+
super().__init__(listener, name, log_level, library)
|
|
161
161
|
get = self._get_method
|
|
162
162
|
# Suite
|
|
163
163
|
self.start_suite = get('start_suite')
|
|
@@ -166,8 +166,8 @@ class ListenerV3Facade(ListenerFacade):
|
|
|
166
166
|
self.start_test = get('start_test')
|
|
167
167
|
self.end_test = get('end_test')
|
|
168
168
|
# Fallbacks for body items
|
|
169
|
-
start_body_item =
|
|
170
|
-
end_body_item =
|
|
169
|
+
start_body_item = get('start_body_item')
|
|
170
|
+
end_body_item = get('end_body_item')
|
|
171
171
|
# Keywords
|
|
172
172
|
self.start_keyword = get('start_keyword', start_body_item)
|
|
173
173
|
self.end_keyword = get('end_keyword', end_body_item)
|
|
@@ -197,6 +197,9 @@ class ListenerV3Facade(ListenerFacade):
|
|
|
197
197
|
self.end_while = get('end_while', end_body_item)
|
|
198
198
|
self.start_while_iteration = get('start_while_iteration', start_body_item)
|
|
199
199
|
self.end_while_iteration = get('end_while_iteration', end_body_item)
|
|
200
|
+
# GROUP
|
|
201
|
+
self.start_group = get('start_group', start_body_item)
|
|
202
|
+
self.end_group = get('end_group', end_body_item)
|
|
200
203
|
# VAR
|
|
201
204
|
self.start_var = get('start_var', start_body_item)
|
|
202
205
|
self.end_var = get('end_var', end_body_item)
|
|
@@ -265,38 +268,39 @@ class ListenerV3Facade(ListenerFacade):
|
|
|
265
268
|
self.end_keyword(data, result)
|
|
266
269
|
|
|
267
270
|
def log_message(self, message):
|
|
268
|
-
if self._is_logged(message
|
|
271
|
+
if self._is_logged(message):
|
|
269
272
|
self._log_message(message)
|
|
270
273
|
|
|
271
274
|
|
|
272
275
|
class ListenerV2Facade(ListenerFacade):
|
|
273
276
|
|
|
274
|
-
def __init__(self, listener, name,
|
|
275
|
-
super().__init__(listener, name,
|
|
277
|
+
def __init__(self, listener, name, log_level, library=None):
|
|
278
|
+
super().__init__(listener, name, log_level, library)
|
|
279
|
+
get = self._get_method
|
|
276
280
|
# Suite
|
|
277
|
-
self._start_suite =
|
|
278
|
-
self._end_suite =
|
|
281
|
+
self._start_suite = get('start_suite')
|
|
282
|
+
self._end_suite = get('end_suite')
|
|
279
283
|
# Test
|
|
280
|
-
self._start_test =
|
|
281
|
-
self._end_test =
|
|
284
|
+
self._start_test = get('start_test')
|
|
285
|
+
self._end_test = get('end_test')
|
|
282
286
|
# Keyword and control structures
|
|
283
|
-
self._start_kw =
|
|
284
|
-
self._end_kw =
|
|
287
|
+
self._start_kw = get('start_keyword')
|
|
288
|
+
self._end_kw = get('end_keyword')
|
|
285
289
|
# Messages
|
|
286
|
-
self._log_message =
|
|
287
|
-
self._message =
|
|
290
|
+
self._log_message = get('log_message')
|
|
291
|
+
self._message = get('message')
|
|
288
292
|
# Imports
|
|
289
|
-
self._library_import =
|
|
290
|
-
self._resource_import =
|
|
291
|
-
self._variables_import =
|
|
293
|
+
self._library_import = get('library_import')
|
|
294
|
+
self._resource_import = get('resource_import')
|
|
295
|
+
self._variables_import = get('variables_import')
|
|
292
296
|
# Result files
|
|
293
|
-
self._output_file =
|
|
294
|
-
self._report_file =
|
|
295
|
-
self._log_file =
|
|
296
|
-
self._xunit_file =
|
|
297
|
-
self._debug_file =
|
|
297
|
+
self._output_file = get('output_file')
|
|
298
|
+
self._report_file = get('report_file')
|
|
299
|
+
self._log_file = get('log_file')
|
|
300
|
+
self._xunit_file = get('xunit_file')
|
|
301
|
+
self._debug_file = get('debug_file')
|
|
298
302
|
# Close
|
|
299
|
-
self._close =
|
|
303
|
+
self._close = get('close')
|
|
300
304
|
|
|
301
305
|
def start_suite(self, data, result):
|
|
302
306
|
self._start_suite(result.name, self._suite_attrs(data, result))
|
|
@@ -363,6 +367,12 @@ class ListenerV2Facade(ListenerFacade):
|
|
|
363
367
|
def end_while_iteration(self, data, result):
|
|
364
368
|
self._end_kw(result._log_name, self._attrs(data, result, end=True))
|
|
365
369
|
|
|
370
|
+
def start_group(self, data, result):
|
|
371
|
+
self._start_kw(result._log_name, self._attrs(data, result, name=result.name))
|
|
372
|
+
|
|
373
|
+
def end_group(self, data, result):
|
|
374
|
+
self._end_kw(result._log_name, self._attrs(data, result, name=result.name, end=True))
|
|
375
|
+
|
|
366
376
|
def start_if_branch(self, data, result):
|
|
367
377
|
extra = {'condition': result.condition} if result.type != result.ELSE else {}
|
|
368
378
|
self._start_kw(result._log_name, self._attrs(data, result, **extra))
|
|
@@ -430,7 +440,7 @@ class ListenerV2Facade(ListenerFacade):
|
|
|
430
440
|
return {'name': result.name, 'value': value, 'scope': result.scope or 'LOCAL'}
|
|
431
441
|
|
|
432
442
|
def log_message(self, message):
|
|
433
|
-
if self._is_logged(message
|
|
443
|
+
if self._is_logged(message):
|
|
434
444
|
self._log_message(self._message_attributes(message))
|
|
435
445
|
|
|
436
446
|
def message(self, message):
|
|
@@ -566,21 +576,15 @@ class ListenerV2Facade(ListenerFacade):
|
|
|
566
576
|
|
|
567
577
|
|
|
568
578
|
class ListenerMethod:
|
|
569
|
-
# Flag to avoid recursive listener calls.
|
|
570
|
-
called = False
|
|
571
579
|
|
|
572
580
|
def __init__(self, method, name):
|
|
573
581
|
self.method = method
|
|
574
582
|
self.listener_name = name
|
|
575
583
|
|
|
576
584
|
def __call__(self, *args):
|
|
577
|
-
if self.method is None:
|
|
578
|
-
return
|
|
579
|
-
if self.called:
|
|
580
|
-
return
|
|
581
585
|
try:
|
|
582
|
-
|
|
583
|
-
|
|
586
|
+
if self.method is not None:
|
|
587
|
+
self.method(*args)
|
|
584
588
|
except TimeoutError:
|
|
585
589
|
# Propagate possible timeouts:
|
|
586
590
|
# https://github.com/robotframework/robotframework/issues/2763
|
|
@@ -590,8 +594,6 @@ class ListenerMethod:
|
|
|
590
594
|
LOGGER.error(f"Calling method '{self.method.__name__}' of listener "
|
|
591
595
|
f"'{self.listener_name}' failed: {message}")
|
|
592
596
|
LOGGER.info(f"Details:\n{details}")
|
|
593
|
-
finally:
|
|
594
|
-
ListenerMethod.called = False
|
|
595
597
|
|
|
596
598
|
def __bool__(self):
|
|
597
599
|
return self.method is not None
|
|
@@ -26,19 +26,15 @@ from .stdoutlogsplitter import StdoutLogSplitter
|
|
|
26
26
|
|
|
27
27
|
def start_body_item(method):
|
|
28
28
|
def wrapper(self, *args):
|
|
29
|
-
|
|
30
|
-
self._started_keywords += 1
|
|
31
|
-
self.log_message = self._log_message
|
|
29
|
+
self._log_message_parents.append(args[-1])
|
|
32
30
|
method(self, *args)
|
|
33
31
|
return wrapper
|
|
34
32
|
|
|
35
33
|
|
|
36
34
|
def end_body_item(method):
|
|
37
35
|
def wrapper(self, *args):
|
|
38
|
-
self._started_keywords -= 1
|
|
39
36
|
method(self, *args)
|
|
40
|
-
|
|
41
|
-
self.log_message = self.message
|
|
37
|
+
self._log_message_parents.pop()
|
|
42
38
|
return wrapper
|
|
43
39
|
|
|
44
40
|
|
|
@@ -55,16 +51,16 @@ class Logger(AbstractLogger):
|
|
|
55
51
|
def __init__(self, register_console_logger=True):
|
|
56
52
|
self._console_logger = None
|
|
57
53
|
self._syslog = None
|
|
58
|
-
self.
|
|
54
|
+
self._output_file = None
|
|
59
55
|
self._cli_listeners = None
|
|
60
56
|
self._lib_listeners = None
|
|
61
57
|
self._other_loggers = []
|
|
62
58
|
self._message_cache = []
|
|
63
59
|
self._log_message_cache = None
|
|
64
|
-
self.
|
|
60
|
+
self._log_message_parents = []
|
|
61
|
+
self._library_import_logging = 0
|
|
65
62
|
self._error_occurred = False
|
|
66
63
|
self._error_listener = None
|
|
67
|
-
self._prev_log_message_handlers = []
|
|
68
64
|
self._enabled = 0
|
|
69
65
|
self._cache_only = False
|
|
70
66
|
if register_console_logger:
|
|
@@ -79,14 +75,14 @@ class Logger(AbstractLogger):
|
|
|
79
75
|
@property
|
|
80
76
|
def start_loggers(self):
|
|
81
77
|
loggers = (self._other_loggers
|
|
82
|
-
+ [self._console_logger, self._syslog, self.
|
|
78
|
+
+ [self._console_logger, self._syslog, self._output_file]
|
|
83
79
|
+ self._listeners)
|
|
84
80
|
return [logger for logger in loggers if logger]
|
|
85
81
|
|
|
86
82
|
@property
|
|
87
83
|
def end_loggers(self):
|
|
88
84
|
loggers = (self._listeners
|
|
89
|
-
+ [self._console_logger, self._syslog, self.
|
|
85
|
+
+ [self._console_logger, self._syslog, self._output_file]
|
|
90
86
|
+ self._other_loggers)
|
|
91
87
|
return [logger for logger in loggers if logger]
|
|
92
88
|
|
|
@@ -133,11 +129,11 @@ class Logger(AbstractLogger):
|
|
|
133
129
|
else:
|
|
134
130
|
self._syslog = self._wrap_and_relay(syslog)
|
|
135
131
|
|
|
136
|
-
def
|
|
137
|
-
self.
|
|
132
|
+
def register_output_file(self, logger):
|
|
133
|
+
self._output_file = self._wrap_and_relay(logger)
|
|
138
134
|
|
|
139
|
-
def
|
|
140
|
-
self.
|
|
135
|
+
def unregister_output_file(self):
|
|
136
|
+
self._output_file = None
|
|
141
137
|
|
|
142
138
|
def register_listeners(self, listeners, library_listeners):
|
|
143
139
|
self._cli_listeners = listeners
|
|
@@ -196,6 +192,12 @@ class Logger(AbstractLogger):
|
|
|
196
192
|
for msg in messages or ():
|
|
197
193
|
self._log_message(msg, no_cache=True)
|
|
198
194
|
|
|
195
|
+
def log_message(self, msg, no_cache=False):
|
|
196
|
+
if self._log_message_parents and not self._library_import_logging:
|
|
197
|
+
self._log_message(msg, no_cache)
|
|
198
|
+
else:
|
|
199
|
+
self.message(msg)
|
|
200
|
+
|
|
199
201
|
def _log_message(self, msg, no_cache=False):
|
|
200
202
|
"""Log messages written (mainly) by libraries."""
|
|
201
203
|
if self._log_message_cache is not None and not no_cache:
|
|
@@ -204,21 +206,20 @@ class Logger(AbstractLogger):
|
|
|
204
206
|
return
|
|
205
207
|
for logger in self:
|
|
206
208
|
logger.log_message(msg)
|
|
209
|
+
if self._log_message_parents and self._output_file.is_logged(msg):
|
|
210
|
+
self._log_message_parents[-1].body.append(msg)
|
|
207
211
|
if msg.level in ('WARN', 'ERROR'):
|
|
208
212
|
self.message(msg)
|
|
209
213
|
|
|
210
|
-
log_message = message
|
|
211
|
-
|
|
212
214
|
def log_output(self, output):
|
|
213
215
|
for msg in StdoutLogSplitter(output):
|
|
214
216
|
self.log_message(msg)
|
|
215
217
|
|
|
216
218
|
def enable_library_import_logging(self):
|
|
217
|
-
self.
|
|
218
|
-
self.log_message = self.message
|
|
219
|
+
self._library_import_logging += 1
|
|
219
220
|
|
|
220
221
|
def disable_library_import_logging(self):
|
|
221
|
-
self.
|
|
222
|
+
self._library_import_logging -= 1
|
|
222
223
|
|
|
223
224
|
def start_suite(self, data, result):
|
|
224
225
|
for logger in self.start_loggers:
|
|
@@ -229,12 +230,14 @@ class Logger(AbstractLogger):
|
|
|
229
230
|
logger.end_suite(data, result)
|
|
230
231
|
|
|
231
232
|
def start_test(self, data, result):
|
|
233
|
+
self._log_message_parents.append(result)
|
|
232
234
|
for logger in self.start_loggers:
|
|
233
235
|
logger.start_test(data, result)
|
|
234
236
|
|
|
235
237
|
def end_test(self, data, result):
|
|
236
238
|
for logger in self.end_loggers:
|
|
237
239
|
logger.end_test(data, result)
|
|
240
|
+
self._log_message_parents.pop()
|
|
238
241
|
|
|
239
242
|
@start_body_item
|
|
240
243
|
def start_keyword(self, data, result):
|
|
@@ -316,6 +319,16 @@ class Logger(AbstractLogger):
|
|
|
316
319
|
for logger in self.end_loggers:
|
|
317
320
|
logger.end_while_iteration(data, result)
|
|
318
321
|
|
|
322
|
+
@start_body_item
|
|
323
|
+
def start_group(self, data, result):
|
|
324
|
+
for logger in self.start_loggers:
|
|
325
|
+
logger.start_group(data, result)
|
|
326
|
+
|
|
327
|
+
@end_body_item
|
|
328
|
+
def end_group(self, data, result):
|
|
329
|
+
for logger in self.end_loggers:
|
|
330
|
+
logger.end_group(data, result)
|
|
331
|
+
|
|
319
332
|
@start_body_item
|
|
320
333
|
def start_if(self, data, result):
|
|
321
334
|
for logger in self.start_loggers:
|
|
@@ -98,6 +98,12 @@ class LoggerApi:
|
|
|
98
98
|
result: 'result.WhileIteration'):
|
|
99
99
|
self.end_body_item(data, result)
|
|
100
100
|
|
|
101
|
+
def start_group(self, data: 'running.Group', result: 'result.Group'):
|
|
102
|
+
self.start_body_item(data, result)
|
|
103
|
+
|
|
104
|
+
def end_group(self, data: 'running.Group', result: 'result.Group'):
|
|
105
|
+
self.end_body_item(data, result)
|
|
106
|
+
|
|
101
107
|
def start_if(self, data: 'running.If', result: 'result.If'):
|
|
102
108
|
self.start_body_item(data, result)
|
|
103
109
|
|
|
@@ -18,20 +18,13 @@ from datetime import datetime
|
|
|
18
18
|
from typing import Callable, Literal
|
|
19
19
|
|
|
20
20
|
from robot.errors import DataError
|
|
21
|
-
from robot.model import
|
|
22
|
-
from robot.
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
'FAIL' : 5,
|
|
29
|
-
'ERROR' : 4,
|
|
30
|
-
'WARN' : 3,
|
|
31
|
-
'INFO' : 2,
|
|
32
|
-
'DEBUG' : 1,
|
|
33
|
-
'TRACE' : 0,
|
|
34
|
-
}
|
|
21
|
+
from robot.model import MessageLevel
|
|
22
|
+
from robot.result import Message as BaseMessage
|
|
23
|
+
from robot.utils import console_encode
|
|
24
|
+
|
|
25
|
+
from .loglevel import LEVELS
|
|
26
|
+
|
|
27
|
+
|
|
35
28
|
PseudoLevel = Literal['HTML', 'CONSOLE']
|
|
36
29
|
|
|
37
30
|
|
|
@@ -47,12 +40,6 @@ def write_to_console(msg, newline=True, stream='stdout'):
|
|
|
47
40
|
|
|
48
41
|
class AbstractLogger:
|
|
49
42
|
|
|
50
|
-
def __init__(self, level='TRACE'):
|
|
51
|
-
self._is_logged = IsLogged(level)
|
|
52
|
-
|
|
53
|
-
def set_level(self, level):
|
|
54
|
-
return self._is_logged.set_level(level)
|
|
55
|
-
|
|
56
43
|
def trace(self, msg):
|
|
57
44
|
self.write(msg, 'TRACE')
|
|
58
45
|
|
|
@@ -90,9 +77,22 @@ class AbstractLogger:
|
|
|
90
77
|
|
|
91
78
|
|
|
92
79
|
class Message(BaseMessage):
|
|
80
|
+
"""Represents message logged during execution.
|
|
81
|
+
|
|
82
|
+
Most messages are logged by libraries. They typically log strings, but
|
|
83
|
+
possible non-string items have been converted to strings already before
|
|
84
|
+
they end up here.
|
|
85
|
+
|
|
86
|
+
In addition to strings, Robot Framework itself logs also callables to make
|
|
87
|
+
constructing messages that are not typically needed lazy. Such messages are
|
|
88
|
+
resolved when they are accessed.
|
|
89
|
+
|
|
90
|
+
Listeners can remove messages by setting the `message` attribute to `None`.
|
|
91
|
+
These messages are not written to the output.xml at all.
|
|
92
|
+
"""
|
|
93
93
|
__slots__ = ['_message']
|
|
94
94
|
|
|
95
|
-
def __init__(self, message: 'str|Callable[[], str]',
|
|
95
|
+
def __init__(self, message: 'str|None|Callable[[], str|None]' = '',
|
|
96
96
|
level: 'MessageLevel|PseudoLevel' = 'INFO',
|
|
97
97
|
html: bool = False,
|
|
98
98
|
timestamp: 'datetime|str|None' = None):
|
|
@@ -110,45 +110,16 @@ class Message(BaseMessage):
|
|
|
110
110
|
raise DataError(f"Invalid log level '{level}'.")
|
|
111
111
|
|
|
112
112
|
@property
|
|
113
|
-
def message(self) -> str:
|
|
113
|
+
def message(self) -> 'str|None':
|
|
114
114
|
self.resolve_delayed_message()
|
|
115
115
|
return self._message
|
|
116
116
|
|
|
117
117
|
@message.setter
|
|
118
|
-
def message(self, message: 'str|Callable[[], str]'):
|
|
119
|
-
if
|
|
120
|
-
|
|
121
|
-
message = safe_str(message)
|
|
122
|
-
if '\r\n' in message:
|
|
123
|
-
message = message.replace('\r\n', '\n')
|
|
118
|
+
def message(self, message: 'str|None|Callable[[], str|None]'):
|
|
119
|
+
if isinstance(message, str) and '\r\n' in message:
|
|
120
|
+
message = message.replace('\r\n', '\n')
|
|
124
121
|
self._message = message
|
|
125
122
|
|
|
126
123
|
def resolve_delayed_message(self):
|
|
127
124
|
if callable(self._message):
|
|
128
|
-
self.
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
class IsLogged:
|
|
132
|
-
|
|
133
|
-
def __init__(self, level):
|
|
134
|
-
self.level = level.upper()
|
|
135
|
-
self._int_level = self._level_to_int(level)
|
|
136
|
-
|
|
137
|
-
def __call__(self, level):
|
|
138
|
-
return self._level_to_int(level) >= self._int_level
|
|
139
|
-
|
|
140
|
-
def set_level(self, level):
|
|
141
|
-
old = self.level
|
|
142
|
-
self.__init__(level)
|
|
143
|
-
return old
|
|
144
|
-
|
|
145
|
-
@classmethod
|
|
146
|
-
def validate_level(cls, level):
|
|
147
|
-
cls._level_to_int(level)
|
|
148
|
-
|
|
149
|
-
@classmethod
|
|
150
|
-
def _level_to_int(cls, level):
|
|
151
|
-
try:
|
|
152
|
-
return LEVELS[level.upper()]
|
|
153
|
-
except KeyError:
|
|
154
|
-
raise DataError("Invalid log level '%s'." % level)
|
|
125
|
+
self.message = self._message()
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Copyright 2008-2015 Nokia Networks
|
|
2
|
+
# Copyright 2016- Robot Framework Foundation
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
from typing import TYPE_CHECKING
|
|
17
|
+
|
|
18
|
+
from robot.errors import DataError
|
|
19
|
+
|
|
20
|
+
if TYPE_CHECKING:
|
|
21
|
+
from .loggerhelper import Message
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
LEVELS = {
|
|
25
|
+
'NONE' : 7,
|
|
26
|
+
'SKIP' : 6,
|
|
27
|
+
'FAIL' : 5,
|
|
28
|
+
'ERROR' : 4,
|
|
29
|
+
'WARN' : 3,
|
|
30
|
+
'INFO' : 2,
|
|
31
|
+
'DEBUG' : 1,
|
|
32
|
+
'TRACE' : 0,
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class LogLevel:
|
|
37
|
+
|
|
38
|
+
def __init__(self, level):
|
|
39
|
+
self.priority = self._get_priority(level)
|
|
40
|
+
self.level = level.upper()
|
|
41
|
+
|
|
42
|
+
def is_logged(self, msg: 'Message'):
|
|
43
|
+
return LEVELS[msg.level] >= self.priority and msg.message is not None
|
|
44
|
+
|
|
45
|
+
def set(self, level):
|
|
46
|
+
old = self.level
|
|
47
|
+
self.__init__(level)
|
|
48
|
+
return old
|
|
49
|
+
|
|
50
|
+
def _get_priority(self, level):
|
|
51
|
+
try:
|
|
52
|
+
return LEVELS[level.upper()]
|
|
53
|
+
except KeyError:
|
|
54
|
+
raise DataError(f"Invalid log level '{level}'.")
|
|
@@ -18,19 +18,19 @@ from .debugfile import DebugFile
|
|
|
18
18
|
from .listeners import Listeners, LibraryListeners
|
|
19
19
|
from .logger import LOGGER
|
|
20
20
|
from .loggerapi import LoggerApi
|
|
21
|
-
from .loggerhelper import AbstractLogger
|
|
22
|
-
from .
|
|
21
|
+
from .loggerhelper import AbstractLogger
|
|
22
|
+
from .loglevel import LogLevel
|
|
23
|
+
from .outputfile import OutputFile
|
|
23
24
|
|
|
24
25
|
|
|
25
26
|
class Output(AbstractLogger, LoggerApi):
|
|
26
27
|
|
|
27
28
|
def __init__(self, settings):
|
|
28
|
-
|
|
29
|
-
self.
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
self.
|
|
33
|
-
self.library_listeners = LibraryListeners(settings.log_level)
|
|
29
|
+
self.log_level = LogLevel(settings.log_level)
|
|
30
|
+
self.output_file = OutputFile(settings.output, self.log_level, settings.rpa,
|
|
31
|
+
legacy_output=settings.legacy_output)
|
|
32
|
+
self.listeners = Listeners(settings.listeners, self.log_level)
|
|
33
|
+
self.library_listeners = LibraryListeners(self.log_level)
|
|
34
34
|
self._register_loggers(DebugFile(settings.debug_file))
|
|
35
35
|
self._settings = settings
|
|
36
36
|
|
|
@@ -39,7 +39,7 @@ class Output(AbstractLogger, LoggerApi):
|
|
|
39
39
|
return self._settings.log_level
|
|
40
40
|
|
|
41
41
|
def _register_loggers(self, debug_file):
|
|
42
|
-
LOGGER.
|
|
42
|
+
LOGGER.register_output_file(self.output_file)
|
|
43
43
|
LOGGER.register_listeners(self.listeners or None, self.library_listeners)
|
|
44
44
|
if debug_file:
|
|
45
45
|
LOGGER.register_logger(debug_file)
|
|
@@ -52,9 +52,9 @@ class Output(AbstractLogger, LoggerApi):
|
|
|
52
52
|
return LOGGER.delayed_logging
|
|
53
53
|
|
|
54
54
|
def close(self, result):
|
|
55
|
-
self.
|
|
56
|
-
self.
|
|
57
|
-
LOGGER.
|
|
55
|
+
self.output_file.statistics(result.statistics)
|
|
56
|
+
self.output_file.close()
|
|
57
|
+
LOGGER.unregister_output_file()
|
|
58
58
|
LOGGER.output_file(self._settings['Output'])
|
|
59
59
|
|
|
60
60
|
def start_suite(self, data, result):
|
|
@@ -117,6 +117,12 @@ class Output(AbstractLogger, LoggerApi):
|
|
|
117
117
|
def end_while_iteration(self, data, result):
|
|
118
118
|
LOGGER.end_while_iteration(data, result)
|
|
119
119
|
|
|
120
|
+
def start_group(self, data, result):
|
|
121
|
+
LOGGER.start_group(data, result)
|
|
122
|
+
|
|
123
|
+
def end_group(self, data, result):
|
|
124
|
+
LOGGER.end_group(data, result)
|
|
125
|
+
|
|
120
126
|
def start_if(self, data, result):
|
|
121
127
|
LOGGER.start_if(data, result)
|
|
122
128
|
|
|
@@ -175,12 +181,10 @@ class Output(AbstractLogger, LoggerApi):
|
|
|
175
181
|
LOGGER.log_message(msg)
|
|
176
182
|
|
|
177
183
|
def trace(self, msg, write_if_flat=True):
|
|
178
|
-
if write_if_flat or not self.
|
|
184
|
+
if write_if_flat or not self.output_file.flatten_level:
|
|
179
185
|
self.write(msg, 'TRACE')
|
|
180
186
|
|
|
181
187
|
def set_log_level(self, level):
|
|
182
|
-
|
|
188
|
+
old = self.log_level.set(level)
|
|
183
189
|
pyloggingconf.set_level(level)
|
|
184
|
-
|
|
185
|
-
self.library_listeners.set_log_level(level)
|
|
186
|
-
return self._xml_logger.set_log_level(level)
|
|
190
|
+
return old
|