Skip to content

Commit 3656fd6

Browse files
authored
Merge pull request #2770 from seleniumbase/update-options-and-uc-mode
Update options and UC Mode
2 parents e693775 + b095b36 commit 3656fd6

19 files changed

+191
-19
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,7 @@ pytest test_coffee_cart.py --trace
671671
--block-images # (Block images from loading during tests.)
672672
--do-not-track # (Indicate to websites that you don't want to be tracked.)
673673
--verify-delay=SECONDS # (The delay before MasterQA verification checks.)
674+
--ee | --esc-end # (Lets the user end the current test via the ESC key.)
674675
--recorder # (Enables the Recorder for turning browser actions into code.)
675676
--rec-behave # (Same as Recorder Mode, but also generates behave-gherkin.)
676677
--rec-sleep # (If the Recorder is enabled, also records self.sleep calls.)

examples/raw_parameter_script.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
sb._reuse_session = False
7777
sb._crumbs = False
7878
sb._final_debug = False
79+
sb.esc_end = False
7980
sb.use_wire = False
8081
sb.enable_3d_apis = False
8182
sb.window_size = None

help_docs/customizing_test_runs.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ pytest my_first_test.py --settings-file=custom_settings.py
164164
--block-images # (Block images from loading during tests.)
165165
--do-not-track # (Indicate to websites that you don't want to be tracked.)
166166
--verify-delay=SECONDS # (The delay before MasterQA verification checks.)
167+
--ee | --esc-end # (Lets the user end the current test via the ESC key.)
167168
--recorder # (Enables the Recorder for turning browser actions into code.)
168169
--rec-behave # (Same as Recorder Mode, but also generates behave-gherkin.)
169170
--rec-sleep # (If the Recorder is enabled, also records self.sleep calls.)

help_docs/method_summary.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,6 +1046,8 @@ driver.uc_open_with_tab(url) # (New tab with default reconnect_time)
10461046

10471047
driver.uc_open_with_reconnect(url, reconnect_time=None) # (New tab)
10481048

1049+
driver.uc_open_with_disconnect(url) # Open in new tab + disconnect()
1050+
10491051
driver.reconnect(timeout) # disconnect() + sleep(timeout) + connect()
10501052

10511053
driver.disconnect() # Stops the webdriver service to prevent detection

help_docs/recorder_mode.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,8 @@ pytest TEST_NAME.py --trace --rec -s
121121
122122
⏺️ Inside recorded tests, you might find the <code>self.open_if_not_url(URL)</code> method, which opens the URL given if the browser is not currently on that page. SeleniumBase uses this method in recorded scripts when the Recorder detects that a browser action changed the current URL. This method prevents an unnecessary page load and shows what page the test visited after a browser action.
123123
124+
⏺️ By launching the Recorder App with <code>sbase recorder --ee</code>, you can end the recording by pressing {<code>SHIFT</code>+<code>ESC</code>} instead of the usual way of ending the recording by typing <code>c</code> from a <code>breakpoint()</code> and pressing <code>Enter</code>. Those buttons don't need to be pressed at the same time, but <code>SHIFT</code> must be pressed directly before <code>ESC</code>.
125+
124126
--------
125127
126128
<div>To learn more about SeleniumBase, check out the Docs Site:</div>

help_docs/uc_mode.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,8 @@ driver.uc_open_with_tab(url)
159159

160160
driver.uc_open_with_reconnect(url, reconnect_time=None)
161161

162+
driver.uc_open_with_disconnect(url)
163+
162164
driver.reconnect(timeout)
163165

164166
driver.disconnect()

mkdocs_build/requirements.txt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,26 @@
11
# mkdocs dependencies for generating the seleniumbase.io website
22
# Minimum Python version: 3.8 (for generating docs only)
33

