robotframework 6.1.1__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.
Files changed (288) hide show
  1. {robotframework-6.1.1/src/robotframework.egg-info → robotframework-7.0a1}/PKG-INFO +3 -6
  2. {robotframework-6.1.1 → robotframework-7.0a1}/setup.py +2 -5
  3. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/api/interfaces.py +35 -48
  4. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/api/parsing.py +4 -2
  5. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/conf/gatherfailed.py +2 -2
  6. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/conf/languages.py +0 -9
  7. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/conf/settings.py +8 -5
  8. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/htmldata/rebot/log.css +4 -0
  9. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/htmldata/rebot/log.html +9 -1
  10. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/htmldata/rebot/model.js +2 -4
  11. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/htmldata/rebot/testdata.js +10 -3
  12. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/htmldata/template.py +3 -3
  13. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/libdocpkg/builder.py +0 -8
  14. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/libdocpkg/datatypes.py +9 -10
  15. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/libdocpkg/htmlutils.py +4 -7
  16. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/libdocpkg/jsonbuilder.py +14 -10
  17. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/libdocpkg/model.py +13 -25
  18. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/libdocpkg/robotbuilder.py +13 -3
  19. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/libdocpkg/xmlbuilder.py +8 -8
  20. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/libdocpkg/xmlwriter.py +12 -38
  21. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/libraries/BuiltIn.py +215 -189
  22. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/libraries/Collections.py +2 -9
  23. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/libraries/DateTime.py +1 -1
  24. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/libraries/OperatingSystem.py +4 -3
  25. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/libraries/Process.py +26 -27
  26. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/libraries/Remote.py +40 -36
  27. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/libraries/String.py +4 -4
  28. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/libraries/XML.py +7 -8
  29. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/libraries/__init__.py +2 -2
  30. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/model/__init__.py +4 -4
  31. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/model/body.py +14 -6
  32. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/model/configurer.py +15 -11
  33. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/model/control.py +151 -81
  34. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/model/filter.py +31 -25
  35. robotframework-7.0a1/src/robot/model/keyword.py +70 -0
  36. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/model/message.py +19 -10
  37. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/model/namepatterns.py +3 -25
  38. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/model/stats.py +9 -15
  39. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/model/tags.py +1 -1
  40. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/model/testcase.py +12 -21
  41. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/model/testsuite.py +16 -22
  42. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/model/visitor.py +35 -8
  43. robotframework-7.0a1/src/robot/output/console/dotted.py +90 -0
  44. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/output/console/quiet.py +3 -2
  45. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/output/console/verbose.py +60 -60
  46. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/output/debugfile.py +36 -23
  47. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/output/filelogger.py +16 -13
  48. robotframework-7.0a1/src/robot/output/listeners.py +586 -0
  49. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/output/logger.py +164 -77
  50. robotframework-7.0a1/src/robot/output/loggerapi.py +152 -0
  51. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/output/loggerhelper.py +23 -56
  52. robotframework-7.0a1/src/robot/output/output.py +158 -0
  53. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/output/stdoutlogsplitter.py +8 -5
  54. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/output/xmllogger.py +163 -109
  55. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/parsing/lexer/blocklexers.py +17 -13
  56. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/parsing/lexer/context.py +12 -2
  57. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/parsing/lexer/lexer.py +1 -1
  58. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/parsing/lexer/settings.py +6 -3
  59. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/parsing/lexer/statementlexers.py +39 -10
  60. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/parsing/lexer/tokens.py +27 -29
  61. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/parsing/model/blocks.py +19 -6
  62. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/parsing/model/statements.py +184 -84
  63. robotframework-7.0a1/src/robot/parsing/model/visitor.py +102 -0
  64. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/reporting/expandkeywordmatcher.py +1 -1
  65. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/reporting/jsbuildingcontext.py +8 -6
  66. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/reporting/jsmodelbuilders.py +88 -61
  67. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/reporting/stringcache.py +4 -3
  68. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/reporting/xunitwriter.py +15 -21
  69. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/result/__init__.py +3 -2
  70. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/result/configurer.py +12 -9
  71. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/result/flattenkeywordmatcher.py +8 -8
  72. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/result/keywordremover.py +71 -54
  73. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/result/merger.py +1 -1
  74. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/result/model.py +400 -316
  75. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/result/modeldeprecation.py +9 -3
  76. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/result/resultbuilder.py +21 -23
  77. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/result/xmlelementhandlers.py +76 -40
  78. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/running/__init__.py +1 -1
  79. robotframework-7.0a1/src/robot/running/arguments/argumentconverter.py +101 -0
  80. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/running/arguments/argumentmapper.py +16 -14
  81. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/running/arguments/argumentresolver.py +41 -33
  82. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/running/arguments/argumentspec.py +24 -90
  83. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/running/arguments/argumentvalidator.py +34 -27
  84. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/running/arguments/customconverters.py +14 -11
  85. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/running/arguments/embedded.py +23 -26
  86. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/running/arguments/typeconverters.py +175 -213
  87. robotframework-7.0a1/src/robot/running/arguments/typeinfo.py +367 -0
  88. robotframework-7.0a1/src/robot/running/arguments/typevalidator.py +62 -0
  89. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/running/bodyrunner.py +83 -68
  90. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/running/builder/parsers.py +8 -10
  91. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/running/builder/settings.py +9 -17
  92. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/running/builder/transformers.py +166 -308
  93. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/running/context.py +80 -25
  94. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/running/handlers.py +11 -16
  95. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/running/handlerstore.py +1 -1
  96. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/running/librarykeywordrunner.py +9 -17
  97. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/running/model.py +109 -32
  98. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/running/namespace.py +18 -19
  99. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/running/statusreporter.py +13 -12
  100. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/running/suiterunner.py +15 -17
  101. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/running/testlibraries.py +33 -40
  102. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/running/usererrorhandler.py +8 -8
  103. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/running/userkeyword.py +13 -8
  104. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/running/userkeywordrunner.py +18 -21
  105. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/testdoc.py +18 -13
  106. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/utils/__init__.py +50 -35
  107. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/utils/connectioncache.py +64 -59
  108. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/utils/encodingsniffer.py +1 -1
  109. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/utils/escaping.py +11 -9
  110. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/utils/markupwriters.py +20 -13
  111. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/utils/normalizing.py +9 -24
  112. robotframework-7.0a1/src/robot/utils/notset.py +33 -0
  113. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/utils/platform.py +15 -5
  114. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/utils/robotpath.py +1 -0
  115. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/utils/robottime.py +120 -88
  116. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/utils/robottypes.py +16 -31
  117. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/utils/setter.py +0 -5
  118. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/utils/text.py +7 -4
  119. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/utils/unic.py +2 -2
  120. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/variables/__init__.py +2 -2
  121. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/variables/assigner.py +17 -19
  122. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/variables/evaluation.py +20 -17
  123. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/variables/filesetter.py +80 -80
  124. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/variables/replacer.py +33 -36
  125. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/variables/scopes.py +3 -3
  126. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/variables/search.py +66 -41
  127. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/variables/store.py +14 -16
  128. robotframework-7.0a1/src/robot/variables/tablesetter.py +164 -0
  129. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/variables/variables.py +1 -1
  130. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/version.py +1 -1
  131. {robotframework-6.1.1 → robotframework-7.0a1/src/robotframework.egg-info}/PKG-INFO +3 -6
  132. {robotframework-6.1.1 → robotframework-7.0a1}/src/robotframework.egg-info/SOURCES.txt +3 -4
  133. {robotframework-6.1.1 → robotframework-7.0a1}/tasks.py +6 -6
  134. robotframework-6.1.1/src/robot/libraries/Reserved.py +0 -48
  135. robotframework-6.1.1/src/robot/model/keyword.py +0 -173
  136. robotframework-6.1.1/src/robot/output/console/dotted.py +0 -90
  137. robotframework-6.1.1/src/robot/output/listenerarguments.py +0 -165
  138. robotframework-6.1.1/src/robot/output/listenermethods.py +0 -113
  139. robotframework-6.1.1/src/robot/output/listeners.py +0 -174
  140. robotframework-6.1.1/src/robot/output/output.py +0 -95
  141. robotframework-6.1.1/src/robot/parsing/model/visitor.py +0 -67
  142. robotframework-6.1.1/src/robot/running/arguments/argumentconverter.py +0 -79
  143. robotframework-6.1.1/src/robot/running/arguments/typevalidator.py +0 -56
  144. robotframework-6.1.1/src/robot/running/modelcombiner.py +0 -32
  145. robotframework-6.1.1/src/robot/variables/tablesetter.py +0 -156
  146. {robotframework-6.1.1 → robotframework-7.0a1}/AUTHORS.rst +0 -0
  147. {robotframework-6.1.1 → robotframework-7.0a1}/BUILD.rst +0 -0
  148. {robotframework-6.1.1 → robotframework-7.0a1}/CONTRIBUTING.rst +0 -0
  149. {robotframework-6.1.1 → robotframework-7.0a1}/COPYRIGHT.txt +0 -0
  150. {robotframework-6.1.1 → robotframework-7.0a1}/INSTALL.rst +0 -0
  151. {robotframework-6.1.1 → robotframework-7.0a1}/LICENSE.txt +0 -0
  152. {robotframework-6.1.1 → robotframework-7.0a1}/MANIFEST.in +0 -0
  153. {robotframework-6.1.1 → robotframework-7.0a1}/README.rst +0 -0
  154. {robotframework-6.1.1 → robotframework-7.0a1}/setup.cfg +0 -0
  155. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/__init__.py +0 -0
  156. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/__main__.py +0 -0
  157. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/api/__init__.py +0 -0
  158. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/api/deco.py +0 -0
  159. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/api/exceptions.py +0 -0
  160. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/api/logger.py +0 -0
  161. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/conf/__init__.py +0 -0
  162. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/errors.py +0 -0
  163. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/htmldata/__init__.py +0 -0
  164. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/htmldata/common/__init__.py +0 -0
  165. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/htmldata/common/js_disabled.css +0 -0
  166. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/htmldata/common/storage.js +0 -0
  167. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/htmldata/htmlfilewriter.py +0 -0
  168. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/htmldata/jsonwriter.py +0 -0
  169. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/htmldata/lib/__init__.py +0 -0
  170. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/htmldata/lib/jquery.highlight.min.js +0 -0
  171. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/htmldata/lib/jquery.min.js +0 -0
  172. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/htmldata/lib/jquery.tablesorter.min.js +0 -0
  173. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/htmldata/lib/jquery.tmpl.min.js +0 -0
  174. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/htmldata/lib/jsxcompressor.min.js +0 -0
  175. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/htmldata/libdoc/__init__.py +0 -0
  176. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/htmldata/libdoc/doc_formatting.css +0 -0
  177. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/htmldata/libdoc/libdoc.css +0 -0
  178. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/htmldata/libdoc/libdoc.html +0 -0
  179. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/htmldata/libdoc/print.css +0 -0
  180. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/htmldata/libdoc/pygments.css +0 -0
  181. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/htmldata/rebot/__init__.py +0 -0
  182. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/htmldata/rebot/common.css +0 -0
  183. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/htmldata/rebot/doc_formatting.css +0 -0
  184. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/htmldata/rebot/fileloading.js +0 -0
  185. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/htmldata/rebot/log.js +0 -0
  186. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/htmldata/rebot/print.css +0 -0
  187. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/htmldata/rebot/report.css +0 -0
  188. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/htmldata/rebot/report.html +0 -0
  189. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/htmldata/rebot/util.js +0 -0
  190. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/htmldata/rebot/view.js +0 -0
  191. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/htmldata/testdoc/__init__.py +0 -0
  192. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/htmldata/testdoc/testdoc.css +0 -0
  193. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/htmldata/testdoc/testdoc.html +0 -0
  194. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/libdoc.py +0 -0
  195. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/libdocpkg/__init__.py +0 -0
  196. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/libdocpkg/consoleviewer.py +0 -0
  197. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/libdocpkg/htmlwriter.py +0 -0
  198. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/libdocpkg/jsonwriter.py +0 -0
  199. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/libdocpkg/output.py +0 -0
  200. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/libdocpkg/standardtypes.py +0 -0
  201. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/libdocpkg/writer.py +0 -0
  202. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/libraries/Dialogs.py +0 -0
  203. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/libraries/Easter.py +0 -0
  204. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/libraries/Screenshot.py +0 -0
  205. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/libraries/Telnet.py +0 -0
  206. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/libraries/dialogs_py.py +0 -0
  207. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/model/fixture.py +0 -0
  208. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/model/itemlist.py +0 -0
  209. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/model/metadata.py +0 -0
  210. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/model/modelobject.py +0 -0
  211. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/model/modifier.py +0 -0
  212. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/model/statistics.py +0 -0
  213. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/model/suitestatistics.py +0 -0
  214. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/model/tagsetter.py +0 -0
  215. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/model/tagstatistics.py +0 -0
  216. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/model/totalstatistics.py +0 -0
  217. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/output/__init__.py +0 -0
  218. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/output/console/__init__.py +0 -0
  219. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/output/console/highlighting.py +0 -0
  220. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/output/librarylogger.py +0 -0
  221. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/output/pyloggingconf.py +0 -0
  222. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/parsing/__init__.py +0 -0
  223. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/parsing/lexer/__init__.py +0 -0
  224. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/parsing/lexer/tokenizer.py +0 -0
  225. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/parsing/model/__init__.py +0 -0
  226. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/parsing/parser/__init__.py +0 -0
  227. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/parsing/parser/blockparsers.py +0 -0
  228. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/parsing/parser/fileparser.py +0 -0
  229. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/parsing/parser/parser.py +0 -0
  230. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/parsing/suitestructure.py +0 -0
  231. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/pythonpathsetter.py +0 -0
  232. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/rebot.py +0 -0
  233. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/reporting/__init__.py +0 -0
  234. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/reporting/jsexecutionresult.py +0 -0
  235. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/reporting/jswriter.py +0 -0
  236. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/reporting/logreportwriters.py +0 -0
  237. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/reporting/outputwriter.py +0 -0
  238. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/reporting/resultwriter.py +0 -0
  239. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/result/executionerrors.py +0 -0
  240. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/result/executionresult.py +0 -0
  241. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/result/messagefilter.py +0 -0
  242. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/result/suiteteardownfailed.py +0 -0
  243. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/result/visitor.py +0 -0
  244. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/run.py +0 -0
  245. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/running/arguments/__init__.py +0 -0
  246. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/running/arguments/argumentparser.py +0 -0
  247. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/running/builder/__init__.py +0 -0
  248. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/running/builder/builders.py +0 -0
  249. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/running/dynamicmethods.py +0 -0
  250. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/running/importer.py +0 -0
  251. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/running/libraryscopes.py +0 -0
  252. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/running/outputcapture.py +0 -0
  253. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/running/randomizer.py +0 -0
  254. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/running/runkwregister.py +0 -0
  255. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/running/signalhandler.py +0 -0
  256. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/running/status.py +0 -0
  257. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/running/timeouts/__init__.py +0 -0
  258. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/running/timeouts/posix.py +0 -0
  259. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/running/timeouts/windows.py +0 -0
  260. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/utils/application.py +0 -0
  261. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/utils/argumentparser.py +0 -0
  262. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/utils/asserts.py +0 -0
  263. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/utils/charwidth.py +0 -0
  264. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/utils/compress.py +0 -0
  265. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/utils/dotdict.py +0 -0
  266. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/utils/encoding.py +0 -0
  267. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/utils/error.py +0 -0
  268. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/utils/etreewrapper.py +0 -0
  269. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/utils/filereader.py +0 -0
  270. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/utils/frange.py +0 -0
  271. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/utils/htmlformatters.py +0 -0
  272. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/utils/importer.py +0 -0
  273. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/utils/markuputils.py +0 -0
  274. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/utils/match.py +0 -0
  275. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/utils/misc.py +0 -0
  276. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/utils/recommendations.py +0 -0
  277. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/utils/restreader.py +0 -0
  278. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/utils/robotenv.py +0 -0
  279. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/utils/robotinspect.py +0 -0
  280. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/utils/robotio.py +0 -0
  281. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/utils/sortable.py +0 -0
  282. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/utils/typehints.py +0 -0
  283. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/variables/finders.py +0 -0
  284. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/variables/notfound.py +0 -0
  285. {robotframework-6.1.1 → robotframework-7.0a1}/src/robot/variables/resolvable.py +0 -0
  286. {robotframework-6.1.1 → robotframework-7.0a1}/src/robotframework.egg-info/dependency_links.txt +0 -0
  287. {robotframework-6.1.1 → robotframework-7.0a1}/src/robotframework.egg-info/entry_points.txt +0 -0
  288. {robotframework-6.1.1 → robotframework-7.0a1}/src/robotframework.egg-info/top_level.txt +0 -0
