cucu 1.3.12__tar.gz → 1.3.21__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.12 → cucu-1.3.21}/PKG-INFO +3 -3
- {cucu-1.3.12 → cucu-1.3.21}/pyproject.toml +3 -3
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/browser/core.py +3 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/browser/selenium.py +7 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/cli/core.py +99 -92
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/cli/run.py +6 -7
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/cli/steps.py +1 -1
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/config.py +2 -1
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/db.py +138 -62
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/environment.py +14 -16
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/formatter/rundb.py +4 -6
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/fuzzy/core.py +2 -2
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/language_server/core.py +1 -1
- cucu-1.3.21/src/cucu/reporter/external/manage_scenario_highlights.js +69 -0
- cucu-1.3.21/src/cucu/reporter/html.py +380 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/reporter/templates/feature.html +2 -2
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/reporter/templates/flat.html +8 -8
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/reporter/templates/index.html +18 -18
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/reporter/templates/scenario.html +52 -34
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/steps/browser_steps.py +19 -1
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/steps/filesystem_steps.py +16 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/steps/table_steps.py +4 -7
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/steps/webserver_steps.py +1 -1
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/utils.py +71 -43
- cucu-1.3.12/src/cucu/reporter/html.py +0 -535
- {cucu-1.3.12 → cucu-1.3.21}/README.md +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/__init__.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/ansi_parser.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/behave_tweaks.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/browser/__init__.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/browser/frames.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/browser/selenium_tweaks.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/cli/__init__.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/cli/thread_dumper.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/edgedriver_autoinstaller/README.md +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/edgedriver_autoinstaller/__init__.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/edgedriver_autoinstaller/utils.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/external/jquery/jquery-3.5.1.min.js +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/formatter/__init__.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/formatter/cucu.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/formatter/json.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/formatter/junit.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/fuzzy/__init__.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/fuzzy/fuzzy.js +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/helpers.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/hooks.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/init_data/.gitignore +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/init_data/README.md +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/init_data/cucurc.yml +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/init_data/data/www/example.html +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/init_data/features/cucurc.yml +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/init_data/features/environment.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/init_data/features/example.feature +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/init_data/features/lint_rules/sid.yaml +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/init_data/features/steps/__init__.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/init_data/features/steps/my_steps.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/language_server/__init__.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/lint/__init__.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/lint/linter.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/lint/rules/format.yaml +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/logger.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/matcher/__init__.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/matcher/core.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/page_checks.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/reporter/__init__.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/reporter/external/bootstrap.min.css +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/reporter/external/bootstrap.min.js +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/reporter/external/dataTables.bootstrap.min.css +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/reporter/external/dataTables.bootstrap.min.js +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/reporter/external/jquery-3.5.1.min.js +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/reporter/external/jquery.dataTables.min.js +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/reporter/external/popper.min.js +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/reporter/favicon.png +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/reporter/templates/layout.html +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/steps/__init__.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/steps/base_steps.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/steps/button_steps.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/steps/checkbox_steps.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/steps/command_steps.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/steps/draggable_steps.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/steps/dropdown_steps.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/steps/file_input_steps.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/steps/flow_control_steps.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/steps/image_steps.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/steps/input_steps.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/steps/link_steps.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/steps/menuitem_steps.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/steps/platform_steps.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/steps/radio_steps.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/steps/section_steps.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/steps/step_utils.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/steps/tab_steps.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/steps/tables.js +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/steps/text_steps.py +0 -0
- {cucu-1.3.12 → cucu-1.3.21}/src/cucu/steps/variable_steps.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: cucu
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.21
|
|
4
4
|
Summary: Easy BDD web testing
|
|
5
5
|
Keywords: cucumber,selenium,behave
|
|
6
6
|
Author: Domino Data Lab, Rodney Gomes, Cedric Young, Xin Dong, Kavya Yakkati, Kevin Garton, Joy Liao
|
|
@@ -23,11 +23,11 @@ Requires-Dist: humanize~=4.13.0
|
|
|
23
23
|
Requires-Dist: importlib-metadata~=8.7.0
|
|
24
24
|
Requires-Dist: jellyfish>=1.1
|
|
25
25
|
Requires-Dist: jinja2~=3.1.3
|
|
26
|
-
Requires-Dist: lsprotocol
|
|
26
|
+
Requires-Dist: lsprotocol>=2025.0.0
|
|
27
27
|
Requires-Dist: mpire~=2.10.2
|
|
28
28
|
Requires-Dist: peewee>=3.18.2
|
|
29
29
|
Requires-Dist: psutil>=6.0
|
|
30
|
-
Requires-Dist: pygls
|
|
30
|
+
Requires-Dist: pygls>=2.0.0
|
|
31
31
|
Requires-Dist: pyyaml~=6.0.1
|
|
32
32
|
Requires-Dist: requests>=2.31.0,<3.0.0
|
|
33
33
|
Requires-Dist: selenium~=4.31
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "cucu"
|
|
3
|
-
version = "1.3.
|
|
3
|
+
version = "1.3.21"
|
|
4
4
|
description = "Easy BDD web testing"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = { text = "The Clear BSD License" }
|
|
@@ -45,11 +45,11 @@ dependencies = [
|
|
|
45
45
|
"importlib-metadata~=8.7.0",
|
|
46
46
|
"jellyfish>=1.1",
|
|
47
47
|
"jinja2~=3.1.3",
|
|
48
|
-
"lsprotocol
|
|
48
|
+
"lsprotocol>=2025.0.0",
|
|
49
49
|
"mpire~=2.10.2",
|
|
50
50
|
"peewee>=3.18.2",
|
|
51
51
|
"psutil>=6.0",
|
|
52
|
-
"pygls
|
|
52
|
+
"pygls>=2.0.0",
|
|
53
53
|
"pyyaml~=6.0.1",
|
|
54
54
|
"requests>=2.31.0,<3.0.0",
|
|
55
55
|
"selenium~=4.31",
|
|
@@ -195,6 +195,13 @@ class Selenium(Browser):
|
|
|
195
195
|
raise Exception(f"unknown browser {browser}")
|
|
196
196
|
|
|
197
197
|
self.driver.set_window_size(width, height)
|
|
198
|
+
session_id = self.get_session_id()
|
|
199
|
+
logger.debug(f"cucu started Selenium session with ID: {session_id}")
|
|
200
|
+
|
|
201
|
+
def get_session_id(self):
|
|
202
|
+
if self.driver:
|
|
203
|
+
return getattr(self.driver, "session_id", None)
|
|
204
|
+
return None
|
|
198
205
|
|
|
199
206
|
def get_log(self):
|
|
200
207
|
if config.CONFIG["CUCU_BROWSER"] == "firefox":
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
-
import glob
|
|
3
|
-
import json
|
|
4
2
|
import os
|
|
5
3
|
import shutil
|
|
6
4
|
import signal
|
|
5
|
+
import sqlite3
|
|
7
6
|
import sys
|
|
8
7
|
import time
|
|
9
8
|
import xml.etree.ElementTree as ET
|
|
@@ -54,7 +53,9 @@ def main():
|
|
|
54
53
|
|
|
55
54
|
|
|
56
55
|
@main.command()
|
|
57
|
-
@click.argument(
|
|
56
|
+
@click.argument(
|
|
57
|
+
"filepath", default="features", type=click.Path(path_type=Path)
|
|
58
|
+
)
|
|
58
59
|
@click.option(
|
|
59
60
|
"-b",
|
|
60
61
|
"--browser",
|
|
@@ -110,6 +111,7 @@ def main():
|
|
|
110
111
|
default=None,
|
|
111
112
|
help="specify the output directory for JUnit XML files, default is "
|
|
112
113
|
"the same location as --results",
|
|
114
|
+
type=click.Path(path_type=Path),
|
|
113
115
|
)
|
|
114
116
|
@click.option(
|
|
115
117
|
"--junit-with-stacktrace",
|
|
@@ -150,18 +152,14 @@ def main():
|
|
|
150
152
|
"--report",
|
|
151
153
|
default="report",
|
|
152
154
|
help="the location to put the test report when --generate-report is used",
|
|
153
|
-
)
|
|
154
|
-
@click.option(
|
|
155
|
-
"--report-only-failures",
|
|
156
|
-
default=False,
|
|
157
|
-
is_flag=True,
|
|
158
|
-
help="when set the HTML test report will only contain the failed test results",
|
|
155
|
+
type=click.Path(path_type=Path),
|
|
159
156
|
)
|
|
160
157
|
@click.option(
|
|
161
158
|
"-r",
|
|
162
159
|
"--results",
|
|
163
160
|
default="results",
|
|
164
161
|
help="the results directory used by cucu",
|
|
162
|
+
type=click.Path(path_type=Path),
|
|
165
163
|
)
|
|
166
164
|
@click.option(
|
|
167
165
|
"--runtime-timeout",
|
|
@@ -224,7 +222,6 @@ def run(
|
|
|
224
222
|
preserve_results,
|
|
225
223
|
record_env_vars,
|
|
226
224
|
report,
|
|
227
|
-
report_only_failures,
|
|
228
225
|
results,
|
|
229
226
|
runtime_timeout,
|
|
230
227
|
feature_timeout,
|
|
@@ -247,7 +244,7 @@ def run(
|
|
|
247
244
|
# when cucu is already running it means that we're running inside
|
|
248
245
|
# another cucu process and therefore we should make sure the results
|
|
249
246
|
# directory isn't the default one and throw an exception otherwise
|
|
250
|
-
if results == "results":
|
|
247
|
+
if results == Path("results"):
|
|
251
248
|
raise Exception(
|
|
252
249
|
"running within cucu but --results was not used, "
|
|
253
250
|
"this would lead to some very difficult to debug "
|
|
@@ -263,10 +260,10 @@ def run(
|
|
|
263
260
|
logger.init_logging(logging_level.upper())
|
|
264
261
|
|
|
265
262
|
if not preserve_results:
|
|
266
|
-
if
|
|
263
|
+
if results.exists():
|
|
267
264
|
shutil.rmtree(results)
|
|
268
265
|
|
|
269
|
-
|
|
266
|
+
results.mkdir(parents=True, exist_ok=True)
|
|
270
267
|
|
|
271
268
|
if selenium_remote_url is not None:
|
|
272
269
|
os.environ["CUCU_SELENIUM_REMOTE_URL"] = selenium_remote_url
|
|
@@ -287,9 +284,6 @@ def run(
|
|
|
287
284
|
if junit_with_stacktrace:
|
|
288
285
|
os.environ["CUCU_JUNIT_WITH_STACKTRACE"] = "true"
|
|
289
286
|
|
|
290
|
-
if report_only_failures:
|
|
291
|
-
os.environ["CUCU_REPORT_ONLY_FAILURES"] = "true"
|
|
292
|
-
|
|
293
287
|
if record_env_vars:
|
|
294
288
|
os.environ["CUCU_RECORD_ENV_VARS"] = "true"
|
|
295
289
|
|
|
@@ -302,12 +296,15 @@ def run(
|
|
|
302
296
|
generate_short_id(worker_id_seed)
|
|
303
297
|
)
|
|
304
298
|
|
|
305
|
-
os.environ["CUCU_FILEPATH"] = CONFIG["CUCU_FILEPATH"] = filepath
|
|
299
|
+
os.environ["CUCU_FILEPATH"] = CONFIG["CUCU_FILEPATH"] = str(filepath)
|
|
306
300
|
|
|
307
301
|
create_run(results, filepath)
|
|
308
302
|
|
|
309
303
|
try:
|
|
310
304
|
if workers is None or workers == 1:
|
|
305
|
+
logger.debug(
|
|
306
|
+
f"Starting cucu_run {CONFIG['CUCU_RUN_ID']} with single worker"
|
|
307
|
+
)
|
|
311
308
|
if runtime_timeout:
|
|
312
309
|
logger.debug("setting up runtime timeout timer")
|
|
313
310
|
|
|
@@ -347,9 +344,11 @@ def run(
|
|
|
347
344
|
raise ClickException("test run failed, see above for details")
|
|
348
345
|
|
|
349
346
|
else:
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
347
|
+
logger.debug(
|
|
348
|
+
f"Starting cucu_run {CONFIG['CUCU_RUN_ID']} with multiple workers: {workers}"
|
|
349
|
+
)
|
|
350
|
+
if filepath.is_dir():
|
|
351
|
+
feature_filepaths = list(filepath.rglob("*.feature"))
|
|
353
352
|
else:
|
|
354
353
|
feature_filepaths = [filepath]
|
|
355
354
|
|
|
@@ -486,8 +485,10 @@ def run(
|
|
|
486
485
|
task_failed.update(async_results)
|
|
487
486
|
|
|
488
487
|
if task_failed:
|
|
489
|
-
failing_features =
|
|
490
|
-
logger.error(
|
|
488
|
+
failing_features = [str(x) for x in task_failed.keys()]
|
|
489
|
+
logger.error(
|
|
490
|
+
f"Failing Features:\n{'\n'.join(failing_features)}"
|
|
491
|
+
)
|
|
491
492
|
raise RuntimeError(
|
|
492
493
|
"there are failures, see above for details"
|
|
493
494
|
)
|
|
@@ -495,65 +496,54 @@ def run(
|
|
|
495
496
|
if dumper is not None:
|
|
496
497
|
dumper.stop()
|
|
497
498
|
|
|
498
|
-
if
|
|
499
|
+
if results.exists():
|
|
499
500
|
finish_worker_record(worker_run_id=CONFIG.get("WORKER_PARENT_ID"))
|
|
500
501
|
consolidate_database_files(results)
|
|
501
502
|
|
|
502
503
|
if generate_report:
|
|
503
504
|
_generate_report(
|
|
504
|
-
results,
|
|
505
|
-
report,
|
|
506
|
-
|
|
507
|
-
junit=junit,
|
|
505
|
+
results_dir=results,
|
|
506
|
+
report_folder=report,
|
|
507
|
+
junit_folder=junit,
|
|
508
508
|
)
|
|
509
509
|
|
|
510
510
|
|
|
511
511
|
def _generate_report(
|
|
512
|
-
results_dir:
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
512
|
+
results_dir: Path,
|
|
513
|
+
report_folder: Path,
|
|
514
|
+
junit_folder: Path | None = None,
|
|
515
|
+
combine: bool = False,
|
|
516
516
|
):
|
|
517
|
-
if
|
|
518
|
-
shutil.rmtree(
|
|
517
|
+
if report_folder.exists():
|
|
518
|
+
shutil.rmtree(report_folder)
|
|
519
519
|
|
|
520
|
-
|
|
520
|
+
report_folder.mkdir(parents=True, exist_ok=True)
|
|
521
521
|
|
|
522
|
-
if
|
|
523
|
-
consolidate_database_files(results_dir)
|
|
522
|
+
if results_dir.exists():
|
|
523
|
+
consolidate_database_files(results_dir, combine)
|
|
524
524
|
|
|
525
|
-
report_location = reporter.generate(
|
|
526
|
-
results_dir, output, only_failures=only_failures
|
|
527
|
-
)
|
|
525
|
+
report_location = reporter.generate(results_dir, report_folder)
|
|
528
526
|
print(f"HTML test report at {report_location}")
|
|
529
527
|
|
|
530
|
-
if
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
"index.html",
|
|
545
|
-
)
|
|
546
|
-
test_case.set("report_path", report_path)
|
|
547
|
-
junit.write(junit_file, encoding="utf-8", xml_declaration=False)
|
|
528
|
+
if junit_folder:
|
|
529
|
+
for junit_file in junit_folder.rglob("*.xml"):
|
|
530
|
+
junit = ET.parse(junit_file)
|
|
531
|
+
test_suite = junit.getroot()
|
|
532
|
+
ts_folder = test_suite.get("foldername")
|
|
533
|
+
for test_case in test_suite.iter("testcase"):
|
|
534
|
+
report_path = os.path.join(
|
|
535
|
+
report_folder,
|
|
536
|
+
ts_folder,
|
|
537
|
+
test_case.get("foldername"),
|
|
538
|
+
"index.html",
|
|
539
|
+
)
|
|
540
|
+
test_case.set("report_path", report_path)
|
|
541
|
+
junit.write(junit_file, encoding="utf-8", xml_declaration=False)
|
|
548
542
|
|
|
549
543
|
|
|
550
544
|
@main.command()
|
|
551
|
-
@click.argument(
|
|
552
|
-
|
|
553
|
-
"--only-failures",
|
|
554
|
-
default=False,
|
|
555
|
-
is_flag=True,
|
|
556
|
-
help="when set the HTML test report will only contain the failed test results",
|
|
545
|
+
@click.argument(
|
|
546
|
+
"results_dir", default="results", type=click.Path(path_type=Path)
|
|
557
547
|
)
|
|
558
548
|
@click.option(
|
|
559
549
|
"-l",
|
|
@@ -567,21 +557,33 @@ def _add_report_path_in_junit(junit_folder, report_folder):
|
|
|
567
557
|
is_flag=True,
|
|
568
558
|
help="when set skips are shown",
|
|
569
559
|
)
|
|
570
|
-
@click.option(
|
|
560
|
+
@click.option(
|
|
561
|
+
"-o",
|
|
562
|
+
"--output",
|
|
563
|
+
default="report",
|
|
564
|
+
type=click.Path(path_type=Path),
|
|
565
|
+
)
|
|
571
566
|
@click.option(
|
|
572
567
|
"-j",
|
|
573
568
|
"--junit",
|
|
574
569
|
default=None,
|
|
575
570
|
help="specify the output directory for JUnit XML files, default is "
|
|
576
571
|
"the same location as --results",
|
|
572
|
+
type=click.Path(path_type=Path),
|
|
573
|
+
)
|
|
574
|
+
@click.option(
|
|
575
|
+
"--combine",
|
|
576
|
+
default=False,
|
|
577
|
+
is_flag=True,
|
|
578
|
+
help="combine multiple cucu_runs into a single report",
|
|
577
579
|
)
|
|
578
580
|
def report(
|
|
579
|
-
results_dir,
|
|
580
|
-
only_failures,
|
|
581
|
+
results_dir: Path,
|
|
581
582
|
logging_level,
|
|
582
583
|
show_skips,
|
|
583
|
-
output,
|
|
584
|
-
junit,
|
|
584
|
+
output: Path,
|
|
585
|
+
junit: Path,
|
|
586
|
+
combine: bool,
|
|
585
587
|
):
|
|
586
588
|
"""
|
|
587
589
|
generate a test report from a results directory
|
|
@@ -594,26 +596,32 @@ def report(
|
|
|
594
596
|
if show_skips:
|
|
595
597
|
os.environ["CUCU_SHOW_SKIPS"] = "true"
|
|
596
598
|
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
599
|
+
run_db_path = results_dir / "run.db"
|
|
600
|
+
if run_db_path.exists():
|
|
601
|
+
# query cucu_run to get the original filepath used during the run
|
|
602
|
+
with sqlite3.connect(run_db_path) as conn:
|
|
603
|
+
cursor = conn.cursor()
|
|
604
|
+
cursor.execute(
|
|
605
|
+
"SELECT filepath FROM cucu_run ORDER BY start_at DESC LIMIT 1"
|
|
606
|
+
)
|
|
607
|
+
row = cursor.fetchone()
|
|
608
|
+
if row:
|
|
609
|
+
filepath = row[0]
|
|
610
|
+
# initialize any underlying custom step code things
|
|
611
|
+
behave_init(filepath)
|
|
609
612
|
|
|
610
613
|
_generate_report(
|
|
611
|
-
results_dir
|
|
614
|
+
results_dir=results_dir,
|
|
615
|
+
report_folder=output,
|
|
616
|
+
junit_folder=junit,
|
|
617
|
+
combine=combine,
|
|
612
618
|
)
|
|
613
619
|
|
|
614
620
|
|
|
615
621
|
@main.command()
|
|
616
|
-
@click.argument(
|
|
622
|
+
@click.argument(
|
|
623
|
+
"filepath", default="features", type=click.Path(path_type=Path)
|
|
624
|
+
)
|
|
617
625
|
@click.option(
|
|
618
626
|
"-f",
|
|
619
627
|
"--format",
|
|
@@ -639,7 +647,7 @@ def steps(filepath, format):
|
|
|
639
647
|
|
|
640
648
|
|
|
641
649
|
@main.command()
|
|
642
|
-
@click.argument("filepath", nargs=-1)
|
|
650
|
+
@click.argument("filepath", type=click.Path(path_type=Path), nargs=-1)
|
|
643
651
|
@click.option(
|
|
644
652
|
"--fix/--no-fix", default=False, help="fix lint violations, default: False"
|
|
645
653
|
)
|
|
@@ -741,7 +749,9 @@ def lsp(logging_level, port):
|
|
|
741
749
|
|
|
742
750
|
|
|
743
751
|
@main.command()
|
|
744
|
-
@click.argument(
|
|
752
|
+
@click.argument(
|
|
753
|
+
"filepath", default="features", type=click.Path(path_type=Path)
|
|
754
|
+
)
|
|
745
755
|
def vars(filepath):
|
|
746
756
|
"""
|
|
747
757
|
print built-in cucu variables
|
|
@@ -766,14 +776,14 @@ def vars(filepath):
|
|
|
766
776
|
|
|
767
777
|
|
|
768
778
|
@main.command()
|
|
769
|
-
@click.argument("
|
|
779
|
+
@click.argument("repo_dir", default="", type=click.Path(path_type=Path))
|
|
770
780
|
@click.option(
|
|
771
781
|
"-l",
|
|
772
782
|
"--logging-level",
|
|
773
783
|
default="INFO",
|
|
774
784
|
help="set logging level to one of debug, warn or info (default)",
|
|
775
785
|
)
|
|
776
|
-
def init(
|
|
786
|
+
def init(repo_dir, logging_level):
|
|
777
787
|
"""
|
|
778
788
|
initialize cucu in the current directory
|
|
779
789
|
|
|
@@ -785,10 +795,9 @@ def init(filepath, logging_level):
|
|
|
785
795
|
init_data_dir = Path(__file__).parent.parent / "init_data"
|
|
786
796
|
|
|
787
797
|
logger.debug(f"cucu init: copy example directory from {init_data_dir=}")
|
|
788
|
-
repo_dir = filepath if filepath.strip() else os.path.join(os.getcwd())
|
|
789
798
|
|
|
790
|
-
features_dir =
|
|
791
|
-
if
|
|
799
|
+
features_dir = repo_dir / "features"
|
|
800
|
+
if features_dir.exists():
|
|
792
801
|
answer = input("Overwrite existing files? [y/N]:")
|
|
793
802
|
if answer.lower() != "y":
|
|
794
803
|
print("Aborted!")
|
|
@@ -874,9 +883,7 @@ def tags(filepath, logging_level):
|
|
|
874
883
|
if not filepath.exists() or not feature_files:
|
|
875
884
|
raise ClickException("No feature files found.")
|
|
876
885
|
|
|
877
|
-
file_locations = [
|
|
878
|
-
FileLocation(os.path.abspath(str(f))) for f in feature_files
|
|
879
|
-
]
|
|
886
|
+
file_locations = [FileLocation(f.absolute()) for f in feature_files]
|
|
880
887
|
features = parse_features(file_locations)
|
|
881
888
|
tag_scenarios = Counter()
|
|
882
889
|
|
|
@@ -85,8 +85,8 @@ def behave(
|
|
|
85
85
|
if debug_on_failure:
|
|
86
86
|
os.environ["CUCU_DEBUG_ON_FAILURE"] = "true"
|
|
87
87
|
|
|
88
|
-
os.environ["CUCU_RESULTS_DIR"] = results
|
|
89
|
-
os.environ["CUCU_JUNIT_DIR"] = junit
|
|
88
|
+
os.environ["CUCU_RESULTS_DIR"] = str(results)
|
|
89
|
+
os.environ["CUCU_JUNIT_DIR"] = str(junit)
|
|
90
90
|
|
|
91
91
|
if secrets:
|
|
92
92
|
os.environ["CUCU_SECRETS"] = secrets
|
|
@@ -123,7 +123,7 @@ def behave(
|
|
|
123
123
|
"--no-logcapture",
|
|
124
124
|
# generate a JSON file containing the exact details of the whole run
|
|
125
125
|
"--format=cucu.formatter.json:CucuJSONFormatter",
|
|
126
|
-
f"--outfile={
|
|
126
|
+
f"--outfile={results / run_json_filename}",
|
|
127
127
|
# console formatter
|
|
128
128
|
"--format=cucu.formatter.cucu:CucuFormatter",
|
|
129
129
|
f"--logging-level={os.environ['CUCU_LOGGING_LEVEL'].upper()}",
|
|
@@ -154,7 +154,7 @@ def behave(
|
|
|
154
154
|
if redirect_output:
|
|
155
155
|
feature_name = get_feature_name(filepath)
|
|
156
156
|
log_filename = f"{feature_name}.log"
|
|
157
|
-
log_filepath =
|
|
157
|
+
log_filepath = results / log_filename
|
|
158
158
|
|
|
159
159
|
CONFIG["__CUCU_PARENT_STDOUT"] = sys.stdout
|
|
160
160
|
|
|
@@ -185,8 +185,7 @@ def behave(
|
|
|
185
185
|
return result
|
|
186
186
|
|
|
187
187
|
|
|
188
|
-
def create_run(
|
|
189
|
-
results_path = Path(results)
|
|
188
|
+
def create_run(results_path: Path, filepath: Path):
|
|
190
189
|
run_json_filepath = results_path / "run_details.json"
|
|
191
190
|
|
|
192
191
|
if run_json_filepath.exists():
|
|
@@ -200,7 +199,7 @@ def create_run(results, filepath):
|
|
|
200
199
|
|
|
201
200
|
run_details = {
|
|
202
201
|
"cucu_run_id": CONFIG["CUCU_RUN_ID"],
|
|
203
|
-
"filepath": filepath,
|
|
202
|
+
"filepath": str(filepath),
|
|
204
203
|
"full_arguments": sys.argv,
|
|
205
204
|
"env": env_values,
|
|
206
205
|
"date": datetime.now().isoformat(),
|
|
@@ -131,7 +131,7 @@ def print_human_readable_steps(filepath=None):
|
|
|
131
131
|
|
|
132
132
|
for step_name in steps:
|
|
133
133
|
if steps[step_name] is not None:
|
|
134
|
-
if filepath in steps[step_name]["location"]["filepath"]:
|
|
134
|
+
if str(filepath) in steps[step_name]["location"]["filepath"]:
|
|
135
135
|
print(f"custom: {step_name}")
|
|
136
136
|
else:
|
|
137
137
|
print(f"cucu: {step_name}")
|
|
@@ -3,6 +3,7 @@ import logging
|
|
|
3
3
|
import os
|
|
4
4
|
import re
|
|
5
5
|
import socket
|
|
6
|
+
from pathlib import Path
|
|
6
7
|
|
|
7
8
|
import yaml
|
|
8
9
|
|
|
@@ -100,7 +101,7 @@ class Config(dict):
|
|
|
100
101
|
else:
|
|
101
102
|
self[key] = config[key]
|
|
102
103
|
|
|
103
|
-
def load_cucurc_files(self, filepath):
|
|
104
|
+
def load_cucurc_files(self, filepath: Path):
|
|
104
105
|
"""
|
|
105
106
|
load in order the ~/.cucurc.yml and then subsequent config files
|
|
106
107
|
starting from the current working directory to the filepath provided
|