seleniumbase 4.41.3__py3-none-any.whl → 4.45.10__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.
Files changed (64) hide show
  1. sbase/steps.py +9 -0
  2. seleniumbase/__version__.py +1 -1
  3. seleniumbase/behave/behave_helper.py +2 -0
  4. seleniumbase/behave/behave_sb.py +21 -8
  5. seleniumbase/common/decorators.py +3 -1
  6. seleniumbase/console_scripts/run.py +1 -0
  7. seleniumbase/console_scripts/sb_caseplans.py +3 -4
  8. seleniumbase/console_scripts/sb_install.py +142 -11
  9. seleniumbase/console_scripts/sb_mkchart.py +1 -2
  10. seleniumbase/console_scripts/sb_mkdir.py +99 -29
  11. seleniumbase/console_scripts/sb_mkfile.py +1 -2
  12. seleniumbase/console_scripts/sb_mkpres.py +1 -2
  13. seleniumbase/console_scripts/sb_mkrec.py +26 -2
  14. seleniumbase/console_scripts/sb_objectify.py +4 -5
  15. seleniumbase/console_scripts/sb_print.py +1 -1
  16. seleniumbase/console_scripts/sb_recorder.py +40 -3
  17. seleniumbase/core/browser_launcher.py +474 -151
  18. seleniumbase/core/detect_b_ver.py +258 -16
  19. seleniumbase/core/log_helper.py +15 -21
  20. seleniumbase/core/mysql.py +1 -1
  21. seleniumbase/core/recorder_helper.py +3 -0
  22. seleniumbase/core/report_helper.py +9 -12
  23. seleniumbase/core/sb_cdp.py +734 -215
  24. seleniumbase/core/sb_driver.py +46 -5
  25. seleniumbase/core/session_helper.py +2 -4
  26. seleniumbase/core/tour_helper.py +1 -2
  27. seleniumbase/drivers/atlas_drivers/__init__.py +0 -0
  28. seleniumbase/drivers/brave_drivers/__init__.py +0 -0
  29. seleniumbase/drivers/chromium_drivers/__init__.py +0 -0
  30. seleniumbase/drivers/comet_drivers/__init__.py +0 -0
  31. seleniumbase/drivers/opera_drivers/__init__.py +0 -0
  32. seleniumbase/fixtures/base_case.py +448 -251
  33. seleniumbase/fixtures/constants.py +36 -9
  34. seleniumbase/fixtures/js_utils.py +77 -18
  35. seleniumbase/fixtures/page_actions.py +41 -13
  36. seleniumbase/fixtures/page_utils.py +19 -12
  37. seleniumbase/fixtures/shared_utils.py +64 -6
  38. seleniumbase/masterqa/master_qa.py +16 -2
  39. seleniumbase/plugins/base_plugin.py +8 -0
  40. seleniumbase/plugins/basic_test_info.py +2 -3
  41. seleniumbase/plugins/driver_manager.py +131 -5
  42. seleniumbase/plugins/page_source.py +2 -3
  43. seleniumbase/plugins/pytest_plugin.py +244 -79
  44. seleniumbase/plugins/sb_manager.py +143 -20
  45. seleniumbase/plugins/selenium_plugin.py +144 -12
  46. seleniumbase/translate/translator.py +2 -3
  47. seleniumbase/undetected/__init__.py +17 -13
  48. seleniumbase/undetected/cdp.py +1 -12
  49. seleniumbase/undetected/cdp_driver/browser.py +330 -129
  50. seleniumbase/undetected/cdp_driver/cdp_util.py +328 -61
  51. seleniumbase/undetected/cdp_driver/config.py +110 -14
  52. seleniumbase/undetected/cdp_driver/connection.py +18 -48
  53. seleniumbase/undetected/cdp_driver/element.py +105 -33
  54. seleniumbase/undetected/cdp_driver/tab.py +414 -39
  55. seleniumbase/utilities/selenium_grid/download_selenium_server.py +1 -1
  56. seleniumbase/utilities/selenium_grid/grid_hub.py +1 -2
  57. seleniumbase/utilities/selenium_grid/grid_node.py +2 -3
  58. seleniumbase/utilities/selenium_ide/convert_ide.py +2 -3
  59. {seleniumbase-4.41.3.dist-info → seleniumbase-4.45.10.dist-info}/METADATA +193 -166
  60. {seleniumbase-4.41.3.dist-info → seleniumbase-4.45.10.dist-info}/RECORD +64 -59
  61. {seleniumbase-4.41.3.dist-info → seleniumbase-4.45.10.dist-info}/licenses/LICENSE +1 -1
  62. {seleniumbase-4.41.3.dist-info → seleniumbase-4.45.10.dist-info}/WHEEL +0 -0
  63. {seleniumbase-4.41.3.dist-info → seleniumbase-4.45.10.dist-info}/entry_points.txt +0 -0
  64. {seleniumbase-4.41.3.dist-info → seleniumbase-4.45.10.dist-info}/top_level.txt +0 -0