@@ -13,17 +13,19 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
+ import re
17
+
16
18
  from robot.output import LEVELS
19
+ from robot.result import Error, Keyword, Message, Return
17
20
 
18
21
  from .jsbuildingcontext import JsBuildingContext
19
22
  from .jsexecutionresult import JsExecutionResult
20
23
 
21
-
22
24
  STATUSES = {'FAIL': 0, 'PASS': 1, 'SKIP': 2, 'NOT RUN': 3}
23
25
  KEYWORD_TYPES = {'KEYWORD': 0, 'SETUP': 1, 'TEARDOWN': 2,
24
26
  'FOR': 3, 'ITERATION': 4, 'IF': 5, 'ELSE IF': 6, 'ELSE': 7,
25
- 'RETURN': 8, 'TRY': 9, 'EXCEPT': 10, 'FINALLY': 11, 'WHILE': 12,
26
- 'CONTINUE': 13, 'BREAK': 14, 'ERROR': 15}
27
+ 'RETURN': 8, 'VAR': 9, 'TRY': 10, 'EXCEPT': 11, 'FINALLY': 12,
28
+ 'WHILE': 13, 'CONTINUE': 14, 'BREAK': 15, 'ERROR': 16}
27
29
 
28
30
 
29
31
  class JsModelBuilder:
@@ -47,49 +49,61 @@ class JsModelBuilder:
47
49
  )
48
50
 
49
51
 
50
- class _Builder:
52
+ class Builder:
53
+ robot_note = re.compile('<span class="robot-note">(.*)</span>')
51
54
 
52
- def __init__(self, context):
55
+ def __init__(self, context: JsBuildingContext):
53
56
  self._context = context
54
57
  self._string = self._context.string
55
58
  self._html = self._context.html
56
59
  self._timestamp = self._context.timestamp
57
60
 
58
- def _get_status(self, item):
61
+ def _get_status(self, item, note_only=False):
59
62
  model = (STATUSES[item.status],
60
- self._timestamp(item.starttime),
61
- item.elapsedtime)
62
- msg = getattr(item, 'message', '')
63
+ self._timestamp(item.start_time),
64
+ round(item.elapsed_time.total_seconds() * 1000))
65
+ msg = item.message
63
66
  if not msg:
64
67
  return model
65
- elif msg.startswith('*HTML*'):
66
- msg = self._string(msg[6:].lstrip(), escape=False)
68
+ if note_only:
69
+ if msg.startswith('*HTML*'):
70
+ match = self.robot_note.search(msg)
71
+ if match:
72
+ index = self._string(match.group(1))
73
+ return model + (index,)
74
+ return model
75
+ if msg.startswith('*HTML*'):
76
+ index = self._string(msg[6:].lstrip(), escape=False)
67
77
  else:
