cucu 1.3.13__py3-none-any.whl → 1.3.15__py3-none-any.whl
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.
- cucu/cli/core.py +10 -1
- cucu/db.py +12 -5
- cucu/reporter/external/manage_scenario_highlights.js +69 -0
- cucu/reporter/html.py +50 -27
- cucu/reporter/templates/scenario.html +5 -1
- cucu/steps/webserver_steps.py +1 -1
- cucu/utils.py +28 -42
- {cucu-1.3.13.dist-info → cucu-1.3.15.dist-info}/METADATA +1 -1
- {cucu-1.3.13.dist-info → cucu-1.3.15.dist-info}/RECORD +11 -10
- {cucu-1.3.13.dist-info → cucu-1.3.15.dist-info}/WHEEL +0 -0
- {cucu-1.3.13.dist-info → cucu-1.3.15.dist-info}/entry_points.txt +0 -0
cucu/cli/core.py
CHANGED
|
@@ -524,6 +524,7 @@ def _generate_report(
|
|
|
524
524
|
report_folder: Path,
|
|
525
525
|
only_failures: False,
|
|
526
526
|
junit_folder: Path | None = None,
|
|
527
|
+
combine: bool = False,
|
|
527
528
|
):
|
|
528
529
|
if report_folder.exists():
|
|
529
530
|
shutil.rmtree(report_folder)
|
|
@@ -531,7 +532,7 @@ def _generate_report(
|
|
|
531
532
|
report_folder.mkdir(parents=True, exist_ok=True)
|
|
532
533
|
|
|
533
534
|
if results_dir.exists():
|
|
534
|
-
consolidate_database_files(results_dir)
|
|
535
|
+
consolidate_database_files(results_dir, combine)
|
|
535
536
|
|
|
536
537
|
report_location = reporter.generate(
|
|
537
538
|
results_dir, report_folder, only_failures=only_failures
|
|
@@ -590,6 +591,12 @@ def _generate_report(
|
|
|
590
591
|
"the same location as --results",
|
|
591
592
|
type=click.Path(path_type=Path),
|
|
592
593
|
)
|
|
594
|
+
@click.option(
|
|
595
|
+
"--combine",
|
|
596
|
+
default=False,
|
|
597
|
+
is_flag=True,
|
|
598
|
+
help="combine multiple cucu_runs into a single report",
|
|
599
|
+
)
|
|
593
600
|
def report(
|
|
594
601
|
results_dir: Path,
|
|
595
602
|
only_failures,
|
|
@@ -597,6 +604,7 @@ def report(
|
|
|
597
604
|
show_skips,
|
|
598
605
|
output: Path,
|
|
599
606
|
junit: Path,
|
|
607
|
+
combine: bool,
|
|
600
608
|
):
|
|
601
609
|
"""
|
|
602
610
|
generate a test report from a results directory
|
|
@@ -627,6 +635,7 @@ def report(
|
|
|
627
635
|
report_folder=output,
|
|
628
636
|
only_failures=only_failures,
|
|
629
637
|
junit_folder=junit,
|
|
638
|
+
combine=combine,
|
|
630
639
|
)
|
|
631
640
|
|
|
632
641
|
|
cucu/db.py
CHANGED
|
@@ -411,16 +411,23 @@ def get_first_cucu_run_filepath():
|
|
|
411
411
|
return run_record.filepath
|
|
412
412
|
|
|
413
413
|
|
|
414
|
-
def consolidate_database_files(results_dir):
|
|
414
|
+
def consolidate_database_files(results_dir, combine=False):
|
|
415
415
|
# This function would need a more advanced approach with peewee, so for now, keep using sqlite3 for consolidation
|
|
416
416
|
results_path = Path(results_dir)
|
|
417
417
|
target_db_path = results_path / "run.db"
|
|
418
418
|
if not target_db_path.exists():
|
|
419
419
|
create_database_file(target_db_path)
|
|
420
420
|
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
421
|
+
if not combine:
|
|
422
|
+
db_files = [
|
|
423
|
+
db for db in results_path.glob("**/run*.db") if db.name != "run.db"
|
|
424
|
+
]
|
|
425
|
+
else:
|
|
426
|
+
# include all run.db files in all subdirectories
|
|
427
|
+
db_files = [
|
|
428
|
+
db for db in results_path.rglob("run*.db") if db != Path("run.db")
|
|
429
|
+
]
|
|
430
|
+
|
|
424
431
|
tables_to_copy = ["cucu_run", "worker", "feature", "scenario", "step"]
|
|
425
432
|
with sqlite3.connect(target_db_path) as target_conn:
|
|
426
433
|
target_cursor = target_conn.cursor()
|
|
@@ -451,7 +458,7 @@ def consolidate_database_files(results_dir):
|
|
|
451
458
|
)
|
|
452
459
|
target_conn.commit()
|
|
453
460
|
|
|
454
|
-
if db_file.name != "run.db":
|
|
461
|
+
if not combine and db_file.name != "run.db":
|
|
455
462
|
# remove the worker db files
|
|
456
463
|
db_file.unlink()
|
|
457
464
|
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
;
|
|
2
|
+
function fitHighlightToImage(highlightDiv) {
|
|
3
|
+
console.log(highlightDiv);
|
|
4
|
+
|
|
5
|
+
// Every highlight element is expected to have an ID of the form
|
|
6
|
+
// <image ID>-highlight . Get the image ID here.
|
|
7
|
+
const sliceEndIndex = highlightDiv.id.length - "-highlight".length;
|
|
8
|
+
|
|
9
|
+
const targetImgId = highlightDiv.id.slice(0, sliceEndIndex);
|
|
10
|
+
const targetImg = document.querySelector(`img#${targetImgId}`);
|
|
11
|
+
const imgViewportRect = targetImg.getBoundingClientRect();
|
|
12
|
+
// Compute absolute coordinates relative to the whole document
|
|
13
|
+
const targetDimensions = {
|
|
14
|
+
height: imgViewportRect["height"],
|
|
15
|
+
width: imgViewportRect["width"],
|
|
16
|
+
top: imgViewportRect["top"] + window.pageYOffset,
|
|
17
|
+
left: imgViewportRect["left"] + window.pageXOffset,
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const updatedHighlightStyle = [
|
|
21
|
+
"position:absolute",
|
|
22
|
+
`height:${targetDimensions["height"] * highlightDiv.getAttribute("height-ratio")}px`,
|
|
23
|
+
`width:${targetDimensions["width"] * highlightDiv.getAttribute("width-ratio")}px`,
|
|
24
|
+
`top:${(targetDimensions["height"] * highlightDiv.getAttribute("top-ratio")) + targetDimensions["top"]}px`,
|
|
25
|
+
`left:${(targetDimensions["width"] * highlightDiv.getAttribute("left-ratio")) + targetDimensions["left"]}px`,
|
|
26
|
+
"border:2px solid magenta",
|
|
27
|
+
"border-radius:2px",
|
|
28
|
+
].join(";");
|
|
29
|
+
highlightDiv.style = updatedHighlightStyle;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
function resizeAllHighlights(){
|
|
33
|
+
const highlights = document.querySelectorAll(".step-image-highlight");
|
|
34
|
+
highlights.forEach(h => fitHighlightToImage(h));
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
// The <summary> elements make the DOM jump around.
|
|
38
|
+
// The delayed resizeAllHighlights helps make sure all the highlights
|
|
39
|
+
// from lower down the page get into the right place after things settle.
|
|
40
|
+
document.querySelectorAll("summary").forEach(
|
|
41
|
+
e => {
|
|
42
|
+
e.addEventListener("click", resizeAllHighlights);
|
|
43
|
+
e.addEventListener(
|
|
44
|
+
"click",
|
|
45
|
+
() => setTimeout(resizeAllHighlights, 10)
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
);
|
|
49
|
+
// The td.data-toggles cause an animation that takes a lot longer than
|
|
50
|
+
// the one from the <summary> elements. As before, the fast
|
|
51
|
+
// resizeAllHighlights makes the ones the user can see first jump into
|
|
52
|
+
// place, then the delayed one helps put the ones lower down into place.
|
|
53
|
+
document.querySelectorAll("td[data-toggle=collapse").forEach(
|
|
54
|
+
e => {
|
|
55
|
+
e.addEventListener(
|
|
56
|
+
"click",
|
|
57
|
+
() => setTimeout(resizeAllHighlights, 10)
|
|
58
|
+
);
|
|
59
|
+
e.addEventListener(
|
|
60
|
+
"click",
|
|
61
|
+
// 400ms value was determined experimentally.
|
|
62
|
+
// It's approximately the duration of the animation triggered
|
|
63
|
+
// by clicking on these elements
|
|
64
|
+
() => setTimeout(resizeAllHighlights, 400)
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
);
|
|
68
|
+
window.onload = resizeAllHighlights;
|
|
69
|
+
window.onresize = resizeAllHighlights;
|
cucu/reporter/html.py
CHANGED
|
@@ -14,7 +14,11 @@ import cucu.db as db
|
|
|
14
14
|
from cucu import format_gherkin_table, logger
|
|
15
15
|
from cucu.ansi_parser import parse_log_to_html
|
|
16
16
|
from cucu.config import CONFIG
|
|
17
|
-
from cucu.utils import
|
|
17
|
+
from cucu.utils import (
|
|
18
|
+
ellipsize_filename,
|
|
19
|
+
generate_short_id,
|
|
20
|
+
get_step_image_dir,
|
|
21
|
+
)
|
|
18
22
|
|
|
19
23
|
|
|
20
24
|
def escape(data):
|
|
@@ -130,6 +134,7 @@ def generate(results, basepath, only_failures=False):
|
|
|
130
134
|
"timestamp": db_step.end_at or "",
|
|
131
135
|
},
|
|
132
136
|
"substep": db_step.is_substep,
|
|
137
|
+
"screenshots": db_step.screenshots,
|
|
133
138
|
}
|
|
134
139
|
|
|
135
140
|
if db_step.text:
|
|
@@ -281,8 +286,6 @@ def generate(results, basepath, only_failures=False):
|
|
|
281
286
|
scenario_started_at = None
|
|
282
287
|
for step in scenario["steps"]:
|
|
283
288
|
total_steps += 1
|
|
284
|
-
image_dir = get_step_image_dir(step_index, step["name"])
|
|
285
|
-
image_dirpath = os.path.join(scenario_filepath, image_dir)
|
|
286
289
|
|
|
287
290
|
# Handle section headings with different levels (# to ####)
|
|
288
291
|
if step["name"].startswith("#"):
|
|
@@ -292,32 +295,52 @@ def generate(results, basepath, only_failures=False):
|
|
|
292
295
|
f"h{step['name'][:4].count('#') + 1}"
|
|
293
296
|
)
|
|
294
297
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
298
|
+
images = []
|
|
299
|
+
image_dir = get_step_image_dir(step_index, step["name"])
|
|
300
|
+
image_dirpath = os.path.join(scenario_filepath, image_dir)
|
|
301
|
+
for screenshot_index, screenshot in enumerate(step["screenshots"]):
|
|
302
|
+
filename = os.path.split(screenshot["filepath"])[-1]
|
|
303
|
+
filepath = os.path.join(image_dirpath, filename)
|
|
304
|
+
if not os.path.exists(filepath):
|
|
305
|
+
continue
|
|
306
|
+
label = screenshot.get("label", step["name"])
|
|
307
|
+
highlight = None
|
|
308
|
+
if (
|
|
309
|
+
screenshot["location"]
|
|
310
|
+
and not CONFIG["CUCU_SKIP_HIGHLIGHT_BORDER"]
|
|
311
|
+
):
|
|
312
|
+
window_height = screenshot["size"]["height"]
|
|
313
|
+
window_width = screenshot["size"]["width"]
|
|
301
314
|
try:
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
"src": urllib.parse.quote(
|
|
314
|
-
os.path.join(image_dir, image_name)
|
|
315
|
-
),
|
|
316
|
-
"index": index,
|
|
317
|
-
"label": label,
|
|
315
|
+
highlight = {
|
|
316
|
+
"height_ratio": screenshot["location"][
|
|
317
|
+
"height"
|
|
318
|
+
]
|
|
319
|
+
/ window_height,
|
|
320
|
+
"width_ratio": screenshot["location"]["width"]
|
|
321
|
+
/ window_width,
|
|
322
|
+
"top_ratio": screenshot["location"]["y"]
|
|
323
|
+
/ window_height,
|
|
324
|
+
"left_ratio": screenshot["location"]["x"]
|
|
325
|
+
/ window_width,
|
|
318
326
|
}
|
|
319
|
-
|
|
320
|
-
|
|
327
|
+
except TypeError:
|
|
328
|
+
# If any of the necessary properties is absent,
|
|
329
|
+
# then oh well, no highlight this time.
|
|
330
|
+
pass
|
|
331
|
+
screenshot_id = f"step-img-{screenshot.get("step_run_id", generate_short_id())}-{screenshot_index:0>4}"
|
|
332
|
+
images.append(
|
|
333
|
+
{
|
|
334
|
+
"src": urllib.parse.quote(
|
|
335
|
+
os.path.join(image_dir, filename)
|
|
336
|
+
),
|
|
337
|
+
"index": screenshot_index,
|
|
338
|
+
"label": label,
|
|
339
|
+
"id": screenshot_id,
|
|
340
|
+
"highlight": highlight,
|
|
341
|
+
}
|
|
342
|
+
)
|
|
343
|
+
step["images"] = sorted(images, key=lambda x: x["index"])
|
|
321
344
|
|
|
322
345
|
if "result" in step:
|
|
323
346
|
if step["result"]["status"] in ["failed", "passed"]:
|
|
@@ -150,7 +150,10 @@
|
|
|
150
150
|
<summary style="color: dimgray;">images ({{ step['images']|length }} images)</summary>
|
|
151
151
|
<div style="margin: 10px 0 0 0;">
|
|
152
152
|
{% for image in step['images'] %}
|
|
153
|
-
<img class="mx-auto d-block img-fluid shadow bg-white rounded" style="margin-bottom:15px" alt='{{ image["label"] }}' title='{{ image["label"] }}' src='{{ image["src"] }}'></img>
|
|
153
|
+
<img class="mx-auto d-block img-fluid shadow bg-white rounded" id='{{image['id']}}' style="margin-bottom:15px" alt='{{ image["label"] }}' title='{{ image["label"] }}' src='{{ image["src"] }}'></img>
|
|
154
|
+
{% if image['highlight'] %}
|
|
155
|
+
<div class="step-image-highlight" id='{{ image["id"]}}-highlight' height-ratio='{{ image['highlight']['height_ratio'] }}' width-ratio='{{ image['highlight']['width_ratio'] }}' top-ratio='{{ image['highlight']['top_ratio'] }}' left-ratio='{{ image['highlight']['left_ratio'] }}'></div>
|
|
156
|
+
{% endif %}
|
|
154
157
|
{% endfor %}
|
|
155
158
|
</div>
|
|
156
159
|
</details>
|
|
@@ -222,4 +225,5 @@
|
|
|
222
225
|
});
|
|
223
226
|
});
|
|
224
227
|
</script>
|
|
228
|
+
<script src="../../external/manage_scenario_highlights.js"></script>
|
|
225
229
|
{% endblock %}
|
cucu/steps/webserver_steps.py
CHANGED
|
@@ -35,7 +35,7 @@ def run_webserver_for_scenario(ctx, directory, variable):
|
|
|
35
35
|
CONFIG[variable] = str(port)
|
|
36
36
|
|
|
37
37
|
with socket.create_connection(("localhost", port), timeout=5):
|
|
38
|
-
logger.debug(f"Webserver is running at {port=}
|
|
38
|
+
logger.debug(f"Webserver is running at {port=}")
|
|
39
39
|
|
|
40
40
|
def shutdown_webserver(_):
|
|
41
41
|
httpd.shutdown()
|
cucu/utils.py
CHANGED
|
@@ -245,56 +245,42 @@ def take_screenshot(ctx, step_name, label="", element=None):
|
|
|
245
245
|
os.mkdir(screenshot_dir)
|
|
246
246
|
|
|
247
247
|
if len(label) > 0:
|
|
248
|
-
label =
|
|
249
|
-
filename = f"{CONFIG['__STEP_SCREENSHOT_COUNT']:0>4}{label}.png"
|
|
248
|
+
label = CONFIG.hide_secrets(label).replace("/", "_")
|
|
249
|
+
filename = f"{CONFIG['__STEP_SCREENSHOT_COUNT']:0>4} - {label}.png"
|
|
250
250
|
filename = ellipsize_filename(filename)
|
|
251
251
|
filepath = os.path.join(screenshot_dir, filename)
|
|
252
252
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
clear_highlight = """
|
|
279
|
-
(function() {
|
|
280
|
-
var body = document.querySelector('body');
|
|
281
|
-
var cucu_border = document.getElementById('cucu_border');
|
|
282
|
-
body.removeChild(cucu_border);
|
|
283
|
-
})();
|
|
284
|
-
"""
|
|
285
|
-
ctx.browser.execute(clear_highlight, element)
|
|
286
|
-
|
|
253
|
+
ctx.browser.screenshot(filepath)
|
|
254
|
+
element_info = {
|
|
255
|
+
"x": None,
|
|
256
|
+
"y": None,
|
|
257
|
+
"height": None,
|
|
258
|
+
"width": None,
|
|
259
|
+
}
|
|
260
|
+
if element:
|
|
261
|
+
element_info.update(element.rect)
|
|
262
|
+
# driver.get_window_size returns the size of the window the OS draws for
|
|
263
|
+
# the browser, not the window the browser uses to display the DOM.
|
|
264
|
+
# If we go through JavaScript, we ignore the height of the adress bar
|
|
265
|
+
# and such.
|
|
266
|
+
script = """
|
|
267
|
+
function getDimensionsOfCurrentWindow() {
|
|
268
|
+
const windowSize = {
|
|
269
|
+
width: window.innerWidth,
|
|
270
|
+
height: window.innerHeight,
|
|
271
|
+
};
|
|
272
|
+
return windowSize;
|
|
273
|
+
};
|
|
274
|
+
return getDimensionsOfCurrentWindow();
|
|
275
|
+
"""
|
|
276
|
+
browser_window_size = ctx.browser.execute(script)
|
|
287
277
|
screenshot = {
|
|
288
278
|
"step_name": step_name,
|
|
289
279
|
"label": label,
|
|
290
280
|
"element": element,
|
|
291
|
-
"location":
|
|
292
|
-
if element
|
|
293
|
-
else "",
|
|
294
|
-
"size": f"({element.size['width']},{element.size['height']})"
|
|
295
|
-
if element
|
|
296
|
-
else "",
|
|
281
|
+
"location": element_info,
|
|
297
282
|
"filepath": filepath,
|
|
283
|
+
"size": browser_window_size,
|
|
298
284
|
}
|
|
299
285
|
step.screenshots.append(screenshot)
|
|
300
286
|
|
|
@@ -7,12 +7,12 @@ cucu/browser/frames.py,sha256=IW7kzRJn5PkbMaovIelAeCWO-T-2sOTwqaYBw-0-LKU,3545
|
|
|
7
7
|
cucu/browser/selenium.py,sha256=eUC2DZkhUIZi70sVTaNE_0AhanGTceyx_pCLIT7PN6o,13299
|
|
8
8
|
cucu/browser/selenium_tweaks.py,sha256=oUIhWVhBZbc9qsmQUJMpIr9uUWKxtgZBcnySWU6Yttk,879
|
|
9
9
|
cucu/cli/__init__.py,sha256=uXX5yVG1konJ_INdlrcfMg-Tt_5_cSx29Ed8R8v908A,62
|
|
10
|
-
cucu/cli/core.py,sha256
|
|
10
|
+
cucu/cli/core.py,sha256=-3TWxedDNMR1Jg7qNF5GLdvgn7KgthMwQ0hfeyJi1eg,27509
|
|
11
11
|
cucu/cli/run.py,sha256=6w7lkgf3iWsg9lqrmCJEWmOHGRXJFbVyZItVGGk_9gM,6105
|
|
12
12
|
cucu/cli/steps.py,sha256=5-aOGf3fmcnge4pcFM__4shcA3PZwjKe6oZN6XKY1pM,4215
|
|
13
13
|
cucu/cli/thread_dumper.py,sha256=Z3XnYSxidx6pqjlQ7zu-TKMIYZWk4z9c5YLdPkcemiU,1593
|
|
14
14
|
cucu/config.py,sha256=Pi59JiRcCdzugDwraM4R1hXRkP52123z0hSP8X6lyzI,14970
|
|
15
|
-
cucu/db.py,sha256=
|
|
15
|
+
cucu/db.py,sha256=ZadBBvwwzlHTi-MXMrHlSudpn61zxaTQsDMfCjSGnNk,15323
|
|
16
16
|
cucu/edgedriver_autoinstaller/README.md,sha256=tDkAWIqgRdCjt-oX1nYqikIC_FfiOEM2-pc5S5VbRLo,84
|
|
17
17
|
cucu/edgedriver_autoinstaller/__init__.py,sha256=fo6xJJPvcc5Xvni8epXfxDoPxJH5_b6Vk2jD9JTwfRs,969
|
|
18
18
|
cucu/edgedriver_autoinstaller/utils.py,sha256=iRKTww77CGaTAntt_QDvxlKPxpMU4otx95OeD97khcM,6802
|
|
@@ -54,14 +54,15 @@ cucu/reporter/external/dataTables.bootstrap.min.css,sha256=AVjWb9eSGQ0-3f4WNiVU1
|
|
|
54
54
|
cucu/reporter/external/dataTables.bootstrap.min.js,sha256=H_ZJHj902eqGocNJYjkD3OButj68n-T2NSBjnfV2Qok,4401
|
|
55
55
|
cucu/reporter/external/jquery-3.5.1.min.js,sha256=9_aliU8dGd2tb6OSsuzixeV4y_faTqgFtohetphbbj0,89476
|
|
56
56
|
cucu/reporter/external/jquery.dataTables.min.js,sha256=XNhaB1tBOSFMHu96BSAJpZOJzfZ4SZI1nwAbnwry2UY,90265
|
|
57
|
+
cucu/reporter/external/manage_scenario_highlights.js,sha256=UAGC3CLzTqDdPI9d2tFOeww9afVS5S4J1Elg96x60cY,2669
|
|
57
58
|
cucu/reporter/external/popper.min.js,sha256=pS96pU17yq-gVu4KBQJi38VpSuKN7otMrDQprzf_DWY,19188
|
|
58
59
|
cucu/reporter/favicon.png,sha256=9ikXLAmzfQzy2NQps_8CGaZog2FvQrOX8nnSZ0e1UmM,2161
|
|
59
|
-
cucu/reporter/html.py,sha256=
|
|
60
|
+
cucu/reporter/html.py,sha256=8wXF9ntF5Rkmoe-LWHY0YgxbSwuJGdZ1XTKWD-LFbBE,21009
|
|
60
61
|
cucu/reporter/templates/feature.html,sha256=IBkwGiul-sRO5lT8q8VFXMUJx1owsAd1YbdDzziSjKw,3645
|
|
61
62
|
cucu/reporter/templates/flat.html,sha256=inx9wBo23SKsETA5BqU3GAxM7WaLTsDgCyL_D7TPpdA,2531
|
|
62
63
|
cucu/reporter/templates/index.html,sha256=pJ1eojL19EIUuIiqtALPm3atTabKJb7M1FwGzWpGkdg,2818
|
|
63
64
|
cucu/reporter/templates/layout.html,sha256=2iDRbm8atO8mgHWgijIvDCrBMKvcP6YHrmr95WtJiE4,4561
|
|
64
|
-
cucu/reporter/templates/scenario.html,sha256=
|
|
65
|
+
cucu/reporter/templates/scenario.html,sha256=LWjSj2PNcBpC1EnxCmgnzG8ZLDIXEDF4F1oexfFfx4E,12238
|
|
65
66
|
cucu/steps/__init__.py,sha256=seSmASBlWu6-6wbFbvEbPwigBcRXiYP18C4X_2cW8Ng,753
|
|
66
67
|
cucu/steps/base_steps.py,sha256=0fPvdaKoan8lMAKrDnK0-zrALpxm11P1zVAY5CN7iXA,1893
|
|
67
68
|
cucu/steps/browser_steps.py,sha256=iTRl5ffpf2YrFk5qh655WFHAeSOwoE3HFhmXhjsZtao,12687
|
|
@@ -86,9 +87,9 @@ cucu/steps/table_steps.py,sha256=Xf_9sMZXJRaO64Sd12vCnBm9Olxq1qyyfHHpy_hveWI,137
|
|
|
86
87
|
cucu/steps/tables.js,sha256=Os2a7Fo-cg03XVli7USvcnBVad4N7idXr-HBuzdLvVQ,945
|
|
87
88
|
cucu/steps/text_steps.py,sha256=Jj_GHoHeemNwVdUOdqcehArNp7WM-WMjljA4w0pLXuw,2576
|
|
88
89
|
cucu/steps/variable_steps.py,sha256=WSctH3_xcxjijGPYZlxp-foC_SIAAKtF__saNtgZJbk,2966
|
|
89
|
-
cucu/steps/webserver_steps.py,sha256=
|
|
90
|
-
cucu/utils.py,sha256=
|
|
91
|
-
cucu-1.3.
|
|
92
|
-
cucu-1.3.
|
|
93
|
-
cucu-1.3.
|
|
94
|
-
cucu-1.3.
|
|
90
|
+
cucu/steps/webserver_steps.py,sha256=i11xOmSjhhrQ-2QrDfpjDhWroeJuuGKvbYEsHV1cioI,1406
|
|
91
|
+
cucu/utils.py,sha256=hkvfTpN9bCClZ8ezny8mkAPq0OaR3A3kJi8lzq0zL0Q,10164
|
|
92
|
+
cucu-1.3.15.dist-info/WHEEL,sha256=eh7sammvW2TypMMMGKgsM83HyA_3qQ5Lgg3ynoecH3M,79
|
|
93
|
+
cucu-1.3.15.dist-info/entry_points.txt,sha256=11WRIhQM7LuUnQg1lAoZQoNvvBvYNN1maDgQS4djwJo,40
|
|
94
|
+
cucu-1.3.15.dist-info/METADATA,sha256=VH6FZBTbcc29w_3Rh27ROd7qvLDHvnt9clbzRqmU2lg,16722
|
|
95
|
+
cucu-1.3.15.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|