seleniumbase 4.37.2__py3-none-any.whl → 4.37.3__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.
@@ -1,2 +1,2 @@
1
1
  # seleniumbase package
2
- __version__ = "4.37.2"
2
+ __version__ = "4.37.3"
@@ -162,6 +162,7 @@ class BaseCase(unittest.TestCase):
162
162
  self.__jqc_default_theme = None
163
163
  self.__jqc_default_color = None
164
164
  self.__jqc_default_width = None
165
+ self.__saved_id = None
165
166
  # Requires self._* instead of self.__* for external class use
166
167
  self._language = "English"
167
168
  self._presentation_slides = {}
@@ -15676,19 +15677,24 @@ class BaseCase(unittest.TestCase):
15676
15677
  test_id = "%s.%s" % (file_name, scenario_name)
15677
15678
  return test_id
15678
15679
  elif hasattr(self, "is_context_manager") and self.is_context_manager:
15680
+ if hasattr(self, "_manager_saved_id"):
15681
+ self.__saved_id = self._manager_saved_id
15682
+ if self.__saved_id:
15683
+ return self.__saved_id
15679
15684
  filename = self.__class__.__module__.split(".")[-1] + ".py"
15680
15685
  methodname = self._testMethodName
15681
15686
  context_id = None
15682
15687
  if filename == "base_case.py" or methodname == "runTest":
15683
15688
  import traceback
15684
- stack_base = traceback.format_stack()[0].split(", in ")[0]
15685
- test_base = stack_base.split(", in ")[0].split(os.sep)[-1]
15689
+ stack_base = traceback.format_stack()[0].split(os.sep)[-1]
15690
+ test_base = stack_base.split(", in ")[0]
15686
15691
  if hasattr(self, "cm_filename") and self.cm_filename:
15687
15692
  filename = self.cm_filename
15688
15693
  else:
15689
15694
  filename = test_base.split('"')[0]
15690
15695
  methodname = ".line_" + test_base.split(", line ")[-1]
15691
15696
  context_id = filename.split(".")[0] + methodname
15697
+ self.__saved_id = context_id
15692
15698
  return context_id
