behavex 4.2.3__tar.gz → 4.2.4__tar.gz

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 (242) hide show
  1. {behavex-4.2.3/behavex.egg-info → behavex-4.2.4}/PKG-INFO +2 -2
  2. {behavex-4.2.3 → behavex-4.2.4}/behavex/arguments.py +0 -1
  3. {behavex-4.2.3 → behavex-4.2.4}/behavex/conf_logging.cfg +2 -2
  4. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/formatter_manager.py +25 -22
  5. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/formatters/allure_behavex_formatter.py +22 -13
  6. {behavex-4.2.3 → behavex-4.2.4}/behavex/runner.py +21 -2
  7. {behavex-4.2.3 → behavex-4.2.4}/behavex/utils.py +1 -1
  8. {behavex-4.2.3 → behavex-4.2.4/behavex.egg-info}/PKG-INFO +2 -2
  9. {behavex-4.2.3 → behavex-4.2.4}/behavex.egg-info/requires.txt +1 -1
  10. {behavex-4.2.3 → behavex-4.2.4}/pyproject.toml +2 -2
  11. {behavex-4.2.3 → behavex-4.2.4}/setup.py +2 -2
  12. behavex-4.2.4/tests/features/environment.py +13 -0
  13. behavex-4.2.4/tests/features/secondary_features/environment.py +16 -0
  14. {behavex-4.2.3 → behavex-4.2.4}/tests/features/secondary_features/steps/generic_secondary_steps.py +39 -0
  15. {behavex-4.2.3 → behavex-4.2.4}/tests/features/steps/execution_steps.py +114 -0
  16. behavex-4.2.3/tests/features/environment.py +0 -3
  17. behavex-4.2.3/tests/features/secondary_features/environment.py +0 -6
  18. {behavex-4.2.3 → behavex-4.2.4}/LICENSE +0 -0
  19. {behavex-4.2.3 → behavex-4.2.4}/MANIFEST.in +0 -0
  20. {behavex-4.2.3 → behavex-4.2.4}/README.md +0 -0
  21. {behavex-4.2.3 → behavex-4.2.4}/behavex/.DS_Store +0 -0
  22. {behavex-4.2.3 → behavex-4.2.4}/behavex/__init__.py +0 -0
  23. {behavex-4.2.3 → behavex-4.2.4}/behavex/__main__.py +0 -0
  24. {behavex-4.2.3 → behavex-4.2.4}/behavex/__pycache__/__init__.cpython-310.pyc +0 -0
  25. {behavex-4.2.3 → behavex-4.2.4}/behavex/__pycache__/__init__.cpython-39.pyc +0 -0
  26. {behavex-4.2.3 → behavex-4.2.4}/behavex/__pycache__/__main__.cpython-310.pyc +0 -0
  27. {behavex-4.2.3 → behavex-4.2.4}/behavex/__pycache__/__main__.cpython-39.pyc +0 -0
  28. {behavex-4.2.3 → behavex-4.2.4}/behavex/__pycache__/arguments.cpython-310.pyc +0 -0
  29. {behavex-4.2.3 → behavex-4.2.4}/behavex/__pycache__/arguments.cpython-39.pyc +0 -0
  30. {behavex-4.2.3 → behavex-4.2.4}/behavex/__pycache__/conf_mgr.cpython-310.pyc +0 -0
  31. {behavex-4.2.3 → behavex-4.2.4}/behavex/__pycache__/conf_mgr.cpython-39.pyc +0 -0
  32. {behavex-4.2.3 → behavex-4.2.4}/behavex/__pycache__/environment.cpython-310.pyc +0 -0
  33. {behavex-4.2.3 → behavex-4.2.4}/behavex/__pycache__/environment.cpython-39.pyc +0 -0
  34. {behavex-4.2.3 → behavex-4.2.4}/behavex/__pycache__/execution_singleton.cpython-310.pyc +0 -0
  35. {behavex-4.2.3 → behavex-4.2.4}/behavex/__pycache__/execution_singleton.cpython-39.pyc +0 -0
  36. {behavex-4.2.3 → behavex-4.2.4}/behavex/__pycache__/global_vars.cpython-310.pyc +0 -0
  37. {behavex-4.2.3 → behavex-4.2.4}/behavex/__pycache__/global_vars.cpython-39.pyc +0 -0
  38. {behavex-4.2.3 → behavex-4.2.4}/behavex/__pycache__/progress_bar.cpython-310.pyc +0 -0
  39. {behavex-4.2.3 → behavex-4.2.4}/behavex/__pycache__/progress_bar.cpython-39.pyc +0 -0
  40. {behavex-4.2.3 → behavex-4.2.4}/behavex/__pycache__/runner.cpython-310.pyc +0 -0
  41. {behavex-4.2.3 → behavex-4.2.4}/behavex/__pycache__/runner.cpython-39.pyc +0 -0
  42. {behavex-4.2.3 → behavex-4.2.4}/behavex/__pycache__/utils.cpython-310.pyc +0 -0
  43. {behavex-4.2.3 → behavex-4.2.4}/behavex/__pycache__/utils.cpython-39.pyc +0 -0
  44. {behavex-4.2.3 → behavex-4.2.4}/behavex/conf_behavex.cfg +0 -0
  45. {behavex-4.2.3 → behavex-4.2.4}/behavex/conf_mgr.py +0 -0
  46. {behavex-4.2.3 → behavex-4.2.4}/behavex/environment.py +0 -0
  47. {behavex-4.2.3 → behavex-4.2.4}/behavex/execution_singleton.py +0 -0
  48. {behavex-4.2.3 → behavex-4.2.4}/behavex/global_vars.py +0 -0
  49. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/__init__.py +0 -0
  50. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/__pycache__/__init__.cpython-310.pyc +0 -0
  51. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/__pycache__/__init__.cpython-39.pyc +0 -0
  52. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/__pycache__/formatter_manager.cpython-310.pyc +0 -0
  53. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/__pycache__/formatter_manager.cpython-39.pyc +0 -0
  54. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/__pycache__/jinja_mgr.cpython-310.pyc +0 -0
  55. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/__pycache__/jinja_mgr.cpython-39.pyc +0 -0
  56. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/__pycache__/output_strings.cpython-310.pyc +0 -0
  57. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/__pycache__/output_strings.cpython-39.pyc +0 -0
  58. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/__pycache__/report_html.cpython-310.pyc +0 -0
  59. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/__pycache__/report_html.cpython-39.pyc +0 -0
  60. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/__pycache__/report_json.cpython-310.pyc +0 -0
  61. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/__pycache__/report_json.cpython-39.pyc +0 -0
  62. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/__pycache__/report_utils.cpython-310.pyc +0 -0
  63. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/__pycache__/report_utils.cpython-39.pyc +0 -0
  64. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/__pycache__/report_xml.cpython-310.pyc +0 -0
  65. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/__pycache__/report_xml.cpython-39.pyc +0 -0
  66. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/bootstrap/css/behavex.css +0 -0
  67. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/bootstrap/css/bootstrap-theme.css +0 -0
  68. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/bootstrap/css/bootstrap-theme.min.css +0 -0
  69. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/bootstrap/css/bootstrap-theme.min.css.map +0 -0
  70. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/bootstrap/css/bootstrap.css +0 -0
  71. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/bootstrap/css/bootstrap.min.css +0 -0
  72. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/bootstrap/css/bootstrap.min.css.map +0 -0
  73. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/bootstrap/css/pace-theme-loading-bar.min.css +0 -0
  74. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/bootstrap/fonts/glyphicons-halflings-regular.eot +0 -0
  75. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/bootstrap/fonts/glyphicons-halflings-regular.svg +0 -0
  76. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/bootstrap/fonts/glyphicons-halflings-regular.ttf +0 -0
  77. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/bootstrap/fonts/glyphicons-halflings-regular.woff +0 -0
  78. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/bootstrap/fonts/glyphicons-halflings-regular.woff2 +0 -0
  79. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/bootstrap/js/bootstrap.js +0 -0
  80. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/bootstrap/js/bootstrap.min.js +0 -0
  81. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/bootstrap/js/chart.js +0 -0
  82. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/bootstrap/js/jquery-1.11.0.min.js +0 -0
  83. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/bootstrap/js/jquery-ui.min.js +0 -0
  84. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/bootstrap/js/jquery.tablesorter.min.js +0 -0
  85. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/bootstrap/js/jquery.tooltipster.min.js +0 -0
  86. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/bootstrap/js/pace.min.js +0 -0
  87. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/formatters/__pycache__/allure_behavex_formatter.cpython-310.pyc +0 -0
  88. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/formatters/__pycache__/allure_behavex_formatter.cpython-39.pyc +0 -0
  89. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/jinja/base.jinja2 +0 -0
  90. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/jinja/main.jinja2 +0 -0
  91. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/jinja/manifest.jinja2 +0 -0
  92. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/jinja/xml.jinja2 +0 -0
  93. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/jinja/xml_json.jinja2 +0 -0
  94. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/jinja_mgr.py +0 -0
  95. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/output_strings.py +0 -0
  96. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/report_html.py +0 -0
  97. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/report_json.py +0 -0
  98. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/report_utils.py +0 -0
  99. {behavex-4.2.3 → behavex-4.2.4}/behavex/outputs/report_xml.py +0 -0
  100. {behavex-4.2.3 → behavex-4.2.4}/behavex/progress_bar.py +0 -0
  101. {behavex-4.2.3 → behavex-4.2.4}/behavex/steps/__init__.py +0 -0
  102. {behavex-4.2.3 → behavex-4.2.4}/behavex.egg-info/SOURCES.txt +0 -0
  103. {behavex-4.2.3 → behavex-4.2.4}/behavex.egg-info/dependency_links.txt +0 -0
  104. {behavex-4.2.3 → behavex-4.2.4}/behavex.egg-info/entry_points.txt +0 -0
  105. {behavex-4.2.3 → behavex-4.2.4}/behavex.egg-info/top_level.txt +0 -0
  106. {behavex-4.2.3 → behavex-4.2.4}/docs/conf.py +0 -0
  107. {behavex-4.2.3 → behavex-4.2.4}/output/focused_test_run/outputs/logs/image_attachments_utils/__init__.py +0 -0
  108. {behavex-4.2.3 → behavex-4.2.4}/output/full_test_run/outputs/logs/image_attachments_utils/__init__.py +0 -0
  109. {behavex-4.2.3 → behavex-4.2.4}/output/image_test_verification/outputs/logs/image_attachments_utils/__init__.py +0 -0
  110. {behavex-4.2.3 → behavex-4.2.4}/output/output_001349/outputs/logs/image_attachments_utils/__init__.py +0 -0
  111. {behavex-4.2.3 → behavex-4.2.4}/output/output_003713/outputs/logs/image_attachments_utils/__init__.py +0 -0
  112. {behavex-4.2.3 → behavex-4.2.4}/output/output_004697/outputs/logs/image_attachments_utils/__init__.py +0 -0
  113. {behavex-4.2.3 → behavex-4.2.4}/output/output_006245/outputs/logs/image_attachments_utils/__init__.py +0 -0
  114. {behavex-4.2.3 → behavex-4.2.4}/output/output_008581/outputs/logs/image_attachments_utils/__init__.py +0 -0
  115. {behavex-4.2.3 → behavex-4.2.4}/output/output_014810/outputs/logs/image_attachments_utils/__init__.py +0 -0
  116. {behavex-4.2.3 → behavex-4.2.4}/output/output_034257/outputs/logs/image_attachments_utils/__init__.py +0 -0
  117. {behavex-4.2.3 → behavex-4.2.4}/output/output_049842/outputs/logs/image_attachments_utils/__init__.py +0 -0
  118. {behavex-4.2.3 → behavex-4.2.4}/output/output_057264/outputs/logs/image_attachments_utils/__init__.py +0 -0
  119. {behavex-4.2.3 → behavex-4.2.4}/output/output_065267/outputs/logs/image_attachments_utils/__init__.py +0 -0
  120. {behavex-4.2.3 → behavex-4.2.4}/output/output_071651/outputs/logs/image_attachments_utils/__init__.py +0 -0
  121. {behavex-4.2.3 → behavex-4.2.4}/output/output_080858/outputs/logs/image_attachments_utils/__init__.py +0 -0
  122. {behavex-4.2.3 → behavex-4.2.4}/output/output_107483/outputs/logs/image_attachments_utils/__init__.py +0 -0
  123. {behavex-4.2.3 → behavex-4.2.4}/output/output_116700/outputs/logs/image_attachments_utils/__init__.py +0 -0
  124. {behavex-4.2.3 → behavex-4.2.4}/output/output_120092/outputs/logs/image_attachments_utils/__init__.py +0 -0
  125. {behavex-4.2.3 → behavex-4.2.4}/output/output_140259/outputs/logs/image_attachments_utils/__init__.py +0 -0
  126. {behavex-4.2.3 → behavex-4.2.4}/output/output_143213/outputs/logs/image_attachments_utils/__init__.py +0 -0
  127. {behavex-4.2.3 → behavex-4.2.4}/output/output_146320/outputs/logs/image_attachments_utils/__init__.py +0 -0
  128. {behavex-4.2.3 → behavex-4.2.4}/output/output_146403/outputs/logs/image_attachments_utils/__init__.py +0 -0
  129. {behavex-4.2.3 → behavex-4.2.4}/output/output_154070/outputs/logs/image_attachments_utils/__init__.py +0 -0
  130. {behavex-4.2.3 → behavex-4.2.4}/output/output_159339/outputs/logs/image_attachments_utils/__init__.py +0 -0
  131. {behavex-4.2.3 → behavex-4.2.4}/output/output_164111/outputs/logs/image_attachments_utils/__init__.py +0 -0
  132. {behavex-4.2.3 → behavex-4.2.4}/output/output_188075/outputs/logs/image_attachments_utils/__init__.py +0 -0
  133. {behavex-4.2.3 → behavex-4.2.4}/output/output_189804/outputs/logs/image_attachments_utils/__init__.py +0 -0
  134. {behavex-4.2.3 → behavex-4.2.4}/output/output_195102/outputs/logs/image_attachments_utils/__init__.py +0 -0
  135. {behavex-4.2.3 → behavex-4.2.4}/output/output_206620/outputs/logs/image_attachments_utils/__init__.py +0 -0
  136. {behavex-4.2.3 → behavex-4.2.4}/output/output_238600/outputs/logs/image_attachments_utils/__init__.py +0 -0
  137. {behavex-4.2.3 → behavex-4.2.4}/output/output_251312/outputs/logs/image_attachments_utils/__init__.py +0 -0
  138. {behavex-4.2.3 → behavex-4.2.4}/output/output_260546/outputs/logs/image_attachments_utils/__init__.py +0 -0
  139. {behavex-4.2.3 → behavex-4.2.4}/output/output_288178/outputs/logs/image_attachments_utils/__init__.py +0 -0
  140. {behavex-4.2.3 → behavex-4.2.4}/output/output_304378/outputs/logs/image_attachments_utils/__init__.py +0 -0
  141. {behavex-4.2.3 → behavex-4.2.4}/output/output_323270/outputs/logs/image_attachments_utils/__init__.py +0 -0
  142. {behavex-4.2.3 → behavex-4.2.4}/output/output_328507/outputs/logs/image_attachments_utils/__init__.py +0 -0
  143. {behavex-4.2.3 → behavex-4.2.4}/output/output_344685/outputs/logs/image_attachments_utils/__init__.py +0 -0
  144. {behavex-4.2.3 → behavex-4.2.4}/output/output_344776/outputs/logs/image_attachments_utils/__init__.py +0 -0
  145. {behavex-4.2.3 → behavex-4.2.4}/output/output_344852/outputs/logs/image_attachments_utils/__init__.py +0 -0
  146. {behavex-4.2.3 → behavex-4.2.4}/output/output_348748/outputs/logs/image_attachments_utils/__init__.py +0 -0
  147. {behavex-4.2.3 → behavex-4.2.4}/output/output_372668/outputs/logs/image_attachments_utils/__init__.py +0 -0
  148. {behavex-4.2.3 → behavex-4.2.4}/output/output_376424/outputs/logs/image_attachments_utils/__init__.py +0 -0
  149. {behavex-4.2.3 → behavex-4.2.4}/output/output_382185/outputs/logs/image_attachments_utils/__init__.py +0 -0
  150. {behavex-4.2.3 → behavex-4.2.4}/output/output_405504/outputs/logs/image_attachments_utils/__init__.py +0 -0
  151. {behavex-4.2.3 → behavex-4.2.4}/output/output_422012/outputs/logs/image_attachments_utils/__init__.py +0 -0
  152. {behavex-4.2.3 → behavex-4.2.4}/output/output_423021/outputs/logs/image_attachments_utils/__init__.py +0 -0
  153. {behavex-4.2.3 → behavex-4.2.4}/output/output_426722/outputs/logs/image_attachments_utils/__init__.py +0 -0
  154. {behavex-4.2.3 → behavex-4.2.4}/output/output_434999/outputs/logs/image_attachments_utils/__init__.py +0 -0
  155. {behavex-4.2.3 → behavex-4.2.4}/output/output_435402/outputs/logs/image_attachments_utils/__init__.py +0 -0
  156. {behavex-4.2.3 → behavex-4.2.4}/output/output_440809/outputs/logs/image_attachments_utils/__init__.py +0 -0
  157. {behavex-4.2.3 → behavex-4.2.4}/output/output_449330/outputs/logs/image_attachments_utils/__init__.py +0 -0
  158. {behavex-4.2.3 → behavex-4.2.4}/output/output_450637/outputs/logs/image_attachments_utils/__init__.py +0 -0
  159. {behavex-4.2.3 → behavex-4.2.4}/output/output_450881/outputs/logs/image_attachments_utils/__init__.py +0 -0
  160. {behavex-4.2.3 → behavex-4.2.4}/output/output_465338/outputs/logs/image_attachments_utils/__init__.py +0 -0
  161. {behavex-4.2.3 → behavex-4.2.4}/output/output_475651/outputs/logs/image_attachments_utils/__init__.py +0 -0
  162. {behavex-4.2.3 → behavex-4.2.4}/output/output_479506/outputs/logs/image_attachments_utils/__init__.py +0 -0
  163. {behavex-4.2.3 → behavex-4.2.4}/output/output_489113/outputs/logs/image_attachments_utils/__init__.py +0 -0
  164. {behavex-4.2.3 → behavex-4.2.4}/output/output_495088/outputs/logs/image_attachments_utils/__init__.py +0 -0
  165. {behavex-4.2.3 → behavex-4.2.4}/output/output_496889/outputs/logs/image_attachments_utils/__init__.py +0 -0
  166. {behavex-4.2.3 → behavex-4.2.4}/output/output_497394/outputs/logs/image_attachments_utils/__init__.py +0 -0
  167. {behavex-4.2.3 → behavex-4.2.4}/output/output_540969/outputs/logs/image_attachments_utils/__init__.py +0 -0
  168. {behavex-4.2.3 → behavex-4.2.4}/output/output_574360/outputs/logs/image_attachments_utils/__init__.py +0 -0
  169. {behavex-4.2.3 → behavex-4.2.4}/output/output_577418/outputs/logs/image_attachments_utils/__init__.py +0 -0
  170. {behavex-4.2.3 → behavex-4.2.4}/output/output_579891/outputs/logs/image_attachments_utils/__init__.py +0 -0
  171. {behavex-4.2.3 → behavex-4.2.4}/output/output_588144/outputs/logs/image_attachments_utils/__init__.py +0 -0
  172. {behavex-4.2.3 → behavex-4.2.4}/output/output_590886/outputs/logs/image_attachments_utils/__init__.py +0 -0
  173. {behavex-4.2.3 → behavex-4.2.4}/output/output_596667/outputs/logs/image_attachments_utils/__init__.py +0 -0
  174. {behavex-4.2.3 → behavex-4.2.4}/output/output_601328/outputs/logs/image_attachments_utils/__init__.py +0 -0
  175. {behavex-4.2.3 → behavex-4.2.4}/output/output_602191/outputs/logs/image_attachments_utils/__init__.py +0 -0
  176. {behavex-4.2.3 → behavex-4.2.4}/output/output_631745/outputs/logs/image_attachments_utils/__init__.py +0 -0
  177. {behavex-4.2.3 → behavex-4.2.4}/output/output_634385/outputs/logs/image_attachments_utils/__init__.py +0 -0
  178. {behavex-4.2.3 → behavex-4.2.4}/output/output_646388/outputs/logs/image_attachments_utils/__init__.py +0 -0
  179. {behavex-4.2.3 → behavex-4.2.4}/output/output_654650/outputs/logs/image_attachments_utils/__init__.py +0 -0
  180. {behavex-4.2.3 → behavex-4.2.4}/output/output_656366/outputs/logs/image_attachments_utils/__init__.py +0 -0
  181. {behavex-4.2.3 → behavex-4.2.4}/output/output_678770/outputs/logs/image_attachments_utils/__init__.py +0 -0
  182. {behavex-4.2.3 → behavex-4.2.4}/output/output_680470/outputs/logs/image_attachments_utils/__init__.py +0 -0
  183. {behavex-4.2.3 → behavex-4.2.4}/output/output_683436/outputs/logs/image_attachments_utils/__init__.py +0 -0
  184. {behavex-4.2.3 → behavex-4.2.4}/output/output_685176/outputs/logs/image_attachments_utils/__init__.py +0 -0
  185. {behavex-4.2.3 → behavex-4.2.4}/output/output_689341/outputs/logs/image_attachments_utils/__init__.py +0 -0
  186. {behavex-4.2.3 → behavex-4.2.4}/output/output_691007/outputs/logs/image_attachments_utils/__init__.py +0 -0
  187. {behavex-4.2.3 → behavex-4.2.4}/output/output_695521/outputs/logs/image_attachments_utils/__init__.py +0 -0
  188. {behavex-4.2.3 → behavex-4.2.4}/output/output_703468/outputs/logs/image_attachments_utils/__init__.py +0 -0
  189. {behavex-4.2.3 → behavex-4.2.4}/output/output_704571/outputs/logs/image_attachments_utils/__init__.py +0 -0
  190. {behavex-4.2.3 → behavex-4.2.4}/output/output_710568/outputs/logs/image_attachments_utils/__init__.py +0 -0
  191. {behavex-4.2.3 → behavex-4.2.4}/output/output_711677/outputs/logs/image_attachments_utils/__init__.py +0 -0
  192. {behavex-4.2.3 → behavex-4.2.4}/output/output_719414/outputs/logs/image_attachments_utils/__init__.py +0 -0
  193. {behavex-4.2.3 → behavex-4.2.4}/output/output_723957/outputs/logs/image_attachments_utils/__init__.py +0 -0
  194. {behavex-4.2.3 → behavex-4.2.4}/output/output_724106/outputs/logs/image_attachments_utils/__init__.py +0 -0
  195. {behavex-4.2.3 → behavex-4.2.4}/output/output_725084/outputs/logs/image_attachments_utils/__init__.py +0 -0
  196. {behavex-4.2.3 → behavex-4.2.4}/output/output_732485/outputs/logs/image_attachments_utils/__init__.py +0 -0
  197. {behavex-4.2.3 → behavex-4.2.4}/output/output_732517/outputs/logs/image_attachments_utils/__init__.py +0 -0
  198. {behavex-4.2.3 → behavex-4.2.4}/output/output_742134/outputs/logs/image_attachments_utils/__init__.py +0 -0
  199. {behavex-4.2.3 → behavex-4.2.4}/output/output_756176/outputs/logs/image_attachments_utils/__init__.py +0 -0
  200. {behavex-4.2.3 → behavex-4.2.4}/output/output_767286/outputs/logs/image_attachments_utils/__init__.py +0 -0
  201. {behavex-4.2.3 → behavex-4.2.4}/output/output_773557/outputs/logs/image_attachments_utils/__init__.py +0 -0
  202. {behavex-4.2.3 → behavex-4.2.4}/output/output_787703/outputs/logs/image_attachments_utils/__init__.py +0 -0
  203. {behavex-4.2.3 → behavex-4.2.4}/output/output_798702/outputs/logs/image_attachments_utils/__init__.py +0 -0
  204. {behavex-4.2.3 → behavex-4.2.4}/output/output_803377/outputs/logs/image_attachments_utils/__init__.py +0 -0
  205. {behavex-4.2.3 → behavex-4.2.4}/output/output_818000/outputs/logs/image_attachments_utils/__init__.py +0 -0
  206. {behavex-4.2.3 → behavex-4.2.4}/output/output_821244/outputs/logs/image_attachments_utils/__init__.py +0 -0
  207. {behavex-4.2.3 → behavex-4.2.4}/output/output_841973/outputs/logs/image_attachments_utils/__init__.py +0 -0
  208. {behavex-4.2.3 → behavex-4.2.4}/output/output_843772/outputs/logs/image_attachments_utils/__init__.py +0 -0
  209. {behavex-4.2.3 → behavex-4.2.4}/output/output_851821/outputs/logs/image_attachments_utils/__init__.py +0 -0
  210. {behavex-4.2.3 → behavex-4.2.4}/output/output_852322/outputs/logs/image_attachments_utils/__init__.py +0 -0
  211. {behavex-4.2.3 → behavex-4.2.4}/output/output_857146/outputs/logs/image_attachments_utils/__init__.py +0 -0
  212. {behavex-4.2.3 → behavex-4.2.4}/output/output_858906/outputs/logs/image_attachments_utils/__init__.py +0 -0
  213. {behavex-4.2.3 → behavex-4.2.4}/output/output_867706/outputs/logs/image_attachments_utils/__init__.py +0 -0
  214. {behavex-4.2.3 → behavex-4.2.4}/output/output_868972/outputs/logs/image_attachments_utils/__init__.py +0 -0
  215. {behavex-4.2.3 → behavex-4.2.4}/output/output_886897/outputs/logs/image_attachments_utils/__init__.py +0 -0
  216. {behavex-4.2.3 → behavex-4.2.4}/output/output_891058/outputs/logs/image_attachments_utils/__init__.py +0 -0
  217. {behavex-4.2.3 → behavex-4.2.4}/output/output_892919/outputs/logs/image_attachments_utils/__init__.py +0 -0
  218. {behavex-4.2.3 → behavex-4.2.4}/output/output_907134/outputs/logs/image_attachments_utils/__init__.py +0 -0
  219. {behavex-4.2.3 → behavex-4.2.4}/output/output_909239/outputs/logs/image_attachments_utils/__init__.py +0 -0
  220. {behavex-4.2.3 → behavex-4.2.4}/output/output_932996/outputs/logs/image_attachments_utils/__init__.py +0 -0
  221. {behavex-4.2.3 → behavex-4.2.4}/output/output_936717/outputs/logs/image_attachments_utils/__init__.py +0 -0
  222. {behavex-4.2.3 → behavex-4.2.4}/output/output_940684/outputs/logs/image_attachments_utils/__init__.py +0 -0
  223. {behavex-4.2.3 → behavex-4.2.4}/output/output_945860/outputs/logs/image_attachments_utils/__init__.py +0 -0
  224. {behavex-4.2.3 → behavex-4.2.4}/output/output_947760/outputs/logs/image_attachments_utils/__init__.py +0 -0
  225. {behavex-4.2.3 → behavex-4.2.4}/output/output_952517/outputs/logs/image_attachments_utils/__init__.py +0 -0
  226. {behavex-4.2.3 → behavex-4.2.4}/output/output_955858/outputs/logs/image_attachments_utils/__init__.py +0 -0
  227. {behavex-4.2.3 → behavex-4.2.4}/output/output_959703/outputs/logs/image_attachments_utils/__init__.py +0 -0
  228. {behavex-4.2.3 → behavex-4.2.4}/output/output_969405/outputs/logs/image_attachments_utils/__init__.py +0 -0
  229. {behavex-4.2.3 → behavex-4.2.4}/output/output_972545/outputs/logs/image_attachments_utils/__init__.py +0 -0
  230. {behavex-4.2.3 → behavex-4.2.4}/output/outputs/logs/image_attachments_utils/__init__.py +0 -0
  231. {behavex-4.2.3 → behavex-4.2.4}/setup.cfg +0 -0
  232. {behavex-4.2.3 → behavex-4.2.4}/tests/features/crashing_features/environment.py +0 -0
  233. {behavex-4.2.3 → behavex-4.2.4}/tests/features/crashing_features/steps/__init__.py +0 -0
  234. {behavex-4.2.3 → behavex-4.2.4}/tests/features/crashing_features/steps/crashing_steps.py +0 -0
  235. {behavex-4.2.3 → behavex-4.2.4}/tests/features/secondary_features/__init__.py +0 -0
  236. {behavex-4.2.3 → behavex-4.2.4}/tests/features/secondary_features/steps/__init__.py +0 -0
  237. {behavex-4.2.3 → behavex-4.2.4}/tests/features/secondary_features/steps/allure_formatter_secondary_steps.py +0 -0
  238. {behavex-4.2.3 → behavex-4.2.4}/tests/features/steps/__init__.py +0 -0
  239. {behavex-4.2.3 → behavex-4.2.4}/tests/features/steps/allure_formatter_steps.py +0 -0
  240. {behavex-4.2.3 → behavex-4.2.4}/tests/features/steps/allure_formatter_unit_steps.py +0 -0
  241. {behavex-4.2.3 → behavex-4.2.4}/tests/features/steps/install_steps.py +0 -0
  242. {behavex-4.2.3 → behavex-4.2.4}/venv/bin/activate_this.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: behavex
