Skip to content

Commit

Permalink
Merge pull request #95 from hrcorval/release_3.0.0
Browse files Browse the repository at this point in the history
Release 3.0.0
  • Loading branch information
hrcorval committed Aug 10, 2023
2 parents 5ba92ef + 748db17 commit 876c41f
Show file tree
Hide file tree
Showing 12 changed files with 408 additions and 287 deletions.
21 changes: 20 additions & 1 deletion CHANGES.rst
@@ -1,11 +1,30 @@
Version History
===============================================================================

Version: 2.0.2
Version: 3.0.0
-------------------------------------------------------------------------------
ENHANCEMENTS:

* Enable Behavex to execute features located in a different paths (behavex <features_path1> <features_path2> ... <features_pathN>)
* Printing the HTML output report that in the console when behavex execution is finished
* Printing the paths where the features are located when behavex execution is started `Issue #88 <https://github.com/hrcorval/behavex/issues/88>`_
* Printing the summary of executed scenarios when running in parallel
* Major improvement done to enable re-executing failing scenarios in parallel
* Enable scenario outlines to be executed in parallel
* HTML Report layout improvements to properly render long gherkin steps and failure messages. `Issue #81 <https://github.com/hrcorval/behavex/issues/81>`_
* Improvement done when parallel execution cannot be launched due to duplicated scenario names, by throwing an error exit code `Issue #86 <https://github.com/hrcorval/behavex/issues/86>`_

FIXES:

* Fix done when logging exceptions in environment.py module
* Fix done when parsing tags associated to scenario outline examples. `Issue #85 <https://github.com/hrcorval/behavex/issues/85>`_
* Fix done when detecting scenarios (Scenario detection does not work for Non-English languages). `Issue #77 <https://github.com/hrcorval/behavex/issues/77>`_
* Fix done to properly render step.text in HTML report. `Issue #79 <https://github.com/hrcorval/behavex/issues/79>`_
* Fix done when parsing empty feature files.

CONTRIBUTORS:

* Contribution from `seb <https://github.com/sebns>`__ providing the fix to an issue when parsing tags associated to scenario outline examples (Thanks!!)

Version: 2.0.1
-------------------------------------------------------------------------------
Expand Down
39 changes: 32 additions & 7 deletions README.md
Expand Up @@ -42,23 +42,48 @@ The execution is performed in the same way as you do when executing Behave from

Examples:

> behavex -t @TAG_1 -t ~@TAG_2
>Run scenarios tagged as **TAG_1** but not **TAG_2**:
>
> <pre>behavex -t @TAG_1 -t ~@TAG_2</pre>
> behavex -t @TAG_1,@TAG_2
>Run scenarios tagged as **TAG_1** or **TAG_2**:
>
><pre>behavex -t @TAG_1,@TAG_2</pre>
> behavex -t @TAG --parallel-processes 4 --parallel-scheme scenario
>Run scenarios tagged as **TAG_1**, using **4** parallel processes:
>
><pre>behavex -t @TAG_1 --parallel-processes 4 --parallel-scheme scenario</pre>
> behavex -t @TAG --parallel-processes 3
>Run scenarios located at "**features/features_folder_1**" and "**features/features_folder_2**" folders, using **2** parallel processes
>
><pre>behavex features/features_folder_1 features/features_folder_2 --parallel-processes 2
> behavex -t @TAG --dry-run
> >Run scenarios from "**features_folder_1/sample_feature.feature**" feature file, using **2** parallel processes
>
><pre>behavex features_folder_1/sample_feature.feature --parallel-processes 2
> >Run scenarios tagged as **TAG_1** from "**features_folder_1/sample_feature.feature**" feature file, using **2** parallel processes
>
><pre>behavex features_folder_1/sample_feature.feature -t @TAG_1 --parallel-processes 2
>Run scenarios located at "**features/feature_1**" and "**features/feature_2**" folders, using **2** parallel processes
>
><pre>behavex features/feature_1 features/feature_2 --parallel-processes 2
>Run scenarios tagged as **TAG_1**, using **5** parallel processes executing a feature on each process:
>
><pre>behavex -t @TAG_1 --parallel-processes 5 --parallel-scheme feature</pre>
> Perform a dry run of the scenarios tagged as **TAG_1**, and generate the HTML report:
>
><pre>behavex -t @TAG --dry-run</pre>