4-
regex>=2024.4.28
4+
regex>=2024.5.10
55
pymdown-extensions>=10.8.1
6-
pipdeptree>=2.19.1
6+
pipdeptree>=2.20.0
77
python-dateutil>=2.8.2
88
Markdown==3.6
99
markdown2==2.4.13
1010
MarkupSafe==2.1.5
11-
Jinja2==3.1.3
11+
Jinja2==3.1.4
1212
click==8.1.7
1313
ghp-import==2.1.0
1414
watchdog==4.0.0
1515
cairocffi==1.7.0
1616
pathspec==0.12.1
17-
Babel==2.14.0
17+
Babel==2.15.0
1818
paginate==0.5.6
1919
lxml==5.2.1
2020
pyquery==2.0.0
2121
readtime==3.0.0
2222
mkdocs==1.6.0
23-
mkdocs-material==9.5.21
23+
mkdocs-material==9.5.22
2424
mkdocs-exclude-search==0.6.6
2525
mkdocs-simple-hooks==0.1.5
2626
mkdocs-material-extensions==1.3.1

requirements.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ behave==1.2.6
5757
soupsieve==2.4.1;python_version<"3.8"
5858
soupsieve==2.5;python_version>="3.8"
5959
beautifulsoup4==4.12.3
60-
pygments==2.17.2
60+
pygments==2.17.2;python_version<"3.8"
61+
pygments==2.18.0;python_version>="3.8"
6162
pyreadline3==3.4.1;platform_system=="Windows"
6263
tabcompleter==1.3.0
6364
pdbp==1.5.0
@@ -72,7 +73,7 @@ rich==13.7.1
7273
# ("pip install -r requirements.txt" also installs this, but "pip install -e ." won't.)
7374

7475
coverage==7.2.7;python_version<"3.8"
75-
coverage>=7.5.0;python_version>="3.8"
76+
coverage>=7.5.1;python_version>="3.8"
7677
pytest-cov==4.1.0;python_version<"3.8"
7778
pytest-cov>=5.0.0;python_version>="3.8"
7879
flake8==5.0.4;python_version<"3.9"

seleniumbase/__version__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
# seleniumbase package
2-
__version__ = "4.26.3"
2+
__version__ = "4.26.4"

seleniumbase/console_scripts/ReadMe.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,7 @@ sbase codegen new_test.py --url=wikipedia.org
406406
``--edge`` (Use Edge browser instead of Chrome.)
407407
``--gui`` / ``--headed`` (Use headed mode on Linux.)
408408
``--uc`` / ``--undetected`` (Use undetectable mode.)
409+
``--ee`` (Use SHIFT + ESC to end the recording.)
409410
``--overwrite`` (Overwrite file when it exists.)
410411
``--behave`` (Also output Behave/Gherkin files.)
411412

seleniumbase/console_scripts/run.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,7 @@ def show_mkrec_usage():
310310
print(" --edge (Use Edge browser instead of Chrome.)")
311311
print(" --gui / --headed (Use headed mode on Linux.)")
312312
print(" --uc / --undetected (Use undetectable mode.)")
313+
print(" --ee (Use SHIFT + ESC to end the recording.)")
313314
print(" --overwrite (Overwrite file when it exists.)")
314315
print(" --behave (Also output Behave/Gherkin files.)")
315316
print(" Output:")
@@ -336,6 +337,7 @@ def show_codegen_usage():
336337
print(" --edge (Use Edge browser instead of Chrome.)")
337338
print(" --gui / --headed (Use headed mode on Linux.)")
338339
print(" --uc / --undetected (Use undetectable mode.)")
340+
print(" --ee (Use SHIFT + ESC to end the recording.)")
339341
print(" --overwrite (Overwrite file when it exists.)")
340342
print(" --behave (Also output Behave/Gherkin files.)")
341343
print(" Output:")