3
- Version: 4.2.3
3
+ Version: 4.2.4
4
4
  Summary: Agile testing framework on top of Behave (BDD).
5
5
  Home-page: https://github.com/hrcorval/behavex
6
6
  Author: Hernan Rey
@@ -29,7 +29,7 @@ Requires-Python: >=3.5
29
29
  Description-Content-Type: text/markdown
30
30
  License-File: LICENSE
31
31
  Requires-Dist: behave==1.2.6
32
- Requires-Dist: behavex-images>=3.0.10
32
+ Requires-Dist: behavex-images>=3.2.1
33
33
  Requires-Dist: allure-python-commons
34
34
  Requires-Dist: jinja2
35
35
  Requires-Dist: configobj
@@ -333,7 +333,6 @@ def parse_arguments(args):
333
333
  '--formatter-outdir',
334
334
  help="Specify the output directory for the custom formatter relative to the output folder",
335
335
  metavar='DIR',
336
- default='report_artifacts',
337
336
  required=False,
338
337
  )
339
338
 
@@ -11,12 +11,12 @@ keys=simpleFormatter
11
11
  encoding=utf-8-sig
12
12
 
13
13
  [logger_root]
14
- level=DEBUG
14
+ level=INFO
15
15
  handlers=consoleHandler
16
16
 
