From c3ce0b0e8278c1d2a59dce64a0a02d5063b7349b Mon Sep 17 00:00:00 2001
From: Michael Mintz
Date: Wed, 11 Sep 2024 01:14:57 -0400
Subject: [PATCH 1/5] Make the Recorder stealthier
---
seleniumbase/console_scripts/sb_mkrec.py | 35 ++++++++++++++++++++-
seleniumbase/console_scripts/sb_recorder.py | 7 +++++
seleniumbase/fixtures/base_case.py | 5 +++
3 files changed, 46 insertions(+), 1 deletion(-)
diff --git a/seleniumbase/console_scripts/sb_mkrec.py b/seleniumbase/console_scripts/sb_mkrec.py
index 6becb6c48da..65933894b74 100644
--- a/seleniumbase/console_scripts/sb_mkrec.py
+++ b/seleniumbase/console_scripts/sb_mkrec.py
@@ -181,6 +181,28 @@ def main():
data.append("")
data.append("class RecorderTest(BaseCase):")
data.append(" def test_recording(self):")
+ if use_uc:
+ data.append(" if self.undetectable:")
+ if (
+ start_page
+ and (
+ start_page.startswith("http:")
+ or start_page.startswith("https:")
+ or start_page.startswith("file:")
+ )
+ ):
+ used_sp = start_page
+ if '"' not in start_page:
+ used_sp = '"%s"' % start_page
+ elif "'" not in start_page:
+ used_sp = "'%s'" % start_page
+ data.append(
+ " self.uc_open_with_disconnect(\n"
+ " %s\n"
+ " )" % used_sp
+ )
+ else:
+ data.append(" self.disconnect()")
data.append(" if self.recorder_ext:")
data.append(" # When done recording actions,")
data.append(' # type "c", and press [Enter].')
@@ -231,7 +253,18 @@ def main():
)
print(success)
run_cmd = None
- if not start_page:
+ if (
+ not start_page
+ or (
+ use_uc
+ and (
+ start_page.startswith("http:")
+ or start_page.startswith("https:")
+ or start_page.startswith("file:")
+ )
+ and not esc_end
+ )
+ ):
run_cmd = "%s -m pytest %s --rec -q -s" % (sys_executable, file_name)
else:
run_cmd = "%s -m pytest %s --rec -q -s --url=%s" % (
diff --git a/seleniumbase/console_scripts/sb_recorder.py b/seleniumbase/console_scripts/sb_recorder.py
index 056cb2b61f1..0e9e3365f67 100644
--- a/seleniumbase/console_scripts/sb_recorder.py
+++ b/seleniumbase/console_scripts/sb_recorder.py
@@ -197,6 +197,13 @@ def do_playback(file_name, use_chrome, window, demo_mode=False):
command += " --edge"
if demo_mode:
command += " --demo"
+ command_args = sys.argv[2:]
+ if (
+ "--uc" in command_args
+ or "--undetected" in command_args
+ or "--undetectable" in command_args
+ ):
+ command += " --uc"
poll = None
if sb_config.rec_subprocess_used:
poll = sb_config.rec_subprocess_p.poll()
diff --git a/seleniumbase/fixtures/base_case.py b/seleniumbase/fixtures/base_case.py
index 851514a10ee..0d02e781585 100644
--- a/seleniumbase/fixtures/base_case.py
+++ b/seleniumbase/fixtures/base_case.py
@@ -16029,6 +16029,11 @@ def tearDown(self):
# This test already called tearDown()
return
if hasattr(self, "recorder_mode") and self.recorder_mode:
+ if self.undetectable:
+ try:
+ self.driver.window_handles
+ except Exception:
+ self.driver.connect()
self.__process_recorded_actions()
self.__called_teardown = True
self.__called_setup = False
From f745eee9efee6514969b663e9aaea95db98da05d Mon Sep 17 00:00:00 2001
From: Michael Mintz
Date: Wed, 11 Sep 2024 01:16:30 -0400
Subject: [PATCH 2/5] Improve UC Mode
---
seleniumbase/core/browser_launcher.py | 45 +++++++++++++++++++++------
1 file changed, 35 insertions(+), 10 deletions(-)
diff --git a/seleniumbase/core/browser_launcher.py b/seleniumbase/core/browser_launcher.py
index 413aec8d36c..6559cbc186e 100644
--- a/seleniumbase/core/browser_launcher.py
+++ b/seleniumbase/core/browser_launcher.py
@@ -728,8 +728,23 @@ def uc_gui_click_x_y(driver, x, y, timeframe=0.25):
install_pyautogui_if_missing(driver)
import pyautogui
pyautogui = get_configured_pyautogui(pyautogui)
+ connected = True
+ width_ratio = 1.0
if IS_WINDOWS:
- width_ratio = 1.0
+ try:
+ driver.window_handles
+ except Exception:
+ connected = False
+ if (
+ not connected
+ and (
+ not hasattr(sb_config, "_saved_width_ratio")
+ or not sb_config._saved_width_ratio
+ )
+ ):
+ driver.reconnect(0.1)
+ connected = True
+ if IS_WINDOWS and connected:
window_rect = driver.get_window_rect()
width = window_rect["width"]
height = window_rect["height"]
@@ -751,13 +766,24 @@ def uc_gui_click_x_y(driver, x, y, timeframe=0.25):
sb_config._saved_width_ratio = width_ratio
driver.minimize_window()
driver.set_window_rect(win_x, win_y, width, height)
+ elif (
+ IS_WINDOWS
+ and not connected
+ and hasattr(sb_config, "_saved_width_ratio")
+ and sb_config._saved_width_ratio
+ ):
+ width_ratio = sb_config._saved_width_ratio
+ if IS_WINDOWS:
x = x * width_ratio
y = y * width_ratio
_uc_gui_click_x_y(driver, x, y, timeframe=timeframe, uc_lock=False)
return
- page_actions.switch_to_window(
- driver, driver.current_window_handle, 2, uc_lock=False
- )
+ try:
+ page_actions.switch_to_window(
+ driver, driver.current_window_handle, 2, uc_lock=False
+ )
+ except Exception:
+ pass
_uc_gui_click_x_y(driver, x, y, timeframe=timeframe, uc_lock=False)
@@ -958,21 +984,20 @@ def _uc_gui_click_captcha(
pass
reconnect_time = (float(constants.UC.RECONNECT_TIME) / 2.0) + 0.5
if IS_LINUX:
- reconnect_time = constants.UC.RECONNECT_TIME + 0.15
+ reconnect_time = constants.UC.RECONNECT_TIME + 0.2
if not x or not y:
reconnect_time = 1 # Make it quick (it already failed)
driver.reconnect(reconnect_time)
- if blind:
+ if blind or (IS_LINUX and "Just a moment" in driver.title):
retry = True
+ blind = True
if retry and x and y and _on_a_captcha_page(driver):
with gui_lock: # Prevent issues with multiple processes
# Make sure the window is on top
page_actions.switch_to_window(
driver, driver.current_window_handle, 2, uc_lock=False
)
- if not driver.is_element_present("iframe"):
- return
- else:
+ if driver.is_element_present("iframe"):
try:
driver.switch_to_frame(frame)
except Exception:
@@ -1179,7 +1204,7 @@ def _uc_gui_handle_captcha(
pass
reconnect_time = (float(constants.UC.RECONNECT_TIME) / 2.0) + 0.5
if IS_LINUX:
- reconnect_time = constants.UC.RECONNECT_TIME + 0.15
+ reconnect_time = constants.UC.RECONNECT_TIME + 0.2
driver.reconnect(reconnect_time)
From aaa68a6d8470979852ed534427de503dea576e20 Mon Sep 17 00:00:00 2001
From: Michael Mintz
Date: Wed, 11 Sep 2024 01:17:41 -0400
Subject: [PATCH 3/5] Refresh Python dependencies
---
mkdocs_build/requirements.txt | 2 +-
requirements.txt | 8 ++++----
setup.py | 10 +++++-----
3 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/mkdocs_build/requirements.txt b/mkdocs_build/requirements.txt
index 22c596a7931..a9d21ae460e 100644
--- a/mkdocs_build/requirements.txt
+++ b/mkdocs_build/requirements.txt
@@ -3,7 +3,7 @@
regex>=2024.7.24
pymdown-extensions>=10.9
-pipdeptree>=2.23.1
+pipdeptree>=2.23.3
python-dateutil>=2.8.2
Markdown==3.7
markdown2==2.5.0
diff --git a/requirements.txt b/requirements.txt
index a83a65fa9ab..510ce34b74d 100755
--- a/requirements.txt
+++ b/requirements.txt
@@ -11,9 +11,9 @@ attrs>=24.2.0
certifi>=2024.8.30
exceptiongroup>=1.2.2
filelock>=3.12.2;python_version<"3.8"
-filelock>=3.15.4;python_version>="3.8"
+filelock>=3.16.0;python_version>="3.8"
platformdirs>=4.0.0;python_version<"3.8"
-platformdirs>=4.2.2;python_version>="3.8"
+platformdirs>=4.3.2;python_version>="3.8"
typing-extensions>=4.12.2;python_version>="3.8"
parse>=1.20.2
parse-type>=0.6.3
@@ -47,7 +47,7 @@ pluggy==1.2.0;python_version<"3.8"
pluggy==1.5.0;python_version>="3.8"
py==1.11.0
pytest==7.4.4;python_version<"3.8"
-pytest==8.3.2;python_version>="3.8"
+pytest==8.3.3;python_version>="3.8"
pytest-html==2.0.1
pytest-metadata==3.0.0;python_version<"3.8"
pytest-metadata==3.1.1;python_version>="3.8"
@@ -73,7 +73,7 @@ python-xlib==0.33;platform_system=="Linux"
markdown-it-py==2.2.0;python_version<"3.8"
markdown-it-py==3.0.0;python_version>="3.8"
mdurl==0.1.2
-rich==13.8.0
+rich==13.8.1
# --- Testing Requirements --- #
# ("pip install -r requirements.txt" also installs this, but "pip install -e ." won't.)
diff --git a/setup.py b/setup.py
index 968f434b044..c84e5295244 100755
--- a/setup.py
+++ b/setup.py
@@ -159,9 +159,9 @@
"certifi>=2024.8.30",
"exceptiongroup>=1.2.2",
'filelock>=3.12.2;python_version<"3.8"',
- 'filelock>=3.15.4;python_version>="3.8"',
+ 'filelock>=3.16.0;python_version>="3.8"',
'platformdirs>=4.0.0;python_version<"3.8"',
- 'platformdirs>=4.2.2;python_version>="3.8"',
+ 'platformdirs>=4.3.2;python_version>="3.8"',
'typing-extensions>=4.12.2;python_version>="3.8"',
'parse>=1.20.2',
'parse-type>=0.6.3',
@@ -195,7 +195,7 @@
'pluggy==1.5.0;python_version>="3.8"',
"py==1.11.0", # Needed by pytest-html
'pytest==7.4.4;python_version<"3.8"',
- 'pytest==8.3.2;python_version>="3.8"',
+ 'pytest==8.3.3;python_version>="3.8"',
"pytest-html==2.0.1", # Newer ones had issues
'pytest-metadata==3.0.0;python_version<"3.8"',
'pytest-metadata==3.1.1;python_version>="3.8"',
@@ -221,7 +221,7 @@
'markdown-it-py==2.2.0;python_version<"3.8"',
'markdown-it-py==3.0.0;python_version>="3.8"',
'mdurl==0.1.2',
- 'rich==13.8.0',
+ 'rich==13.8.1',
],
extras_require={
# pip install -e .[allure]
@@ -310,7 +310,7 @@
'hyperframe==6.0.1',
'kaitaistruct==0.10',
'pyasn1==0.5.1;python_version<"3.8"',
- 'pyasn1==0.6.0;python_version>="3.8"',
+ 'pyasn1==0.6.1;python_version>="3.8"',
'zstandard==0.23.0',
],
},
From 268e9929d95ff9da2a6bc40422f6df85dab14150 Mon Sep 17 00:00:00 2001
From: Michael Mintz
Date: Wed, 11 Sep 2024 01:18:19 -0400
Subject: [PATCH 4/5] Update the docs
---
README.md | 25 +++++++++++++------------
examples/ReadMe.md | 6 ++++++
integrations/github/workflows/extras.md | 8 ++++----
mkdocs.yml | 1 +
seleniumbase/common/ReadMe.md | 2 +-
5 files changed, 25 insertions(+), 17 deletions(-)
diff --git a/README.md b/README.md
index 241e0190770..0895fe5eb34 100755
--- a/README.md
+++ b/README.md
@@ -14,7 +14,7 @@
All-in-one Browser Automation Framework:
Web Crawling / Testing / Scraping / Stealth
-
+
🚀 Start |
@@ -1361,22 +1361,23 @@ pytest --reruns=1 --reruns-delay=1
-
+
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/examples/ReadMe.md b/examples/ReadMe.md
index 840b616b1bc..0f3102fc0c2 100644
--- a/examples/ReadMe.md
+++ b/examples/ReadMe.md
@@ -251,6 +251,12 @@ python gui_test_runner.py
--------
+
+
+Ask questions. Find answers. Learn how to automate!
+
+--------
+
diff --git a/integrations/github/workflows/extras.md b/integrations/github/workflows/extras.md
index 5d72984e721..a5d67509d15 100644
--- a/integrations/github/workflows/extras.md
+++ b/integrations/github/workflows/extras.md
@@ -1,10 +1,10 @@
Integrations for GitHub Actions:
### Uploading Artifacts:
-* Here's an example using [upload-artifact@v2](https://github.com/actions/upload-artifact) to push up a SeleniumBase-generated artifact.
+* Here's an example using [upload-artifact@v4](https://github.com/actions/upload-artifact) to push up a SeleniumBase-generated artifact.
-```
- - uses: actions/upload-artifact@v2
+```yml
+ - uses: actions/upload-artifact@v4
with:
name: Click to download the presentation
path: saved_presentations/my_presentation.html
@@ -18,7 +18,7 @@
* For this particular action, ``SLACK_CHANNEL`` is an optional environment variable that defaults to the webhook token channel if not specified.
* The following example shows how to put a link to your workflow as the ``SLACK_MESSAGE`` (Lets you see artifacts pushed up, such as from the SeleniumBase Presenter feature!):
-```
+```yml
- name: Slack notification
uses: rtCamp/action-slack-notify@master
env:
diff --git a/mkdocs.yml b/mkdocs.yml
index 6a87aaefed4..ea530a02353 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -75,6 +75,7 @@ plugins:
- examples/case_summary.md
- help_docs/chinese.md
- integrations/katalon/ReadMe.md
+ - help_docs/ReadMe.md
- help_docs/verify_webdriver.md
- help_docs/webdriver_installation.md
- seleniumbase/masterqa/ReadMe.md
diff --git a/seleniumbase/common/ReadMe.md b/seleniumbase/common/ReadMe.md
index f8193129368..6927fa3ca9a 100644
--- a/seleniumbase/common/ReadMe.md
+++ b/seleniumbase/common/ReadMe.md
@@ -1,6 +1,6 @@
-## Using [seleniumbase/common](https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/common) methods.
+## [seleniumbase/common](https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/common) decorators and security.
### Part 1: Decorators - (from [decorators.py](https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/common/decorators.py))
From b1698a166cefb916e50a8d8744798007ad598852 Mon Sep 17 00:00:00 2001
From: Michael Mintz
Date: Wed, 11 Sep 2024 01:18:45 -0400
Subject: [PATCH 5/5] Version 4.30.4
---
seleniumbase/__version__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/seleniumbase/__version__.py b/seleniumbase/__version__.py
index 0305db40ed2..a408493f059 100755
--- a/seleniumbase/__version__.py
+++ b/seleniumbase/__version__.py
@@ -1,2 +1,2 @@
# seleniumbase package
-__version__ = "4.30.3"
+__version__ = "4.30.4"