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
|
@@ -36,7 +36,7 @@ from robot.utils import (DotDict, escape, format_assign_message, get_error_messa
|
|
|
36
36
|
from robot.utils.asserts import assert_equal, assert_not_equal
|
|
37
37
|
from robot.variables import (evaluate_expression, is_dict_variable,
|
|
38
38
|
is_list_variable, search_variable,
|
|
39
|
-
|
|
39
|
+
DictVariableResolver, VariableResolver)
|
|
40
40
|
from robot.version import get_version
|
|
41
41
|
|
|
42
42
|
|
|
@@ -153,8 +153,8 @@ class _Converter(_BuiltInBase):
|
|
|
153
153
|
return int(item, self._convert_to_integer(base))
|
|
154
154
|
return int(item)
|
|
155
155
|
except:
|
|
156
|
-
raise RuntimeError("'
|
|
157
|
-
|
|
156
|
+
raise RuntimeError(f"'{orig}' cannot be converted to an integer: "
|
|
157
|
+
f"{get_error_message()}")
|
|
158
158
|
|
|
159
159
|
def _get_base(self, item, base):
|
|
160
160
|
if not is_string(item):
|
|
@@ -300,8 +300,8 @@ class _Converter(_BuiltInBase):
|
|
|
300
300
|
try:
|
|
301
301
|
return float(self._convert_to_integer(item))
|
|
302
302
|
except RuntimeError:
|
|
303
|
-
raise RuntimeError("'
|
|
304
|
-
"point number:
|
|
303
|
+
raise RuntimeError(f"'{item}' cannot be converted to a floating "
|
|
304
|
+
f"point number: {error}")
|
|
305
305
|
|
|
306
306
|
def convert_to_string(self, item):
|
|
307
307
|
"""Converts the given item to a Unicode string.
|
|
@@ -380,12 +380,12 @@ class _Converter(_BuiltInBase):
|
|
|
380
380
|
"""
|
|
381
381
|
try:
|
|
382
382
|
try:
|
|
383
|
-
ordinals = getattr(self, '_get_ordinals_from_
|
|
383
|
+
ordinals = getattr(self, f'_get_ordinals_from_{input_type}')
|
|
384
384
|
except AttributeError:
|
|
385
|
-
raise RuntimeError("Invalid input type '
|
|
385
|
+
raise RuntimeError(f"Invalid input type '{input_type}'.")
|
|
386
386
|
return bytes(bytearray(o for o in ordinals(input)))
|
|
387
387
|
except:
|
|
388
|
-
raise RuntimeError("Creating bytes failed:
|
|
388
|
+
raise RuntimeError("Creating bytes failed: " + get_error_message())
|
|
389
389
|
|
|
390
390
|
def _get_ordinals_from_text(self, input):
|
|
391
391
|
for char in input:
|
|
@@ -395,8 +395,7 @@ class _Converter(_BuiltInBase):
|
|
|
395
395
|
def _test_ordinal(self, ordinal, original, type):
|
|
396
396
|
if 0 <= ordinal <= 255:
|
|
397
397
|
return ordinal
|
|
398
|
-
raise RuntimeError("
|
|
399
|
-
% (type, original))
|
|
398
|
+
raise RuntimeError(f"{type} '{original}' cannot be represented as a byte.")
|
|
400
399
|
|
|
401
400
|
def _get_ordinals_from_int(self, input):
|
|
402
401
|
if is_string(input):
|
|
@@ -422,7 +421,7 @@ class _Converter(_BuiltInBase):
|
|
|
422
421
|
return input
|
|
423
422
|
input = ''.join(input.split())
|
|
424
423
|
if len(input) % length != 0:
|
|
425
|
-
raise RuntimeError('Expected input to be multiple of
|
|
424
|
+
raise RuntimeError(f'Expected input to be multiple of {length}.')
|
|
426
425
|
return (input[i:i+length] for i in range(0, len(input), length))
|
|
427
426
|
|
|
428
427
|
def create_list(self, *items):
|
|
@@ -472,7 +471,7 @@ class _Converter(_BuiltInBase):
|
|
|
472
471
|
"""
|
|
473
472
|
separate, combined = self._split_dict_items(items)
|
|
474
473
|
result = DotDict(self._format_separate_dict_items(separate))
|
|
475
|
-
combined =
|
|
474
|
+
combined = DictVariableResolver(combined).resolve(self._variables)
|
|
476
475
|
result.update(combined)
|
|
477
476
|
return result
|
|
478
477
|
|
|
@@ -488,8 +487,8 @@ class _Converter(_BuiltInBase):
|
|
|
488
487
|
def _format_separate_dict_items(self, separate):
|
|
489
488
|
separate = self._variables.replace_list(separate)
|
|
490
489
|
if len(separate) % 2 != 0:
|
|
491
|
-
raise DataError('Expected even number of keys and values,
|
|
492
|
-
|
|
490
|
+
raise DataError(f'Expected even number of keys and values, '
|
|
491
|
+
f'got {len(separate)}.')
|
|
493
492
|
return [separate[i:i+2] for i in range(0, len(separate), 2)]
|
|
494
493
|
|
|
495
494
|
|
|
@@ -549,7 +548,7 @@ class _Verify(_BuiltInBase):
|
|
|
549
548
|
and how ``msg`` can be used to override the default error message.
|
|
550
549
|
"""
|
|
551
550
|
if self._is_true(condition):
|
|
552
|
-
raise AssertionError(msg or "'
|
|
551
|
+
raise AssertionError(msg or f"'{condition}' should not be true.")
|
|
553
552
|
|
|
554
553
|
def should_be_true(self, condition, msg=None):
|
|
555
554
|
"""Fails if the given condition is not true.
|
|
@@ -580,7 +579,7 @@ class _Verify(_BuiltInBase):
|
|
|
580
579
|
| Should Be True | $status == 'PASS' | # Expected string must be quoted |
|
|
581
580
|
"""
|
|
582
581
|
if not self._is_true(condition):
|
|
583
|
-
raise AssertionError(msg or "'
|
|
582
|
+
raise AssertionError(msg or f"'{condition}' should be true.")
|
|
584
583
|
|
|
585
584
|
def should_be_equal(self, first, second, msg=None, values=True,
|
|
586
585
|
ignore_case=False, formatter='str', strip_spaces=False,
|
|
@@ -627,8 +626,8 @@ class _Verify(_BuiltInBase):
|
|
|
627
626
|
self._log_types_at_info_if_different(first, second)
|
|
628
627
|
if is_string(first) and is_string(second):
|
|
629
628
|
if ignore_case:
|
|
630
|
-
first = first.
|
|
631
|
-
second = second.
|
|
629
|
+
first = first.casefold()
|
|
630
|
+
second = second.casefold()
|
|
632
631
|
if strip_spaces:
|
|
633
632
|
first = self._strip_spaces(first, strip_spaces)
|
|
634
633
|
second = self._strip_spaces(second, strip_spaces)
|
|
@@ -655,14 +654,14 @@ class _Verify(_BuiltInBase):
|
|
|
655
654
|
second_lines = second.splitlines(True)
|
|
656
655
|
if len(first_lines) < 3 or len(second_lines) < 3:
|
|
657
656
|
return
|
|
658
|
-
self.log("
|
|
657
|
+
self.log(f"{first.rstrip()}\n\n!=\n\n{second.rstrip()}")
|
|
659
658
|
diffs = list(difflib.unified_diff(first_lines, second_lines,
|
|
660
659
|
fromfile='first', tofile='second',
|
|
661
660
|
lineterm=''))
|
|
662
661
|
diffs[3:] = [item[0] + formatter(item[1:]).rstrip() for item in diffs[3:]]
|
|
663
662
|
prefix = 'Multiline strings are different:'
|
|
664
663
|
if msg:
|
|
665
|
-
prefix = '
|
|
664
|
+
prefix = f'{msg}: {prefix}'
|
|
666
665
|
raise AssertionError('\n'.join([prefix] + diffs))
|
|
667
666
|
|
|
668
667
|
def _include_values(self, values):
|
|
@@ -709,8 +708,8 @@ class _Verify(_BuiltInBase):
|
|
|
709
708
|
self._log_types_at_info_if_different(first, second)
|
|
710
709
|
if is_string(first) and is_string(second):
|
|
711
710
|
if ignore_case:
|
|
712
|
-
first = first.
|
|
713
|
-
second = second.
|
|
711
|
+
first = first.casefold()
|
|
712
|
+
second = second.casefold()
|
|
714
713
|
if strip_spaces:
|
|
715
714
|
first = self._strip_spaces(first, strip_spaces)
|
|
716
715
|
second = self._strip_spaces(second, strip_spaces)
|
|
@@ -845,8 +844,8 @@ class _Verify(_BuiltInBase):
|
|
|
845
844
|
first = safe_str(first)
|
|
846
845
|
second = safe_str(second)
|
|
847
846
|
if ignore_case:
|
|
848
|
-
first = first.
|
|
849
|
-
second = second.
|
|
847
|
+
first = first.casefold()
|
|
848
|
+
second = second.casefold()
|
|
850
849
|
if strip_spaces:
|
|
851
850
|
first = self._strip_spaces(first, strip_spaces)
|
|
852
851
|
second = self._strip_spaces(second, strip_spaces)
|
|
@@ -886,8 +885,8 @@ class _Verify(_BuiltInBase):
|
|
|
886
885
|
first = safe_str(first)
|
|
887
886
|
second = safe_str(second)
|
|
888
887
|
if ignore_case:
|
|
889
|
-
first = first.
|
|
890
|
-
second = second.
|
|
888
|
+
first = first.casefold()
|
|
889
|
+
second = second.casefold()
|
|
891
890
|
if strip_spaces:
|
|
892
891
|
first = self._strip_spaces(first, strip_spaces)
|
|
893
892
|
second = self._strip_spaces(second, strip_spaces)
|
|
@@ -906,8 +905,8 @@ class _Verify(_BuiltInBase):
|
|
|
906
905
|
of the ``ignore_case``, ``strip_spaces``, and ``collapse_spaces`` options.
|
|
907
906
|
"""
|
|
908
907
|
if ignore_case:
|
|
909
|
-
str1 = str1.
|
|
910
|
-
str2 = str2.
|
|
908
|
+
str1 = str1.casefold()
|
|
909
|
+
str2 = str2.casefold()
|
|
911
910
|
if strip_spaces:
|
|
912
911
|
str1 = self._strip_spaces(str1, strip_spaces)
|
|
913
912
|
str2 = self._strip_spaces(str2, strip_spaces)
|
|
@@ -927,8 +926,8 @@ class _Verify(_BuiltInBase):
|
|
|
927
926
|
of the ``ignore_case``, ``strip_spaces``, and ``collapse_spaces`` options.
|
|
928
927
|
"""
|
|
929
928
|
if ignore_case:
|
|
930
|
-
str1 = str1.
|
|
931
|
-
str2 = str2.
|
|
929
|
+
str1 = str1.casefold()
|
|
930
|
+
str2 = str2.casefold()
|
|
932
931
|
if strip_spaces:
|
|
933
932
|
str1 = self._strip_spaces(str1, strip_spaces)
|
|
934
933
|
str2 = self._strip_spaces(str2, strip_spaces)
|
|
@@ -949,8 +948,8 @@ class _Verify(_BuiltInBase):
|
|
|
949
948
|
of the ``ignore_case``, ``strip_spaces``, and ``collapse_spaces`` options.
|
|
950
949
|
"""
|
|
951
950
|
if ignore_case:
|
|
952
|
-
str1 = str1.
|
|
953
|
-
str2 = str2.
|
|
951
|
+
str1 = str1.casefold()
|
|
952
|
+
str2 = str2.casefold()
|
|
954
953
|
if strip_spaces:
|
|
955
954
|
str1 = self._strip_spaces(str1, strip_spaces)
|
|
956
955
|
str2 = self._strip_spaces(str2, strip_spaces)
|
|
@@ -970,8 +969,8 @@ class _Verify(_BuiltInBase):
|
|
|
970
969
|
of the ``ignore_case``, ``strip_spaces``, and ``collapse_spaces`` options.
|
|
971
970
|
"""
|
|
972
971
|
if ignore_case:
|
|
973
|
-
str1 = str1.
|
|
974
|
-
str2 = str2.
|
|
972
|
+
str1 = str1.casefold()
|
|
973
|
+
str2 = str2.casefold()
|
|
975
974
|
if strip_spaces:
|
|
976
975
|
str1 = self._strip_spaces(str1, strip_spaces)
|
|
977
976
|
str2 = self._strip_spaces(str2, strip_spaces)
|
|
@@ -1018,11 +1017,11 @@ class _Verify(_BuiltInBase):
|
|
|
1018
1017
|
# case-insensitive comparisons.
|
|
1019
1018
|
orig_container = container
|
|
1020
1019
|
if ignore_case and is_string(item):
|
|
1021
|
-
item = item.
|
|
1020
|
+
item = item.casefold()
|
|
1022
1021
|
if is_string(container):
|
|
1023
|
-
container = container.
|
|
1022
|
+
container = container.casefold()
|
|
1024
1023
|
elif is_list_like(container):
|
|
1025
|
-
container = set(x.
|
|
1024
|
+
container = set(x.casefold() if is_string(x) else x for x in container)
|
|
1026
1025
|
if strip_spaces and is_string(item):
|
|
1027
1026
|
item = self._strip_spaces(item, strip_spaces)
|
|
1028
1027
|
if is_string(container):
|
|
@@ -1074,11 +1073,11 @@ class _Verify(_BuiltInBase):
|
|
|
1074
1073
|
"""
|
|
1075
1074
|
orig_container = container
|
|
1076
1075
|
if ignore_case and is_string(item):
|
|
1077
|
-
item = item.
|
|
1076
|
+
item = item.casefold()
|
|
1078
1077
|
if is_string(container):
|
|
1079
|
-
container = container.
|
|
1078
|
+
container = container.casefold()
|
|
1080
1079
|
elif is_list_like(container):
|
|
1081
|
-
container = set(x.
|
|
1080
|
+
container = set(x.casefold() if is_string(x) else x for x in container)
|
|
1082
1081
|
if strip_spaces and is_string(item):
|
|
1083
1082
|
item = self._strip_spaces(item, strip_spaces)
|
|
1084
1083
|
if is_string(container):
|
|
@@ -1123,17 +1122,17 @@ class _Verify(_BuiltInBase):
|
|
|
1123
1122
|
strip_spaces = configuration.pop('strip_spaces', False)
|
|
1124
1123
|
collapse_spaces = is_truthy(configuration.pop('collapse_spaces', False))
|
|
1125
1124
|
if configuration:
|
|
1126
|
-
raise RuntimeError("Unsupported configuration parameter
|
|
1127
|
-
|
|
1125
|
+
raise RuntimeError(f"Unsupported configuration parameter{s(configuration)}: "
|
|
1126
|
+
f"{seq2str(sorted(configuration))}.")
|
|
1128
1127
|
if not items:
|
|
1129
1128
|
raise RuntimeError('One or more items required.')
|
|
1130
1129
|
orig_container = container
|
|
1131
1130
|
if ignore_case:
|
|
1132
|
-
items = [x.
|
|
1131
|
+
items = [x.casefold() if is_string(x) else x for x in items]
|
|
1133
1132
|
if is_string(container):
|
|
1134
|
-
container = container.
|
|
1133
|
+
container = container.casefold()
|
|
1135
1134
|
elif is_list_like(container):
|
|
1136
|
-
container = set(x.
|
|
1135
|
+
container = set(x.casefold() if is_string(x) else x for x in container)
|
|
1137
1136
|
if strip_spaces:
|
|
1138
1137
|
items = [self._strip_spaces(x, strip_spaces) for x in items]
|
|
1139
1138
|
if is_string(container):
|
|
@@ -1181,17 +1180,17 @@ class _Verify(_BuiltInBase):
|
|
|
1181
1180
|
strip_spaces = configuration.pop('strip_spaces', False)
|
|
1182
1181
|
collapse_spaces = is_truthy(configuration.pop('collapse_spaces', False))
|
|
1183
1182
|
if configuration:
|
|
1184
|
-
raise RuntimeError("Unsupported configuration parameter
|
|
1185
|
-
|
|
1183
|
+
raise RuntimeError(f"Unsupported configuration parameter{s(configuration)}: "
|
|
1184
|
+
f"{seq2str(sorted(configuration))}.")
|
|
1186
1185
|
if not items:
|
|
1187
1186
|
raise RuntimeError('One or more items required.')
|
|
1188
1187
|
orig_container = container
|
|
1189
1188
|
if ignore_case:
|
|
1190
|
-
items = [x.
|
|
1189
|
+
items = [x.casefold() if is_string(x) else x for x in items]
|
|
1191
1190
|
if is_string(container):
|
|
1192
|
-
container = container.
|
|
1191
|
+
container = container.casefold()
|
|
1193
1192
|
elif is_list_like(container):
|
|
1194
|
-
container = set(x.
|
|
1193
|
+
container = set(x.casefold() if is_string(x) else x for x in container)
|
|
1195
1194
|
if strip_spaces:
|
|
1196
1195
|
items = [self._strip_spaces(x, strip_spaces) for x in items]
|
|
1197
1196
|
if is_string(container):
|
|
@@ -1247,11 +1246,11 @@ class _Verify(_BuiltInBase):
|
|
|
1247
1246
|
orig_container = container
|
|
1248
1247
|
if is_string(item):
|
|
1249
1248
|
if ignore_case:
|
|
1250
|
-
item = item.
|
|
1249
|
+
item = item.casefold()
|
|
1251
1250
|
if is_string(container):
|
|
1252
|
-
container = container.
|
|
1251
|
+
container = container.casefold()
|
|
1253
1252
|
elif is_list_like(container):
|
|
1254
|
-
container = [x.
|
|
1253
|
+
container = [x.casefold() if is_string(x) else x for x in container]
|
|
1255
1254
|
if strip_spaces:
|
|
1256
1255
|
item = self._strip_spaces(item, strip_spaces)
|
|
1257
1256
|
if is_string(container):
|
|
@@ -1266,8 +1265,8 @@ class _Verify(_BuiltInBase):
|
|
|
1266
1265
|
container = [self._collapse_spaces(x) for x in container]
|
|
1267
1266
|
x = self.get_count(container, item)
|
|
1268
1267
|
if not msg:
|
|
1269
|
-
msg = "
|
|
1270
|
-
|
|
1268
|
+
msg = (f"{orig_container!r} contains '{item}' {x} time{s(x)}, "
|
|
1269
|
+
f"not {count} time{s(count)}.")
|
|
1271
1270
|
self.should_be_equal_as_integers(x, count, msg, values=False)
|
|
1272
1271
|
|
|
1273
1272
|
def get_count(self, container, item):
|
|
@@ -1284,10 +1283,10 @@ class _Verify(_BuiltInBase):
|
|
|
1284
1283
|
try:
|
|
1285
1284
|
container = list(container)
|
|
1286
1285
|
except:
|
|
1287
|
-
raise RuntimeError("Converting '
|
|
1288
|
-
|
|
1286
|
+
raise RuntimeError(f"Converting '{container}' to list failed: "
|
|
1287
|
+
f"{get_error_message()}")
|
|
1289
1288
|
count = container.count(item)
|
|
1290
|
-
self.log('Item found from container
|
|
1289
|
+
self.log(f'Item found from container {count} time{s(count)}.')
|
|
1291
1290
|
return count
|
|
1292
1291
|
|
|
1293
1292
|
def should_not_match(self, string, pattern, msg=None, values=True,
|
|
@@ -1407,7 +1406,7 @@ class _Verify(_BuiltInBase):
|
|
|
1407
1406
|
Empty`.
|
|
1408
1407
|
"""
|
|
1409
1408
|
length = self._get_length(item)
|
|
1410
|
-
self.log('Length is
|
|
1409
|
+
self.log(f'Length is {length}.')
|
|
1411
1410
|
return length
|
|
1412
1411
|
|
|
1413
1412
|
def _get_length(self, item):
|
|
@@ -1431,7 +1430,7 @@ class _Verify(_BuiltInBase):
|
|
|
1431
1430
|
except RERAISED_EXCEPTIONS:
|
|
1432
1431
|
raise
|
|
1433
1432
|
except:
|
|
1434
|
-
raise RuntimeError("Could not get length of '
|
|
1433
|
+
raise RuntimeError(f"Could not get length of '{item}'.")
|
|
1435
1434
|
|
|
1436
1435
|
def length_should_be(self, item, length, msg=None):
|
|
1437
1436
|
"""Verifies that the length of the given item is correct.
|
|
@@ -1442,8 +1441,8 @@ class _Verify(_BuiltInBase):
|
|
|
1442
1441
|
length = self._convert_to_integer(length)
|
|
1443
1442
|
actual = self.get_length(item)
|
|
1444
1443
|
if actual != length:
|
|
1445
|
-
raise AssertionError(msg or "Length of '
|
|
1446
|
-
|
|
1444
|
+
raise AssertionError(msg or f"Length of '{item}' should be {length} "
|
|
1445
|
+
f"but is {actual}.")
|
|
1447
1446
|
|
|
1448
1447
|
def should_be_empty(self, item, msg=None):
|
|
1449
1448
|
"""Verifies that the given item is empty.
|
|
@@ -1452,7 +1451,7 @@ class _Verify(_BuiltInBase):
|
|
|
1452
1451
|
default error message can be overridden with the ``msg`` argument.
|
|
1453
1452
|
"""
|
|
1454
1453
|
if self.get_length(item) > 0:
|
|
1455
|
-
raise AssertionError(msg or "'
|
|
1454
|
+
raise AssertionError(msg or f"'{item}' should be empty.")
|
|
1456
1455
|
|
|
1457
1456
|
def should_not_be_empty(self, item, msg=None):
|
|
1458
1457
|
"""Verifies that the given item is not empty.
|
|
@@ -1461,18 +1460,18 @@ class _Verify(_BuiltInBase):
|
|
|
1461
1460
|
default error message can be overridden with the ``msg`` argument.
|
|
1462
1461
|
"""
|
|
1463
1462
|
if self.get_length(item) == 0:
|
|
1464
|
-
raise AssertionError(msg or "'
|
|
1463
|
+
raise AssertionError(msg or f"'{item}' should not be empty.")
|
|
1465
1464
|
|
|
1466
1465
|
def _get_string_msg(self, item1, item2, custom_message, include_values,
|
|
1467
1466
|
delimiter, quote_item1=True, quote_item2=True):
|
|
1468
1467
|
if custom_message and not self._include_values(include_values):
|
|
1469
1468
|
return custom_message
|
|
1470
|
-
item1 = "'
|
|
1471
|
-
item2 = "'
|
|
1472
|
-
default_message = '
|
|
1469
|
+
item1 = f"'{safe_str(item1)}'" if quote_item1 else safe_str(item1)
|
|
1470
|
+
item2 = f"'{safe_str(item2)}'" if quote_item2 else safe_str(item2)
|
|
1471
|
+
default_message = f'{item1} {delimiter} {item2}'
|
|
1473
1472
|
if not custom_message:
|
|
1474
1473
|
return default_message
|
|
1475
|
-
return '
|
|
1474
|
+
return f'{custom_message}: {default_message}'
|
|
1476
1475
|
|
|
1477
1476
|
|
|
1478
1477
|
class _Variables(_BuiltInBase):
|
|
@@ -1533,7 +1532,7 @@ class _Variables(_BuiltInBase):
|
|
|
1533
1532
|
def log_variables(self, level='INFO'):
|
|
1534
1533
|
"""Logs all variables in the current scope with given log level."""
|
|
1535
1534
|
variables = self.get_variables()
|
|
1536
|
-
for name in sorted(variables, key=lambda s: s[2:-1].
|
|
1535
|
+
for name in sorted(variables, key=lambda s: s[2:-1].casefold()):
|
|
1537
1536
|
name, value = self._get_logged_variable(name, variables)
|
|
1538
1537
|
msg = format_assign_message(name, value, cut_long=False)
|
|
1539
1538
|
self.log(msg, level)
|
|
@@ -1569,7 +1568,7 @@ class _Variables(_BuiltInBase):
|
|
|
1569
1568
|
self._variables.replace_scalar(name)
|
|
1570
1569
|
except VariableError:
|
|
1571
1570
|
raise AssertionError(self._variables.replace_string(msg)
|
|
1572
|
-
if msg else "Variable '
|
|
1571
|
+
if msg else f"Variable '{name}' does not exist.")
|
|
1573
1572
|
|
|
1574
1573
|
@run_keyword_variant(resolve=0)
|
|
1575
1574
|
def variable_should_not_exist(self, name, msg=None):
|
|
@@ -1591,14 +1590,14 @@ class _Variables(_BuiltInBase):
|
|
|
1591
1590
|
pass
|
|
1592
1591
|
else:
|
|
1593
1592
|
raise AssertionError(self._variables.replace_string(msg)
|
|
1594
|
-
if msg else "Variable '
|
|
1593
|
+
if msg else f"Variable '{name}' exists.")
|
|
1595
1594
|
|
|
1596
1595
|
def replace_variables(self, text):
|
|
1597
1596
|
"""Replaces variables in the given text with their current values.
|
|
1598
1597
|
|
|
1599
1598
|
If the text contains undefined variables, this keyword fails.
|
|
1600
1599
|
If the given ``text`` contains only a single variable, its value is
|
|
1601
|
-
returned as-is and it can be any object. Otherwise this keyword
|
|
1600
|
+
returned as-is and it can be any object. Otherwise, this keyword
|
|
1602
1601
|
always returns a string.
|
|
1603
1602
|
|
|
1604
1603
|
Example:
|
|
@@ -1621,16 +1620,23 @@ class _Variables(_BuiltInBase):
|
|
|
1621
1620
|
It is recommended to use `Create List` when creating new lists.
|
|
1622
1621
|
|
|
1623
1622
|
Examples:
|
|
1624
|
-
| ${hi} =
|
|
1625
|
-
| ${hi2} =
|
|
1626
|
-
| ${var1}
|
|
1627
|
-
| @{list} =
|
|
1628
|
-
| ${item1}
|
|
1623
|
+
| ${hi} = Set Variable Hello, world!
|
|
1624
|
+
| ${hi2} = Set Variable I said: ${hi}
|
|
1625
|
+
| ${var1} ${var2} = Set Variable Hello world
|
|
1626
|
+
| @{list} = Set Variable ${list with some items}
|
|
1627
|
+
| ${item1} ${item2} = Set Variable ${list with 2 items}
|
|
1629
1628
|
|
|
1630
1629
|
Variables created with this keyword are available only in the
|
|
1631
1630
|
scope where they are created. See `Set Global Variable`,
|
|
1632
1631
|
`Set Test Variable` and `Set Suite Variable` for information on how to
|
|
1633
1632
|
set variables so that they are available also in a larger scope.
|
|
1633
|
+
|
|
1634
|
+
*NOTE:* The ``VAR`` syntax introduced in Robot Framework 7.0 is generally
|
|
1635
|
+
recommended over this keyword. The basic usage is shown below and the Robot
|
|
1636
|
+
Framework User Guide explains the syntax in detail.
|
|
1637
|
+
|
|
1638
|
+
| VAR ${hi} Hello, world!
|
|
1639
|
+
| VAR ${hi2} I said: ${hi}
|
|
1634
1640
|
"""
|
|
1635
1641
|
if len(values) == 0:
|
|
1636
1642
|
return ''
|
|
@@ -1670,10 +1676,13 @@ class _Variables(_BuiltInBase):
|
|
|
1670
1676
|
``${name}``.
|
|
1671
1677
|
|
|
1672
1678
|
See also `Set Global Variable` and `Set Test Variable`.
|
|
1679
|
+
|
|
1680
|
+
*NOTE:* The ``VAR`` syntax introduced in Robot Framework 7.0 is recommended
|
|
1681
|
+
over this keyword.
|
|
1673
1682
|
"""
|
|
1674
1683
|
name = self._get_var_name(name)
|
|
1675
1684
|
value = self._get_var_value(name, values)
|
|
1676
|
-
self._variables.
|
|
1685
|
+
self._variables.set_local(name, value)
|
|
1677
1686
|
self._log_set_variable(name, value)
|
|
1678
1687
|
|
|
1679
1688
|
@run_keyword_variant(resolve=0)
|
|
@@ -1696,6 +1705,9 @@ class _Variables(_BuiltInBase):
|
|
|
1696
1705
|
|
|
1697
1706
|
When creating automated tasks, not tests, it is possible to use `Set
|
|
1698
1707
|
Task Variable`. See also `Set Global Variable` and `Set Local Variable`.
|
|
1708
|
+
|
|
1709
|
+
*NOTE:* The ``VAR`` syntax introduced in Robot Framework 7.0 is recommended
|
|
1710
|
+
over this keyword.
|
|
1699
1711
|
"""
|
|
1700
1712
|
name = self._get_var_name(name)
|
|
1701
1713
|
value = self._get_var_value(name, values)
|
|
@@ -1708,6 +1720,9 @@ class _Variables(_BuiltInBase):
|
|
|
1708
1720
|
|
|
1709
1721
|
This is an alias for `Set Test Variable` that is more applicable when
|
|
1710
1722
|
creating tasks, not tests.
|
|
1723
|
+
|
|
1724
|
+
*NOTE:* The ``VAR`` syntax introduced in Robot Framework 7.0 is recommended
|
|
1725
|
+
over this keyword.
|
|
1711
1726
|
"""
|
|
1712
1727
|
self.set_test_variable(name, *values)
|
|
1713
1728
|
|
|
@@ -1760,6 +1775,14 @@ class _Variables(_BuiltInBase):
|
|
|
1760
1775
|
| Set Suite Variable &DICT &{EMPTY}
|
|
1761
1776
|
|
|
1762
1777
|
See also `Set Global Variable`, `Set Test Variable` and `Set Local Variable`.
|
|
1778
|
+
|
|
1779
|
+
*NOTE:* The ``VAR`` syntax introduced in Robot Framework 7.0 is recommended
|
|
1780
|
+
over this keyword. The basic usage is shown below and the Robot Framework
|
|
1781
|
+
User Guide explains the syntax in detail.
|
|
1782
|
+
|
|
1783
|
+
| VAR ${SCALAR} Hello, world! scope=SUITE
|
|
1784
|
+
| VAR @{LIST} First item Second item scope=SUITE
|
|
1785
|
+
| VAR &{DICT} key=value foo=bar scope=SUITE
|
|
1763
1786
|
"""
|
|
1764
1787
|
name = self._get_var_name(name)
|
|
1765
1788
|
if values and is_string(values[-1]) and values[-1].startswith('children='):
|
|
@@ -1793,6 +1816,9 @@ class _Variables(_BuiltInBase):
|
|
|
1793
1816
|
section for information why it is recommended to give the variable name
|
|
1794
1817
|
in escaped format like ``$name`` or ``\${name}`` instead of the normal
|
|
1795
1818
|
``${name}``.
|
|
1819
|
+
|
|
1820
|
+
*NOTE:* The ``VAR`` syntax introduced in Robot Framework 7.0 is recommended
|
|
1821
|
+
over this keyword.
|
|
1796
1822
|
"""
|
|
1797
1823
|
name = self._get_var_name(name)
|
|
1798
1824
|
value = self._get_var_value(name, values)
|
|
@@ -1814,7 +1840,7 @@ class _Variables(_BuiltInBase):
|
|
|
1814
1840
|
match.resolve_base(self._variables)
|
|
1815
1841
|
valid = match.is_assign() if require_assign else match.is_variable()
|
|
1816
1842
|
if not valid:
|
|
1817
|
-
raise DataError("Invalid variable name '
|
|
1843
|
+
raise DataError(f"Invalid variable name '{name}'.")
|
|
1818
1844
|
return str(match)
|
|
1819
1845
|
|
|
1820
1846
|
def _resolve_var_name(self, name):
|
|
@@ -1823,7 +1849,7 @@ class _Variables(_BuiltInBase):
|
|
|
1823
1849
|
if len(name) < 2 or name[0] not in '$@&':
|
|
1824
1850
|
raise ValueError
|
|
1825
1851
|
if name[1] != '{':
|
|
1826
|
-
name = '
|
|
1852
|
+
name = f'{name[0]}{{{name[1:]}}}'
|
|
1827
1853
|
match = search_variable(name, identifiers='$@&', ignore_errors=True)
|
|
1828
1854
|
match.resolve_base(self._variables)
|
|
1829
1855
|
if not match.is_assign():
|
|
@@ -1839,11 +1865,12 @@ class _Variables(_BuiltInBase):
|
|
|
1839
1865
|
# handling non-string values somehow. For details see
|
|
1840
1866
|
# https://github.com/robotframework/robotframework/issues/1919
|
|
1841
1867
|
if len(values) != 1 or is_list_variable(values[0]):
|
|
1842
|
-
raise DataError("Setting list value to scalar variable '
|
|
1843
|
-
"is not supported anymore. Create list "
|
|
1844
|
-
"
|
|
1868
|
+
raise DataError(f"Setting list value to scalar variable '{name}' "
|
|
1869
|
+
f"is not supported anymore. Create list variable "
|
|
1870
|
+
f"'@{name[1:]}' instead.")
|
|
1845
1871
|
return self._variables.replace_scalar(values[0])
|
|
1846
|
-
|
|
1872
|
+
resolver = VariableResolver.from_name_and_value(name, values)
|
|
1873
|
+
return resolver.resolve(self._variables)
|
|
1847
1874
|
|
|
1848
1875
|
def _log_set_variable(self, name, value):
|
|
1849
1876
|
self.log(format_assign_message(name, value))
|
|
@@ -1870,14 +1897,14 @@ class _RunKeyword(_BuiltInBase):
|
|
|
1870
1897
|
ctx = self._context
|
|
1871
1898
|
if not (ctx.dry_run or self._accepts_embedded_arguments(name, ctx)):
|
|
1872
1899
|
name, args = self._replace_variables_in_name([name] + list(args))
|
|
1873
|
-
parent = ctx.steps[-1] if ctx.steps else (ctx.test or ctx.suite)
|
|
1900
|
+
parent = ctx.steps[-1][0] if ctx.steps else (ctx.test or ctx.suite)
|
|
1874
1901
|
kw = Keyword(name, args=args, parent=parent,
|
|
1875
1902
|
lineno=getattr(parent, 'lineno', None))
|
|
1876
1903
|
return kw.run(ctx)
|
|
1877
1904
|
|
|
1878
1905
|
def _accepts_embedded_arguments(self, name, ctx):
|
|
1879
1906
|
if '{' in name:
|
|
1880
|
-
runner = ctx.get_runner(name)
|
|
1907
|
+
runner = ctx.get_runner(name, recommend_on_failure=False)
|
|
1881
1908
|
return runner and hasattr(runner, 'embedded_args')
|
|
1882
1909
|
return False
|
|
1883
1910
|
|
|
@@ -2048,7 +2075,7 @@ class _RunKeyword(_BuiltInBase):
|
|
|
2048
2075
|
index = list(args).index(control_word)
|
|
2049
2076
|
branch = self._variables.replace_list(args[index+1:], required)
|
|
2050
2077
|
if len(branch) < required:
|
|
2051
|
-
raise DataError('
|
|
2078
|
+
raise DataError(f'{control_word} requires {required_error}.')
|
|
2052
2079
|
return args[:index], branch
|
|
2053
2080
|
|
|
2054
2081
|
@run_keyword_variant(resolve=1, dry_run=True)
|
|
@@ -2105,7 +2132,7 @@ class _RunKeyword(_BuiltInBase):
|
|
|
2105
2132
|
"""
|
|
2106
2133
|
status, message = self.run_keyword_and_ignore_error(name, *args)
|
|
2107
2134
|
if status == 'FAIL':
|
|
2108
|
-
logger.warn("Executing keyword '
|
|
2135
|
+
logger.warn(f"Executing keyword '{name}' failed:\n{message}")
|
|
2109
2136
|
return status, message
|
|
2110
2137
|
|
|
2111
2138
|
@run_keyword_variant(resolve=0, dry_run=True)
|
|
@@ -2206,11 +2233,9 @@ class _RunKeyword(_BuiltInBase):
|
|
|
2206
2233
|
raise
|
|
2207
2234
|
error = err.message
|
|
2208
2235
|
else:
|
|
2209
|
-
raise AssertionError("Expected error '
|
|
2210
|
-
% expected_error)
|
|
2236
|
+
raise AssertionError(f"Expected error '{expected_error}' did not occur.")
|
|
2211
2237
|
if not self._error_is_expected(error, expected_error):
|
|
2212
|
-
raise AssertionError("Expected error '
|
|
2213
|
-
% (expected_error, error))
|
|
2238
|
+
raise AssertionError(f"Expected error '{expected_error}' but got '{error}'.")
|
|
2214
2239
|
return error
|
|
2215
2240
|
|
|
2216
2241
|
def _error_is_expected(self, error, expected_error):
|
|
@@ -2218,7 +2243,7 @@ class _RunKeyword(_BuiltInBase):
|
|
|
2218
2243
|
matchers = {'GLOB': glob,
|
|
2219
2244
|
'EQUALS': lambda s, p: s == p,
|
|
2220
2245
|
'STARTS': lambda s, p: s.startswith(p),
|
|
2221
|
-
'REGEXP': lambda s, p: re.
|
|
2246
|
+
'REGEXP': lambda s, p: re.fullmatch(p, s) is not None}
|
|
2222
2247
|
prefixes = tuple(prefix + ':' for prefix in matchers)
|
|
2223
2248
|
if not expected_error.startswith(prefixes):
|
|
2224
2249
|
return glob(error, expected_error)
|
|
@@ -2287,21 +2312,20 @@ class _RunKeyword(_BuiltInBase):
|
|
|
2287
2312
|
|
|
2288
2313
|
def _keywords_repeated_by_count(self, count, name, args):
|
|
2289
2314
|
if count <= 0:
|
|
2290
|
-
self.log("Keyword '
|
|
2315
|
+
self.log(f"Keyword '{name}' repeated zero times.")
|
|
2291
2316
|
for i in range(count):
|
|
2292
|
-
self.log("Repeating keyword, round
|
|
2317
|
+
self.log(f"Repeating keyword, round {i+1}/{count}.")
|
|
2293
2318
|
yield name, args
|
|
2294
2319
|
|
|
2295
2320
|
def _keywords_repeated_by_timeout(self, timeout, name, args):
|
|
2296
2321
|
if timeout <= 0:
|
|
2297
|
-
self.log("Keyword '
|
|
2298
|
-
|
|
2322
|
+
self.log(f"Keyword '{name}' repeated zero times.")
|
|
2323
|
+
round = 0
|
|
2299
2324
|
maxtime = time.time() + timeout
|
|
2300
2325
|
while time.time() < maxtime:
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
secs_to_timestr(maxtime - time.time(), compact=True)))
|
|
2326
|
+
round += 1
|
|
2327
|
+
remaining = secs_to_timestr(maxtime - time.time(), compact=True)
|
|
2328
|
+
self.log(f"Repeating keyword, round {round}, {remaining} remaining.")
|
|
2305
2329
|
yield name, args
|
|
2306
2330
|
|
|
2307
2331
|
@run_keyword_variant(resolve=2, dry_run=True)
|
|
@@ -2354,11 +2378,11 @@ class _RunKeyword(_BuiltInBase):
|
|
|
2354
2378
|
except ValueError:
|
|
2355
2379
|
timeout = timestr_to_secs(retry)
|
|
2356
2380
|
maxtime = time.time() + timeout
|
|
2357
|
-
message = 'for
|
|
2381
|
+
message = f'for {secs_to_timestr(timeout)}'
|
|
2358
2382
|
else:
|
|
2359
2383
|
if count <= 0:
|
|
2360
|
-
raise ValueError('Retry count
|
|
2361
|
-
message = '
|
|
2384
|
+
raise ValueError(f'Retry count {count} is not positive.')
|
|
2385
|
+
message = f'{count} time{s(count)}'
|
|
2362
2386
|
if is_string(retry_interval) and normalize(retry_interval).startswith('strict:'):
|
|
2363
2387
|
retry_interval = retry_interval.split(':', 1)[1].strip()
|
|
2364
2388
|
strict_interval = True
|
|
@@ -2374,16 +2398,18 @@ class _RunKeyword(_BuiltInBase):
|
|
|
2374
2398
|
raise
|
|
2375
2399
|
count -= 1
|
|
2376
2400
|
if time.time() > maxtime > 0 or count == 0:
|
|
2377
|
-
raise AssertionError("Keyword '
|
|
2378
|
-
"The last error was:
|
|
2401
|
+
raise AssertionError(f"Keyword '{name}' failed after retrying "
|
|
2402
|
+
f"{message}. The last error was: {err}")
|
|
2379
2403
|
finally:
|
|
2380
2404
|
if strict_interval:
|
|
2381
|
-
|
|
2382
|
-
sleep_time = retry_interval -
|
|
2405
|
+
execution_time = time.time() - start_time
|
|
2406
|
+
sleep_time = retry_interval - execution_time
|
|
2383
2407
|
if sleep_time < 0:
|
|
2384
|
-
logger.warn(
|
|
2385
|
-
|
|
2386
|
-
|
|
2408
|
+
logger.warn(
|
|
2409
|
+
f"Keyword execution time {secs_to_timestr(execution_time)} "
|
|
2410
|
+
f"is longer than retry interval "
|
|
2411
|
+
f"{secs_to_timestr(retry_interval)}."
|
|
2412
|
+
)
|
|
2387
2413
|
self._sleep_in_parts(sleep_time)
|
|
2388
2414
|
|
|
2389
2415
|
@run_keyword_variant(resolve=1)
|
|
@@ -2426,19 +2452,21 @@ class _RunKeyword(_BuiltInBase):
|
|
|
2426
2452
|
Use `Get Variable Value` if you need to set variables
|
|
2427
2453
|
dynamically based on whether a variable exist or not.
|
|
2428
2454
|
"""
|
|
2429
|
-
values =
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2455
|
+
values = list(values)
|
|
2456
|
+
while True:
|
|
2457
|
+
values = self._verify_values_for_set_variable_if(values)
|
|
2458
|
+
if self._is_true(condition):
|
|
2459
|
+
return self._variables.replace_scalar(values[0])
|
|
2460
|
+
if len(values) == 1:
|
|
2461
|
+
return None
|
|
2462
|
+
if len(values) == 2:
|
|
2463
|
+
return self._variables.replace_scalar(values[1])
|
|
2464
|
+
condition, *values = values[1:]
|
|
2465
|
+
condition = self._variables.replace_scalar(condition)
|
|
2466
|
+
|
|
2467
|
+
def _verify_values_for_set_variable_if(self, values):
|
|
2438
2468
|
if not values:
|
|
2439
|
-
|
|
2440
|
-
return [None]
|
|
2441
|
-
raise RuntimeError('At least one value is required')
|
|
2469
|
+
raise RuntimeError('At least one value is required.')
|
|
2442
2470
|
if is_list_variable(values[0]):
|
|
2443
2471
|
values[:1] = [escape(item) for item in self._variables[values[0]]]
|
|
2444
2472
|
return self._verify_values_for_set_variable_if(values)
|
|
@@ -2520,10 +2548,9 @@ class _RunKeyword(_BuiltInBase):
|
|
|
2520
2548
|
if suite.statistics.failed > 0:
|
|
2521
2549
|
return self.run_keyword(name, *args)
|
|
2522
2550
|
|
|
2523
|
-
def _get_suite_in_teardown(self,
|
|
2551
|
+
def _get_suite_in_teardown(self, kw):
|
|
2524
2552
|
if not self._context.in_suite_teardown:
|
|
2525
|
-
raise RuntimeError("Keyword '
|
|
2526
|
-
% kwname)
|
|
2553
|
+
raise RuntimeError(f"Keyword '{kw}' can only be used in suite teardown.")
|
|
2527
2554
|
return self._context.suite
|
|
2528
2555
|
|
|
2529
2556
|
|
|
@@ -2872,7 +2899,7 @@ class _Control(_BuiltInBase):
|
|
|
2872
2899
|
Passing execution in the middle of a test, setup or teardown should be
|
|
2873
2900
|
used with care. In the worst case it leads to tests that skip all the
|
|
2874
2901
|
parts that could actually uncover problems in the tested application.
|
|
2875
|
-
In cases where execution cannot continue
|
|
2902
|
+
In cases where execution cannot continue due to external factors,
|
|
2876
2903
|
it is often safer to fail the test case and make it non-critical.
|
|
2877
2904
|
"""
|
|
2878
2905
|
message = message.strip()
|
|
@@ -2880,7 +2907,7 @@ class _Control(_BuiltInBase):
|
|
|
2880
2907
|
raise RuntimeError('Message cannot be empty.')
|
|
2881
2908
|
self._set_and_remove_tags(tags)
|
|
2882
2909
|
log_message, level = self._get_logged_test_message_and_level(message)
|
|
2883
|
-
self.log('Execution passed with message:\n
|
|
2910
|
+
self.log(f'Execution passed with message:\n{log_message}', level)
|
|
2884
2911
|
raise PassExecution(message)
|
|
2885
2912
|
|
|
2886
2913
|
@run_keyword_variant(resolve=1)
|
|
@@ -2931,7 +2958,7 @@ class _Misc(_BuiltInBase):
|
|
|
2931
2958
|
if seconds < 0:
|
|
2932
2959
|
seconds = 0
|
|
2933
2960
|
self._sleep_in_parts(seconds)
|
|
2934
|
-
self.log('Slept
|
|
2961
|
+
self.log(f'Slept {secs_to_timestr(seconds)}.')
|
|
2935
2962
|
if reason:
|
|
2936
2963
|
self.log(reason)
|
|
2937
2964
|
|
|
@@ -3050,8 +3077,8 @@ class _Misc(_BuiltInBase):
|
|
|
3050
3077
|
'len': len,
|
|
3051
3078
|
'type': lambda x: type(x).__name__}[formatter.lower()]
|
|
3052
3079
|
except KeyError:
|
|
3053
|
-
raise ValueError("Invalid formatter '
|
|
3054
|
-
"'str', 'repr', 'ascii', 'len', and 'type'."
|
|
3080
|
+
raise ValueError(f"Invalid formatter '{formatter}'. Available "
|
|
3081
|
+
f"'str', 'repr', 'ascii', 'len', and 'type'.")
|
|
3055
3082
|
|
|
3056
3083
|
@run_keyword_variant(resolve=0)
|
|
3057
3084
|
def log_many(self, *messages):
|
|
@@ -3078,7 +3105,7 @@ class _Misc(_BuiltInBase):
|
|
|
3078
3105
|
yield item
|
|
3079
3106
|
elif match.is_dict_variable():
|
|
3080
3107
|
for name, value in value.items():
|
|
3081
|
-
yield '
|
|
3108
|
+
yield f'{name}={value}'
|
|
3082
3109
|
else:
|
|
3083
3110
|
yield value
|
|
3084
3111
|
|
|
@@ -3131,18 +3158,14 @@ class _Misc(_BuiltInBase):
|
|
|
3131
3158
|
"""Sets the log threshold to the specified level and returns the old level.
|
|
3132
3159
|
|
|
3133
3160
|
Messages below the level will not logged. The default logging level is
|
|
3134
|
-
INFO, but it can be overridden with the command line option
|
|
3135
|
-
``--loglevel``.
|
|
3161
|
+
INFO, but it can be overridden with the command line option ``--loglevel``.
|
|
3136
3162
|
|
|
3137
|
-
The available levels: TRACE, DEBUG, INFO (default), WARN, ERROR and NONE
|
|
3138
|
-
logging).
|
|
3163
|
+
The available levels: TRACE, DEBUG, INFO (default), WARN, ERROR and NONE
|
|
3164
|
+
(no logging).
|
|
3139
3165
|
"""
|
|
3140
|
-
|
|
3141
|
-
old = self._context.output.set_log_level(level)
|
|
3142
|
-
except DataError as err:
|
|
3143
|
-
raise RuntimeError(str(err))
|
|
3166
|
+
old = self._context.output.set_log_level(level)
|
|
3144
3167
|
self._namespace.variables.set_global('${LOG_LEVEL}', level.upper())
|
|
3145
|
-
self.log('Log level changed from
|
|
3168
|
+
self.log(f'Log level changed from {old} to {level.upper()}.', level='DEBUG')
|
|
3146
3169
|
return old
|
|
3147
3170
|
|
|
3148
3171
|
def reload_library(self, name_or_instance):
|
|
@@ -3156,8 +3179,7 @@ class _Misc(_BuiltInBase):
|
|
|
3156
3179
|
calls this keyword as a method.
|
|
3157
3180
|
"""
|
|
3158
3181
|
library = self._namespace.reload_library(name_or_instance)
|
|
3159
|
-
self.log('Reloaded library
|
|
3160
|
-
len(library)))
|
|
3182
|
+
self.log(f'Reloaded library {library.name} with {len(library)} keywords.')
|
|
3161
3183
|
|
|
3162
3184
|
@run_keyword_variant(resolve=0)
|
|
3163
3185
|
def import_library(self, name, *args):
|
|
@@ -3523,7 +3545,7 @@ class _Misc(_BuiltInBase):
|
|
|
3523
3545
|
if self._context.in_test_teardown:
|
|
3524
3546
|
self._variables.set_test("${TEST_MESSAGE}", test.message)
|
|
3525
3547
|
message, level = self._get_logged_test_message_and_level(test.message)
|
|
3526
|
-
self.log('Set test message to:\n
|
|
3548
|
+
self.log(f'Set test message to:\n{message}', level)
|
|
3527
3549
|
|
|
3528
3550
|
def _get_new_text(self, old, new, append, handle_html=False):
|
|
3529
3551
|
if not is_string(new):
|
|
@@ -3534,10 +3556,10 @@ class _Misc(_BuiltInBase):
|
|
|
3534
3556
|
if new.startswith('*HTML*'):
|
|
3535
3557
|
new = new[6:].lstrip()
|
|
3536
3558
|
if not old.startswith('*HTML*'):
|
|
3537
|
-
old = '*HTML*
|
|
3559
|
+
old = f'*HTML* {html_escape(old)}'
|
|
3538
3560
|
elif old.startswith('*HTML*'):
|
|
3539
3561
|
new = html_escape(new)
|
|
3540
|
-
return '
|
|
3562
|
+
return f'{old} {new}'
|
|
3541
3563
|
|
|
3542
3564
|
def _get_logged_test_message_and_level(self, message):
|
|
3543
3565
|
if message.startswith('*HTML*'):
|
|
@@ -3561,12 +3583,12 @@ class _Misc(_BuiltInBase):
|
|
|
3561
3583
|
"used in suite setup or teardown.")
|
|
3562
3584
|
test.doc = self._get_new_text(test.doc, doc, append)
|
|
3563
3585
|
self._variables.set_test('${TEST_DOCUMENTATION}', test.doc)
|
|
3564
|
-
self.log('Set test documentation to:\n
|
|
3586
|
+
self.log(f'Set test documentation to:\n{test.doc}')
|
|
3565
3587
|
|
|
3566
3588
|
def set_suite_documentation(self, doc, append=False, top=False):
|
|
3567
3589
|
"""Sets documentation for the current test suite.
|
|
3568
3590
|
|
|
3569
|
-
By default the possible existing documentation is overwritten, but
|
|
3591
|
+
By default, the possible existing documentation is overwritten, but
|
|
3570
3592
|
this can be changed using the optional ``append`` argument similarly
|
|
3571
3593
|
as with `Set Test Message` keyword.
|
|
3572
3594
|
|
|
@@ -3581,12 +3603,12 @@ class _Misc(_BuiltInBase):
|
|
|
3581
3603
|
suite = self._get_context(top).suite
|
|
3582
3604
|
suite.doc = self._get_new_text(suite.doc, doc, append)
|
|
3583
3605
|
self._variables.set_suite('${SUITE_DOCUMENTATION}', suite.doc, top)
|
|
3584
|
-
self.log('Set suite documentation to:\n
|
|
3606
|
+
self.log(f'Set suite documentation to:\n{suite.doc}')
|
|
3585
3607
|
|
|
3586
3608
|
def set_suite_metadata(self, name, value, append=False, top=False):
|
|
3587
3609
|
"""Sets metadata for the current test suite.
|
|
3588
3610
|
|
|
3589
|
-
By default possible existing metadata values are overwritten, but
|
|
3611
|
+
By default, possible existing metadata values are overwritten, but
|
|
3590
3612
|
this can be changed using the optional ``append`` argument similarly
|
|
3591
3613
|
as with `Set Test Message` keyword.
|
|
3592
3614
|
|
|
@@ -3604,7 +3626,7 @@ class _Misc(_BuiltInBase):
|
|
|
3604
3626
|
original = metadata.get(name, '')
|
|
3605
3627
|
metadata[name] = self._get_new_text(original, value, append)
|
|
3606
3628
|
self._variables.set_suite('${SUITE_METADATA}', metadata.copy(), top)
|
|
3607
|
-
self.log("Set suite metadata '
|
|
3629
|
+
self.log(f"Set suite metadata '{name}' to value '{metadata[name]}'.")
|
|
3608
3630
|
|
|
3609
3631
|
def set_tags(self, *tags):
|
|
3610
3632
|
"""Adds given ``tags`` for the current test or all tests in a suite.
|
|
@@ -3629,7 +3651,7 @@ class _Misc(_BuiltInBase):
|
|
|
3629
3651
|
ctx.suite.set_tags(tags, persist=True)
|
|
3630
3652
|
else:
|
|
3631
3653
|
raise RuntimeError("'Set Tags' cannot be used in suite teardown.")
|
|
3632
|
-
self.log('Set tag
|
|
3654
|
+
self.log(f'Set tag{s(tags)} {seq2str((tags))}.')
|
|
3633
3655
|
|
|
3634
3656
|
def remove_tags(self, *tags):
|
|
3635
3657
|
"""Removes given ``tags`` from the current test or all tests in a suite.
|
|
@@ -3657,7 +3679,7 @@ class _Misc(_BuiltInBase):
|
|
|
3657
3679
|
ctx.suite.set_tags(remove=tags, persist=True)
|
|
3658
3680
|
else:
|
|
3659
3681
|
raise RuntimeError("'Remove Tags' cannot be used in suite teardown.")
|
|
3660
|
-
self.log('Removed tag
|
|
3682
|
+
self.log(f'Removed tag{s(tags)} {seq2str((tags))}.')
|
|
3661
3683
|
|
|
3662
3684
|
def get_library_instance(self, name=None, all=False):
|
|
3663
3685
|
"""Returns the currently active instance of the specified library.
|
|
@@ -3672,8 +3694,7 @@ class _Misc(_BuiltInBase):
|
|
|
3672
3694
|
| seleniumlib = BuiltIn().get_library_instance('SeleniumLibrary')
|
|
3673
3695
|
| title = seleniumlib.get_title()
|
|
3674
3696
|
| if not title.startswith(expected):
|
|
3675
|
-
| raise AssertionError("Title '
|
|
3676
|
-
| % (title, expected))
|
|
3697
|
+
| raise AssertionError(f"Title '{title}' did not start with '{expected}'.")
|
|
3677
3698
|
|
|
3678
3699
|
It is also possible to use this keyword in the test data and
|
|
3679
3700
|
pass the returned library instance to another keyword. If a
|
|
@@ -3716,40 +3737,6 @@ class BuiltIn(_Verify, _Converter, _Variables, _RunKeyword, _Control, _Misc):
|
|
|
3716
3737
|
HTML in messages is not limited to BuiltIn library but works with any
|
|
3717
3738
|
error message.
|
|
3718
3739
|
|
|
3719
|
-
= Using variables with keywords creating or accessing variables =
|
|
3720
|
-
|
|
3721
|
-
This library has special keywords `Set Global Variable`, `Set Suite Variable`,
|
|
3722
|
-
`Set Test Variable` and `Set Local Variable` for creating variables in
|
|
3723
|
-
different scopes. These keywords take the variable name and its value as
|
|
3724
|
-
arguments. The name can be given using the normal ``${variable}`` syntax or
|
|
3725
|
-
in escaped format either like ``$variable`` or ``\${variable}``. For example,
|
|
3726
|
-
these are typically equivalent and create new suite level variable
|
|
3727
|
-
``${name}`` with value ``value``:
|
|
3728
|
-
|
|
3729
|
-
| Set Suite Variable ${name} value
|
|
3730
|
-
| Set Suite Variable $name value
|
|
3731
|
-
| Set Suite Variable \${name} value
|
|
3732
|
-
|
|
3733
|
-
A problem with using the normal ``${variable}`` syntax is that these
|
|
3734
|
-
keywords cannot easily know is the idea to create a variable with exactly
|
|
3735
|
-
that name or does that variable actually contain the name of the variable
|
|
3736
|
-
to create. If the variable does not initially exist, it will always be
|
|
3737
|
-
created. If it exists and its value is a variable name either in the normal
|
|
3738
|
-
or in the escaped syntax, variable with _that_ name is created instead.
|
|
3739
|
-
For example, if ``${name}`` variable would exist and contain value
|
|
3740
|
-
``$example``, these examples would create different variables:
|
|
3741
|
-
|
|
3742
|
-
| Set Suite Variable ${name} value # Creates ${example}.
|
|
3743
|
-
| Set Suite Variable $name value # Creates ${name}.
|
|
3744
|
-
| Set Suite Variable \${name} value # Creates ${name}.
|
|
3745
|
-
|
|
3746
|
-
Because the behavior when using the normal ``${variable}`` syntax depends
|
|
3747
|
-
on the possible existing value of the variable, it is *highly recommended
|
|
3748
|
-
to use the escaped ``$variable`` or ``\${variable}`` format instead*.
|
|
3749
|
-
|
|
3750
|
-
This same problem occurs also with special keywords for accessing variables
|
|
3751
|
-
`Get Variable Value`, `Variable Should Exist` and `Variable Should Not Exist`.
|
|
3752
|
-
|
|
3753
3740
|
= Evaluating expressions =
|
|
3754
3741
|
|
|
3755
3742
|
Many keywords, such as `Evaluate`, `Run Keyword If` and `Should Be True`,
|
|
@@ -3814,6 +3801,45 @@ class BuiltIn(_Verify, _Converter, _Variables, _RunKeyword, _Control, _Misc):
|
|
|
3814
3801
|
to move the logic into a library. That eases maintenance and can also
|
|
3815
3802
|
enhance execution speed.
|
|
3816
3803
|
|
|
3804
|
+
= Using variables with keywords creating or accessing variables =
|
|
3805
|
+
|
|
3806
|
+
This library has special keywords `Set Global Variable`, `Set Suite Variable`,
|
|
3807
|
+
`Set Test Variable` and `Set Local Variable` for creating variables in
|
|
3808
|
+
different scopes. These keywords take the variable name and its value as
|
|
3809
|
+
arguments. The name can be given using the normal ``${variable}`` syntax or
|
|
3810
|
+
in escaped format either like ``$variable`` or ``\${variable}``. For example,
|
|
3811
|
+
these are typically equivalent and create new suite level variable
|
|
3812
|
+
``${name}`` with value ``value``:
|
|
3813
|
+
|
|
3814
|
+
| Set Suite Variable ${name} value
|
|
3815
|
+
| Set Suite Variable $name value
|
|
3816
|
+
| Set Suite Variable \${name} value
|
|
3817
|
+
|
|
3818
|
+
A problem with using the normal ``${variable}`` syntax is that these
|
|
3819
|
+
keywords cannot easily know is the idea to create a variable with exactly
|
|
3820
|
+
that name or does that variable actually contain the name of the variable
|
|
3821
|
+
to create. If the variable does not initially exist, it will always be
|
|
3822
|
+
created. If it exists and its value is a variable name either in the normal
|
|
3823
|
+
or in the escaped syntax, variable with _that_ name is created instead.
|
|
3824
|
+
For example, if ``${name}`` variable would exist and contain value
|
|
3825
|
+
``$example``, these examples would create different variables:
|
|
3826
|
+
|
|
3827
|
+
| Set Suite Variable ${name} value # Creates ${example}.
|
|
3828
|
+
| Set Suite Variable $name value # Creates ${name}.
|
|
3829
|
+
| Set Suite Variable \${name} value # Creates ${name}.
|
|
3830
|
+
|
|
3831
|
+
Because the behavior when using the normal ``${variable}`` syntax depends
|
|
3832
|
+
on the possible existing value of the variable, it is *highly recommended
|
|
3833
|
+
to use the escaped ``$variable`` or ``\${variable}`` format instead*.
|
|
3834
|
+
|
|
3835
|
+
This same problem occurs also with special keywords for accessing variables
|
|
3836
|
+
`Get Variable Value`, `Variable Should Exist` and `Variable Should Not Exist`.
|
|
3837
|
+
|
|
3838
|
+
*NOTE:* It is recommended to use the ``VAR`` syntax introduced in Robot
|
|
3839
|
+
Framework 7.0 for creating variables in different scopes instead of the
|
|
3840
|
+
`Set Global/Suite/Test/Local Variable` keywords. It makes creating variables
|
|
3841
|
+
uniform and avoids all the problems discussed above.
|
|
3842
|
+
|
|
3817
3843
|
= Boolean arguments =
|
|
3818
3844
|
|
|
3819
3845
|
Some keywords accept arguments that are handled as Boolean values true or
|