17
17
  [handler_consoleHandler]
18
18
  class=StreamHandler
19
- level=DEBUG
19
+ level=INFO
20
20
  encoding=utf-8-sig
21
21
  formatter=simpleFormatter
22
22
  args=(sys.stdout, )
@@ -9,16 +9,20 @@ Formatter manager module to handle custom formatters.
9
9
  import importlib
10
10
  import os
11
11
  import sys
12
- from typing import Optional, Type
12
+ from typing import (Any, Dict, Optional, # pyright: ignore[reportDeprecated]
13
+ Type)
13
14
 
14
15
  from behavex.conf_mgr import get_env, get_param
15
16
 
17
+ # Formatter Constants
18
+ DEFAULT_FORMATTER_DIR = 'report-artifacts'
19
+
16
20
 
17
21
  class FormatterManager:
18
22
  """Manager class for handling custom formatters in BehaveX."""
19
23
 
20
24
  @staticmethod
21
- def load_formatter(formatter_spec: str) -> Optional[Type]:
25
+ def load_formatter(formatter_spec: str) -> Optional[Type[Any]]: #pyright: ignore[reportDeprecated]
22
26
  """
23
27
  Load a formatter class from a module path specification.
24
28
 
@@ -64,25 +68,27 @@ class FormatterManager:
64
68
  return None
65
69
 
66
70
  @staticmethod
67
- def get_formatter_output_dir() -> str:
71
+ def get_formatter_output_dir(formatter_spec: str) -> Optional[str]: #pyright: ignore[reportDeprecated]
68
72
  """
