cucu 1.2.2__tar.gz → 1.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.

Potentially problematic release.


This version of cucu might be problematic. Click here for more details.

Files changed (94) hide show
  1. {cucu-1.2.2 → cucu-1.2.4}/PKG-INFO +12 -11
  2. {cucu-1.2.2 → cucu-1.2.4}/pyproject.toml +3 -3
  3. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/browser/core.py +12 -0
  4. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/browser/selenium.py +50 -0
  5. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/config.py +8 -1
  6. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/environment.py +6 -6
  7. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/reporter/templates/scenario.html +2 -2
  8. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/steps/browser_steps.py +64 -2
  9. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/utils.py +0 -13
  10. cucu-1.2.2/.gitignore +0 -191
  11. cucu-1.2.2/CHANGELOG.md +0 -421
  12. cucu-1.2.2/LICENSE +0 -32
  13. {cucu-1.2.2 → cucu-1.2.4}/README.md +0 -0
  14. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/__init__.py +0 -0
  15. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/ansi_parser.py +0 -0
  16. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/behave_tweaks.py +0 -0
  17. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/browser/__init__.py +0 -0
  18. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/browser/frames.py +0 -0
  19. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/browser/selenium_tweaks.py +0 -0
  20. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/cli/__init__.py +0 -0
  21. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/cli/core.py +0 -0
  22. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/cli/run.py +0 -0
  23. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/cli/steps.py +0 -0
  24. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/cli/thread_dumper.py +0 -0
  25. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/edgedriver_autoinstaller/README.md +0 -0
  26. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/edgedriver_autoinstaller/__init__.py +0 -0
  27. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/edgedriver_autoinstaller/utils.py +0 -0
  28. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/external/jquery/jquery-3.5.1.min.js +0 -0
  29. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/formatter/__init__.py +0 -0
  30. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/formatter/cucu.py +0 -0
  31. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/formatter/json.py +0 -0
  32. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/formatter/junit.py +0 -0
  33. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/fuzzy/__init__.py +0 -0
  34. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/fuzzy/core.py +0 -0
  35. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/fuzzy/fuzzy.js +0 -0
  36. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/helpers.py +0 -0
  37. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/hooks.py +0 -0
  38. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/init_data/.gitignore +0 -0
  39. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/init_data/README.md +0 -0
  40. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/init_data/cucurc.yml +0 -0
  41. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/init_data/data/www/example.html +0 -0
  42. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/init_data/features/cucurc.yml +0 -0
  43. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/init_data/features/environment.py +0 -0
  44. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/init_data/features/example.feature +0 -0
  45. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/init_data/features/lint_rules/sid.yaml +0 -0
  46. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/init_data/features/steps/__init__.py +0 -0
  47. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/init_data/features/steps/my_steps.py +0 -0
  48. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/language_server/__init__.py +0 -0
  49. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/language_server/core.py +0 -0
  50. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/lint/__init__.py +0 -0
  51. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/lint/linter.py +0 -0
  52. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/lint/rules/format.yaml +0 -0
  53. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/logger.py +0 -0
  54. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/matcher/__init__.py +0 -0
  55. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/matcher/core.py +0 -0
  56. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/page_checks.py +0 -0
  57. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/reporter/__init__.py +0 -0
  58. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/reporter/external/bootstrap.min.css +0 -0
  59. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/reporter/external/bootstrap.min.js +0 -0
  60. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/reporter/external/dataTables.bootstrap.min.css +0 -0
  61. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/reporter/external/dataTables.bootstrap.min.js +0 -0
  62. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/reporter/external/jquery-3.5.1.min.js +0 -0
  63. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/reporter/external/jquery.dataTables.min.js +0 -0
  64. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/reporter/external/popper.min.js +0 -0
  65. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/reporter/favicon.png +0 -0
  66. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/reporter/html.py +0 -0
  67. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/reporter/templates/feature.html +0 -0
  68. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/reporter/templates/flat.html +0 -0
  69. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/reporter/templates/index.html +0 -0
  70. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/reporter/templates/layout.html +0 -0
  71. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/steps/__init__.py +0 -0
  72. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/steps/base_steps.py +0 -0
  73. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/steps/button_steps.py +0 -0
  74. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/steps/checkbox_steps.py +0 -0
  75. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/steps/command_steps.py +0 -0
  76. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/steps/draggable_steps.py +0 -0
  77. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/steps/dropdown_steps.py +0 -0
  78. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/steps/file_input_steps.py +0 -0
  79. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/steps/filesystem_steps.py +0 -0
  80. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/steps/flow_control_steps.py +0 -0
  81. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/steps/image_steps.py +0 -0
  82. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/steps/input_steps.py +0 -0
  83. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/steps/link_steps.py +0 -0
  84. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/steps/menuitem_steps.py +0 -0
  85. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/steps/platform_steps.py +0 -0
  86. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/steps/radio_steps.py +0 -0
  87. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/steps/section_steps.py +0 -0
  88. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/steps/step_utils.py +0 -0
  89. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/steps/tab_steps.py +0 -0
  90. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/steps/table_steps.py +0 -0
  91. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/steps/tables.js +0 -0
  92. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/steps/text_steps.py +0 -0
  93. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/steps/variable_steps.py +0 -0
  94. {cucu-1.2.2 → cucu-1.2.4}/src/cucu/steps/webserver_steps.py +0 -0
@@ -1,23 +1,18 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.3
2
2
  Name: cucu
3
- Version: 1.2.2
3
+ Version: 1.2.4
4
4
  Summary: Easy BDD web testing
5
- Project-URL: Homepage, https://github.com/dominodatalab/cucu/wiki
6
- Project-URL: Download, https://pypi.org/project/cucu/
7
- Project-URL: Source Code, https://github.com/dominodatalab/cucu
5
+ Keywords: cucumber,selenium,behave
6
+ Author: Domino Data Lab, Rodney Gomes, Cedric Young, Xin Dong, Kavya, Kevin Garton, Joy Liao
8
7
  Author-email: Domino Data Lab <open-source@dominodatalab.com>, Rodney Gomes <107359+rlgomes@users.noreply.github.com>, Cedric Young <4129217+ccedricyoung@users.noreply.github.com>, Xin Dong <104880864+ddl-xin@users.noreply.github.com>, Kavya <91882851+ddl-kavya@users.noreply.github.com>, Kevin Garton <71028750+ddl-kgarton@users.noreply.github.com>, Joy Liao <107583686+ddl-joy-liao@users.noreply.github.com>
9
- Maintainer-email: Domino Data Lab <open-source@dominodatalab.com>, Cedric Young <4129217+ccedricyoung@users.noreply.github.com>, Kevin Garton <71028750+ddl-kgarton@users.noreply.github.com>, Brian Colby <92048365+ddl-bcolby@users.noreply.github.com>
10
8
  License: The Clear BSD License
11
- License-File: LICENSE
12
- Keywords: behave,cucumber,selenium
13
9
  Classifier: Development Status :: 4 - Beta
14
10
  Classifier: Environment :: Console
15
11
  Classifier: Intended Audience :: Developers
16
12
  Classifier: License :: OSI Approved :: BSD License
17
- Classifier: Natural Language :: English
18
13
  Classifier: Operating System :: OS Independent
14
+ Classifier: Natural Language :: English
19
15
  Classifier: Topic :: Software Development :: Testing :: BDD
20
- Requires-Python: >=3.10
21
16
  Requires-Dist: beautifulsoup4~=4.13.3
22
17
  Requires-Dist: behave==1.2.6
23
18
  Requires-Dist: chromedriver-autoinstaller~=0.6.2
@@ -33,10 +28,16 @@ Requires-Dist: mpire~=2.10.2
33
28
  Requires-Dist: psutil>=6.0
34
29
  Requires-Dist: pygls~=1.3.1
35
30
  Requires-Dist: pyyaml~=6.0.1
36
- Requires-Dist: requests<3.0.0,>=2.31.0
31
+ Requires-Dist: requests>=2.31.0,<3.0.0
37
32
  Requires-Dist: selenium~=4.31
38
33
  Requires-Dist: tabulate~=0.9.0
39
34
  Requires-Dist: tenacity>=9.0
35
+ Maintainer: Domino Data Lab, Cedric Young, Kevin Garton, Brian Colby
36
+ Maintainer-email: Domino Data Lab <open-source@dominodatalab.com>, Cedric Young <4129217+ccedricyoung@users.noreply.github.com>, Kevin Garton <71028750+ddl-kgarton@users.noreply.github.com>, Brian Colby <92048365+ddl-bcolby@users.noreply.github.com>
37
+ Requires-Python: >=3.10
38
+ Project-URL: Download, https://pypi.org/project/cucu/
39
+ Project-URL: Homepage, https://github.com/dominodatalab/cucu/wiki
40
+ Project-URL: Source Code, https://github.com/dominodatalab/cucu
40
41
  Description-Content-Type: text/markdown
41
42
 
42
43
  [![pypi](https://img.shields.io/pypi/v/cucu.svg)](https://pypi.org/project/cucu/)
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "cucu"
3
- version = "1.2.2"
3
+ version = "1.2.4"
4
4
  description = "Easy BDD web testing"
5
5
  readme = "README.md"
6
6
  license = { text = "The Clear BSD License" }
@@ -65,8 +65,8 @@ Download = "https://pypi.org/project/cucu/"
65
65
  cucu = "cucu.cli:main"
66
66
 
67
67
  [build-system]
68
- requires = ["hatchling"]
69
- build-backend = "hatchling.build"
68
+ requires = ["uv_build>=0.7.19,<0.8.0"]
69
+ build-backend = "uv_build"
70
70
 
71
71
  [tool.hatch.build.targets.sdist]
72
72
  include = [
@@ -55,6 +55,18 @@ class Browser:
55
55
  def close_window(self):
56
56
  raise RuntimeError("implement me")
57
57
 
58
+ def get_tab_info(self):
59
+ raise RuntimeError("implement me")
60
+
61
+ def get_all_tabs_info(self):
62
+ raise RuntimeError("implement me")
63
+
64
+ def switch_to_nth_tab(self, tab_index):
65
+ raise RuntimeError("implement me")
66
+
67
+ def switch_to_tab_that_matches_regex(self, text):
68
+ raise RuntimeError("implement me")
69
+
58
70
  def quit(self):
59
71
  raise RuntimeError("implement me")
60
72
 
@@ -1,5 +1,6 @@
1
1
  import logging
2
2
  import os
3
+ import re
3
4
 
4
5
  import chromedriver_autoinstaller
5
6
  import geckodriver_autoinstaller
@@ -226,6 +227,55 @@ class Selenium(Browser):
226
227
  raise RuntimeError("no previous browser tab available")
227
228
  self.driver.switch_to.window(window_handles[window_handle_index - 1])
228
229
 
230
+ def switch_to_nth_tab(self, tab_number):
231
+ print(f"tab_number, {tab_number}")
232
+ window_handles = self.driver.window_handles
233
+ total_tabs = len(window_handles)
234
+ if tab_number > total_tabs:
235
+ raise RuntimeError(f"no {tab_number} browser tab available")
236
+ self.driver.switch_to.window(window_handles[tab_number])
237
+
238
+ def switch_to_tab_that_matches_regex(self, title_pattern):
239
+ window_handles = self.driver.window_handles
240
+
241
+ for handle in window_handles:
242
+ self.driver.switch_to.window(handle)
243
+ if re.search(title_pattern, self.driver.title):
244
+ return
245
+
246
+ raise Exception(f"No tab title matches pattern: {title_pattern}")
247
+
248
+ def get_tab_info(self):
249
+ window_handles = self.driver.window_handles
250
+ current_window = self.driver.current_window_handle
251
+ window_handle_index = window_handles.index(current_window)
252
+
253
+ return {
254
+ "tab_count": len(window_handles),
255
+ "index": window_handle_index,
256
+ "title": self.driver.title,
257
+ "url": self.driver.current_url,
258
+ }
259
+
260
+ def get_all_tabs_info(self):
261
+ window_handles = self.driver.window_handles
262
+ current_window = self.driver.current_window_handle
263
+ tabs_info = []
264
+
265
+ for handle in window_handles:
266
+ self.driver.switch_to.window(handle)
267
+ tabs_info.append(
268
+ {
269
+ "title": self.driver.title,
270
+ "url": self.driver.current_url,
271
+ }
272
+ )
273
+
274
+ # Switch back to the original window
275
+ self.driver.switch_to.window(current_window)
276
+
277
+ return tabs_info
278
+
229
279
  def back(self):
230
280
  self.driver.back()
231
281
  self.wait_for_page_to_load()
@@ -313,7 +313,14 @@ class Config(dict):
313
313
  v = f"'{v}'"
314
314
  config[k] = v
315
315
 
316
- return yaml.dump(config)
316
+ # Resolve non-atomic classes to their string representation
317
+ yaml.representer.SafeRepresenter.add_representer(
318
+ None,
319
+ lambda dumper, data: dumper.represent_scalar(
320
+ "tag:yaml.org,2002:str", str(data)
321
+ ),
322
+ )
323
+ return yaml.safe_dump(config)
317
324
 
318
325
 
319
326
  # global config object
@@ -10,7 +10,7 @@ from functools import partial
10
10
  from cucu import config, init_scenario_hook_variables, logger
11
11
  from cucu.config import CONFIG
12
12
  from cucu.page_checks import init_page_checks
13
- from cucu.utils import ellipsize_filename, get_tab_information, take_screenshot
13
+ from cucu.utils import ellipsize_filename, take_screenshot
14
14
 
15
15
  CONFIG.define(
16
16
  "FEATURE_RESULTS_DIR",
@@ -264,11 +264,11 @@ def after_step(ctx, step):
264
264
  if ctx.browser is not None and ctx.current_step.has_substeps is False:
265
265
  take_screenshot(ctx, step.name, label=f"After {step.name}")
266
266
 
267
- tab_info = get_tab_information(ctx)
268
- total_tabs = tab_info["window_count"]
269
- current_tab = tab_info["current_index"] + 1
270
- title = tab_info["current_title"]
271
- url = tab_info["current_url"]
267
+ tab_info = ctx.browser.get_tab_info()
268
+ total_tabs = tab_info["tab_count"]
269
+ current_tab = tab_info["index"] + 1
270
+ title = tab_info["title"]
271
+ url = tab_info["url"]
272
272
  log_message = (
273
273
  f"\ntab({current_tab} of {total_tabs}): {title}\nurl: {url}\n"
274
274
  )
@@ -75,7 +75,7 @@
75
75
  {% endif %}
76
76
  </td>
77
77
  <td style="text-align: right; margin-top: auto;" class="col-2">
78
- <pre style="display: inline; color: gray;">Offset and Duration (s)</pre>
78
+ <pre style="display: inline; color: gray;">Start Time and Duration (s)</pre>
79
79
  </td>
80
80
  </tr>
81
81
  {% for step in steps %}
@@ -88,7 +88,7 @@
88
88
  {% if step['result'] is defined %}
89
89
  {% set step_status = step['result']['status'] %}
90
90
  {% if step['result']['status'] == 'failed' or step['result']['status'] == 'passed' %}
91
- {% set step_timing = "{} for {:.3f}s".format(step["result"]["time_offset"].strftime("%H:%M:%S"), step["result"]["duration"]) %}
91
+ {% set step_timing = "{} for {:.3f}s".format(step["result"]["timestamp"].strftime("%H:%M:%S"), step["result"]["duration"]) %}
92
92
  {% set step_start = step["result"]["timestamp"] %}
93
93
  {% endif %}
94
94
  {% else %}
@@ -32,7 +32,7 @@ def open_a_browser(ctx, url):
32
32
  Given I open a browser at the url "https://www.google.com"
33
33
  """
34
34
  if ctx.browser is None:
35
- ctx.browser = open_browser(ctx)
35
+ ctx.browser = retry(open_browser)(ctx)
36
36
  ctx.browsers.append(ctx.browser)
37
37
  else:
38
38
  logger.debug("browser already open so using existing instance")
@@ -43,7 +43,7 @@ def open_a_browser(ctx, url):
43
43
 
44
44
  @step('I open a new browser at the url "{url}"')
45
45
  def open_a_new_browser(ctx, url):
46
- ctx.browser = open_browser(ctx)
46
+ ctx.browser = retry(open_browser)(ctx)
47
47
  ctx.browsers.append(ctx.browser)
48
48
  logger.debug(f"navigating to url #{url}")
49
49
  ctx.browser.navigate(url)
@@ -219,6 +219,68 @@ def wait_to_switch_to_previous_browser_tab(ctx):
219
219
  retry(switch_to_previous_tab)(ctx)
220
220
 
221
221
 
222
+ def switch_to_nth_tab(ctx, tab_number):
223
+ ctx.check_browser_initialized()
224
+ ctx.browser.switch_to_nth_tab(tab_number)
225
+
226
+
227
+ @step('I switch to the "{nth:nth}" browser tab')
228
+ def switch_to_nth_browser_tab(ctx, nth):
229
+ switch_to_nth_tab(ctx, nth)
230
+
231
+
232
+ @step('I wait to switch to the "{nth:nth}" browser tab')
233
+ def wait_to_switch_to_nth_browser_tab(ctx, nth):
234
+ retry(switch_to_nth_tab)(ctx, nth)
235
+
236
+
237
+ def switch_to_tab_matching_regex(ctx, regex):
238
+ ctx.check_browser_initialized()
239
+ ctx.browser.switch_to_tab_that_matches_regex(regex)
240
+
241
+
242
+ @step('I switch to the browser tab that matches "{regex}"')
243
+ def switch_to_browser_tab_matching_regex(ctx, regex):
244
+ switch_to_tab_matching_regex(ctx, regex)
245
+
246
+
247
+ @step('I wait to switch to the browser tab that matches "{regex}"')
248
+ def wait_to_switch_to_browser_tab_matching_regex(ctx, regex):
249
+ retry(switch_to_tab_matching_regex)(ctx, regex)
250
+
251
+
252
+ @step('I save the browser tabs info to the variable "{variable}"')
253
+ def save_browser_tabs_info_to_variable(ctx, variable):
254
+ ctx.check_browser_initialized()
255
+ tabs_info = ctx.browser.get_all_tabs_info()
256
+ lst_tab_info = [
257
+ f"tab({index + 1}): {tab['title']}, url: {tab['url']}"
258
+ for index, tab in enumerate(tabs_info)
259
+ ]
260
+ config.CONFIG[variable] = lst_tab_info
261
+
262
+
263
+ @step("I list the current browser tab info")
264
+ def list_current_browser_tab_info(ctx):
265
+ ctx.check_browser_initialized()
266
+ tab_info = ctx.browser.get_tab_info()
267
+ current_tab = tab_info["index"] + 1
268
+ title = tab_info["title"]
269
+ url = tab_info["url"]
270
+ print(f"\ntab({current_tab}): {title}\nurl: {url}\n")
271
+
272
+
273
+ @step("I list all browser tabs info")
274
+ def list_browser_tabs_info(ctx):
275
+ ctx.check_browser_initialized()
276
+ all_tabs_info = ctx.browser.get_all_tabs_info()
277
+ for index, tab in enumerate(all_tabs_info):
278
+ tab_index = index + 1
279
+ title = tab["title"]
280
+ url = tab["url"]
281
+ print(f"\ntab({tab_index}): {title}\nurl: {url}\n")
282
+
283
+
222
284
  def save_downloaded_file(ctx, filename):
223
285
  ctx.check_browser_initialized()
224
286
 
@@ -274,19 +274,6 @@ def take_screenshot(ctx, step_name, label="", element=None):
274
274
  CONFIG["__STEP_SCREENSHOT_COUNT"] += 1
275
275
 
276
276
 
277
- def get_tab_information(ctx):
278
- driver = ctx.browser.driver
279
- window_handles = driver.window_handles
280
- current_window = driver.current_window_handle
281
- window_handle_index = window_handles.index(current_window)
282
- return {
283
- "window_count": len(window_handles),
284
- "current_index": window_handle_index,
285
- "current_title": driver.title,
286
- "current_url": driver.current_url,
287
- }
288
-
289
-
290
277
  def find_n_click_input_parent_label(ctx, input_element):
291
278
  """
292
279
  Clicks the nearest parent <label> of an input elemnt (if input is visually hidden or size is zero).
cucu-1.2.2/.gitignore DELETED
@@ -1,191 +0,0 @@
1
- dist
2
- .cache
3
- .coverage.*
4
- .DS_Store
5
- *.egg-info
6
- htmlcov
7
- .nox
8
- .ruff_cache
9
- terraform.tfstate
10
- terraform.tfstate.backup
11
- .terraform
12
- .pytest_cache
13
- __pycache__
14
- *.pyc
15
- pygls.log
16
- junit_results/
17
- report/
18
- results/
19
- .monitor.png
20
- geckodriver.log
21
-
22
- # Byte-compiled / optimized / DLL files
23
- __pycache__/
24
- *.py[cod]
25
- *$py.class
26
-
27
- # C extensions
28
- *.so
29
-
30
- # Distribution / packaging
31
- .Python
32
- build/
33
- develop-eggs/
34
- dist/
35
- downloads/
36
- eggs/
37
- .eggs/
38
- lib/
39
- lib64/
40
- parts/
41
- sdist/
42
- var/
43
- wheels/
44
- share/python-wheels/
45
- *.egg-info/
46
- .installed.cfg
47
- *.egg
48
- MANIFEST
49
-
50
- ## COMMON - PYTHON (from https://github.com/github/gitignore/blob/main/Python.gitignore)
51
- # PyInstaller
52
- # Usually these files are written by a python script from a template
53
- # before PyInstaller builds the exe, so as to inject date/other infos into it.
54
- *.manifest
55
- *.spec
56
-
57
- # Installer logs
58
- pip-log.txt
59
- pip-delete-this-directory.txt
60
-
61
- # Unit test / coverage reports
62
- htmlcov/
63
- .tox/
64
- .nox/
65
- .coverage
66
- .coverage.*
67
- .cache
68
- nosetests.xml
69
- coverage.xml
70
- coverage.json
71
- *.cover
72
- *.py,cover
73
- .hypothesis/
74
- .pytest_cache/
75
- cover/
76
-
77
- # Translations
78
- *.mo
79
- *.pot
80
-
81
- # Django stuff:
82
- local_settings.py
83
- db.sqlite3
84
- db.sqlite3-journal
85
-
86
- # Flask stuff:
87
- instance/
88
- .webassets-cache
89
-
90
- # Scrapy stuff:
91
- .scrapy
92
-
93
- # Sphinx documentation
94
- docs/_build/
95
-
96
- # PyBuilder
97
- .pybuilder/
98
- target/
99
-
100
- # Jupyter Notebook
101
- .ipynb_checkpoints
102
-
103
- # IPython
104
- profile_default/
105
- ipython_config.py
106
-
107
-
108
- # PEP 582; used by e.g. github.com/David-OConnor/pyflow
109
- __pypackages__/
110
-
111
- # Celery stuff
112
- celerybeat-schedule
113
- celerybeat.pid
114
-
115
- # SageMath parsed files
116
- *.sage.py
117
-
118
- # Environments
119
- .venv
120
- env/
121
- venv/
122
- ENV/
123
- env.bak/
124
- venv.bak/
125
-
126
- # Spyder project settings
127
- .spyderproject
128
- .spyproject
129
-
130
- # Rope project settings
131
- .ropeproject
132
-
133
- # mkdocs documentation
134
- /site
135
-
136
- # mypy
137
- .mypy_cache/
138
- .dmypy.json
139
- dmypy.json
140
-
141
- # Pyre type checker
142
- .pyre/
143
-
144
- # pytype static type analyzer
145
- .pytype/
146
-
147
- # Cython debug symbols
148
- cython_debug/
149
-
150
-
151
- ## COMMON - TERRAFORM (from https://github.com/github/gitignore/blob/main/Terraform.gitignore)
152
- # Local .terraform directories
153
- **/.terraform/*
154
-
155
- # .tfstate files
156
- *.tfstate
157
- *.tfstate.*
158
-
159
- # Crash log files
160
- crash.log
161
- crash.*.log
162
-
163
- # Exclude all .tfvars files, which are likely to contain sensitive data, such as
164
- # password, private keys, and other secrets. These should not be part of version
165
- # control as they are data points which are potentially sensitive and subject
166
- # to change depending on the environment.
167
- *.tfvars
168
- *.tfvars.json
169
-
170
- # Ignore override files as they are usually used to override resources locally and so
171
- # are not checked in
172
- override.tf
173
- override.tf.json
174
- *_override.tf
175
- *_override.tf.json
176
-
177
- # Include override files you do wish to add to version control using negated pattern
178
- # !example_override.tf
179
-
180
- # Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
181
- # example: *tfplan*
182
-
183
- # Ignore CLI configuration files
184
- .terraformrc
185
- terraform.rc
186
-
187
- # VSCode
188
- .vscode
189
-
190
- # generated during test run
191
- skip_first_scenario.txt
cucu-1.2.2/CHANGELOG.md DELETED
@@ -1,421 +0,0 @@
1
- # Changelog
2
-
3
- All notable changes to this project will be documented in this file.
4
-
5
- The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
- and this project closely adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
-
8
-
9
- ## 1.2.2
10
- - Chore - make lint also run ruff format --check
11
- - Add - tags command to list tags and affected scenario counts
12
- - Add - click parent label of an input element when the size of the input element is zero
13
-
14
- ## 1.2.1
15
- - Add - tab information to html report and cucu debug console log
16
-
17
- ## 1.2.0
18
- - Add - levels 2-4 to section step
19
- - Change - rename comment step to section step
20
- - Add - linting for section step
21
- - Change - min python to 3.10
22
-
23
- ## 1.1.2
24
- - Add - `cucu init` command to setup new projects
25
-
26
- ## 1.1.1
27
- - Chore - bump coverage lib from 7.6.12 to 7.8.0
28
- - Chore - change CI to not use experimental COVERAGE_CORE=sysmon
29
-
30
- ## 1.1.0
31
- - Add - now python 3.13 compatible
32
- - Change - use stdlib pdb instead of unsupported ipdb
33
- - Change - rename CUCU_IPDB_ON_FAILURE => to CUCU_DEBUG_ON_FAILURE
34
- - Chore - bump selenium lib to 4.31.0
35
-
36
- ## 1.0.13
37
- - Change - rename logger.warn to logger.warning
38
-
39
- ## 1.0.12
40
- - Chore - add coverage badge
41
- - Chore - add docs on dev automation
42
- - CI - fix renovate config
43
- - CI - change renovate to ignore python minor versions
44
- - CI - fix for bots
45
- - Chore - bump dep versions
46
-
47
- ## 1.0.11
48
- - Chore - bump psutil
49
-
50
- ## 1.0.10
51
- - Chore - change package homepage to wiki page
52
-
53
- ## 1.0.9
54
- - Chore - update for selenium 4.28
55
- - Chore - update CI with selenium docker images to 126
56
-
57
- ## 1.0.8
58
- - Chore - bump pypi publishing GH action version
59
-
60
- ## 1.0.7
61
- - Fix - stablize CI runs (increase workers, add envvar tweaks)
62
- - Fix - parse --workers correctly
63
- - Fix - Ctrl-C to terminate for multi-workers
64
- - Fix - ensure testing webserver is online
65
- - Change - use fork when not MacOS for multi-worker
66
- - Chore - bump jellyfish to 1.1.3
67
-
68
- ## 1.0.6
69
- - Chore - relax required versions for requests library
70
-
71
- ## 1.0.5
72
- - Fix - Resolved issues with the drag-and-drop feature to ensure compatibility with all input options.
73
-
74
- ## 1.0.4
75
- - Change - for retry steps, also log before and after call messages
76
-
77
- ## 1.0.3
78
- - Add - functional test for drag and drop file functionality
79
-
80
- ## 1.0.2
81
- - Chore - fix logo for pypi
82
-
83
- ## 1.0.1
84
- - Chore - fix pyproject.toml authors and urls
85
- - Change - add pre-commit to makefile
86
-
87
- ## 1.0.0
88
- - Change to 1.0.0!
89
- - Chore - fix GH workflow for test publish
90
-
91
- ## 0.207.0
92
- - Chore - prep for publish - p2
93
- - Replace poetry with uv
94
- - Set default local python to 3.12
95
- - Run pre-commit with uv
96
- - Fix isort with ruff
97
-
98
- ## 0.206.0
99
- - Chore - prep for publish
100
- - Replace black with ruff
101
- - Remove detect-secrets to be replaced by GH repo security
102
- - Remove bandit to be replaced by GH CodeQL
103
- - Cleanup makefile
104
-
105
- ## 0.205.0
106
- - Change - increase information logged for failing before_scenario_hooks
107
-
108
- ## 0.204.0
109
- - Chore - add gh workflows for publishing
110
- - Chore - fix project metadata
111
-
112
- ## 0.203.0
113
- - Chore - move repo GH org locations
114
- - Chore - remove sonarqube
115
-
116
- ## 0.202.0
117
- - Add - wait step to saving values from any table cells to a variable
118
-
119
- ## 0.201.0
120
- - Change - add report path to the JUnit files when available
121
-
122
- ## 0.200.0
123
- - Change - increase the log level of scheduling a feature file
124
-
125
- ## 0.199.0
126
- - Chore - remove deprecated CI
127
- - Chore - add PR template
128
-
129
- ## 0.198.0
130
- - Chore - add sonarqube
131
- - Chore - refactor circle config (config-drive executor, embed commands, move workflows up)
132
- - Chore - configure renovate
133
- - Chore - remove dependabot config (duplicates renovate)
134
- - Chore - remove safety (duplicates sonarqube)
135
- - Change - swap pebble for mpire, kill procs on run timeout
136
-
137
- ## 0.197.0
138
- - Fix - before all hooks are now executed
139
-
140
- ## 0.196.0
141
- - Fix - after scenario hook error message unintentionally replaces scenario error message
142
-
143
- ## 0.195.0
144
- - Fix - HTML report is generated into a wrong folder
145
- - Change - `&` is replaced in file name
146
- - Change - shortened feature name and scenario name are recorded in JUnit
147
-
148
- ## 0.194.0
149
- - Fix - Ignore exceptions while key in desired dynamic dropdown value
150
-
151
- ## 0.193.0
152
- - Change - Set default value of `CUCU_SKIP_HIGHLIGHT_BORDER` to `True`
153
-
154
- ## 0.192.0
155
- - Fix - test status should be independent of ‘mht data' and 'browser logs' download status.
156
-
157
- ## 0.191.0
158
- - Change - shorten fienames and paths, remove quotes, '{,},#' from file names.
159
-
160
- ## 0.190.0
161
- - Add - screenshot highlight on find functions
162
- - Change - highlight to be separate overlay element
163
- - Change - enable element border highlight be default
164
- - Change - enable CUCU_MONITOR_PNG by default
165
- - Chore - CI downgrade to python 3.11 for stability
166
- - Chore - CI unpin remote docker executor
167
- - Chore - bump packages
168
- | | Package | From | To |
169
- |--|--------------------------------------------------------------------|-----------|----------|
170
- | | [coverage](https://github.com/nedbat/coveragepy) | `7.4.2` | `7.4.3` |
171
- | | [importlib-metadata](https://github.com/python/importlib_metadata) | `6.11.0` | `7.0.1` |
172
- | | [black](https://github.com/psf/black) | `23.12.1` | `24.2.0` |
173
- | | [pytest](https://github.com/pytest-dev/pytest) | `7.4.4` | `8.0.2` |
174
- | | [ruff](https://github.com/astral-sh/ruff) | `0.1.15` | `0.2.2` |
175
- | | [safety](https://github.com/pyupio/safety) | `2.4.0b2` | `3.0.1` |
176
- | | bandit | `1.7.5` | `1.7.7` |
177
- | | jinja2 | `3.1.2` | `3.1.3` |
178
- - Chore - black format files
179
-
180
- ## 0.189.0
181
- - Change - after-hook failures will report as 'passed' instead of 'failed/errored' to testrail and html reports
182
-
183
- ## 0.188.0
184
- - Fix - how element size is gotten in fuzzy find
185
-
186
- ## 0.187.0
187
- - Fix - clearing input sometimes causes the input to be not interactable
188
-
189
- ## 0.186.0
190
- - Fix - handle mht data response that is not of type dictionary
191
-
192
- ## 0.185.0
193
- - Change - hook failures will report as 'errored' instead of 'failed' to testrail and html reports
194
-
195
- ## 0.184.0
196
- - Change - Added step duration to failure step
197
-
198
- ## 0.183.0
199
- - Change - Added ability to take multiple screenshots per step
200
-
201
- ## 0.182.0
202
- - Chore - Update docker README for ARM64 based CPU
203
- - Chore - Add seleniarm_hub bash file
204
-
205
- ## 0.181.0
206
- - Change - only obfuscate values in config yaml file
207
-
208
- ## 0.180.0
209
- - Change - only obfuscate certain parts in json output
210
-
211
- ## 0.179.0
212
- - Fix - step that expects to not see a table
213
-
214
- ## 0.178.0
215
- - Add - error message to json and junit
216
- - Change - print expected and found tables on fail
217
- - Chore - bump pebble
218
-
219
- ## 0.177.0
220
- - Fix - text regex steps mess up the fuzzy find js code
221
- - Chore - bump dependencies
222
- - Chore - update pip in CI pre-commit
223
- - Chore - group dependabot updates
224
-
225
- ## 0.176.0
226
- - Add - preliminary border injection behind feature flag
227
-
228
- ## 0.175.0
229
- - Change - left pad duration with zeroes for better alphabetical sorting in flat.html report
230
-
231
- ## 0.174.0
232
- - Chore - prevent secrets from being merged to main
233
- - Chore - stabilize CI by reducing workers
234
-
235
- ## 0.173.0
236
- - Add - functions and steps for dragging and dropping elements
237
- - Add - add helper function for two interacting elements
238
-
239
- ## 0.172.0
240
- - Add repository and homepage fields to solve an issue with pip/poetry failing to install this package.
241
-
242
- ## 0.171.0
243
- - Change - shorten image filenames for OS compatibiltiy
244
- - Add - enable install on python 3.12
245
- - Change - CI - use python 3.12
246
- - Change - CI - use selenium 117 images
247
- - Change - CI - chain jobs
248
- - Change - CI - pre-commit use smaller resource
249
- - Change - increase runtime-timeout values
250
-
251
- ## 0.170.0
252
- - Change - retry ElementNotInteractableException exception when clicking a dynamically generated dropdown option
253
-
254
- ## 0.169.0
255
- - Add - step and test for waiting until a table has a certain number of rows
256
-
257
- ## 0.168.0
258
- - Add - step and test for clicking a table column within a table row that has specified text
259
-
260
- ## 0.167.0
261
- - Fix - fuzzy JS code injection in web page redirection
262
-
263
- ## 0.166.0
264
- - Add - functions and steps for clicking a row in a table
265
-
266
- ## 0.165.0
267
- - Change - update dependencies
268
-
269
- ## 0.164.0
270
- - Change - improve colorized log html file
271
-
272
- ## 0.163.0
273
- - Change - enable color output in cucu logs when running in parallel
274
-
275
- ## 0.162.0
276
- - Fix - use absolute path when uploading files using drag and drop
277
-
278
- ## 0.161.0
279
- - Change - add .txt as browser console log file suffix
280
-
281
- ## 0.160.0
282
- - Add - drag and drop file upload step
283
-
284
- ## 0.159.0
285
- - Change - ignore exceptions from sub_headers hook
286
- - Security - update Certifi to remove e-Tugra root certificate
287
- - Change - use isinstance instead of direct type compare
288
-
289
- ## 0.158.0
290
- - Add - steps to handle dynamic dropdown
291
- - Change - improve the robustness of selecting options in a dropdown
292
- - Change - fuzzy find won't consider elements with either 0 width or 0 height
293
-
294
- ## 0.157.0
295
- - Add - differentiate between cucu built-in and custom steps
296
- ## 0.156.0
297
- - Add - option to only find web elements with the name inside in fuzzy find
298
- - Change - when finding dropdown options when the dropdown is not a select element, only considers name inside option
299
-
300
- ## 0.155.0
301
- - Add - timestamp tooltip to steps in html report
302
-
303
- ## 0.154.0
304
- - Add - steps to check if the nth button is disabled
305
-
306
- ## 0.153.0
307
- - Fix - js function fails because element text is undefined
308
-
309
- ## 0.152.0
310
- - Change - exact text match has higher priority in fuzzy find
311
- - Change - immediate sibling has higher priority in fuzzy find
312
-
313
- ## 0.151.0
314
- - Fix - standardize junit.xml names to match with feature names
315
-
316
- ## 0.150.0
317
- - Fix - standardize json and log file names to match with feature names
318
-
319
- ## 0.149.0
320
- - Fix - run_steps re-raise StopRetryException
321
-
322
- ## 0.148.0
323
- - Fix - step image filenames that have redacted secrets
324
-
325
- ## 0.147.0
326
- - Change - move config reload earlier
327
-
328
- ## 0.146.0
329
- - Add - reload saved scenario config in reporting
330
- - Change - report shows "flat.html" link in stdout
331
-
332
- ## 0.145.0
333
- - Fix - reporting when file names have secrets
334
-
335
- ## 0.144.0
336
- - Fix - preserve parent security CUCU_SECRETS setting
337
- - Change - ignore objects in hide_secrets
338
- - Change - skip secrets in config dump
339
-
340
- ## 0.143.0
341
- - Fix - fuzzy find detect text with padding for radio buttons
342
-
343
- ## 0.142.0
344
- - Change - hooks to LIFO order
345
-
346
- ## 0.141.0
347
- - Fix - runtime dependency
348
-
349
- ## 0.140.0
350
- - Add - favicon to HTML report
351
- - Add - save config per scenario
352
- - Change - enable MHT web page snapshot for all chrome scenarios
353
- - Dev - move hide_secrets into Config
354
- - Dev - update CI to use python 3.11
355
- - Dev - update CI to use selenium-standalone 114.0
356
-
357
- ## 0.139.0
358
- - Change - migrate to pygls 1.x
359
- - Change - move configs into pyproject.toml
360
- - Change - pyproject.toml author to ddl
361
- - Change - update packages
362
- - Dev - build remove unneeded upload artifacts
363
- - Dev - removed pyenv since using poetry
364
- - Fix - makefile test command
365
-
366
- ## 0.138.0
367
- - Change - cucu to load unique named jQuery
368
-
369
- ## 0.137.0
370
- - Add - MHT web page snapshot
371
- - Change - Output table indecies to stdout
372
-
373
- ## 0.136.0
374
- - Add - more debug logs in cucu steps
375
-
376
- ## 0.135.0
377
-
378
- Prep for packaging
379
-
380
- ### Add
381
- - add various project files
382
- - CHANGELOG.md
383
- - CODE_OF_CONDUCT.md
384
- - CONTRIBUTING.md - content moved from README.md
385
- - CONTRIBUTORS.md
386
- - LICENSE
387
- - logo.png
388
- - add dev tools
389
- - detect private keys in pre-commit
390
- - bandit secure patterns
391
- - isort linter
392
- - ruff linter
393
- - safety deps checker
394
-
395
- ### Change
396
- - change makefile
397
- - change tooling and pyproject.toml
398
- - add project classifiers
399
-
400
- ### Remove
401
- - remove unused libs (nox, retrying, strip-ansi, flake8)
402
- - remove noxfile.py
403
- - remove unused DESIGN.md
404
-
405
- ### Fix
406
- - fix many import sorts
407
-
408
- ### Secure
409
- - add bandit and safety
410
- - ignore with noseq for subprocess and html
411
-
412
- ----
413
- # Template
414
- ## [{version}]
415
-
416
- ### Add
417
- ### Change
418
- ### Deprecate
419
- ### Remove
420
- ### Fix
421
- ### Secure
cucu-1.2.2/LICENSE DELETED
@@ -1,32 +0,0 @@
1
- The Clear BSD License
2
-
3
- Copyright (c) 2023 "Domino Data Lab <open-source@dominodatalab.com>"
4
- All rights reserved.
5
-
6
- Redistribution and use in source and binary forms, with or without
7
- modification, are permitted (subject to the limitations in the disclaimer
8
- below) provided that the following conditions are met:
9
-
10
- * Redistributions of source code must retain the above copyright notice,
11
- this list of conditions and the following disclaimer.
12
-
13
- * Redistributions in binary form must reproduce the above copyright
14
- notice, this list of conditions and the following disclaimer in the
15
- documentation and/or other materials provided with the distribution.
16
-
17
- * Neither the name of the copyright holder nor the names of its
18
- contributors may be used to endorse or promote products derived from this
19
- software without specific prior written permission.
20
-
21
- NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY
22
- THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
23
- CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25
- PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
26
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
29
- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
30
- IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31
- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32
- POSSIBILITY OF SUCH DAMAGE.
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