Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions examples/cdp_mode/raw_cdp_clearcote.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,17 @@
sb.click('button[aria-label="Marker 2"]')
sb.click('button[aria-label="Marker 3"]')
sb.press_keys("input", "audit")
sb.set_value('input[type="range"]', "100")
sb.select_option_by_text("select", "Mouse")
sb.click('button:contains("Run the audit")')
sb.sleep(6)
sb.assert_element("div.text-emerald-700", timeout=8)
sb.assert_element("div.text-successText", timeout=8)
try:
sb.assert_text("100", "div.text-emerald-700", timeout=5)
sb.highlight('div.text-emerald-700:contains("100")')
sb.assert_text("100", "div.text-successText", timeout=5)
sb.highlight('div.text-successText:contains("100")')
print(" ✅ The browser fingerprint is clean! Score: 100")
except Exception:
score = sb.get_text("div.text-emerald-700")
score = sb.get_text("div.text-successText")
print(f" ❌ Fingerprint tampering detected! Score: {score}")
sb.sleep(1)
folder = "downloaded_files"
Expand Down
2 changes: 1 addition & 1 deletion examples/cdp_mode/raw_cdp_immoscout.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
(PyAutoGUI is installed at runtime if not yet installed.)"""
from seleniumbase import sb_cdp

sb = sb_cdp.Chrome(use_chromium=True, locale="en")
sb = sb_cdp.Chrome(locale="en")
sb.goto("https://www.immoscout24.ch/en/real-estate/rent")
sb.sleep(1.6)
sb.solve_captcha()
Expand Down
6 changes: 4 additions & 2 deletions examples/cdp_mode/raw_easyjet.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
sb.sleep(1.8)
sb.click_if_visible("button#ensRejectAds", timeout=2)
sb.sleep(1)
sb.click('input[name="from"]')
input_from = 'input[name="from"]'
sb.click(input_from)
sb.sleep(1)
sb.press_keys('input[name="from"]', "London Gatwick")
sb.clear(input_from)
sb.press_keys(input_from, "London Gatwick")
sb.sleep(1)
sb.click('span[data-testid="airport-name"]')
sb.sleep(1)
Expand Down
6 changes: 3 additions & 3 deletions examples/cdp_mode/raw_hilton.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
with SB(uc=True, test=True, locale="en", use_chromium=True) as sb:
sb.activate_cdp_mode()
sb.goto("https://www.hilton.com/en/")
sb.sleep(4.5)
sb.sleep(4.2)
location = "Sunnyvale, CA, USA"
location_input = "input#location-input"
sb.wait_for_element(location_input)
Expand All @@ -17,9 +17,9 @@
sb.click('button[aria-current="date"]')
sb.sleep(1.2)
sb.click_if_visible('[role="dialog"] button.btn--solid')
sb.sleep(1.5)
sb.sleep(1.4)
sb.click('button[data-testid="search-submit-button"]')
sb.sleep(6.5)
sb.sleep(6.4)
sb.reconnect()
for window in sb.driver.window_handles:
sb.switch_to_window(window)
Expand Down
8 changes: 2 additions & 6 deletions examples/cdp_mode/raw_southwest.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,20 @@
sb.sleep(0.5)
sb.gui_click_element("input#originationAirportCode")
sb.sleep(0.2)
sb.select("input#originationAirportCode").clear_input()
sb.sleep(0.2)
sb.clear("input#originationAirportCode")
sb.uc_gui_press_keys(" " + "\n")
sb.sleep(0.5)
sb.gui_click_element("input#originationAirportCode")
sb.sleep(0.4)
sb.uc_gui_press_keys(origin + "\n")
sb.sleep(0.4)
sb.gui_click_element("h1")
sb.sleep(0.3)
sb.gui_click_element("input#destinationAirportCode")
sb.sleep(0.2)
sb.select("input#destinationAirportCode").clear_input()
sb.sleep(0.2)
sb.clear("input#destinationAirportCode")
sb.uc_gui_press_keys(destination + "\n")
sb.sleep(0.4)
sb.gui_click_element("h1")
sb.sleep(0.2)
sb.click_if_visible("button#onetrust-accept-btn-handler")
sb.sleep(0.1)
sb.click('form button[data-test="submitField"]')
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ setuptools~=70.2;python_version<"3.10"
setuptools>=83.0.0;python_version>="3.10"
wheel>=0.47.0
attrs>=26.1.0
certifi>=2026.6.17
certifi>=2026.7.22
exceptiongroup>=1.3.1
websockets~=15.0.1;python_version<"3.10"
websockets>=16.1.1;python_version>="3.10"
Expand Down
2 changes: 1 addition & 1 deletion seleniumbase/__version__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# seleniumbase package
__version__ = "4.51.5"
__version__ = "4.51.6"
4 changes: 4 additions & 0 deletions seleniumbase/core/sb_cdp.py
Original file line number Diff line number Diff line change
Expand Up @@ -1170,6 +1170,10 @@ def clear_input(self, selector, timeout=None):
self.__slow_mode_pause_if_set()
self.loop.run_until_complete(self.page.sleep(0.025))

def clear(self, selector, timeout=None):
"""Same as clear_input(), which clears the text field."""
self.clear_input(selector=selector, timeout=timeout)

def set_value(self, selector, text, timeout=None):
"""Similar to send_keys(), but clears the text field first."""
if not timeout:
Expand Down
2 changes: 2 additions & 0 deletions seleniumbase/fixtures/base_case.py
Original file line number Diff line number Diff line change
Expand Up @@ -5109,6 +5109,8 @@ def activate_cdp_mode(self, url=None, **kwargs):
self.click_captcha = self.cdp.click_captcha
if hasattr(self.cdp, "add_handler"):
self.add_handler = self.cdp.add_handler
if hasattr(self.cdp, "clear_input"):
self.clear_input = self.cdp.clear_input
if hasattr(self.cdp, "close_active_tab"):
self.close_active_tab = self.cdp.close_active_tab
if hasattr(self.cdp, "find_element_by_text"):
Expand Down
23 changes: 19 additions & 4 deletions seleniumbase/undetected/cdp_driver/element.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import asyncio
import logging
import pathlib
import random
import secrets
import typing
from contextlib import suppress
Expand Down Expand Up @@ -522,29 +523,37 @@ async def mouse_click_async(
using_pim = await self.tab.evaluate(script2)
if not using_px and not using_pim:
asyncio.create_task(self.flash_async(0.25))'''
with suppress(Exception):
await self.mouse_move_async()
await asyncio.sleep(random.uniform(0.003, 0.005))
x = center[0] + random.uniform(-0.8, 0.8)
y = center[1] + random.uniform(-0.8, 0.8)
asyncio.create_task(
self._tab.send(
cdp.input_.dispatch_mouse_event(
"mousePressed",
x=center[0],
y=center[1],
x=x,
y=y,
modifiers=modifiers,
button=cdp.input_.MouseButton(button),
buttons=buttons,
click_count=1,
force=0.5,
)
),
)
await asyncio.sleep(random.uniform(0.011, 0.015))
asyncio.create_task(
self._tab.send(
cdp.input_.dispatch_mouse_event(
"mouseReleased",
x=center[0],
y=center[1],
x=x + random.uniform(-0.12, 0.12),
y=y + random.uniform(-0.12, 0.12),
modifiers=modifiers,
button=cdp.input_.MouseButton(button),
buttons=buttons,
click_count=1,
force=0.0,
)
),
)
Expand Down Expand Up @@ -580,6 +589,9 @@ async def mouse_click_with_offset_async(
logger.debug("Clicking on location: %.2f, %.2f" % center_pos)
else:
logger.debug("Clicking on location: %.2f, %.2f" % (x_pos, y_pos))
with suppress(Exception):
await self.mouse_move_async()
await asyncio.sleep(random.uniform(0.003, 0.005))
script1 = 'sessionStorage.getItem("pxsid") !== null;'
script2 = 'sessionStorage.getItem("PIM-SESSION-ID") !== null;'
using_px = True
Expand All @@ -605,6 +617,7 @@ async def mouse_click_with_offset_async(
button=cdp.input_.MouseButton(button),
buttons=buttons,
click_count=1,
force=0.5,
)
)
)
Expand All @@ -618,6 +631,7 @@ async def mouse_click_with_offset_async(
button=cdp.input_.MouseButton(button),
buttons=buttons,
click_count=1,
force=0.0,
)
),
)
Expand Down Expand Up @@ -884,6 +898,7 @@ async def send_keys_async(self, text: str):
)
)
# 4. Trigger keyup DOM event
await asyncio.sleep(random.uniform(0.011, 0.015))
await self._tab.send(
cdp.input_.dispatch_key_event(
type_="keyUp",
Expand Down
7 changes: 4 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@
'setuptools>=83.0.0;python_version>="3.10"',
'wheel>=0.47.0',
'attrs>=26.1.0',
'certifi>=2026.6.17',
'certifi>=2026.7.22',
'exceptiongroup>=1.3.1',
'websockets~=15.0.1;python_version<"3.10"',
'websockets>=16.1.1;python_version>="3.10"',
Expand Down Expand Up @@ -302,9 +302,10 @@
# pip install -e .[playwright]
# (For the Playwright integration.)
"playwright": [
'playwright>=1.60.0',
'playwright>=1.60.0;python_version<"3.10"',
'playwright>=1.61.0;python_version>="3.10"',
'greenlet>=3.2.5;python_version<"3.10"',
'greenlet>=3.5.3;python_version>="3.10"',
'greenlet>=3.5.4;python_version>="3.10"',
],
# pip install -e .[pyautogui]
# (Already a required dependency on Linux now.)
Expand Down