69
- Get the output directory for the custom formatter.
73
+ Get the preferred output directory from a formatter class.
74
+
75
+ Args:
76
+ formatter_spec: String in format "module_path:FormatterClass"
70
77
 
71
78
  Returns:
72
- Absolute path to the formatter output directory, or None if no custom directory is specified
79
+ The formatter's preferred output directory, or None if not found
73
80
  """
74
- base_output = get_env('OUTPUT', 'output')
75
- formatter_outdir = get_param('formatter_outdir', '')
76
-
77
- # Return None if no custom formatter output directory is specified
78
- # This allows formatters to use their own default directories
79
- if not formatter_outdir or formatter_outdir == 'report_artifacts':
80
- return None
81
+ try:
82
+ formatter_class = FormatterManager.load_formatter(formatter_spec)
83
+ if formatter_class and hasattr(formatter_class, 'DEFAULT_OUTPUT_DIR'):
84
+ return formatter_class.DEFAULT_OUTPUT_DIR
85
+ except Exception as e:
86
+ print(f"Warning: Could not load formatter {formatter_spec} to get output directory: {str(e)}")
81
87
 
82
- return os.path.join(base_output, formatter_outdir)
88
+ return None
83
89
 
84
90
  @staticmethod
85
- def format_results(json_output: dict) -> None:
91
+ def format_results(json_output: Dict[str, Any]) -> None: #pyright: ignore[reportDeprecated]
86
92
  """