68
- msg = self._string(msg)
69
- return model + (msg,)
78
+ index = self._string(msg)
79
+ return model + (index,)
70
80
 
71
- def _build_keywords(self, steps, split=False):
81
+ def _build_body(self, body, split=False):
72
82
  splitting = self._context.start_splitting_if_needed(split)
73
- # tuple([<listcomp>>]) is faster than tuple(<genex>) with short lists.
74
- model = tuple([self._build_keyword(step) for step in steps])
83
+ # tuple([<listcomp>]) is faster than tuple(<genex>) with short lists.
84
+ model = tuple([self._build_body_item(item) for item in body])
75
85
  return model if not splitting else self._context.end_splitting(model)
76
86
 
77
- def _build_keyword(self, step):
87
+ def _build_body_item(self, item):
78
88
  raise NotImplementedError
79
89
 
80
90
 
81
- class SuiteBuilder(_Builder):
91
+ class SuiteBuilder(Builder):
82
92
 
83
93
  def __init__(self, context):
84
- _Builder.__init__(self, context)
94
+ super().__init__(context)
85
95
  self._build_suite = self.build
86
96
  self._build_test = TestBuilder(context).build
87
- self._build_keyword = KeywordBuilder(context).build
97
+ self._build_body_item = BodyItemBuilder(context).build
88
98
 
89
99
  def build(self, suite):
90
100
  with self._context.prune_input(suite.tests, suite.suites):
91
101
  stats = self._get_statistics(suite) # Must be done before pruning
92
- kws = [kw for kw in (suite.setup, suite.teardown) if kw]
102
+ fixture = []
103
+ if suite.has_setup:
104
+ fixture.append(suite.setup)
105
+ if suite.has_teardown:
106
+ fixture.append(suite.teardown)
93
107
  return (self._string(suite.name, attr=True),
94
108
  self._string(suite.source),
95
109
  self._context.relative_source(suite.source),
@@ -98,7 +112,7 @@ class SuiteBuilder(_Builder):
98
112
  self._get_status(suite),
99
113
  tuple(self._build_suite(s) for s in suite.suites),
100
114
  tuple(self._build_test(t) for t in suite.tests),
101
- tuple(self._build_keyword(k, split=True) for k in kws),
115
+ tuple(self._build_body_item(kw, split=True) for kw in fixture),
102
116
  stats)
103
117
 
104
118
  def _yield_metadata(self, suite):
@@ -111,63 +125,76 @@ class SuiteBuilder(_Builder):
111
125
  return (stats.total, stats.passed, stats.failed, stats.skipped)
112
126
 
113
127
 
114
- class TestBuilder(_Builder):
128
+ class TestBuilder(Builder):
115
129
 
116
130
  def __init__(self, context):
117
- _Builder.__init__(self, context)
118
- self._build_keyword = KeywordBuilder(context).build
131
+ super().__init__(context)
132
+ self._build_body_item = BodyItemBuilder(context).build
119
133
 
120
134
  def build(self, test):
121
- kws = self._get_keywords(test)
135
+ body = self._get_body_items(test)
122
136
  with self._context.prune_input(test.body):
123
137
  return (self._string(test.name, attr=True),
124
138
  self._string(test.timeout),
125
139
  self._html(test.doc),
126
140
  tuple(self._string(t) for t in test.tags),
127
141
  self._get_status(test),
128
- self._build_keywords(kws, split=True))
142
+ self._build_body(body, split=True))
129
143
 
130
- def _get_keywords(self, test):
131
- kws = []
132
- if test.setup:
133
- kws.append(test.setup)
134
- kws.extend(test.body.flatten())
135
- if test.teardown:
136
- kws.append(test.teardown)
137
- return kws
144
+ def _get_body_items(self, test):
145
+ body = test.body.flatten()
146
+ if test.has_setup:
147
+ body.insert(0, test.setup)
148
+ if test.has_teardown:
149
+ body.append(test.teardown)
150
+ return body
138
151
 
139
152
 
140
- class KeywordBuilder(_Builder):
153
+ class BodyItemBuilder(Builder):
141
154
 
142
155
  def __init__(self, context):
143
- _Builder.__init__(self, context)
144
- self._build_keyword = self.build
156
+ super().__init__(context)
157
+ self._build_body_item = self.build
145
158
  self._build_message = MessageBuilder(context).build
146
159
 
147
160
  def build(self, item, split=False):
148
- if item.type == item.MESSAGE:
161
+ if isinstance(item, Message):
149
162
  return self._build_message(item)
150
- return self.build_keyword(item, split)
151
-
152
- def build_keyword(self, kw, split=False):
163
+ with self._context.prune_input(item.body):
164
+ if isinstance (item, Keyword):
165
+ return self._build_keyword(item, split)
166
+ if isinstance(item, (Return, Error)):
167
+ return self._build(item, args=' '.join(item.values), split=split)
168
+ return self._build(item, item._log_name, split=split)
169
+
170
+ def _build_keyword(self, kw: Keyword, split):
153
171
  self._context.check_expansion(kw)
154
- items = kw.body.flatten()
155
- if getattr(kw, 'has_teardown', False):
156
- items.append(kw.teardown)
157
- with self._context.prune_input(kw.body):
158
- return (KEYWORD_TYPES[kw.type],
159
- self._string(kw.kwname, attr=True),
160
- self._string(kw.libname, attr=True),
161
- self._string(kw.timeout),
162
- self._html(kw.doc),
163
- self._string(', '.join(kw.args)),
164
- self._string(', '.join(kw.assign)),
165
- self._string(', '.join(kw.tags)),
166
- self._get_status(kw),
167
- self._build_keywords(items, split))
168
-
169
-
170
- class MessageBuilder(_Builder):
172
+ body = kw.body.flatten()
173
+ if kw.has_setup:
174
+ body.insert(0, kw.setup)
175
+ if kw.has_teardown:
176
+ body.append(kw.teardown)
177
+ return self._build(kw, kw.name, kw.owner, kw.timeout, kw.doc,
178
+ ' '.join(kw.args), ' '.join(kw.assign),
179
+ ', '.join(kw.tags), body, split=split)
180
+
181
+ def _build(self, item, name='', owner='', timeout='', doc='', args='', assign='',
182
+ tags='', body=None, split=False):
183
+ if body is None:
184
+ body = item.body.flatten()
185
+ return (KEYWORD_TYPES[item.type],
186
+ self._string(name, attr=True),
187
+ self._string(owner, attr=True),
188
+ self._string(timeout),
189
+ self._html(doc),
190
+ self._string(args),
191
+ self._string(assign),
192
+ self._string(tags),
193
+ self._get_status(item, note_only=True),
194
+ self._build_body(body, split))
195
+
196
+
197
+ class MessageBuilder(Builder):
171
198
 
172
199
  def build(self, msg):
173
200
  if msg.level in ('WARN', 'ERROR'):
@@ -196,10 +223,10 @@ class StatisticsBuilder:
196
223
  for stat in stats)
197
224
 
198
225
 
199
- class ErrorsBuilder(_Builder):
226
+ class ErrorsBuilder(Builder):
200
227
 
201
228
  def __init__(self, context):
202
- _Builder.__init__(self, context)
229
+ super().__init__(context)
203
230
  self._build_message = ErrorMessageBuilder(context).build
204
231
 
205
232
  def build(self, errors):
@@ -16,21 +16,22 @@
16
16
  from robot.utils import compress_text, html_format
17
17
 
18
18
 
19
+ # TODO: can this be removed?
19
20
  class StringIndex(int):
20
21
  pass
21
22
 
22
23
 
23
24
  class StringCache:
25
+ empty = StringIndex(0)
24
26
  _compress_threshold = 80
25
27
  _use_compressed_threshold = 1.1
26
- _zero_index = StringIndex(0)
27
28
 
28
29
  def __init__(self):
29
- self._cache = {('', False): self._zero_index}
30
+ self._cache = {('', False): self.empty}
30
31
 
31
32
  def add(self, text, html=False):
32
33
  if not text:
33
- return self._zero_index
34
+ return self.empty
34
35
  key = (text, html)
35
36
  if key not in self._cache:
36
37
  self._cache[key] = StringIndex(len(self._cache))
@@ -13,7 +13,7 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- from robot.result import ResultVisitor
16
+ from robot.result import ResultVisitor, TestCase, TestSuite
17
17
  from robot.utils import XmlWriter
18
18
 
19
19
 
@@ -38,32 +38,34 @@ class XUnitFileWriter(ResultVisitor):
38
38
  def __init__(self, xml_writer):
39
39
  self._writer = xml_writer
40
40
 
41
- def start_suite(self, suite):
41
+ def start_suite(self, suite: TestSuite):
42
42
  stats = suite.statistics # Accessing property only once.