15693
15699
  test_id = "%s.%s.%s" % (
15694
15700
  self.__class__.__module__,
@@ -23,7 +23,7 @@ with SB(uc=True) as sb: # Many args! Eg. SB(browser="edge")
23
23
 
24
24
  #########################################
25
25
  """
26
- from contextlib import contextmanager
26
+ from contextlib import contextmanager, suppress
27
27
 
28
28
 
29
29
  @contextmanager # Usage: -> ``with SB() as sb:``
@@ -258,6 +258,7 @@ def SB(
258
258
  time_limit (float): SECONDS (Safely fail tests that exceed the time limit)
259
259
  """
260
260
  import colorama
261
+ import gc
261
262
  import os
262
263
  import sys
263
264
  import time
@@ -1231,6 +1232,15 @@ def SB(
1231
1232
  sb.cap_file = sb_config.cap_file
1232
1233
  sb.cap_string = sb_config.cap_string
1233
1234
  sb._has_failure = False # This may change
1235
+
1236
+ with suppress(Exception):
1237
+ stack_base = traceback.format_stack()[0].split(os.sep)[-1]
1238
+ test_base = stack_base.split(", in ")[0]
1239
+ filename = test_base.split('"')[0]
1240
+ methodname = ".line_" + test_base.split(", line ")[-1]
1241
+ context_id = filename.split(".")[0] + methodname
1242
+ sb._manager_saved_id = context_id
1243
+
1234
1244
  if hasattr(sb_config, "headless_active"):
1235
1245
  sb.headless_active = sb_config.headless_active
1236
1246
  else:
@@ -1357,6 +1367,7 @@ def SB(
1357
1367
  "%s%s%s%s%s"
1358
1368
  % (c1, left_space, end_text, right_space, cr)
1359
1369
  )
1370
+ gc.collect()
1360
1371
  if test and test_name and not test_passed and raise_test_failure:
1361
1372
  raise exception
1362
1373
  elif (
@@ -145,9 +145,14 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
145
145
  debug_port = 9222
146
146
  special_port_free = False # If the port isn't free, don't use 9222
147
147
  try:
148
- res = requests.get("http://127.0.0.1:9222", timeout=1)
149
- if res.status_code != 200:
150
- raise Exception("The port is free! It will be used!")
148
+ with requests.Session() as session:
149
+ res = session.get(
150
+ "http://127.0.0.1:9222",
151
+ headers={"Connection": "close"},
152
+ timeout=2,
153
+ )
154
+ if res.status_code != 200:
155
+ raise Exception("The port is free! It will be used!")
151
156
  except Exception:
152
157
  # Use port 9222, which outputs to chrome://inspect/#devices
153
158
  special_port_free = True
@@ -462,9 +467,7 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
462
467
  with suppress(Exception):
463
468
  for window_handle in self.window_handles:
464
469
  self.switch_to.window(window_handle)
465
- if self.current_url.startswith(
466
- "chrome-extension://"
467
- ):
470
+ if self.current_url.startswith("chrome-extension://"):
468
471
  # https://issues.chromium.org/issues/396611138
469
472
  # (Remove the Linux conditional when resolved)
470
473
  # (So that close() is always called)
@@ -559,10 +562,18 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
559
562
  logger.debug(e, exc_info=True)
560
563
  except Exception:
561
564
  pass
565
+ with suppress(Exception):
566
+ self.stop_client()
567
+ with suppress(Exception):
568
+ if hasattr(self, "command_executor") and self.command_executor:
569
+ self.command_executor.close()
570
+
571
+ # Remove instance reference to allow garbage collection
572
+ Chrome._instances.discard(self)
573
+
562
574
  if hasattr(self, "service") and getattr(self.service, "process", None):
563
575
  logger.debug("Stopping webdriver service")
564
576
  with suppress(Exception):
565
- self.stop_client()
566
577
  try:
567
578
  self.service.send_remote_shutdown_command()
568
579
  except TypeError:
@@ -570,10 +581,12 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
570
581
  finally:
571
582
  with suppress(Exception):
572
583
  self.service._terminate_process()
573
- with suppress(Exception):
574
- if self.reactor and isinstance(self.reactor, Reactor):
575
- logger.debug("Shutting down Reactor")
584
+ if self.reactor and hasattr(self.reactor, "event"):
585
+ logger.debug("Shutting down Reactor")
586
+ with suppress(Exception):
576
587
  self.reactor.event.set()
588
+ self.reactor.join(timeout=2)
589
+ self.reactor = None
577
590
  if (
578
591
  hasattr(self, "keep_user_data_dir")
579
592
  and hasattr(self, "user_data_dir")
@@ -53,28 +53,58 @@ class CDP:
53
53
  self._session = requests.Session()
54
54
  self._last_resp = None
55
55
  self._last_json = None
56
- resp = self.get(self.endpoints.json)
57
- self.sessionId = resp[0]["id"]
58
- self.wsurl = resp[0]["webSocketDebuggerUrl"]
56
+ with requests.Session() as session:
57
+ resp = session.get(
58
+ self.server_addr + self.endpoints.json,
59
+ headers={"Connection": "close"},
60
+ timeout=2,
61
+ )
62
+ self.sessionId = resp.json()[0]["id"]
63
+ self.wsurl = resp.json()[0]["webSocketDebuggerUrl"]
59
64
 
60
65
  def tab_activate(self, id=None):
61
66
  if not id:
62
67
  active_tab = self.tab_list()[0]
63
68
  id = active_tab.id
64
69
  self.wsurl = active_tab.webSocketDebuggerUrl
65
- return self.post(self.endpoints["activate"].format(id=id))
70
+ with requests.Session() as session:
71
+ resp = session.post(
72
+ self.server_addr + self.endpoints["activate"].format(id=id),
73
+ headers={"Connection": "close"},
74
+ timeout=2,
75
+ )
76
+ return resp.json()
66
77
 
67
78
  def tab_list(self):
68
- retval = self.get(self.endpoints["list"])
69
- return [PageElement(o) for o in retval]
79
+ with requests.Session() as session:
80
+ resp = session.get(
81
+ self.server_addr + self.endpoints["list"],
82
+ headers={"Connection": "close"},
83
+ timeout=2,
84
+ )
85
+ retval = resp.json()
86
+ return [PageElement(o) for o in retval]
70
87
 
71
88
  def tab_new(self, url):
72
- return self.post(self.endpoints["new"].format(url=url))
89
+ with requests.Session() as session:
90
+ resp = session.post(
91
+ self.server_addr + self.endpoints["new"].format(url=url),
92
+ headers={"Connection": "close"},
93
+ timeout=2,
94
+ )
95
+ return resp.json()
73
96
 
74
97
  def tab_close_last_opened(self):
75
98
  sessions = self.tab_list()
76
99
  opentabs = [s for s in sessions if s["type"] == "page"]
77
- return self.post(self.endpoints["close"].format(id=opentabs[-1]["id"]))
100
+ with requests.Session() as session:
101
+ endp_close = self.endpoints["close"]
102
+ resp = session.post(
103
+ self.server_addr + endp_close.format(id=opentabs[-1]["id"]),
104
+ headers={"Connection": "close"},
105
+ timeout=2,
106
+ )
107
+ return resp.json()
78
108
 
79
109
  async def send(self, method, params):
80
110
  pip_find_lock = fasteners.InterProcessLock(
@@ -101,14 +131,19 @@ class CDP:
101
131
  from urllib.parse import unquote
102
132
 
103
133
  uri = unquote(uri, errors="strict")
104
- resp = self._session.get(self.server_addr + uri)
105
- try:
106
- self._last_resp = resp
107
- self._last_json = resp.json()
108
- except Exception:
109
- return
110
- else:
111
- return self._last_json
134
+ with requests.Session() as session:
135
+ resp = session.get(
136
+ self.server_addr + uri,
137
+ headers={"Connection": "close"},
138
+ timeout=2,
139
+ )
140
+ try:
141
+ self._last_resp = resp
142
+ self._last_json = resp.json()
143
+ except Exception:
144
+ return
145
+ else:
146
+ return self._last_json
112
147
 
113
148
  def post(self, uri, data=None):
114
149
  from urllib.parse import unquote
@@ -116,12 +151,18 @@ class CDP:
116
151
  uri = unquote(uri, errors="strict")
117
152
  if not data:
118
153
  data = {}
119
- resp = self._session.post(self.server_addr + uri, json=data)
120
- try:
121
- self._last_resp = resp
122
- self._last_json = resp.json()
123
- except Exception:
124
- return self._last_resp
154
+ with requests.Session() as session:
155
+ resp = session.post(
156
+ self.server_addr + uri,
157
+ json=data,
158
+ headers={"Connection": "close"},
159
+ timeout=2,
160
+ )
161
+ try:
162
+ self._last_resp = resp
163
+ self._last_json = resp.json()
164
+ except Exception:
165
+ return self._last_resp
125
166
 
126
167
  @property
127
168
  def last_json(self):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: seleniumbase
3
- Version: 4.37.2
3
+ Version: 4.37.3
4
4
  Summary: A complete web automation framework for end-to-end testing.
5
5
  Home-page: https://github.com/seleniumbase/SeleniumBase
6
6
  Author: Michael Mintz
@@ -60,7 +60,7 @@ Requires-Python: >=3.8
60
60
  Description-Content-Type: text/markdown
61
61
  License-File: LICENSE
62
62
  Requires-Dist: pip>=25.0.1
63
- Requires-Dist: packaging>=24.2
63
+ Requires-Dist: packaging>=25.0
64
64
  Requires-Dist: setuptools~=70.2; python_version < "3.10"
65
65
  Requires-Dist: setuptools>=78.1.0; python_version >= "3.10"
66
66
  Requires-Dist: wheel>=0.45.1
@@ -122,7 +122,7 @@ Requires-Dist: pytest-xdist==3.6.1
122
122
  Requires-Dist: parameterized==0.9.0
123
123
  Requires-Dist: behave==1.2.6
124
124
  Requires-Dist: soupsieve==2.6
125
- Requires-Dist: beautifulsoup4==4.13.3
125
+ Requires-Dist: beautifulsoup4==4.13.4
126
126
  Requires-Dist: pyotp==2.9.0
127
127
  Requires-Dist: python-xlib==0.33; platform_system == "Linux"
128
128
  Requires-Dist: markdown-it-py==3.0.0
@@ -153,14 +153,14 @@ Requires-Dist: mss==9.0.2; python_version < "3.9" and extra == "mss"
153
153
  Requires-Dist: mss==10.0.0; python_version >= "3.9" and extra == "mss"
154
154
  Provides-Extra: pdfminer
155
155
  Requires-Dist: pdfminer.six==20250324; python_version < "3.9" and extra == "pdfminer"
156
- Requires-Dist: pdfminer.six==20250327; python_version >= "3.9" and extra == "pdfminer"
156
+ Requires-Dist: pdfminer.six==20250416; python_version >= "3.9" and extra == "pdfminer"
157
157
  Requires-Dist: cryptography==39.0.2; python_version < "3.9" and extra == "pdfminer"
158
158
  Requires-Dist: cryptography==44.0.2; python_version >= "3.9" and extra == "pdfminer"
159
159
  Requires-Dist: cffi==1.17.1; extra == "pdfminer"
160
160
  Requires-Dist: pycparser==2.22; extra == "pdfminer"
161
161
  Provides-Extra: pillow
162
162
  Requires-Dist: Pillow>=10.4.0; python_version < "3.9" and extra == "pillow"
163
- Requires-Dist: Pillow>=11.2.0; python_version >= "3.9" and extra == "pillow"
163
+ Requires-Dist: Pillow>=11.2.1; python_version >= "3.9" and extra == "pillow"
164
164
  Provides-Extra: pip-system-certs
165
165
  Requires-Dist: pip-system-certs==4.0; platform_system == "Windows" and extra == "pip-system-certs"
166
166
  Provides-Extra: proxy
@@ -3,7 +3,7 @@ sbase/__main__.py,sha256=G0bVB1-DM4PGwQ1KyOupaWCs4ePbChZNNWuX2htim5U,647
3
3
  sbase/steps.py,sha256=_WvAjydKqZfTdnZW9LPKkRty-g-lfdUPmLqnZj6ulcs,43013
4
4
  seleniumbase/__init__.py,sha256=JFEY9P5QJqsa1M6ghzLMH2eIPQyh85iglCaQwg8Y8z4,2498
5
5
  seleniumbase/__main__.py,sha256=dn1p6dgCchmcH1zzTzzQvFwwdQQqnTGH6ULV9m4hv24,654
6
- seleniumbase/__version__.py,sha256=Vmyu1nrXKb5h1xNjtD4ZvuGS53Y5AVtMxP5LqAt56mM,46
6
+ seleniumbase/__version__.py,sha256=uQkPKpOd701lSNAcmP0xwf5XtKD8my3v_4H69aSGYOs,46
7
7
  seleniumbase/behave/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
8
  seleniumbase/behave/behave_helper.py,sha256=elkl8P9eLulRAioLstE9baYNM9N_PHBmAOcajX-pH_Y,24198
9
9
  seleniumbase/behave/behave_sb.py,sha256=qQF85LoohJBfrPK5ZcPi50v-pWtOrC9qcN1B3Ki_3tY,59401
@@ -65,7 +65,7 @@ seleniumbase/extensions/disable_csp.zip,sha256=5RvomXnm2PdivUVcxTV6jfvD8WhTEsQYH
65
65
  seleniumbase/extensions/recorder.zip,sha256=OOyzF-Ize2cSRu1CqhzSAq5vusI9hqLLd2OIApUHesI,11918
66
66
  seleniumbase/extensions/sbase_ext.zip,sha256=3s1N8zrVaMz8RQEOIoBzC3KDjtmHwVZRvVsX25Odr_s,8175
67
67
  seleniumbase/fixtures/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
68
- seleniumbase/fixtures/base_case.py,sha256=tv65GtPheFm9T2B2VtGP8ooDRejOtyAizcICYw7I_GY,725685
68
+ seleniumbase/fixtures/base_case.py,sha256=Bo1kcrg9hCk5COTdTp52znlgq6797CmpSuOeyn98I_s,725922
69
69
  seleniumbase/fixtures/constants.py,sha256=WMrItuNyKq3XVJ64NluLIRc4gJCxDw8K8qXED0b9S2w,13752
70
70
  seleniumbase/fixtures/css_to_xpath.py,sha256=9ouDB1xl4MJ2os6JOgTIAyHKOQfuxtxvXC3O5hSnEKA,1954
71
71
  seleniumbase/fixtures/errors.py,sha256=KyxuEVx_e3MPhVrJfNIa_3ltMpbCFxfy_jxK8RFNTns,555
@@ -90,7 +90,7 @@ seleniumbase/plugins/driver_manager.py,sha256=1l4fxISvGV62gfDxp3yfYE2zz4WKJFLE0t
90
90
  seleniumbase/plugins/page_source.py,sha256=loTnXxOj4kxEukuTZEiGyvKBhY3KDVDMnNlHHheTBDE,1889
91
91
  seleniumbase/plugins/pytest_plugin.py,sha256=952AIyaH-PdmNksoeXjzhXxoc8Z53yV-WPjlrHhp2OM,108382
92
92
  seleniumbase/plugins/s3_logging_plugin.py,sha256=WDfertQgGOW_SRJpFMaekYD6vBVW9VO62POtXXy2HCM,2319
93
- seleniumbase/plugins/sb_manager.py,sha256=D-Aes1I7cA59XrHBZhLTLimNTtSU_3bVjhwobx8wjDU,56863
93
+ seleniumbase/plugins/sb_manager.py,sha256=0pO-gmcVi1FWssV1Yue1F5J3uSzQYdYiOt2-u5MEWGQ,57261
94
94
  seleniumbase/plugins/screen_shots.py,sha256=1hrXw-hzuZ1BR6Yh7AyWX2ABnvnP73-RCbwdz958gj4,1127
95
95
  seleniumbase/plugins/selenium_plugin.py,sha256=y0eNco8T4KgGLProLPHPLw479QH5lRms4wqwOnTgkSc,60081
96
96
  seleniumbase/resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -106,8 +106,8 @@ seleniumbase/translate/portuguese.py,sha256=x3P4qxp56UiI41GoaL7JbUvFRYsgXU1EKjTg
106
106
  seleniumbase/translate/russian.py,sha256=TyN9n0b4GRWDEYnHRGw1rfNAscdDmP3F3Y3aySM3C7s,27978
107
107
  seleniumbase/translate/spanish.py,sha256=hh3xgW1Pq122SHYVvJAxFaXhFrjniOVncVbJbfWqOUM,25528
108
108
  seleniumbase/translate/translator.py,sha256=wPhZH6e5NhmebYL1kP2eGxUcVy1gfTb6XCH8ATEPpxE,49238
109
- seleniumbase/undetected/__init__.py,sha256=xvbUlPJEF7nAkdy9bxca5W-ltX6cI38lMyJGwVetPPM,26230
110
- seleniumbase/undetected/cdp.py,sha256=RLpwZnhUvmK9tgXcZIBBQedwk2q7Jj_EXZkmzI8WUqk,4023
109
+ seleniumbase/undetected/__init__.py,sha256=5TPgl94SdYCLMRqINx0P4BSfRuJZdCh6hGDl54EOZ9g,26738
110
+ seleniumbase/undetected/cdp.py,sha256=G6nLStm1l8PmZlKIyMnFcYMV7HD5kiGb-9BaqPjVP3I,5497
111
111
  seleniumbase/undetected/dprocess.py,sha256=83EV8ZHJWHG1TSUv9JNClBhdgiBXlkCc6mJ--HsoP3k,1681
112
112
  seleniumbase/undetected/options.py,sha256=BoNuwhrG7oOvuLvTwkvsWCF36pMkS1tHCG-XpP4_EkI,3001
113
113
  seleniumbase/undetected/patcher.py,sha256=fXh99P2D9XPdYTFtsDYXk1ZUSh8Elkg-dGeMhUihmu4,11445
@@ -135,9 +135,9 @@ seleniumbase/utilities/selenium_grid/start-grid-hub.bat,sha256=Ftq-GrAKRYH2ssDPr
135
135
  seleniumbase/utilities/selenium_grid/start-grid-hub.sh,sha256=KADv0RUHONLL2_I443QFK8PryBpDmKn5Gy0s4o0vDSM,106
136
136
  seleniumbase/utilities/selenium_ide/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
137
137
  seleniumbase/utilities/selenium_ide/convert_ide.py,sha256=pZFnqEJQEKZPyNFjkLD29s2HPQgCrWW9XJWpCPhWOoM,31691
138
- seleniumbase-4.37.2.dist-info/licenses/LICENSE,sha256=BRblZsX7HyPUjQmYTiyWr_e9tzWvmR3R4SFclM2R3W0,1085
139
- seleniumbase-4.37.2.dist-info/METADATA,sha256=EccEGDheFz8nOIVDlmy7PSFeMeU6F6Uk6L-PJksB9dE,86879
140
- seleniumbase-4.37.2.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
141
- seleniumbase-4.37.2.dist-info/entry_points.txt,sha256=CNrh2EKNaHYEhO6pP1RJyVLB99LkDDYX7TnUK8xfjqk,623
142
- seleniumbase-4.37.2.dist-info/top_level.txt,sha256=4N97aBOQ8ETCnDnokBsWb07lJfTaq3C1ZzYRxvLMxqU,19
143
- seleniumbase-4.37.2.dist-info/RECORD,,
138
+ seleniumbase-4.37.3.dist-info/licenses/LICENSE,sha256=BRblZsX7HyPUjQmYTiyWr_e9tzWvmR3R4SFclM2R3W0,1085
139
+ seleniumbase-4.37.3.dist-info/METADATA,sha256=ptbx4ZZxtJy4wvgjdvL2NuNOK08yEyqZf9_7dALaFRs,86879
140
+ seleniumbase-4.37.3.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
141
+ seleniumbase-4.37.3.dist-info/entry_points.txt,sha256=CNrh2EKNaHYEhO6pP1RJyVLB99LkDDYX7TnUK8xfjqk,623
142
+ seleniumbase-4.37.3.dist-info/top_level.txt,sha256=4N97aBOQ8ETCnDnokBsWb07lJfTaq3C1ZzYRxvLMxqU,19
143
+ seleniumbase-4.37.3.dist-info/RECORD,,