cucu 1.3.0__tar.gz → 1.3.2__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.
Potentially problematic release.
This version of cucu might be problematic. Click here for more details.
- {cucu-1.3.0 → cucu-1.3.2}/PKG-INFO +1 -1
- {cucu-1.3.0 → cucu-1.3.2}/pyproject.toml +1 -1
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/cli/core.py +6 -2
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/db.py +32 -14
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/environment.py +23 -9
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/utils.py +6 -6
- {cucu-1.3.0 → cucu-1.3.2}/README.md +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/__init__.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/ansi_parser.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/behave_tweaks.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/browser/__init__.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/browser/core.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/browser/frames.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/browser/selenium.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/browser/selenium_tweaks.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/cli/__init__.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/cli/run.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/cli/steps.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/cli/thread_dumper.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/config.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/edgedriver_autoinstaller/README.md +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/edgedriver_autoinstaller/__init__.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/edgedriver_autoinstaller/utils.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/external/jquery/jquery-3.5.1.min.js +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/formatter/__init__.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/formatter/cucu.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/formatter/json.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/formatter/junit.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/fuzzy/__init__.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/fuzzy/core.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/fuzzy/fuzzy.js +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/helpers.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/hooks.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/init_data/.gitignore +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/init_data/README.md +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/init_data/cucurc.yml +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/init_data/data/www/example.html +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/init_data/features/cucurc.yml +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/init_data/features/environment.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/init_data/features/example.feature +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/init_data/features/lint_rules/sid.yaml +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/init_data/features/steps/__init__.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/init_data/features/steps/my_steps.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/language_server/__init__.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/language_server/core.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/lint/__init__.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/lint/linter.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/lint/rules/format.yaml +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/logger.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/matcher/__init__.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/matcher/core.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/page_checks.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/reporter/__init__.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/reporter/external/bootstrap.min.css +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/reporter/external/bootstrap.min.js +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/reporter/external/dataTables.bootstrap.min.css +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/reporter/external/dataTables.bootstrap.min.js +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/reporter/external/jquery-3.5.1.min.js +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/reporter/external/jquery.dataTables.min.js +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/reporter/external/popper.min.js +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/reporter/favicon.png +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/reporter/html.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/reporter/templates/feature.html +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/reporter/templates/flat.html +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/reporter/templates/index.html +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/reporter/templates/layout.html +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/reporter/templates/scenario.html +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/steps/__init__.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/steps/base_steps.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/steps/browser_steps.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/steps/button_steps.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/steps/checkbox_steps.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/steps/command_steps.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/steps/draggable_steps.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/steps/dropdown_steps.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/steps/file_input_steps.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/steps/filesystem_steps.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/steps/flow_control_steps.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/steps/image_steps.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/steps/input_steps.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/steps/link_steps.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/steps/menuitem_steps.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/steps/platform_steps.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/steps/radio_steps.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/steps/section_steps.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/steps/step_utils.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/steps/tab_steps.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/steps/table_steps.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/steps/tables.js +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/steps/text_steps.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/steps/variable_steps.py +0 -0
- {cucu-1.3.0 → cucu-1.3.2}/src/cucu/steps/webserver_steps.py +0 -0
|
@@ -241,6 +241,8 @@ def run(
|
|
|
241
241
|
):
|
|
242
242
|
"""
|
|
243
243
|
run a set of feature files
|
|
244
|
+
|
|
245
|
+
Note: All the os.environ variables are set to be available in the child processes
|
|
244
246
|
"""
|
|
245
247
|
init_global_hook_variables()
|
|
246
248
|
dumper = None
|
|
@@ -300,7 +302,9 @@ def run(
|
|
|
300
302
|
os.environ["CUCU_RECORD_ENV_VARS"] = "true"
|
|
301
303
|
|
|
302
304
|
os.environ["CUCU_RUN_ID"] = CONFIG["CUCU_RUN_ID"] = generate_short_id()
|
|
303
|
-
CONFIG["WORKER_RUN_ID"] =
|
|
305
|
+
os.environ["WORKER_PARENT_ID"] = CONFIG["WORKER_RUN_ID"] = (
|
|
306
|
+
generate_short_id()
|
|
307
|
+
)
|
|
304
308
|
if not dry_run:
|
|
305
309
|
create_run(results, filepath)
|
|
306
310
|
|
|
@@ -494,7 +498,7 @@ def run(
|
|
|
494
498
|
dumper.stop()
|
|
495
499
|
|
|
496
500
|
if not dry_run and os.path.exists(results):
|
|
497
|
-
finish_worker_record()
|
|
501
|
+
finish_worker_record(worker_run_id=CONFIG.get("WORKER_PARENT_ID"))
|
|
498
502
|
consolidate_database_files(results)
|
|
499
503
|
|
|
500
504
|
if generate_report:
|
|
@@ -38,6 +38,7 @@ class cucu_run(BaseModel):
|
|
|
38
38
|
full_arguments = JSONField()
|
|
39
39
|
date = TextField()
|
|
40
40
|
start_at = DateTimeField()
|
|
41
|
+
end_at = DateTimeField(null=True)
|
|
41
42
|
|
|
42
43
|
|
|
43
44
|
class worker(BaseModel):
|
|
@@ -47,6 +48,14 @@ class worker(BaseModel):
|
|
|
47
48
|
field="cucu_run_id",
|
|
48
49
|
backref="workers",
|
|
49
50
|
column_name="cucu_run_id",
|
|
51
|
+
null=True,
|
|
52
|
+
)
|
|
53
|
+
parent_id = ForeignKeyField(
|
|
54
|
+
"self",
|
|
55
|
+
field="worker_run_id",
|
|
56
|
+
backref="child_workers",
|
|
57
|
+
column_name="parent_id",
|
|
58
|
+
null=True,
|
|
50
59
|
)
|
|
51
60
|
start_at = DateTimeField()
|
|
52
61
|
end_at = DateTimeField(null=True)
|
|
@@ -114,32 +123,32 @@ class step(BaseModel):
|
|
|
114
123
|
duration = FloatField(null=True)
|
|
115
124
|
start_at = DateTimeField()
|
|
116
125
|
end_at = DateTimeField(null=True)
|
|
117
|
-
debug_output =
|
|
126
|
+
debug_output = TextField(null=True)
|
|
118
127
|
browser_logs = TextField(null=True)
|
|
119
128
|
browser_info = JSONField(null=True)
|
|
120
129
|
screenshots = JSONField(null=True)
|
|
121
130
|
|
|
122
131
|
|
|
123
132
|
def record_cucu_run():
|
|
124
|
-
worker_run_id = CONFIG["WORKER_RUN_ID"]
|
|
125
133
|
cucu_run_id_val = CONFIG["CUCU_RUN_ID"]
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
"worker_run_id": worker_run_id,
|
|
129
|
-
"full_arguments": sys.argv,
|
|
130
|
-
"date": datetime.now().isoformat(),
|
|
131
|
-
}
|
|
134
|
+
worker_run_id = CONFIG["WORKER_RUN_ID"]
|
|
135
|
+
|
|
132
136
|
db.connect(reuse_if_open=True)
|
|
137
|
+
start_at = datetime.now().isoformat()
|
|
133
138
|
cucu_run.create(
|
|
134
139
|
cucu_run_id=cucu_run_id_val,
|
|
135
|
-
full_arguments=
|
|
136
|
-
date=
|
|
137
|
-
start_at=
|
|
140
|
+
full_arguments=sys.argv,
|
|
141
|
+
date=start_at,
|
|
142
|
+
start_at=start_at,
|
|
138
143
|
)
|
|
144
|
+
|
|
139
145
|
worker.create(
|
|
140
146
|
worker_run_id=worker_run_id,
|
|
141
147
|
cucu_run_id=cucu_run_id_val,
|
|
142
|
-
|
|
148
|
+
parent_id=CONFIG.get("WORKER_PARENT_ID")
|
|
149
|
+
if CONFIG.get("WORKER_PARENT_ID") != worker_run_id
|
|
150
|
+
else None,
|
|
151
|
+
start_at=datetime.now().isoformat(),
|
|
143
152
|
)
|
|
144
153
|
db.close()
|
|
145
154
|
return str(db_filepath)
|
|
@@ -266,12 +275,21 @@ def finish_feature_record(feature_obj):
|
|
|
266
275
|
db.close()
|
|
267
276
|
|
|
268
277
|
|
|
269
|
-
def finish_worker_record(custom_data=None):
|
|
278
|
+
def finish_worker_record(custom_data=None, worker_run_id=None):
|
|
270
279
|
db.connect(reuse_if_open=True)
|
|
280
|
+
target_worker_run_id = worker_run_id or CONFIG["WORKER_RUN_ID"]
|
|
271
281
|
worker.update(
|
|
272
282
|
end_at=datetime.now().isoformat(),
|
|
273
283
|
custom_data=custom_data,
|
|
274
|
-
).where(worker.worker_run_id ==
|
|
284
|
+
).where(worker.worker_run_id == target_worker_run_id).execute()
|
|
285
|
+
db.close()
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
def finish_cucu_run_record():
|
|
289
|
+
db.connect(reuse_if_open=True)
|
|
290
|
+
cucu_run.update(
|
|
291
|
+
end_at=datetime.now().isoformat(),
|
|
292
|
+
).where(cucu_run.cucu_run_id == CONFIG["CUCU_RUN_ID"]).execute()
|
|
275
293
|
db.close()
|
|
276
294
|
|
|
277
295
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import datetime
|
|
2
2
|
import json
|
|
3
|
+
import os
|
|
3
4
|
import sys
|
|
4
5
|
import traceback
|
|
5
6
|
from functools import partial
|
|
@@ -11,6 +12,7 @@ from cucu import config, init_scenario_hook_variables, logger
|
|
|
11
12
|
from cucu.config import CONFIG
|
|
12
13
|
from cucu.db import (
|
|
13
14
|
create_database_file,
|
|
15
|
+
finish_cucu_run_record,
|
|
14
16
|
finish_feature_record,
|
|
15
17
|
finish_scenario_record,
|
|
16
18
|
finish_step_record,
|
|
@@ -58,16 +60,27 @@ def before_all(ctx):
|
|
|
58
60
|
ctx.check_browser_initialized = partial(check_browser_initialized, ctx)
|
|
59
61
|
ctx.worker_custom_data = {}
|
|
60
62
|
|
|
61
|
-
CONFIG["WORKER_RUN_ID"]
|
|
63
|
+
if CONFIG["WORKER_RUN_ID"] != CONFIG["WORKER_PARENT_ID"]:
|
|
64
|
+
logger.debug(
|
|
65
|
+
"Create a new worker db since this isn't the parent process"
|
|
66
|
+
)
|
|
67
|
+
# use seed unique enough for multiple cucu_runs to be combined
|
|
68
|
+
worker_id_seed = f"{CONFIG['WORKER_PARENT_ID']}_{os.getpid()}"
|
|
69
|
+
CONFIG["WORKER_RUN_ID"] = generate_short_id(worker_id_seed)
|
|
70
|
+
|
|
71
|
+
results_path = Path(CONFIG["CUCU_RESULTS_DIR"])
|
|
72
|
+
worker_run_id = CONFIG["WORKER_RUN_ID"]
|
|
73
|
+
cucu_run_id = CONFIG["CUCU_RUN_ID"]
|
|
74
|
+
CONFIG["RUN_DB_PATH"] = run_db_path = (
|
|
75
|
+
results_path / f"run_{cucu_run_id}_{worker_run_id}.db"
|
|
76
|
+
)
|
|
77
|
+
if not run_db_path.exists():
|
|
78
|
+
logger.debug(
|
|
79
|
+
f"Creating new run database file: {run_db_path} for {worker_id_seed}"
|
|
80
|
+
)
|
|
81
|
+
create_database_file(run_db_path)
|
|
82
|
+
record_cucu_run()
|
|
62
83
|
|
|
63
|
-
results_path = Path(CONFIG["CUCU_RESULTS_DIR"])
|
|
64
|
-
worker_run_id = CONFIG["WORKER_RUN_ID"]
|
|
65
|
-
cucu_run_id = CONFIG["CUCU_RUN_ID"]
|
|
66
|
-
CONFIG["RUN_DB_PATH"] = run_db_path = (
|
|
67
|
-
results_path / f"run_{cucu_run_id}_{worker_run_id}.db"
|
|
68
|
-
)
|
|
69
|
-
create_database_file(run_db_path)
|
|
70
|
-
record_cucu_run()
|
|
71
84
|
CONFIG.snapshot("before_all")
|
|
72
85
|
|
|
73
86
|
for hook in CONFIG["__CUCU_BEFORE_ALL_HOOKS"]:
|
|
@@ -80,6 +93,7 @@ def after_all(ctx):
|
|
|
80
93
|
hook(ctx)
|
|
81
94
|
|
|
82
95
|
finish_worker_record(ctx.worker_custom_data)
|
|
96
|
+
finish_cucu_run_record()
|
|
83
97
|
CONFIG.restore(with_pop=True)
|
|
84
98
|
|
|
85
99
|
|
|
@@ -43,14 +43,14 @@ class StopRetryException(Exception):
|
|
|
43
43
|
pass
|
|
44
44
|
|
|
45
45
|
|
|
46
|
-
def generate_short_id():
|
|
46
|
+
def generate_short_id(seed=None):
|
|
47
47
|
"""
|
|
48
|
-
Generate a short 7-character ID based on current performance counter.
|
|
49
|
-
Used for both cucu_run_id and scenario_run_id.
|
|
48
|
+
Generate a short 7-character ID based on seed (defaults to current performance counter).
|
|
50
49
|
"""
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
50
|
+
if seed is None:
|
|
51
|
+
seed = time.perf_counter()
|
|
52
|
+
|
|
53
|
+
return hashlib.sha256(str(seed).encode("utf-8")).hexdigest()[:7]
|
|
54
54
|
|
|
55
55
|
|
|
56
56
|
def format_gherkin_table(table, headings=[], prefix=""):
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|