43
43
  attrs = {'name': suite.name,
44
- 'tests': f'{stats.total}',
44
+ 'tests': str(stats.total),
45
45
  'errors': '0',
46
- 'failures': f'{stats.failed}',
47
- 'skipped': f'{stats.skipped}',
48
- 'time': self._time_as_seconds(suite.elapsedtime),
49
- 'timestamp' : self._starttime_to_isoformat(suite.starttime)}
46
+ 'failures': str(stats.failed),
47
+ 'skipped': str(stats.skipped),
48
+ 'time': format(suite.elapsed_time.total_seconds(), '.3f'),
49
+ 'timestamp': suite.start_time.isoformat() if suite.start_time else None}
50
50
  self._writer.start('testsuite', attrs)
51
51
 
52
- def end_suite(self, suite):
52
+ def end_suite(self, suite: TestSuite):
53
53
  if suite.metadata or suite.doc:
54
54
  self._writer.start('properties')
55
55
  if suite.doc:
56
- self._writer.element('property', attrs={'name': 'Documentation', 'value': suite.doc})
56
+ self._writer.element('property', attrs={'name': 'Documentation',
57
+ 'value': suite.doc})
57
58
  for meta_name, meta_value in suite.metadata.items():
58
- self._writer.element('property', attrs={'name': meta_name, 'value': meta_value})
59
+ self._writer.element('property', attrs={'name': meta_name,
60
+ 'value': meta_value})
59
61
  self._writer.end('properties')
60
62
  self._writer.end('testsuite')
61
63
 
62
- def visit_test(self, test):
64
+ def visit_test(self, test: TestCase):
63
65
  self._writer.start('testcase',
64
- {'classname': test.parent.longname,
66
+ {'classname': test.parent.full_name,
65
67
  'name': test.name,
66
- 'time': self._time_as_seconds(test.elapsedtime)})
68
+ 'time': format(test.elapsed_time.total_seconds(), '.3f')})
67
69
  if test.failed:
68
70
  self._writer.element('failure', attrs={'message': test.message,
69
71
  'type': 'AssertionError'})
@@ -72,9 +74,6 @@ class XUnitFileWriter(ResultVisitor):
72
74
  'type': 'SkipExecution'})
73
75
  self._writer.end('testcase')
74
76
 
75
- def _time_as_seconds(self, millis):
76
- return format(millis / 1000, '.3f')
77
-
78
77
  def visit_keyword(self, kw):
79
78
  pass
80
79
 
@@ -86,8 +85,3 @@ class XUnitFileWriter(ResultVisitor):
86
85
 
87
86
  def end_result(self, result):
88
87
  self._writer.close()
89
-
90
- def _starttime_to_isoformat(self, stime):
91
- if not stime:
92
- return None
93
- return f'{stime[:4]}-{stime[4:6]}-{stime[6:8]}T{stime[9:22]}000'
@@ -38,7 +38,8 @@ __ http://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#
38
38
  """
39
39
 
40
40
  from .executionresult import Result
41
- from .model import (Break, Continue, Error, For, ForIteration, If, IfBranch, Keyword, Message,
42
- Return, TestCase, TestSuite, Try, TryBranch, While, WhileIteration)
41
+ from .model import (Break, Continue, Error, For, ForIteration, If, IfBranch, Keyword,
42
+ Message, Return, TestCase, TestSuite, Try, TryBranch, Var, While,
43
+ WhileIteration)
43
44
  from .resultbuilder import ExecutionResult, ExecutionResultBuilder
44
45
  from .visitor import ResultVisitor
@@ -14,7 +14,7 @@
14
14
  # limitations under the License.
15
15
 
16
16
  from robot import model
17
- from robot.utils import is_string, secs_to_timestamp, timestamp_to_secs
17
+ from robot.utils import is_string, parse_timestamp
18
18
 
19
19
 
20
20
  class SuiteConfigurer(model.SuiteConfigurer):
@@ -32,11 +32,11 @@ class SuiteConfigurer(model.SuiteConfigurer):
32
32
 
33
33
  def __init__(self, remove_keywords=None, log_level=None, start_time=None,
34
34
  end_time=None, **base_config):
35
- model.SuiteConfigurer.__init__(self, **base_config)
35
+ super().__init__(**base_config)
36
36
  self.remove_keywords = self._get_remove_keywords(remove_keywords)
37
37
  self.log_level = log_level
38
- self.start_time = self._get_time(start_time)
39
- self.end_time = self._get_time(end_time)
38
+ self.start_time = self._to_datetime(start_time)
39
+ self.end_time = self._to_datetime(end_time)
40
40
 
41
41
  def _get_remove_keywords(self, value):
42
42
  if value is None:
@@ -45,14 +45,13 @@ class SuiteConfigurer(model.SuiteConfigurer):
45
45
  return [value]
46
46
  return value
47
47
 
48
- def _get_time(self, timestamp):
48
+ def _to_datetime(self, timestamp):
49
49
  if not timestamp:
50
50
  return None
51
51
  try:
52
- secs = timestamp_to_secs(timestamp, seps=' :.-_')
52
+ return parse_timestamp(timestamp)
53
53
  except ValueError:
54
54
  return None
55
- return secs_to_timestamp(secs, millis=True)
56
55
 
57
56
  def visit_suite(self, suite):
58
57
  model.SuiteConfigurer.visit_suite(self, suite)
@@ -66,6 +65,10 @@ class SuiteConfigurer(model.SuiteConfigurer):
66
65
 
67
66
  def _set_times(self, suite):
68
67
  if self.start_time:
69
- suite.starttime = self.start_time
68
+ suite.end_time = suite.end_time # Preserve original value.
69
+ suite.elapsed_time = None # Force re-calculation.
70
+ suite.start_time = self.start_time
70
71
  if self.end_time:
71
- suite.endtime = self.end_time
72
+ suite.start_time = suite.start_time
73
+ suite.elapsed_time = None
74
+ suite.end_time = self.end_time
@@ -15,7 +15,7 @@
15
15
 
16
16
  from robot.errors import DataError
17
17
  from robot.model import TagPatterns
18
- from robot.utils import MultiMatcher, is_list_like
18
+ from robot.utils import MultiMatcher
19
19
 
20
20
 
21
21
  def validate_flatten_keyword(options):
@@ -34,7 +34,7 @@ def validate_flatten_keyword(options):
34
34
  class FlattenByTypeMatcher:
35
35
 
36
36
  def __init__(self, flatten):
37
- if not is_list_like(flatten):
37
+ if isinstance(flatten, str):
38
38
  flatten = [flatten]
39
39
  flatten = [f.lower() for f in flatten]
40
40
  self.types = set()
@@ -55,13 +55,13 @@ class FlattenByTypeMatcher:
55
55
  class FlattenByNameMatcher:
56
56
 
57
57
  def __init__(self, flatten):
58
- if not is_list_like(flatten):
58
+ if isinstance(flatten, str):
59
59
  flatten = [flatten]
60
60
  names = [n[5:] for n in flatten if n[:5].lower() == 'name:']
61
61
  self._matcher = MultiMatcher(names)
62
62
 
63
- def match(self, kwname, libname=None):
64
- name = '%s.%s' % (libname, kwname) if libname else kwname
63
+ def match(self, name, owner=None):
64
+ name = f'{owner}.{name}' if owner else name
65
65
  return self._matcher.match(name)
66
66
 
67
67
  def __bool__(self):
@@ -71,13 +71,13 @@ class FlattenByNameMatcher:
71
71
  class FlattenByTagMatcher:
72
72
 
73
73
  def __init__(self, flatten):
74
- if not is_list_like(flatten):
74
+ if isinstance(flatten, str):
75
75
  flatten = [flatten]
76
76
  patterns = [p[4:] for p in flatten if p[:4].lower() == 'tag:']
77
77
  self._matcher = TagPatterns(patterns)
78
78
 
79
- def match(self, kwtags):
80
- return self._matcher.match(kwtags)
79
+ def match(self, tags):
80
+ return self._matcher.match(tags)
81
81
 
82
82
  def __bool__(self):
83
83
  return bool(self._matcher)
@@ -13,37 +13,40 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
+ from abc import ABC
17
+
16
18
  from robot.errors import DataError
17
19
  from robot.model import SuiteVisitor, TagPattern
18
- from robot.utils import Matcher, plural_or_not
19
-
20
-
21
- def KeywordRemover(how):
22
- upper = how.upper()
23
- if upper.startswith('NAME:'):
24
- return ByNameKeywordRemover(pattern=how[5:])
25
- if upper.startswith('TAG:'):
26
- return ByTagKeywordRemover(pattern=how[4:])
27
- try:
28
- return {'ALL': AllKeywordsRemover,
29
- 'PASSED': PassedKeywordRemover,
30
- 'FOR': ForLoopItemsRemover,
31
- 'WHILE': WhileLoopItemsRemover,
32
- 'WUKS': WaitUntilKeywordSucceedsRemover}[upper]()
33
- except KeyError:
34
- raise DataError(f"Expected 'ALL', 'PASSED', 'NAME:<pattern>', 'TAG:<pattern>', "
35
- f"'FOR' or 'WUKS', got '{how}'.")
20
+ from robot.utils import html_escape, Matcher, plural_or_not
36
21
 
37
22
 
38
- class _KeywordRemover(SuiteVisitor):
39
- _message = 'Keyword data removed using --RemoveKeywords option.'
23
+ class KeywordRemover(SuiteVisitor, ABC):
24
+ message = 'Content removed using the --remove-keywords option.'
40
25
 
41
26
  def __init__(self):
42
- self._removal_message = RemovalMessage(self._message)
27
+ self.removal_message = RemovalMessage(self.message)
28
+
29
+ @classmethod
30
+ def from_config(cls, conf):
31
+ upper = conf.upper()
32
+ if upper.startswith('NAME:'):
33
+ return ByNameKeywordRemover(pattern=conf[5:])
34
+ if upper.startswith('TAG:'):
35
+ return ByTagKeywordRemover(pattern=conf[4:])
36
+ try:
37
+ return {'ALL': AllKeywordsRemover,
38
+ 'PASSED': PassedKeywordRemover,
39
+ 'FOR': ForLoopItemsRemover,
40
+ 'WHILE': WhileLoopItemsRemover,
41
+ 'WUKS': WaitUntilKeywordSucceedsRemover}[upper]()
42
+ except KeyError:
43
+ raise DataError(f"Expected 'ALL', 'PASSED', 'NAME:<pattern>', "
44
+ f"'TAG:<pattern>', 'FOR' or 'WUKS', got '{conf}'.")
43
45
 
44
46
  def _clear_content(self, item):
45
- item.body.clear()
46
- self._removal_message.set(item)
47
+ if item.body:
48
+ item.body.clear()
49
+ self.removal_message.set_to(item)
47
50
 
48
51
  def _failed_or_warning_or_error(self, item):
49
52
  return not item.passed or self._warning_or_error(item)
@@ -54,19 +57,25 @@ class _KeywordRemover(SuiteVisitor):
54
57
  return finder.found
55
58
 
56
59
 
57
- class AllKeywordsRemover(_KeywordRemover):
60
+ class AllKeywordsRemover(KeywordRemover):
58
61
 
59
- def visit_keyword(self, keyword):
60
- self._clear_content(keyword)
62
+ def start_body_item(self, item):
63
+ self._clear_content(item)
61
64
 
62
- def visit_for(self, for_):
63
- self._clear_content(for_)
65
+ def start_if(self, item):
66
+ pass
64
67
 
65
- def visit_if_branch(self, branch):
66
- self._clear_content(branch)
68
+ def start_if_branch(self, item):
69
+ self._clear_content(item)
67
70
 
71
+ def start_try(self, item):
72
+ pass
73
+
74
+ def start_try_branch(self, item):
75
+ self._clear_content(item)
68
76
 
69
- class PassedKeywordRemover(_KeywordRemover):
77
+
78
+ class PassedKeywordRemover(KeywordRemover):
70
79
 
71
80
  def start_suite(self, suite):
72
81
  if not suite.statistics.failed:
@@ -76,28 +85,28 @@ class PassedKeywordRemover(_KeywordRemover):
76
85
 
77
86
  def visit_test(self, test):
78
87
  if not self._failed_or_warning_or_error(test):
79
- for keyword in test.body:
80
- self._clear_content(keyword)
88
+ for item in test.body:
89
+ self._clear_content(item)
81
90
 
82
91
  def visit_keyword(self, keyword):
83
92
  pass
84
93
 
85
94
 
86
- class ByNameKeywordRemover(_KeywordRemover):
95
+ class ByNameKeywordRemover(KeywordRemover):
87
96
 
88
97
  def __init__(self, pattern):
89
- _KeywordRemover.__init__(self)
98
+ super().__init__()
90
99
  self._matcher = Matcher(pattern, ignore='_')
91
100
 
92
101
  def start_keyword(self, kw):
93
- if self._matcher.match(kw.name) and not self._warning_or_error(kw):
102
+ if self._matcher.match(kw.full_name) and not self._warning_or_error(kw):
94
103
  self._clear_content(kw)
95
104
 
96
105
 
97
- class ByTagKeywordRemover(_KeywordRemover):
106
+ class ByTagKeywordRemover(KeywordRemover):
98
107
 
99
108
  def __init__(self, pattern):
100
- _KeywordRemover.__init__(self)
109
+ super().__init__()
101
110
  self._pattern = TagPattern.from_string(pattern)
102
111
 
103
112
  def start_keyword(self, kw):
@@ -105,13 +114,13 @@ class ByTagKeywordRemover(_KeywordRemover):
105
114
  self._clear_content(kw)
106
115
 
107
116
 
108
- class _LoopItemsRemover(_KeywordRemover):
109
- _message = '%d passing step%s removed using --RemoveKeywords option.'
117
+ class LoopItemsRemover(KeywordRemover, ABC):
118
+ message = '{count} passing item{s} removed using the --remove-keywords option.'
110
119
 
111
120
  def _remove_from_loop(self, loop):
112
121
  before = len(loop.body)
113
122
  self._remove_keywords(loop.body)
114
- self._removal_message.set_if_removed(loop, before)
123
+ self.removal_message.set_to_if_removed(loop, before)
115
124
 
116
125
  def _remove_keywords(self, body):
117
126
  iterations = body.filter(messages=False)
@@ -120,26 +129,26 @@ class _LoopItemsRemover(_KeywordRemover):
120
129
  body.remove(it)
121
130
 
122
131
 
123
- class ForLoopItemsRemover(_LoopItemsRemover):
132
+ class ForLoopItemsRemover(LoopItemsRemover):
124
133
 
125
134
  def start_for(self, for_):
126
135
  self._remove_from_loop(for_)
127
136
 
128
137
 
129
- class WhileLoopItemsRemover(_LoopItemsRemover):
138
+ class WhileLoopItemsRemover(LoopItemsRemover):
130
139
 
131
140
  def start_while(self, while_):
132
141
  self._remove_from_loop(while_)
133
142
 
134
143
 
135
- class WaitUntilKeywordSucceedsRemover(_KeywordRemover):
136
- _message = '%d failing step%s removed using --RemoveKeywords option.'
144
+ class WaitUntilKeywordSucceedsRemover(KeywordRemover):
145
+ message = '{count} failing item{s} removed using the --remove-keywords option.'
137
146
 
138
147
  def start_keyword(self, kw):
139
- if kw.libname == 'BuiltIn' and kw.kwname == 'Wait Until Keyword Succeeds':
148
+ if kw.owner == 'BuiltIn' and kw.name == 'Wait Until Keyword Succeeds':
140
149
  before = len(kw.body)
141
150
  self._remove_keywords(kw.body)
142
- self._removal_message.set_if_removed(kw, before)
151
+ self.removal_message.set_to_if_removed(kw, before)
143
152
 
144
153
  def _remove_keywords(self, body):
145
154
  keywords = body.filter(messages=False)
@@ -172,12 +181,20 @@ class WarningAndErrorFinder(SuiteVisitor):
172
181
  class RemovalMessage:
173
182
 
174
183
  def __init__(self, message):
175
- self._message = message
184
+ self.message = message
176
185
 
177
- def set_if_removed(self, kw, len_before):
178
- removed = len_before - len(kw.body)
186
+ def set_to_if_removed(self, item, len_before):
187
+ removed = len_before - len(item.body)
179
188
  if removed:
180
- self.set(kw, self._message % (removed, plural_or_not(removed)))
181
-
182
- def set(self, kw, message=None):
183
- kw.doc = ('%s\n\n_%s_' % (kw.doc, message or self._message)).strip()
189
+ message = self.message.format(count=removed, s=plural_or_not(removed))
190
+ self.set_to(item, message)
191
+
192
+ def set_to(self, item, message=None):
193
+ if not item.message:
194
+ start = ''
195
+ elif item.message.startswith('*HTML*'):
196
+ start = item.message[6:].strip() + '<hr>'
197
+ else:
198
+ start = html_escape(item.message) + '<hr>'
199
+ message = message or self.message
200
+ item.message = f'*HTML* {start}<span class="robot-note">{message}</span>'