87
93
  Format test results using the specified custom formatter.
88
94
 
@@ -97,20 +103,17 @@ class FormatterManager:
97
103
  if not formatter_class:
98
104
  return
99
105
 
100
- output_dir = FormatterManager.get_formatter_output_dir()
101
-
102
- # Create the output directory only if a custom one is specified
103
- if output_dir:
104
- os.makedirs(output_dir, exist_ok=True)
106
+ # The formatter will handle its own output directory setup
107
+ # No need to create directories here since formatters manage their own paths
105
108
 
106
109
  try:
107
110
  formatter = formatter_class()
108
111
  # Check if the formatter has the expected method
109
- if not hasattr(formatter, 'parse_json_to_allure'):
110
- print(f"Formatter {formatter_class.__name__} does not implement required method 'parse_json_to_allure'")
112
+ if not hasattr(formatter, 'launch_json_formatter'):
113
+ print(f"Formatter {formatter_class.__name__} does not implement required method 'launch_json_formatter'")
111
114
  return
112
115
 
113
- formatter.parse_json_to_allure(json_output)
116
+ formatter.launch_json_formatter(json_output)
114
117
  except Exception as e:
115
118
  print(f"Error running formatter {formatter_spec}: {str(e)}")
116
119
  import traceback
@@ -31,7 +31,6 @@ import os
31
31
  import re