## Constraints

* BehaveX is currently implemented on top of Behave **v1.2.6**, and not all Behave arguments are yet supported.
* The parallel execution implementation is based on concurrent Behave processes. Therefore, any code in the **before_all** and **after_all** hooks in the **environment.py** module will be executed in each parallel process. The same applies to the **before_feature** and **after_feature** hooks when the parallel execution is set by scenario.
* The library is provided as is, and no tests have been implemented for the framework yet (initial versions had tests, but they were deprecated). Any contributions to testing would be greatly appreciated.
* There may be inaccuracies in some English translations, and some docstrings are currently empty. We expect to fix these issues soon.

### Additional Comments

Expand Down Expand Up @@ -112,7 +137,7 @@ Parallel test executions can be performed by **feature** or by **scenario**.
Examples:
> behavex --parallel-processes 3
> behavex -t @TAG --parallel-processes 3
> behavex -t @\<TAG\> --parallel-processes 3
> behavex -t @\<TAG\> --parallel-processes 2 --parallel-scheme scenario
Expand Down
9 changes: 9 additions & 0 deletions behavex/global_vars.py
Expand Up @@ -23,6 +23,7 @@ def __init__(self):
}
self._retried_scenarios = {}
self._steps_definitions = {}
self._rerun_failures = False

@property
def execution_path(self):
Expand Down Expand Up @@ -56,5 +57,13 @@ def retried_scenarios(self, feature_name):
def steps_definitions(self):
return self._steps_definitions

@property
def rerun_failures(self):
return self._rerun_failures

@rerun_failures.setter
def rerun_failures(self, rerun_failures):
self._rerun_failures = rerun_failures