@@ -40,6 +40,10 @@ class OSType(object):
40
40
  class ChromeType(object):
41
41
  GOOGLE = "google-chrome"
42
42
  MSEDGE = "edge"
43
+ OPERA = "opera"
44
+ BRAVE = "brave"
45
+ COMET = "comet"
46
+ ATLAS = "atlas"
43
47
 
44
48
 
45
49
  PATTERN = {
@@ -96,13 +100,27 @@ def linux_browser_apps_to_cmd(*apps):
96
100
  )
97
101
 
98
102
 
99
- def chrome_on_linux_path(chromium_ok=False):
103
+ def chrome_on_linux_path(chromium_ok=False, browser_type=None):
104
+ if browser_type and browser_type != ChromeType.GOOGLE:
105
+ return ""
100
106
  if os_name() != OSType.LINUX:
101
107
  return ""
102
- paths = ["/bin/google-chrome", "/bin/google-chrome-stable"]
108
+ paths = [
109
+ "/bin/google-chrome",
110
+ "/bin/google-chrome-stable",
111
+ "/usr/bin/google-chrome",
112
+ "/usr/bin/google-chrome-stable"
113
+ ]
103
114
  for path in paths:
104
- if os.path.exists(path) and os.access(path, os.X_OK):
105
- return path
115
+ try:
116
+ if (
117
+ os.path.exists(path)
118
+ and os.access(path, os.R_OK)
119
+ and os.access(path, os.X_OK)
120
+ ):
121
+ return path
122
+ except Exception:
123
+ pass
106
124
  paths = os.environ["PATH"].split(os.pathsep)
107
125
  binaries = []
108
126
  binaries.append("google-chrome")
@@ -116,17 +134,38 @@ def chrome_on_linux_path(chromium_ok=False):
116
134
  for binary in binaries:
117
135
  for path in paths:
118
136
  full_path = os.path.join(path, binary)
119
- if os.path.exists(full_path) and os.access(full_path, os.X_OK):
120
- return full_path
137
+ try:
138
+ if (
139
+ os.path.exists(full_path)
140
+ and os.access(full_path, os.R_OK)
141
+ and os.access(full_path, os.X_OK)
142
+ ):
143
+ return full_path
144
+ except Exception:
145
+ pass
121
146
  if chromium_ok:
122
- paths = ["/bin/chromium", "/bin/chromium-browser"]
147
+ paths = [
148
+ "/bin/chromium",
149
+ "/bin/chromium-browser",
150
+ "/usr/bin/chromium",
151
+ "/usr/bin/chromium-browser"
152
+ ]
123
153
  for path in paths:
124
- if os.path.exists(path) and os.access(path, os.X_OK):
125
- return path
154
+ try:
155
+ if (
156
+ os.path.exists(path)
157
+ and os.access(path, os.R_OK)
158
+ and os.access(path, os.X_OK)
159
+ ):
160
+ return path
161
+ except Exception:
162
+ pass
126
163
  return "/usr/bin/google-chrome"
127
164
 
128
165
 
129
- def edge_on_linux_path():
166
+ def edge_on_linux_path(browser_type=None):
167
+ if browser_type and browser_type != ChromeType.MSEDGE:
168
+ return ""
130
169
  if os_name() != OSType.LINUX:
131
170
  return ""
132
171
  paths = os.environ["PATH"].split(os.pathsep)
@@ -143,7 +182,60 @@ def edge_on_linux_path():
143
182
  return "/usr/bin/microsoft-edge"
144
183
 
145
184
 
146
- def chrome_on_windows_path():
185
+ def opera_on_linux_path(browser_type=None):
186
+ if browser_type and browser_type != ChromeType.OPERA:
187
+ return ""
188
+ if os_name() != OSType.LINUX:
189
+ return ""
190
+ paths = os.environ["PATH"].split(os.pathsep)
191
+ binaries = []
192
+ binaries.append("opera")
193
+ binaries.append("opera-stable")
194
+ for binary in binaries:
195
+ for path in paths:
196
+ full_path = os.path.join(path, binary)
197
+ if os.path.exists(full_path) and os.access(full_path, os.X_OK):
198
+ return full_path
199
+ return "/usr/bin/opera-stable"
200
+
201
+
202
+ def brave_on_linux_path(browser_type=None):
203
+ if browser_type and browser_type != ChromeType.BRAVE:
204
+ return ""
205
+ if os_name() != OSType.LINUX:
206
+ return ""
207
+ paths = os.environ["PATH"].split(os.pathsep)
208
+ binaries = []
209
+ binaries.append("brave-browser")
210
+ binaries.append("brave")
211
+ binaries.append("brave-browser-stable")
212
+ for binary in binaries:
213
+ for path in paths:
214
+ full_path = os.path.join(path, binary)
215
+ if os.path.exists(full_path) and os.access(full_path, os.X_OK):
216
+ return full_path
217
+ return "/usr/bin/brave-browser"
218
+
219
+
220
+ def comet_on_linux_path(browser_type=None):
221
+ if browser_type and browser_type != ChromeType.COMET:
222
+ return ""
223
+ if os_name() != OSType.LINUX:
224
+ return ""
225
+ return "" # Comet Browser isn't supported on Linux yet
226
+
227
+
228
+ def atlas_on_linux_path(browser_type=None):
229
+ if browser_type and browser_type != ChromeType.ATLAS:
230
+ return ""
231
+ if os_name() != OSType.LINUX:
232
+ return ""
233
+ return "" # Atlas Browser isn't supported on Linux yet
234
+
235
+
236
+ def chrome_on_windows_path(browser_type=None):
237
+ if browser_type and browser_type != ChromeType.GOOGLE:
238
+ return ""
147
239
  if os_name() != OSType.WIN:
148
240
  return ""
149
241
  candidates = []
@@ -171,7 +263,9 @@ def chrome_on_windows_path():
171
263
  return ""
172
264
 
173
265
 
174
- def edge_on_windows_path():
266
+ def edge_on_windows_path(browser_type=None):
267
+ if browser_type and browser_type != ChromeType.MSEDGE:
268
+ return ""
175
269
  if os_name() != OSType.WIN:
176
270
  return ""
177
271
  candidates = []
@@ -199,6 +293,124 @@ def edge_on_windows_path():
199
293
  return ""
200
294
 
201
295
 