32
32
  import sys
33
33
  import uuid
34
- from datetime import datetime
35
34
  from pathlib import Path
36
35
 
37
36
  from allure_commons.model2 import (Attachment, Parameter, TestResult,
@@ -40,13 +39,15 @@ from allure_commons.types import AttachmentType
40
39
  from allure_commons.utils import now
41
40
 
42
41
  from behavex.conf_mgr import get_env, get_param
43
- from behavex.outputs.formatter_manager import FormatterManager
44
42
  from behavex.outputs.report_utils import get_string_hash
45
43
 
46
44
 
47
45
  class AllureBehaveXFormatter:
48
46
  """Allure formatter for BehaveX test results."""
49
47
 
48
+ # Default output directory for this formatter
49
+ DEFAULT_OUTPUT_DIR = 'allure-results'
50
+
50
51
  def _get_step_line_from_image(self, filename):
51
52
  """Extract step line number from image filename.
52
53
 
@@ -243,7 +244,11 @@ class AllureBehaveXFormatter:
243
244
  TestResult: The updated test case with evidence attachments
244
245
  """
245
246
 
246
- evidence_dir = os.path.join(get_env('logs', 'output/allure-results'), str(scenario_hash), 'evidence')
247
+ logs_dir = get_env('logs')
248
+ if logs_dir is None:
249
+ # Handle standalone script execution case
250
+ logs_dir = os.path.join(os.path.dirname(output_dir), 'outputs', 'logs')
251
+ evidence_dir = os.path.join(logs_dir, str(scenario_hash), 'evidence')
247
252
 
248
253
  if not os.path.exists(evidence_dir):
249
254
  return test_case
@@ -297,19 +302,20 @@ class AllureBehaveXFormatter:
297
302
 
298
303
  return test_case
299
304
 
300
- def parse_json_to_allure(self, json_data):
305
+ def launch_json_formatter(self, json_data):
301
306
  """
302
- Parses the JSON report data and converts it into Allure-compatible results.
307
+ Generic method to launch the formatter and process JSON test results.
303
308
 
304
309
  Args:
305
310
  json_data (dict): Dictionary containing the test results data.
306
311
  """
307
- # Get the formatter output directory from FormatterManager
308
- formatter_output_dir = FormatterManager.get_formatter_output_dir()
312
+ # Use the LOGS environment variable which is set consistently by the runner
313
+ # This ensures evidence, logs, and allure results are all in the same location
314
+ output_dir = get_env('logs')
309
315
 
310
- # If a custom output directory is specified, use it.
311
- # Otherwise, default to 'output/allure-results'.
312
- output_dir = formatter_output_dir or os.path.join(get_env('OUTPUT', 'output'), 'allure-results')
316
+ # Fallback if LOGS is not set (for standalone script execution)
317
+ if not output_dir:
318
+ output_dir = os.path.join(get_env('OUTPUT') or 'output', self.DEFAULT_OUTPUT_DIR)
313
319
 
314
320
  os.makedirs(output_dir, exist_ok=True)
315
321
 
@@ -487,7 +493,11 @@ class AllureBehaveXFormatter:
487
493
  # Process scenario logs as attachment
488
494
  if get_param('formatter_attach_logs'):
489
495
  scenario_hash = scenario.get('identifier_hash', get_string_hash(f"{str(feature['filename'])}-{str(scenario['line'])}"))
490
- log_path = os.path.join(get_env('logs', 'output/allure-results'), str(scenario_hash), 'scenario.log')
496
+ logs_dir_for_log = get_env('logs')
497
+ if logs_dir_for_log is None:
498
+ # Handle standalone script execution case
499
+ logs_dir_for_log = os.path.join(os.path.dirname(output_dir), 'outputs', 'logs')
500
+ log_path = os.path.join(logs_dir_for_log, str(scenario_hash), 'scenario.log')
491
501
  if os.path.exists(log_path):
492
502
  # Use relative path for the source if possible to avoid duplication
493
503
  rel_path = os.path.relpath(log_path, output_dir) if output_dir in log_path else log_path
@@ -637,7 +647,6 @@ class AllureBehaveXFormatter:
637
647
  with open(os.path.join(output_dir, "environment-categories.json"), "w") as f:
638
648
  json.dump(env_categories, f, indent=2)
639
649
 
640
-
641
650
  def main():
642
651
  parser = argparse.ArgumentParser(description='Parse BehaveX report.json into Allure format')
643
652
  parser.add_argument('--report-path',
@@ -651,7 +660,7 @@ def main():
651
660
 
652
661
  try:
653
662
  with open(args.report_path) as f:
654
- formatter.parse_json_to_allure(json.load(f))
663
+ formatter.launch_json_formatter(json.load(f))
655
664
  except FileNotFoundError:
656
665
  print(f"Error: Could not find report file at {args.report_path}")
657
666
  sys.exit(1)
@@ -43,6 +43,8 @@ from behavex.environment import extend_behave_hooks
43
43
  from behavex.execution_singleton import ExecutionSingleton
44
44
  from behavex.global_vars import global_vars
45
45
  from behavex.outputs import report_xml
46
+ from behavex.outputs.formatter_manager import (DEFAULT_FORMATTER_DIR,
47
+ FormatterManager)
46
48
  from behavex.outputs.report_json import generate_execution_info
47
49
  from behavex.outputs.report_utils import (get_overall_status,
48
50
  match_for_execution,
@@ -1085,8 +1087,25 @@ def _set_env_variables(args):
1085
1087
  if get_param('name'):
1086
1088
  set_env_variable('NAME', args.name)
1087
1089
  if get_param('formatter'):
1088
- formatter_outdir = get_param('formatter_outdir')
1089
- set_env_variable('LOGS', os.path.join(get_env('output'), formatter_outdir))
1090
+ formatter_outdir = get_param('formatter_outdir', '')
1091
+ formatter_spec = get_param('formatter')
1092
+
1093
+ # If no formatter output directory is specified, use the default
1094
+ if not formatter_outdir:
1095
+ formatter_outdir = DEFAULT_FORMATTER_DIR
1096
+
1097
+ # Special handling for custom formatters with default settings
1098
+ if formatter_outdir == DEFAULT_FORMATTER_DIR and formatter_spec:
1099
+ # Try to dynamically get the formatter's preferred output directory
1100
+ custom_formatter_dir = FormatterManager.get_formatter_output_dir(formatter_spec)
1101
+ if custom_formatter_dir:
1102
+ # Use the formatter's preferred directory to maintain consistency
1103
+ set_env_variable('LOGS', os.path.join(get_env('output'), custom_formatter_dir))
1104
+ else:
1105
+ # Fallback to default formatter directory
1106
+ set_env_variable('LOGS', os.path.join(get_env('output'), formatter_outdir))
1107
+ else:
1108
+ set_env_variable('LOGS', os.path.join(get_env('output'), formatter_outdir))
1090
1109
  else:
1091
1110
  set_env_variable('LOGS', os.path.join(get_env('output'), 'outputs', 'logs'))
1092
1111
  for arg in BEHAVEX_ARGS[4:]:
@@ -79,7 +79,7 @@ def get_logging_level():
79
79
  log_level = get_param('logging_level')
80
80
  else:
81
81
  log_level = LOGGING_CFG['logger_root']['level']
82
- log_level = LOGGING_LEVELS.get(log_level.lower(), logging.DEBUG)
82
+ log_level = LOGGING_LEVELS.get(log_level.lower(), logging.INFO)
83
83
  return log_level
84
84
 
85
85
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: behavex
3
- Version: 4.2.3
3
+ Version: 4.2.4
4
4
  Summary: Agile testing framework on top of Behave (BDD).
5
5
  Home-page: https://github.com/hrcorval/behavex
6
6
  Author: Hernan Rey
@@ -29,7 +29,7 @@ Requires-Python: >=3.5
29
29
  Description-Content-Type: text/markdown
30
30
  License-File: LICENSE
31
31
  Requires-Dist: behave==1.2.6
32
- Requires-Dist: behavex-images>=3.0.10
32
+ Requires-Dist: behavex-images>=3.2.1
33
33
  Requires-Dist: allure-python-commons
34
34
  Requires-Dist: jinja2
35
35
  Requires-Dist: configobj
@@ -1,5 +1,5 @@
1
1
  behave==1.2.6
2
- behavex-images>=3.0.10
2
+ behavex-images>=3.2.1
3
3
  allure-python-commons
4
4
  jinja2
5
5
  configobj
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "behavex"
7
- version = "4.2.3"
7
+ version = "4.2.4"
8
8
  description = "Agile testing framework on top of Behave (BDD)."
9
9
  readme = "README.md"
10
10
  license = { text = "MIT" }
@@ -14,7 +14,7 @@ authors = [
14
14
  requires-python = ">=3.5"
15
15
  dependencies = [
16
16
  "behave==1.2.6",
17
- "behavex-images>=3.0.10",
17
+ "behavex-images>=3.2.1",
18
18
  "allure-python-commons",
19
19
  "jinja2",
20
20
  "configobj",
@@ -6,7 +6,7 @@ with open('README.md', 'r') as fh:
6
6
 
7
7
  setup(
8
8
  name='behavex',
9
- version='4.2.3',
9
+ version='4.2.4',
10
10
  license="MIT",
11
11
  platforms=['any'],
12
12
  python_requires='>=3.5',
@@ -25,7 +25,7 @@ setup(
25
25
  },
26
26
  install_requires=[
27
27
  'behave==1.2.6',
28
- 'behavex-images>=3.2.0',
28
+ 'behavex-images>=3.2.1',
29
29
  'allure-python-commons',
30
30
  'jinja2',
31
31
  'configobj',
@@ -0,0 +1,13 @@
1
+
2
+ def before_all(context):
3
+ # Configure behavex-images to always attach images to reports
4
+ try:
5
+ from behavex_images import image_attachments
6
+ from behavex_images.image_attachments import AttachmentsCondition
7
+ image_attachments.set_attachments_condition(context, AttachmentsCondition.ALWAYS)
8
+ except ImportError:
9
+ pass # behavex-images not available
10
+
11
+
12
+ def before_scenario(context, scenario):
13
+ context.progress_bar = False
@@ -0,0 +1,16 @@
1
+
2
+ def before_all(context):
3
+ # Configure behavex-images to always attach images to reports
4
+ try:
5
+ from behavex_images import image_attachments
6
+ from behavex_images.image_attachments import AttachmentsCondition
7
+ image_attachments.set_attachments_condition(context, AttachmentsCondition.ALWAYS)
8
+ except ImportError:
9
+ pass # behavex-images not available
10
+
11
+
12
+ def after_scenario(context, scenario):
13
+ if hasattr(context, 'new_scenario_name'):
14
+ scenario.name = context.new_scenario_name
15
+ if hasattr(context, 'new_feature_name'):
16
+ scenario.feature.name = context.new_feature_name
@@ -1,7 +1,19 @@
1
1
  import logging
2
+ import os
2
3
 
3
4
  from behave import given, then, when
4
5
 
6
+ # Get paths
7
+ root_project_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..', '..'))
8
+ test_images_path = os.path.join(root_project_path, 'tests', 'test_images')
9
+
10
+ # Import behavex-images functionality
11
+ try:
12
+ from behavex_images import image_attachments
13
+ behavex_images_available = True
14
+ except ImportError:
15
+ behavex_images_available = False
16
+
5
17
 
6
18
  @given('a failing condition')
7
19
  def step_impl(context):
@@ -56,3 +68,30 @@ def step_impl(context, feature_or_scenario, suffix):
56
68
  logging.info('I rename the scenario from \n"{}" \nto \n"{}"'.format(context.scenario.name, context.new_scenario_name))
57
69
  else:
58
70
  raise ValueError('Invalid element, it should be "feature" or "scenario"')
71
+
72
+
73
+ @given('I take a screenshot using test image {image_number}')
74
+ def step_take_screenshot_using_test_image(context, image_number):
75
+ """Attach a test image file using behavex-images"""
76
+ if not behavex_images_available:
77
+ logging.warning("behavex-images not available, skipping image attachment")
78
+ return
79
+
80
+ image_path = os.path.join(test_images_path, f'test_image_{image_number}.png')
81
+ if os.path.exists(image_path):
82
+ image_attachments.attach_image_file(context, image_path)
83
+ logging.info(f"Attached test image: {image_path}")
84
+ else:
85
+ raise FileNotFoundError(f"Test image not found: {image_path}")
86
+
87
+
88
+ @when('I validate image attachments')
89
+ def step_validate_image_attachments(context):
90
+ """Simple validation step for image attachments"""
91
+ logging.info("Validating image attachments")
92
+
93
+
94
+ @then('I should see attached images in the output')
95
+ def step_verify_attached_images_in_output(context):
96
+ """Verify that images were attached"""
97
+ logging.info("Images were attached to the test output")
@@ -8,6 +8,15 @@ from behave import given, then, when
8
8
 
9
9
  root_project_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..'))
10
10
  tests_features_path = os.path.join(root_project_path, 'tests', 'features')
11
+ test_images_path = os.path.join(root_project_path, 'tests', 'test_images')
12
+
13
+ # Import behavex-images functionality
14
+ try:
15
+ from behavex_images import image_attachments
16
+ behavex_images_available = True
17
+ except ImportError:
18
+ behavex_images_available = False
19
+ logging.warning("behavex-images not available, image attachment tests will be skipped")
11
20
 
12
21
 
13
22
  @given('The progress bar is enabled')
@@ -118,6 +127,7 @@ def run_command_with_scheme_processes_and_tags(context, scenario_name=None, argu
118
127
  tags_array = []
119
128
  else:
120
129
  tags_array = get_tags_arguments(tags)
130
+ feature_path_2 = None
121
131
  if feature_name:
122
132
  if feature_name_2:
123
133
  feature_path = os.path.join(tests_features_path, 'secondary_features', feature_name)
@@ -294,6 +304,110 @@ def get_total_scenarios_in_junit_reports(context, consider_skipped_scenarios=Tru
294
304
  return total_scenarios_in_junit_reports
295
305
 
296
306
 
307
+ @given('I take a screenshot using test image {image_number}')
308
+ def step_take_screenshot_using_test_image(context, image_number):
309
+ """Attach a test image file using behavex-images"""
310
+ if not behavex_images_available:
311
+ logging.warning("behavex-images not available, skipping image attachment")
312
+ return
313
+
314
+ # Import here to avoid issues if behavex-images is not available
315
+ from behavex_images import image_attachments
316
+
317
+ image_path = os.path.join(test_images_path, f'test_image_{image_number}.png')
318
+ if os.path.exists(image_path):
319
+ image_attachments.attach_image_file(context, image_path)
320
+ logging.info(f"Attached test image: {image_path}")
321
+ else:
322
+ raise FileNotFoundError(f"Test image not found: {image_path}")
323
+
324
+
325
+ @when('I run the behavex command with image attachments')
326
+ def step_run_behavex_with_image_attachments(context):
327
+ """Run behavex with HTML formatter and image attachments enabled"""
328
+ context.output_path = os.path.join('output', 'output_{}'.format(get_random_number(6)))
329
+ execution_args = [
330
+ 'behavex',
331
+ os.path.join(tests_features_path, 'secondary_features', 'simple_image_tests.feature'),
332
+ '-o', context.output_path,
333
+ '-t', '@IMAGE_ATTACHMENT',
334
+ '-t', '@HTML_REPORT'
335
+ ]
336
+ execute_command(context, execution_args)
337
+
338
+
339
+ @when('I run the behavex command with allure formatter and image attachments')
340
+ def step_run_behavex_with_allure_and_image_attachments(context):
341
+ """Run behavex with Allure formatter and image attachments enabled"""
342
+ context.output_path = os.path.join('output', 'output_{}'.format(get_random_number(6)))
343
+ execution_args = [
344
+ 'behavex',
345
+ os.path.join(tests_features_path, 'secondary_features', 'simple_image_tests.feature'),
346
+ '-o', context.output_path,
347
+ '--formatter=behavex.outputs.formatters.allure_behavex_formatter:AllureBehaveXFormatter',
348
+ '-t', '@IMAGE_ATTACHMENT',
349
+ '-t', '@ALLURE_FORMATTER'
350
+ ]
351
+ execute_command(context, execution_args)
352
+
353
+
354
+ @then('I should see the HTML report contains screenshots')
355
+ def step_verify_html_report_contains_screenshots(context):
356
+ """Verify that the HTML report contains attached screenshots"""
357
+ html_report_path = os.path.join(context.output_path, 'report.html')
358
+ if os.path.exists(html_report_path):
359
+ with open(html_report_path, 'r', encoding='utf-8') as f:
360
+ html_content = f.read()
361
+ # Look for image references in the HTML
362
+ assert 'test_image_' in html_content, "Screenshots not found in HTML report"
363
+ logging.info("Screenshots found in HTML report")
364
+ else:
365
+ raise FileNotFoundError(f"HTML report not found: {html_report_path}")
366
+
367
+
368
+ @then('I should see the HTML report contains the image gallery icon')
369
+ def step_verify_html_report_contains_gallery_icon(context):
370
+ """Verify that the HTML report contains the image gallery icon"""
371
+ html_report_path = os.path.join(context.output_path, 'report.html')
372
+ if os.path.exists(html_report_path):
373
+ with open(html_report_path, 'r', encoding='utf-8') as f:
374
+ html_content = f.read()
375
+ # Look for the specific gallery icon HTML element
376
+ gallery_icon = '<span class="glyphicon glyphicon-picture">'
377
+ assert gallery_icon in html_content, "Image gallery icon not found in HTML report"
378
+ logging.info("Image gallery icon found in HTML report")
379
+ else:
380
+ raise FileNotFoundError(f"HTML report not found: {html_report_path}")
381
+
382
+
383
+ @then('I should see that images are stored in the allure formatter output directory')
384
+ def step_verify_images_in_allure_output(context):
385
+ """Verify that images are stored in the Allure formatter output directory"""
386
+ allure_results_path = os.path.join(context.output_path, 'allure-results')
387
+ if os.path.exists(allure_results_path):
388
+ # Look for image attachments in allure results
389
+ allure_files = os.listdir(allure_results_path)
390
+ image_files = [f for f in allure_files if f.endswith('.png') or f.endswith('.jpg') or f.endswith('.jpeg')]
391
+ assert len(image_files) > 0, "No image files found in Allure output directory"
392
+ logging.info(f"Found {len(image_files)} image files in Allure output directory")
393
+
394
+ # Also check for attachment references in JSON files
395
+ json_files = [f for f in allure_files if f.endswith('.json')]
396
+ found_attachment_reference = False
397
+ for json_file in json_files:
398
+ json_path = os.path.join(allure_results_path, json_file)
399
+ with open(json_path, 'r', encoding='utf-8') as f:
400
+ json_content = f.read()
401
+ if 'attachments' in json_content and 'image' in json_content:
402
+ found_attachment_reference = True
403
+ break
404
+
405
+ assert found_attachment_reference, "No image attachment references found in Allure JSON files"
406
+ logging.info("Image attachment references found in Allure JSON files")
407
+ else:
408
+ raise FileNotFoundError(f"Allure results directory not found: {allure_results_path}")
409
+
410
+
297
411
  def execute_command(context, execution_args, print_output=True):
298
412
  if "progress_bar" in context and context.progress_bar:
299
413
  execution_args.insert(2, '--show-progress-bar')
@@ -1,3 +0,0 @@
1
-
2
- def before_scenario(context, scenario):
3
- context.progress_bar = False
@@ -1,6 +0,0 @@
1
-
2
- def after_scenario(context, scenario):
3
- if hasattr(context, 'new_scenario_name'):
4
- scenario.name = context.new_scenario_name
5
- if hasattr(context, 'new_feature_name'):
6
- scenario.feature.name = context.new_feature_name
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes