Skip to content

Commit

Permalink
Merge pull request #3304 from seleniumbase/cdp-mode-patch-15
Browse files Browse the repository at this point in the history
CDP Mode - Patch 15
  • Loading branch information
mdmintz authored Nov 30, 2024
2 parents c81ab62 + 99c0f8a commit 667602c
Show file tree
Hide file tree
Showing 11 changed files with 194 additions and 127 deletions.
4 changes: 4 additions & 0 deletions examples/cdp_mode/ReadMe.md
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,10 @@ sb.cdp.assert_text(text, selector="html")
sb.cdp.assert_exact_text(text, selector="html")
sb.cdp.assert_true()
sb.cdp.assert_false()
sb.cdp.assert_equal(first, second)
sb.cdp.assert_not_equal(first, second)
sb.cdp.assert_in(first, second)
sb.cdp.assert_not_in(first, second)
sb.cdp.scroll_into_view(selector)
sb.cdp.scroll_to_y(y)
sb.cdp.scroll_to_top()
Expand Down
12 changes: 12 additions & 0 deletions examples/cdp_mode/raw_fingerprint.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from seleniumbase import SB

with SB(uc=True, test=True, incognito=True) as sb:
url = "https://demo.fingerprint.com/playground"
sb.activate_cdp_mode(url)
sb.sleep(1)
sb.cdp.highlight('a[href*="browser-bot-detection"]')
bot_row_selector = 'table:contains("Bot") tr:nth-of-type(3)'
print(sb.cdp.get_text(bot_row_selector))
sb.cdp.assert_text("Bot Not detected", bot_row_selector)
sb.cdp.highlight(bot_row_selector)
sb.sleep(2)
19 changes: 19 additions & 0 deletions examples/cdp_mode/raw_handle_alerts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
"""To handle alerts in CDP Mode, reconnect and use WebDriver."""
from seleniumbase import SB

with SB(uc=True, test=True) as sb:
url = "https://the-internet.herokuapp.com/javascript_alerts"
sb.activate_cdp_mode(url)
sb.reconnect()
sb.cdp.gui_click_element('button[onclick="jsAlert()"]')
sb.sleep(1)
sb.accept_alert()
sb.sleep(1)
sb.cdp.gui_click_element('button[onclick="jsConfirm()"]')
sb.sleep(1)
sb.dismiss_alert()
sb.sleep(1)
sb.cdp.gui_click_element('button[onclick="jsPrompt()"]')
sb.sleep(1)
sb.uc_gui_write("Here is my prompt answer\n")
sb.sleep(1)
8 changes: 4 additions & 4 deletions examples/migration/protractor/ReadMe.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@
```bash
$ pytest --rs -v --guest
=========================== test session starts ============================
platform darwin -- Python 3.11.2, pytest-7.4.0, pluggy-1.2.0 -- /Users/michael/.virtualenvs/sb_venv/bin/python
metadata: {'Python': '3.11.2', 'Platform': 'macOS-13.2.1-arm64-arm-64bit', 'Packages': {'pytest': '7.4.0', 'pluggy': '1.2.0'}, 'Plugins': {'html': '2.0.1', 'rerunfailures': '12.0', 'metadata': '3.0.0', 'ordering': '0.6', 'xdist': '3.3.1', 'seleniumbase': '4.15.10'}}
platform darwin -- Python 3.11.9, pytest-8.3.3, pluggy-1.5.0 -- /Users/michael/.virtualenvs/sbase11/bin/python
metadata: {'Python': '3.11.9', 'Platform': 'macOS-13.2.1-arm64-arm-64bit', 'Packages': {'pytest': '8.3.3', 'pluggy': '1.5.0'}, 'Plugins': {'cov': '6.0.0', 'html': '2.0.1', 'metadata': '3.1.1', 'seleniumbase': '4.33.2', 'ordering': '0.6', 'rerunfailures': '15.0', 'xdist': '3.6.1'}}
rootdir: /Users/michael/github/SeleniumBase/examples
configfile: pytest.ini
plugins: html-2.0.1, rerunfailures-12.0, metadata-3.0.0, ordering-0.6, xdist-3.3.1, seleniumbase-4.15.10
collected 4 items
plugins: html-2.0.1, metadata-3.1.1, seleniumbase-4.33.2, ordering-0.6, rerunfailures-15.0, xdist-3.6.1
collected 4 items

example_test.py::AngularJSHomePageTests::test_greet_user PASSED
example_test.py::AngularJSHomePageTests::test_todo_list PASSED
Expand Down
2 changes: 2 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ plugins:
- CONTRIBUTING.md
- SECURITY.md
- examples/case_summary.md
- examples/migration/raw_selenium/ReadMe.md
- help_docs/chinese.md
- integrations/katalon/ReadMe.md
- help_docs/ReadMe.md
Expand Down Expand Up @@ -174,6 +175,7 @@ nav:
- 📃 Desired Capabilities: help_docs/desired_capabilities.md
- 📜 Useful grep commands: help_docs/useful_grep_commands.md
- ⚙️ Downloading drivers: help_docs/webdriver_installation.md
- ✅ Selenium Migration: examples/migration/raw_selenium/ReadMe.md
- ✔️ Verifying drivers: help_docs/verify_webdriver.md
- Behave-BDD Integration:
- 🐝 Behave-BDD ReadMe: examples/behave_bdd/ReadMe.md
Expand Down
13 changes: 11 additions & 2 deletions mkdocs_build/prepare.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,17 @@ def main(*args, **kwargs):
scanned_dir_list = []
scanned_dir_list.append("help_docs")
scanned_dir_list.append("examples")
scanned_dir_list.append("examples/behave_bdd")
scanned_dir_list.append("examples/example_logs")
scanned_dir_list.append("examples/cdp_mode")
scanned_dir_list.append("examples/master_qa")
scanned_dir_list.append("examples/presenter")
scanned_dir_list.append("examples/behave_bdd")
scanned_dir_list.append("examples/chart_maker")
scanned_dir_list.append("examples/example_logs")
scanned_dir_list.append("examples/tour_examples")
scanned_dir_list.append("examples/visual_testing")
scanned_dir_list.append("integrations/google_cloud")
scanned_dir_list.append("seleniumbase/console_scripts")
scanned_dir_list.append("examples/migration/raw_selenium")
for scanned_dir in scanned_dir_list:
for dir_ in os.listdir(ROOT_DIR / scanned_dir):
files_to_process.append(os.path.join(scanned_dir, dir_))
Expand Down Expand Up @@ -159,6 +162,12 @@ def main(*args, **kwargs):
)
if alt_link_badge in line:
line = line.replace(alt_link_badge, back_to_gh)
changed = True
if "/help_docs/uc_mode/" in line and file_.count("/") >= 2:
line = line.replace(
"/help_docs/uc_mode/", "/../help_docs/uc_mode/"
)
changed = True
if "<!-- GitHub Only -->" in line:
changed = True
continue
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.33.1"
__version__ = "4.33.2"
4 changes: 4 additions & 0 deletions seleniumbase/core/browser_launcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -703,6 +703,10 @@ def uc_open_with_cdp_mode(driver, url=None):
cdp.assert_exact_text = CDPM.assert_exact_text
cdp.assert_true = CDPM.assert_true
cdp.assert_false = CDPM.assert_false
cdp.assert_equal = CDPM.assert_equal
cdp.assert_not_equal = CDPM.assert_not_equal
cdp.assert_in = CDPM.assert_in
cdp.assert_not_in = CDPM.assert_not_in
cdp.scroll_into_view = CDPM.scroll_into_view
cdp.scroll_to_y = CDPM.scroll_to_y
cdp.scroll_to_top = CDPM.scroll_to_top
Expand Down
49 changes: 28 additions & 21 deletions seleniumbase/core/sb_cdp.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,23 +135,10 @@ def find_element(
self.__add_light_pause()
selector = self.__convert_to_css_if_xpath(selector)
early_failure = False
if (":contains(" in selector):
tag_name = selector.split(":contains(")[0].split(" ")[-1]
text = selector.split(":contains(")[1].split(")")[0][1:-1]
with suppress(Exception):
self.loop.run_until_complete(
self.page.select(tag_name, timeout=timeout)
)
self.loop.run_until_complete(
self.page.find(text, timeout=timeout)
)
elements = []
with suppress(Exception):
elements = self.find_elements_by_text(text, tag_name=tag_name)
if elements:
return self.__add_sync_methods(elements[0])
else:
early_failure = True
if (":contains(") in selector:
selector, _ = page_utils.recalculate_selector(
selector, by="css selector", xp_ok=True
)
failure = False
try:
if early_failure:
Expand Down Expand Up @@ -726,12 +713,16 @@ def set_value(self, selector, text, timeout=settings.SMALL_TIMEOUT):

def evaluate(self, expression):
"""Run a JavaScript expression and return the result."""
if expression.startswith("return "):
expression = expression[len("return "):]
return self.loop.run_until_complete(
self.page.evaluate(expression)
)

def js_dumps(self, obj_name):
"""Similar to evaluate(), but for dictionary results."""
if obj_name.startswith("return "):
obj_name = obj_name[len("return "):]
return self.loop.run_until_complete(
self.page.js_dumps(obj_name)
)
Expand Down Expand Up @@ -1648,11 +1639,11 @@ def assert_text(
text = text.strip()
element = None
try:
element = self.select(selector, timeout=timeout)
element = self.find_element(selector, timeout=timeout)
except Exception:
raise Exception("Element {%s} not found!" % selector)
for i in range(30):
if self.is_element_visible(selector) and text in element.text_all:
if text in element.text_all:
return True
time.sleep(0.1)
raise Exception(
Expand Down Expand Up @@ -1683,11 +1674,27 @@ def assert_exact_text(

def assert_true(self, expression):
if not expression:
raise AssertionError("%s is not true")
raise AssertionError("%s is not true" % expression)

def assert_false(self, expression):
if expression:
raise AssertionError("%s is not false")
raise AssertionError("%s is not false" % expression)

def assert_equal(self, first, second):
if first != second:
raise AssertionError("%s is not equal to %s" % (first, second))

def assert_not_equal(self, first, second):
if first == second:
raise AssertionError("%s is equal to %s" % (first, second))

def assert_in(self, first, second):
if first not in second:
raise AssertionError("%s is not in %s" % (first, second))

def assert_not_in(self, first, second):
if first in second:
raise AssertionError("%s is in %s" % (first, second))

def scroll_into_view(self, selector):
self.find_element(selector).scroll_into_view()
Expand Down
28 changes: 15 additions & 13 deletions seleniumbase/fixtures/base_case.py
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ def click(
original_by = by
selector, by = self.__recalculate_selector(selector, by)
if self.__is_cdp_swap_needed():
self.cdp.click(selector)
self.cdp.click(selector, timeout=timeout)
return
if delay and (type(delay) in [int, float]) and delay > 0:
time.sleep(delay)
Expand Down Expand Up @@ -885,7 +885,7 @@ def update_text(
timeout = self.__get_new_timeout(timeout)
selector, by = self.__recalculate_selector(selector, by)
if self.__is_cdp_swap_needed():
self.cdp.type(selector, text)
self.cdp.type(selector, text, timeout=timeout)
return
if self.__is_shadow_selector(selector):
self.__shadow_type(selector, text, timeout)
Expand Down Expand Up @@ -1112,7 +1112,7 @@ def send_keys(self, selector, text, by="css selector", timeout=None):
def press_keys(self, selector, text, by="css selector", timeout=None):
"""Use send_keys() to press one key at a time."""
if self.__is_cdp_swap_needed():
self.cdp.press_keys(selector, text)
self.cdp.press_keys(selector, text, timeout=timeout)
return
self.wait_for_ready_state_complete()
element = self.wait_for_element_present(
Expand Down Expand Up @@ -1597,7 +1597,7 @@ def click_link_text(self, link_text, timeout=None):
"""This method clicks link text on a page."""
self.__check_scope()
if self.__is_cdp_swap_needed():
self.cdp.find_element(link_text).click()
self.cdp.find_element(link_text, timeout=timeout).click()
return
self.__skip_if_esc()
if not timeout:
Expand Down Expand Up @@ -3380,6 +3380,8 @@ def open_html_file(self, html_file):

def execute_script(self, script, *args, **kwargs):
self.__check_scope()
if self.__is_cdp_swap_needed():
return self.cdp.evaluate(script)
self._check_browser()
return self.driver.execute_script(script, *args, **kwargs)

Expand Down Expand Up @@ -6308,7 +6310,7 @@ def js_click(
If "all_matches" is False, only the first match is clicked.
If "scroll" is False, won't scroll unless running in Demo Mode."""
if self.__is_cdp_swap_needed():
self.cdp.click(selector)
self.cdp.click(selector, timeout=timeout)
return
self.wait_for_ready_state_complete()
if not timeout or timeout is True:
Expand Down Expand Up @@ -8245,7 +8247,7 @@ def enter_mfa_code(
timeout = settings.SMALL_TIMEOUT
if self.__is_cdp_swap_needed():
mfa_code = self.get_mfa_code(totp_key)
self.cdp.type(selector, mfa_code + "\n")
self.cdp.type(selector, mfa_code + "\n", timeout=timeout)
return
self.wait_for_element_visible(selector, by=by, timeout=timeout)
if self.recorder_mode and self.__current_url_is_recordable():
Expand Down Expand Up @@ -9003,7 +9005,7 @@ def wait_for_element_visible(
original_selector = selector
selector, by = self.__recalculate_selector(selector, by)
if self.__is_cdp_swap_needed():
return self.cdp.select(selector)
return self.cdp.select(selector, timeout=timeout)
if self.__is_shadow_selector(selector):
return self.__get_shadow_element(selector, timeout)
return page_actions.wait_for_element_visible(
Expand All @@ -9026,7 +9028,7 @@ def wait_for_element_clickable(
original_selector = selector
selector, by = self.__recalculate_selector(selector, by)
if self.__is_cdp_swap_needed():
return self.cdp.select(selector)
return self.cdp.select(selector, timeout=timeout)
elif self.__is_shadow_selector(selector):
# If a shadow selector, use visible instead of clickable
return self.__wait_for_shadow_element_visible(selector, timeout)
Expand Down Expand Up @@ -9427,7 +9429,7 @@ def wait_for_element_present(
original_selector = selector
selector, by = self.__recalculate_selector(selector, by)
if self.__is_cdp_swap_needed():
return self.cdp.select(selector)
return self.cdp.select(selector, timeout=timeout)
elif self.__is_shadow_selector(selector):
return self.__wait_for_shadow_element_present(selector, timeout)
return page_actions.wait_for_element_present(
Expand All @@ -9449,7 +9451,7 @@ def wait_for_element(self, selector, by="css selector", timeout=None):
original_selector = selector
selector, by = self.__recalculate_selector(selector, by)
if self.__is_cdp_swap_needed():
return self.cdp.select(selector)
return self.cdp.select(selector, timeout=timeout)
if self.recorder_mode and self.__current_url_is_recordable():
if self.get_session_storage_item("pause_recorder") == "no":
if by == By.XPATH:
Expand Down Expand Up @@ -9492,7 +9494,7 @@ def wait_for_query_selector(
timeout = self.__get_new_timeout(timeout)
css_selector = self.convert_to_css_selector(selector, by=by)
if self.__is_cdp_swap_needed():
return self.cdp.select(css_selector)
return self.cdp.select(css_selector, timeout=timeout)
return js_utils.wait_for_css_query_selector(
self.driver, css_selector, timeout
)
Expand Down Expand Up @@ -9713,7 +9715,7 @@ def wait_for_text_visible(
text = self.__get_type_checked_text(text)
selector, by = self.__recalculate_selector(selector, by)
if self.__is_cdp_swap_needed():
return self.cdp.find_element(selector)
return self.cdp.find_element(selector, timeout=timeout)
elif self.__is_shadow_selector(selector):
return self.__wait_for_shadow_text_visible(text, selector, timeout)
return page_actions.wait_for_text_visible(
Expand Down Expand Up @@ -10093,7 +10095,7 @@ def assert_link_text(self, link_text, timeout=None):
if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT:
timeout = self.__get_new_timeout(timeout)
if self.__is_cdp_swap_needed():
self.cdp.find_element(link_text)
self.cdp.find_element(link_text, timeout=timeout)
return
self.wait_for_link_text_visible(link_text, timeout=timeout)
if self.demo_mode:
Expand Down
Loading

0 comments on commit 667602c

Please sign in to comment.