296
+ def opera_on_windows_path(browser_type=None):
297
+ if browser_type and browser_type != ChromeType.OPERA:
298
+ return ""
299
+ if os_name() != OSType.WIN:
300
+ return ""
301
+ candidates = []
302
+ for item in map(
303
+ os.environ.get,
304
+ (
305
+ "PROGRAMFILES",
306
+ "PROGRAMFILES(X86)",
307
+ "LOCALAPPDATA",
308
+ "PROGRAMW6432",
309
+ ),
310
+ ):
311
+ for subitem in (
312
+ "Programs/Opera",
313
+ "Opera",
314
+ "Opera/Application",
315
+ ):
316
+ try:
317
+ candidates.append(os.sep.join((item, subitem, "opera.exe")))
318
+ except TypeError:
319
+ pass
320
+ for candidate in candidates:
321
+ if os.path.exists(candidate) and os.access(candidate, os.X_OK):
322
+ return os.path.normpath(candidate)
323
+ return ""
324
+
325
+
326
+ def brave_on_windows_path(browser_type=None):
327
+ if browser_type and browser_type != ChromeType.BRAVE:
328
+ return ""
329
+ if os_name() != OSType.WIN:
330
+ return ""
331
+ candidates = []
332
+ for item in map(
333
+ os.environ.get,
334
+ (
335
+ "PROGRAMFILES",
336
+ "PROGRAMFILES(X86)",
337
+ "LOCALAPPDATA",
338
+ "PROGRAMW6432",
339
+ ),
340
+ ):
341
+ for subitem in (
342
+ "BraveSoftware/Brave-Browser/Application",
343
+ ):
344
+ try:
345
+ candidates.append(os.sep.join((item, subitem, "brave.exe")))
346
+ except TypeError:
347
+ pass
348
+ for candidate in candidates:
349
+ if os.path.exists(candidate) and os.access(candidate, os.X_OK):
350
+ return os.path.normpath(candidate)
351
+ return ""
352
+
353
+
354
+ def comet_on_windows_path(browser_type=None):
355
+ if browser_type and browser_type != ChromeType.COMET:
356
+ return ""
357
+ if os_name() != OSType.WIN:
358
+ return ""
359
+ candidates = []
360
+ for item in map(
361
+ os.environ.get,
362
+ (
363
+ "LOCALAPPDATA",
364
+ "PROGRAMFILES",
365
+ "PROGRAMFILES(X86)",
366
+ "PROGRAMW6432",
367
+ ),
368
+ ):
369
+ for subitem in (
370
+ "Perplexity/Comet/Application",
371
+ "Comet/Application",
372
+ "Programs/Comet",
373
+ ):
374
+ try:
375
+ candidates.append(os.sep.join((item, subitem, "comet.exe")))
376
+ except TypeError:
377
+ pass
378
+ for candidate in candidates:
379
+ if os.path.exists(candidate) and os.access(candidate, os.X_OK):
380
+ return os.path.normpath(candidate)
381
+ return ""
382
+
383
+
384
+ def atlas_on_windows_path(browser_type=None):
385
+ if browser_type and browser_type != ChromeType.ATLAS:
386
+ return ""
387
+ if os_name() != OSType.WIN:
388
+ return ""
389
+ candidates = []
390
+ for item in map(
391
+ os.environ.get,
392
+ (
393
+ "LOCALAPPDATA",
394
+ "PROGRAMFILES",
395
+ "PROGRAMFILES(X86)",
396
+ "PROGRAMW6432",
397
+ ),
398
+ ):
399
+ for subitem in (
400
+ "OpenAI/Atlas/Application",
401
+ "Atlas/Application",
402
+ "Programs/Atlas",
403
+ ):
404
+ try:
405
+ candidates.append(os.sep.join((item, subitem, "atlas.exe")))
406
+ except TypeError:
407
+ pass
408
+ for candidate in candidates:
409
+ if os.path.exists(candidate) and os.access(candidate, os.X_OK):
410
+ return os.path.normpath(candidate)
411
+ return ""
412
+
413
+
202
414
  def windows_browser_apps_to_cmd(*apps):
203
415
  """Create analogue of browser --version command for windows."""
204
416
  powershell = determine_powershell()
@@ -211,18 +423,48 @@ def windows_browser_apps_to_cmd(*apps):
211
423
 
212
424
  def get_binary_location(browser_type, chromium_ok=False):
213
425
  """Return the full path of the browser binary."""
426
+ if browser_type.lower() == "chrome":
427
+ browser_type = "google-chrome"
428
+ elif browser_type.lower() == "msedge":
429
+ browser_type = "edge"
430
+ else:
431
+ browser_type = browser_type.lower()
214
432
  cmd_mapping = {
215
433
  ChromeType.GOOGLE: {
216
- OSType.LINUX: chrome_on_linux_path(chromium_ok),
434
+ OSType.LINUX: chrome_on_linux_path(chromium_ok, browser_type),
217
435
  OSType.MAC: r"/Applications/Google Chrome.app"
218
436
  r"/Contents/MacOS/Google Chrome",
219
- OSType.WIN: chrome_on_windows_path(),
437
+ OSType.WIN: chrome_on_windows_path(browser_type),
220
438
  },
221
439
  ChromeType.MSEDGE: {
222
- OSType.LINUX: edge_on_linux_path(),
440
+ OSType.LINUX: edge_on_linux_path(browser_type),
223
441
  OSType.MAC: r"/Applications/Microsoft Edge.app"
224
442
  r"/Contents/MacOS/Microsoft Edge",
225
- OSType.WIN: edge_on_windows_path(),
443
+ OSType.WIN: edge_on_windows_path(browser_type),
444
+ },
445
+ ChromeType.OPERA: {
446
+ OSType.LINUX: opera_on_linux_path(browser_type),
447
+ OSType.MAC: r"/Applications/Opera.app"
448
+ r"/Contents/MacOS/Opera",
449
+ OSType.WIN: opera_on_windows_path(browser_type),
450
+ },
451
+ ChromeType.BRAVE: {
452
+ OSType.LINUX: brave_on_linux_path(browser_type),
453
+ OSType.MAC: r"/Applications/Brave Browser.app"
454
+ r"/Contents/MacOS/Brave Browser",
455
+ OSType.WIN: brave_on_windows_path(browser_type),
456
+ },
457
+ ChromeType.COMET: {
458
+ OSType.LINUX: comet_on_linux_path(browser_type),
459
+ OSType.MAC: r"/Applications/Comet.app"
460
+ r"/Contents/MacOS/Comet",
461
+ OSType.WIN: comet_on_windows_path(browser_type),
462
+ },
463
+ ChromeType.ATLAS: {
464
+ OSType.LINUX: atlas_on_linux_path(browser_type),
465
+ OSType.MAC: r"/Applications/ChatGPT Atlas.app"
466
+ r"/Contents/MacOS/ChatGPT Atlas",
467
+ OSType.WIN: atlas_on_windows_path(browser_type),
226
468
  },
227
469
  }
228
470
  return cmd_mapping[browser_type][os_name()]
@@ -1,4 +1,3 @@
1
- import codecs
2
1
  import os
3
2
  import shutil
4
3
  import sys
@@ -26,7 +25,7 @@ def log_screenshot(test_logpath, driver, screenshot=None, get=False):
26
25
  screenshot_skipped = constants.Warnings.SCREENSHOT_SKIPPED
27
26
  screenshot_warning = constants.Warnings.SCREENSHOT_UNDEFINED
28
27
  if (
29
- (hasattr(sb_config, "no_screenshot") and sb_config.no_screenshot)
28
+ getattr(sb_config, "no_screenshot", None)
30
29
  or screenshot == screenshot_skipped
31
30
  ):
32
31
  if get:
@@ -37,7 +36,7 @@ def log_screenshot(test_logpath, driver, screenshot=None, get=False):
37
36
  element = driver.find_element("tag name", "body")
38
37
  screenshot = element.screenshot_as_base64
39
38
  if screenshot != screenshot_warning:
40
- with open(screenshot_path, "wb") as file:
39
+ with open(screenshot_path, mode="wb") as file:
41
40
  file.write(screenshot)
42
41
  with suppress(Exception):
43
42
  shared_utils.make_writable(screenshot_path)
@@ -187,14 +186,10 @@ def log_test_failure_data(test, test_logpath, driver, browser, url=None):
187
186
  data_to_save.append(
188
187
  "--------------------------------------------------------------------"
189
188
  )
190
- if (
191
- hasattr(test, "_outcome")
192
- and hasattr(test._outcome, "errors")
193
- and test._outcome.errors
194
- ):
189
+ if hasattr(test, "_outcome") and getattr(test._outcome, "errors", None):
195
190
  try:
196
- exc_message = test._outcome.errors[0][1][1]
197
- traceback_address = test._outcome.errors[0][1][2]
191
+ exc_message = test._outcome.errors[-1][1][1]
192
+ traceback_address = test._outcome.errors[-1][1][2]
198
193
  traceback_list = traceback.format_list(
199
194
  traceback.extract_tb(traceback_address)[1:]
200
195
  )
@@ -226,12 +221,11 @@ def log_test_failure_data(test, test_logpath, driver, browser, url=None):
226
221
  data_to_save.append("Exception: %s" % exc_message)
227
222
  else:
228
223
  traceback_message = None
229
- if hasattr(test, "is_behave") and test.is_behave:
224
+ if getattr(test, "is_behave", None):
230
225
  if sb_config.behave_scenario.status.name == "failed":
231
226
  if (
232
227
  hasattr(sb_config, "behave_step")
233
- and hasattr(sb_config.behave_step, "error_message")
234
- and sb_config.behave_step.error_message
228
+ and getattr(sb_config.behave_step, "error_message", None)
235
229
  ):
236
230
  traceback_message = sb_config.behave_step.error_message
237
231
  else:
@@ -263,7 +257,7 @@ def log_test_failure_data(test, test_logpath, driver, browser, url=None):
263
257
  )
264
258
  else:
265
259
  message = None
266
- if hasattr(test, "is_behave") and test.is_behave:
260
+ if getattr(test, "is_behave", None):
267
261
  message = "Behave step was not implemented or skipped!"
268
262
  else:
269
263
  message = "Traceback not found!"
@@ -282,7 +276,7 @@ def log_test_failure_data(test, test_logpath, driver, browser, url=None):
282
276
  data_to_save.append("Exception: %s" % sb_config._excinfo_value)
283
277
  else:
284
278
  data_to_save.append("Traceback:\n %s" % traceback_message)
285
- if hasattr(test, "is_nosetest") and test.is_nosetest:
279
+ if getattr(test, "is_nosetest", None):
286
280
  # Also save the data for the report
287
281
  sb_config._report_test_id = test_id
288
282
  sb_config._report_fail_page = last_page
@@ -298,7 +292,7 @@ def log_test_failure_data(test, test_logpath, driver, browser, url=None):
298
292
  with suppress(Exception):
299
293
  os.makedirs(test_logpath)
300
294
  with suppress(Exception):
301
- log_file = codecs.open(basic_file_path, "w+", encoding="utf-8")
295
+ log_file = open(basic_file_path, mode="w+", encoding="utf-8")
302
296
  log_file.writelines("\r\n".join(data_to_save))
303
297
  log_file.close()
304
298
  shared_utils.make_writable(basic_file_path)
@@ -353,7 +347,7 @@ def log_skipped_test_data(test, test_logpath, driver, browser, reason):
353
347
  data_to_save.append("")
354
348
  file_path = os.path.join(test_logpath, "skip_reason.txt")
355
349
  with suppress(Exception):
356
- log_file = codecs.open(file_path, "w+", encoding="utf-8")
350
+ log_file = open(file_path, mode="w+", encoding="utf-8")
357
351
  log_file.writelines("\r\n".join(data_to_save))
358
352
  log_file.close()
359
353
  shared_utils.make_writable(file_path)
@@ -388,14 +382,14 @@ def log_page_source(test_logpath, driver, source=None):
388
382
  os.makedirs(test_logpath)
389
383
  html_file_path = os.path.join(test_logpath, html_file_name)
390
384
  with suppress(Exception):
391
- html_file = codecs.open(html_file_path, "w+", encoding="utf-8")
385
+ html_file = open(html_file_path, mode="w+", encoding="utf-8")
392
386
  html_file.write(page_source)
393
387
  html_file.close()
394
388
  shared_utils.make_writable(html_file_path)
395
389
 
396
390
 
397
391
  def get_test_id(test):
398
- if hasattr(test, "is_behave") and test.is_behave:
392
+ if getattr(test, "is_behave", None):
399
393
  file_name = sb_config.behave_scenario.filename
400
394
  line_num = sb_config.behave_line_num
401
395
  scenario_name = sb_config.behave_scenario.name
@@ -403,7 +397,7 @@ def get_test_id(test):
403
397
  scenario_name = scenario_name.split(" -- @")[0]
404
398
  test_id = "%s:%s => %s" % (file_name, line_num, scenario_name)
405
399
  return test_id
406
- elif hasattr(test, "is_context_manager") and test.is_context_manager:
400
+ elif getattr(test, "is_context_manager", None):
407
401
  filename = test.__class__.__module__.split(".")[-1] + ".py"
408
402
  classname = test.__class__.__name__
409
403
  methodname = test._testMethodName
@@ -413,7 +407,7 @@ def get_test_id(test):
413
407
 
414
408
  stack_base = traceback.format_stack()[0].split(", in ")[0]
415
409
  test_base = stack_base.split(", in ")[0].split(os.sep)[-1]
416
- if hasattr(test, "cm_filename") and test.cm_filename:
410
+ if getattr(test, "cm_filename", None):
417
411
  filename = test.cm_filename
418
412
  else:
419
413
  filename = test_base.split('"')[0]
@@ -42,7 +42,7 @@ class DatabaseManager:
42
42
  db_user = settings.DB_USERNAME
43
43
  db_pass = settings.DB_PASSWORD
44
44
  db_schema = settings.DB_SCHEMA
45
- if hasattr(sb_config, "settings_file") and sb_config.settings_file:
45
+ if getattr(sb_config, "settings_file", None):
46
46
  override = settings_parser.set_settings(sb_config.settings_file)
47
47
  if "DB_HOST" in override.keys():
48
48
  db_server = override["DB_HOST"]
@@ -556,6 +556,9 @@ def generate_sbase_code(srt_actions):
556
556
  elif action[0] == "ss_tl":
557
557
  method = "save_screenshot_to_logs"
558
558
  sb_actions.append("self.%s()" % method)
559
+ elif action[0] == "pdftl":
560
+ method = "save_as_pdf_to_logs"
561
+ sb_actions.append("self.%s()" % method)
559
562
  elif action[0] == "spstl":
560
563
  method = "save_page_source_to_logs"
561
564
  sb_actions.append("self.%s()" % method)
@@ -1,4 +1,3 @@
1
- import codecs
2
1
  import os
3
2
  import shutil
4
3
  import sys
@@ -48,7 +47,9 @@ def save_test_failure_data(test, name, folder=None):
48
47
  failure_data_file_path = os.path.join(file_path, name)
49
48
  else:
50
49
  failure_data_file_path = name
51
- failure_data_file = codecs.open(failure_data_file_path, "w+", "utf-8")
50
+ failure_data_file = open(
51
+ failure_data_file_path, mode="w+", encoding="utf-8"
52
+ )
52
53
  data_to_save = []
53
54
  if not hasattr(sb_config, "_report_test_id"):
54
55
  exc_message = "(Unknown Exception)"
@@ -99,18 +100,14 @@ def process_failures(test, test_count, duration):
99
100
  bad_page_image = "failure_%s.png" % test_count
100
101
  bad_page_data = "failure_%s.txt" % test_count
101
102
  screenshot_path = os.path.join(LATEST_REPORT_DIR, bad_page_image)
102
- if hasattr(test, "_last_page_screenshot") and test._last_page_screenshot:
103
- with open(screenshot_path, "wb") as file:
103
+ if getattr(test, "_last_page_screenshot", None):
104
+ with open(screenshot_path, mode="wb") as file:
104
105
  file.write(test._last_page_screenshot)
105
106
  save_test_failure_data(test, bad_page_data, folder=LATEST_REPORT_DIR)
106
107
  exc_message = None
107
- if (
108
- hasattr(test, "_outcome")
109
- and hasattr(test._outcome, "errors")
110
- and test._outcome.errors
111
- ):
108
+ if hasattr(test, "_outcome") and getattr(test._outcome, "errors", None):
112
109
  try:
113
- exc_message = test._outcome.errors[0][1][1]
110
+ exc_message = test._outcome.errors[-1][1][1]
114
111
  except Exception:
115
112
  exc_message = "(Unknown Exception)"
116
113
  else:
@@ -173,7 +170,7 @@ def add_bad_page_log_file(page_results_list):
173
170
  abs_path = os.path.abspath(".")
174
171
  file_path = os.path.join(abs_path, LATEST_REPORT_DIR)
175
172
  log_file = os.path.join(file_path, RESULTS_TABLE)
176
- f = open(log_file, "w")
173
+ f = open(log_file, mode="w")
177
174
  h_p1 = '"Num","Result","Stacktrace","Screenshot",'
178
175
  h_p2 = '"URL","Browser","Epoch Time","Duration",'
179
176
  h_p3 = '"Test Case Address","Additional Info"\n'
@@ -198,7 +195,7 @@ def add_results_page(html):
198
195
  file_path = os.path.join(abs_path, LATEST_REPORT_DIR)
199
196
  results_file_name = HTML_REPORT
200
197
  results_file = os.path.join(file_path, results_file_name)
201
- f = open(results_file, "w")
198
+ f = open(results_file, mode="w")
202
199
  f.write(html)
203
200
  f.close()
204
201
  return results_file