seleniumbase/console_scripts/sb_mkrec.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ def main():
9393
invalid_cmd = None
9494
use_edge = False
9595
use_uc = False
96+
esc_end = False
9697
start_page = None
9798
next_is_url = False
9899
use_colors = True
@@ -145,6 +146,8 @@ def main():
145146
help_me = True
146147
elif option.lower() == "--edge":
147148
use_edge = True
149+
elif option.lower() == "--ee":
150+
esc_end = True
148151
elif option.lower() in ("--gui", "--headed"):
149152
if "linux" in sys.platform:
150153
force_gui = True
@@ -183,6 +186,42 @@ def main():
183186
data.append(' # type "c", and press [Enter].')
184187
data.append(" import pdb; pdb.set_trace()")
185188
data.append("")
189+
190+
if esc_end:
191+
msg = ">>> Use [SHIFT + ESC] in the browser to end recording!"
192+
d2 = []
193+
d2.append("from seleniumbase import BaseCase")
194+
d2.append("")
195+
d2.append("")
196+
d2.append("class RecorderTest(BaseCase):")
197+
d2.append(" def test_recording(self):")
198+
d2.append(" if self.recorder_ext:")
199+
d2.append(" print(")
200+
d2.append(' "\\n\\n%s\\n"' % msg)
201+
d2.append(" )")
202+
d2.append(' script = self._get_rec_shift_esc_script()')
203+
d2.append(' esc = "return document.sb_esc_end;"')
204+
d2.append(" start_time = self.time()")
205+
d2.append(" last_handles_num = self._get_num_handles()")
206+
d2.append(" for i in range(1200):")
207+
d2.append(" try:")
208+
d2.append(" self.execute_script(script)")
209+
d2.append(" handles_num = self._get_num_handles()")
210+
d2.append(" if handles_num < 1:")
211+
d2.append(" return")
212+
d2.append(" elif handles_num != last_handles_num:")
213+
d2.append(" self.switch_to_window(-1)")
214+
d2.append(" last_handles_num = handles_num")
215+
d2.append(' if self.execute_script(esc) == "yes":')
216+
d2.append(" return")
217+
d2.append(" elif self.time() - start_time > 600:")
218+
d2.append(" return")
219+
d2.append(" self.sleep(0.5)")
220+
d2.append(" except Exception:")
221+
d2.append(" return")
222+
d2.append("")
223+
data = d2
224+
186225
file = codecs.open(file_path, "w+", "utf-8")
187226
file.writelines("\r\n".join(data))
188227
file.close()

seleniumbase/console_scripts/sb_recorder.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,8 @@ def do_recording(file_name, url, overwrite_enabled, use_chrome, window):
162162
or "--undetectable" in command_args
163163
):
164164
command += " --uc"
165+
if "--ee" in command_args:
166+
command += " --ee"
165167
command += add_on
166168
poll = None
167169
if sb_config.rec_subprocess_used:

seleniumbase/core/browser_launcher.py

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -443,8 +443,32 @@ def uc_open_with_reconnect(driver, url, reconnect_time=None):
443443
js_utils.call_me_later(driver, script, 3)
444444
time.sleep(0.007)
445445
driver.close()
446-
driver.reconnect(reconnect_time)
447-
driver.switch_to.window(driver.window_handles[-1])
446+
if reconnect_time == "disconnect":
447+
driver.disconnect()
448+
time.sleep(0.007)
449+
else:
450+
driver.reconnect(reconnect_time)
451+
driver.switch_to.window(driver.window_handles[-1])
452+
else:
453+
driver.default_get(url) # The original one
454+
return None
455+
456+
457+
def uc_open_with_disconnect(driver, url):
458+
"""Open a url and disconnect chromedriver.
459+
Note: You can't perform Selenium actions again
460+
until after you've called driver.connect()."""
461+
if url.startswith("//"):
462+
url = "https:" + url
463+
elif ":" not in url:
464+
url = "https://" + url
465+
if (url.startswith("http:") or url.startswith("https:")):
466+
script = 'window.open("%s","_blank");' % url
467+
js_utils.call_me_later(driver, script, 3)
468+
time.sleep(0.007)
469+
driver.close()
470+
driver.disconnect()
471+
time.sleep(0.007)
448472
else:
449473
driver.default_get(url) # The original one
450474
return None
@@ -3754,6 +3778,11 @@ def get_local_driver(
37543778
driver, *args, **kwargs
37553779
)
37563780
)
3781+
driver.uc_open_with_disconnect = (
3782+
lambda *args, **kwargs: uc_open_with_disconnect(
3783+
driver, *args, **kwargs
3784+
)
3785+
)
37573786
driver.uc_click = lambda *args, **kwargs: uc_click(
37583787
driver, *args, **kwargs
37593788
)

0 commit comments

Comments
 (0)