global_vars = GlobalVars()
29 changes: 13 additions & 16 deletions behavex/outputs/bootstrap/css/behavex.css
Expand Up @@ -235,7 +235,7 @@ table th {
margin-right: 4px
}
.ul-tags-behavex {
padding-left: 3px;
padding-left: 1px;
float: left;
}
.label-behavex {
Expand Down Expand Up @@ -280,20 +280,10 @@ table th {
margin: 0px;
width: 100%;
}
.ul-step-error {
font-size: 13px;
font-weight: 100;
border: 1px solid #765453;
border-radius: 5px;
padding-left: 15px;
width: 100%;
margin-left: 3px;
padding-top: 3px;
margin-bottom: 3px;
}
body {
padding-left: 20px;
padding-right: 20px;
min-width: 900px;
}
.scenario-step {
width: 100%;
Expand Down Expand Up @@ -366,10 +356,6 @@ ul.list-unstyled.scenario-step > li {
height: 94%;
width: 100%;
}
.attr_text{
margin: 2px;
padding-left: 14px;
}
.ui-menu{
color: #4F4F4F;
background-color: #EEEEEE;
Expand All @@ -378,3 +364,14 @@ ul.list-unstyled.scenario-step > li {
position: fixed;
top: -1000px;
}
.report-filter{
min-width: 210px;
}
.gherkin{
overflow-x: auto;
white-space: nowrap;
max-width: calc(100% - 10px);
}
.table-scenario{
table-layout: fixed;
}
2 changes: 1 addition & 1 deletion behavex/outputs/bootstrap/css/bootstrap.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

58 changes: 30 additions & 28 deletions behavex/outputs/jinja/main.jinja2
Expand Up @@ -164,7 +164,7 @@
<div class="panel-body">
<div class="container-fluid behavex-row-total">
<div class="row"><br>
<div class="col-sm-4 pull-left">
<div class="col-sm-3 pull-left report-filter">
<div class="form-group form-group-sm">
<b>
<label class="control-label pull-left"
Expand All @@ -177,7 +177,7 @@
</b>
</div>
</div>
<div class="col-sm-4 pull-left">
<div class="col-sm-3 pull-left report-filter">
<div class="form-group form-group-sm">
<label class="control-label pull-left"
style="padding-top: 5px;padding-right:3px;font-size: 12px;">
Expand All @@ -193,7 +193,7 @@
</select>
</div>
</div>
<div class="col-sm-2 pull-left">
<div class="col-sm-3 pull-left report-filter">
<div class="form-group form-group-sm">
<label class="control-label pull-left"
style="padding-top: 5px;padding-right:3px;font-size: 12px;">
Expand All @@ -209,7 +209,7 @@
</select>
</div>
</div>
<div class="col-sm-2 pull-left" >
<div class="col-sm-3 pull-left" >
<div class="form-group form-group-sm">
<button type="button" class="btn btn-info btn-xs"
id="button-reset-filter" data-reset-filter>
Expand Down Expand Up @@ -241,7 +241,7 @@
{%- macro print_feature(feature) -%}
<div class="panel-default feature behavex_letter">
<div class="panel-body">
<table class="table table-bordered behavex_letter" >
<table class="table table-bordered behavex_letter table-scenario" >
{%- if feature.background.steps|count > 0 -%}
<tr style="display: none" data-info-background="{{ feature.name }}"
class="panel-header">
Expand Down Expand Up @@ -288,10 +288,10 @@
</a>
{%- endif -%}
</th>
<th style="width: 90px;height: 24px" class="text-center">Type</th>
<th style="width: 90px;height: 24px" class="text-center">Status</th>
<th style="width: 90px;height: 24px" class="text-center">Duration</th>
<th style="height: 24px" class="text-center">Evidence</th>
<th style="width: 80px;height: 24px" class="text-center">Type</th>
<th style="width: 80px;height: 24px" class="text-center">Status</th>
<th style="width: 80px;height: 24px" class="text-center">Duration</th>
<th style="width: 180px;height: 24px" class="text-center">Evidence</th>
</tr>
{%- for scenario in feature.scenarios -%}
{%- set concat_feature_and_scenario_name = feature.name + "-" + scenario.name -%}
Expand All @@ -318,19 +318,21 @@
{% endif %}
</div>
<div data-div-id_hash="{{ scenario.id_hash }}"
style="display: None" class="pull-left">
<ul class="list-unstyled ul-tags-behavex label-behavex" style="width:100%;height:20px;font-size: 10px">
{%- for tag in scenario.tags -%}
{%- if [tag]|match_for_execution -%}
<li style="float:left;vertical-align: middle;padding:4px 14px 2px 2px;"
class="{{ [scenario.status]|calculate_color}}-behavex" title="{{ 'report.execution_tag'|get_text }}">
<a class="link-cursor text-info" onclick="show_tag('{{ tag }}');">{{ tag }}</a></li>
{%- else -%}
<li style="float:left;vertical-align: middle;padding:4px 14px 2px 2px;">
<a class="link-cursor text-secondary" onclick="show_tag('{{ tag }}');">{{ tag }}</a></li>
{%- endif -%}
{%- endfor -%}
</ul>
style="display: None" class="pull-left gherkin">
{% if scenario.tags %}
<ul class="list-unstyled ul-tags-behavex label-behavex" style="font-size: 10px">
{%- for tag in scenario.tags -%}
{%- if [tag]|match_for_execution -%}
<li style="float:left;vertical-align: middle;padding:4px 14px 2px 2px;"
class="{{ [scenario.status]|calculate_color}}-behavex" title="{{ 'report.execution_tag'|get_text }}">
<a class="link-cursor text-info" onclick="show_tag('{{ tag }}');">{{ tag }}</a></li>
{%- else -%}
<li style="float:left;vertical-align: middle;padding:4px 14px 2px 2px;">
<a class="link-cursor text-secondary" onclick="show_tag('{{ tag }}');">{{ tag }}</a></li>
{%- endif -%}
{%- endfor -%}
</ul>
{% endif %}
{%- if scenario.error_background and (scenario.status == 'failed' or scenario.status == 'untested' )-%}
<br>
<p style="padding-left:12px;padding-top:15px;padding-bottom:2px" data-div-id_hash="{{ scenario.id_hash }}">
Expand Down Expand Up @@ -438,7 +440,7 @@
</div>
{%- endmacro -%}
{%- macro print_step(scenario, step) -%}
<li style="width: 100%"><b>{{ step|resolving_type(scenario)|safe }}</b> {{ ((step.name) ~ test_status_text)|e }}
<li style="width: 100%;float: left;"><b>{{ step|resolving_type(scenario)|safe }}</b> {{ ((step.name) ~ test_status_text)|e }}
{%- if 'table' in step -%}
<table class="table table-hover behavex_letter table-step-value">
<tr class="{{scenario.status|resolving_color_class}} table-header">
Expand All @@ -457,18 +459,18 @@
</table>
{%- endif -%}
{% if step.text is defined and step.text != "None" %}
<div class="small attr_text">
{{ step.text|replace_enter|e|replace("&lt;br&gt;", "<br>")|replace('&nbsp;', ' ')}}
<div>
<pre class="small behavex_letter">{{ step.text|safe}}</pre>
</div>

{% endif%}
{%- if step.status == 'failed' or step.status == 'undefined' -%}
<p class="p-step-error"><b>&nbsp;&nbsp;(Step {{step.status }})</b></p>
{%- set error_msg, error_lines, error_step = scenario|gather_errors(true) -%}
{%- if error_msg or error_lines -%}
<ul class="list-unstyled pull-left ul-step-error">
<ul class="list-unstyled">
<li>
<small>
<pre class="red-behavex behavex_letter">
{%- if error_msg -%}
{%- for line in error_msg -%}
{%- if line -%}
Expand All @@ -482,7 +484,7 @@
{%- endif -%}
{%- endfor -%}
{%- endif -%}
</small>
</pre>
</li>
</ul>
{%- endif -%}
Expand Down
7 changes: 1 addition & 6 deletions behavex/outputs/jinja_mgr.py
Expand Up @@ -71,7 +71,6 @@ def __init__(self, template_path):
self.add_filter(get_path_extra_logs, 'get_path_extra_logs')
self.add_filter(get_relative_extra_logs_path, 'get_relative_extra_logs_path')
self.add_filter(clean_invalid_xml_chars, 'CIXC')
self.add_filter(replace_enter, 'replace_enter')
self.add_filter(normalize_path, 'normalize_path')
self.template_env.globals.update(get_env=get_env)
# self.template_env.globals.keys() has been forced to be a list
Expand Down Expand Up @@ -284,7 +283,7 @@ def to_string_list(tags):


def _print_error(line):
return line
return line.replace('/n', os.linesep)


def clean_invalid_xml_chars(xml_content):
Expand Down Expand Up @@ -365,9 +364,5 @@ def clean_char(char):
return char


def replace_enter(text):
return text.replace(os.linesep, '<br>')


def normalize_path(text):
return os.path.normpath(text)
1 change: 1 addition & 0 deletions behavex/outputs/output_strings.py
Expand Up @@ -54,6 +54,7 @@
'serial_execution': '{0}\nRunning serial features (tagged as @SERIAL)'
'.\n\n{0}'.format('*' * 60),
'running_parallels': '{0}\nRunning parallel features.\n\n{0}'.format('*' * 60),
'empty_scenario_descriptions': u'{0}\nThere are features containing scenarios with empty descriptions: \n* {1}.\n\n{0}'.format('*' * 60, {}),
'run_behave': u"Running feature '{}'.",
},
'scenario': {
Expand Down
6 changes: 5 additions & 1 deletion behavex/outputs/report_utils.py
Expand Up @@ -358,7 +358,11 @@ def create_log_path(name, execution_retry=False):
return path
path = initial_path + u'_' + str(scenario_outline_index)
scenario_outline_index += 1
os.makedirs(path)
try:
os.makedirs(path)
except FileExistsError:
# path already exists
pass
return path


Expand Down

0 comments on commit 876c41f

Please sign in to comment.