Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 667602c

Browse files
authored
Merge pull request #3304 from seleniumbase/cdp-mode-patch-15
CDP Mode - Patch 15
2 parents c81ab62 + 99c0f8a commit 667602c

File tree

11 files changed

+194
-127
lines changed

11 files changed

+194
-127
lines changed

‎examples/cdp_mode/ReadMe.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,10 @@ sb.cdp.assert_text(text, selector="html")
419419
sb.cdp.assert_exact_text(text, selector="html")
420420
sb.cdp.assert_true()
421421
sb.cdp.assert_false()
422+
sb.cdp.assert_equal(first, second)
423+
sb.cdp.assert_not_equal(first, second)
424+
sb.cdp.assert_in(first, second)
425+
sb.cdp.assert_not_in(first, second)
422426
sb.cdp.scroll_into_view(selector)
423427
sb.cdp.scroll_to_y(y)
424428
sb.cdp.scroll_to_top()

‎examples/cdp_mode/raw_fingerprint.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from seleniumbase import SB
2+
3+
with SB(uc=True, test=True, incognito=True) as sb:
4+
url = "https://demo.fingerprint.com/playground"
5+
sb.activate_cdp_mode(url)
6+
sb.sleep(1)
7+
sb.cdp.highlight('a[href*="browser-bot-detection"]')
8+
bot_row_selector = 'table:contains("Bot") tr:nth-of-type(3)'
9+
print(sb.cdp.get_text(bot_row_selector))
10+
sb.cdp.assert_text("Bot Not detected", bot_row_selector)
11+
sb.cdp.highlight(bot_row_selector)
12+
sb.sleep(2)

‎examples/cdp_mode/raw_handle_alerts.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
"""To handle alerts in CDP Mode, reconnect and use WebDriver."""
2+
from seleniumbase import SB
3+
4+
with SB(uc=True, test=True) as sb:
5+
url = "https://the-internet.herokuapp.com/javascript_alerts"
6+
sb.activate_cdp_mode(url)
7+
sb.reconnect()
8+
sb.cdp.gui_click_element('button[onclick="jsAlert()"]')
9+
sb.sleep(1)
10+
sb.accept_alert()
11+
sb.sleep(1)
12+
sb.cdp.gui_click_element('button[onclick="jsConfirm()"]')
13+
sb.sleep(1)
14+
sb.dismiss_alert()
15+
sb.sleep(1)
16+
sb.cdp.gui_click_element('button[onclick="jsPrompt()"]')
17+
sb.sleep(1)
18+
sb.uc_gui_write("Here is my prompt answer\n")
19+
sb.sleep(1)

‎examples/migration/protractor/ReadMe.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@
99
```bash
1010
$ pytest --rs -v --guest
1111
=========================== test session starts ============================
12-
platform darwin -- Python 3.11.2, pytest-7.4.0, pluggy-1.2.0 -- /Users/michael/.virtualenvs/sb_venv/bin/python
13-
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'}}
12+
platform darwin -- Python 3.11.9, pytest-8.3.3, pluggy-1.5.0 -- /Users/michael/.virtualenvs/sbase11/bin/python
13+
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'}}
1414
rootdir: /Users/michael/github/SeleniumBase/examples
1515
configfile: pytest.ini
16-
plugins: html-2.0.1, rerunfailures-12.0, metadata-3.0.0, ordering-0.6, xdist-3.3.1, seleniumbase-4.15.10
17-
collected 4 items
16+
plugins: html-2.0.1, metadata-3.1.1, seleniumbase-4.33.2, ordering-0.6, rerunfailures-15.0, xdist-3.6.1
17+
collected 4 items
1818

1919
example_test.py::AngularJSHomePageTests::test_greet_user PASSED
2020
example_test.py::AngularJSHomePageTests::test_todo_list PASSED

‎mkdocs.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ plugins:
7373
- CONTRIBUTING.md
7474
- SECURITY.md
7575
- examples/case_summary.md
76+
- examples/migration/raw_selenium/ReadMe.md
7677
- help_docs/chinese.md
7778
- integrations/katalon/ReadMe.md
7879
- help_docs/ReadMe.md
@@ -174,6 +175,7 @@ nav:
174175
- 📃 Desired Capabilities: help_docs/desired_capabilities.md
175176
- 📜 Useful grep commands: help_docs/useful_grep_commands.md
176177
- ⚙️ Downloading drivers: help_docs/webdriver_installation.md
178+
- ✅ Selenium Migration: examples/migration/raw_selenium/ReadMe.md
177179
- ✔️ Verifying drivers: help_docs/verify_webdriver.md
178180
- Behave-BDD Integration:
179181
- 🐝 Behave-BDD ReadMe: examples/behave_bdd/ReadMe.md

‎mkdocs_build/prepare.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,14 +76,17 @@ def main(*args, **kwargs):
7676
scanned_dir_list = []
7777
scanned_dir_list.append("help_docs")
7878
scanned_dir_list.append("examples")
79-
scanned_dir_list.append("examples/behave_bdd")
80-
scanned_dir_list.append("examples/example_logs")
79+
scanned_dir_list.append("examples/cdp_mode")
80+
scanned_dir_list.append("examples/master_qa")
8181
scanned_dir_list.append("examples/presenter")
82+
scanned_dir_list.append("examples/behave_bdd")
8283
scanned_dir_list.append("examples/chart_maker")
84+
scanned_dir_list.append("examples/example_logs")
8385
scanned_dir_list.append("examples/tour_examples")
8486
scanned_dir_list.append("examples/visual_testing")
8587
scanned_dir_list.append("integrations/google_cloud")
8688
scanned_dir_list.append("seleniumbase/console_scripts")
89+
scanned_dir_list.append("examples/migration/raw_selenium")
8790
for scanned_dir in scanned_dir_list:
8891
for dir_ in os.listdir(ROOT_DIR / scanned_dir):
8992
files_to_process.append(os.path.join(scanned_dir, dir_))
@@ -159,6 +162,12 @@ def main(*args, **kwargs):
159162
)
160163
if alt_link_badge in line:
161164
line = line.replace(alt_link_badge, back_to_gh)
165+
changed = True
166+
if "/help_docs/uc_mode/" in line and file_.count("/") >= 2:
167+
line = line.replace(
168+
"/help_docs/uc_mode/", "/../help_docs/uc_mode/"
169+
)
170+
changed = True
162171
if "<!-- GitHub Only -->" in line:
163172
changed = True
164173
continue

‎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.33.1"
2+
__version__ = "4.33.2"

‎seleniumbase/core/browser_launcher.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,10 @@ def uc_open_with_cdp_mode(driver, url=None):
703703
cdp.assert_exact_text = CDPM.assert_exact_text
704704
cdp.assert_true = CDPM.assert_true
705705
cdp.assert_false = CDPM.assert_false
706+
cdp.assert_equal = CDPM.assert_equal
707+
cdp.assert_not_equal = CDPM.assert_not_equal
708+
cdp.assert_in = CDPM.assert_in
709+
cdp.assert_not_in = CDPM.assert_not_in
706710
cdp.scroll_into_view = CDPM.scroll_into_view
707711
cdp.scroll_to_y = CDPM.scroll_to_y
708712
cdp.scroll_to_top = CDPM.scroll_to_top

‎seleniumbase/core/sb_cdp.py

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -135,23 +135,10 @@ def find_element(
135135
self.__add_light_pause()
136136
selector = self.__convert_to_css_if_xpath(selector)
137137
early_failure = False
138-
if (":contains(" in selector):
139-
tag_name = selector.split(":contains(")[0].split(" ")[-1]
140-
text = selector.split(":contains(")[1].split(")")[0][1:-1]
141-
with suppress(Exception):
142-
self.loop.run_until_complete(
143-
self.page.select(tag_name, timeout=timeout)
144-
)
145-
self.loop.run_until_complete(
146-
self.page.find(text, timeout=timeout)
147-
)
148-
elements = []
149-
with suppress(Exception):
150-
elements = self.find_elements_by_text(text, tag_name=tag_name)
151-
if elements:
152-
return self.__add_sync_methods(elements[0])
153-
else:
154-
early_failure = True
138+
if (":contains(") in selector:
139+
selector, _ = page_utils.recalculate_selector(
140+
selector, by="css selector", xp_ok=True
141+
)
155142
failure = False
156143
try:
157144
if early_failure:
@@ -726,12 +713,16 @@ def set_value(self, selector, text, timeout=settings.SMALL_TIMEOUT):
726713

727714
def evaluate(self, expression):
728715
"""Run a JavaScript expression and return the result."""
716+
if expression.startswith("return "):
717+
expression = expression[len("return "):]
729718
return self.loop.run_until_complete(
730719
self.page.evaluate(expression)
731720
)
732721

733722
def js_dumps(self, obj_name):
734723
"""Similar to evaluate(), but for dictionary results."""
724+
if obj_name.startswith("return "):
725+
obj_name = obj_name[len("return "):]
735726
return self.loop.run_until_complete(
736727
self.page.js_dumps(obj_name)
737728
)
@@ -1648,11 +1639,11 @@ def assert_text(
16481639
text = text.strip()
16491640
element = None
16501641
try:
1651-
element = self.select(selector, timeout=timeout)
1642+
element = self.find_element(selector, timeout=timeout)
16521643
except Exception:
16531644
raise Exception("Element {%s} not found!" % selector)
16541645
for i in range(30):
1655-
if self.is_element_visible(selector) andtext in element.text_all:
1646+
if text in element.text_all:
16561647
return True
16571648
time.sleep(0.1)
16581649
raise Exception(
@@ -1683,11 +1674,27 @@ def assert_exact_text(
16831674

16841675
def assert_true(self, expression):
16851676
if not expression:
1686-
raise AssertionError("%s is not true")
1677+
raise AssertionError("%s is not true"%expression)
16871678

16881679
def assert_false(self, expression):
16891680
if expression:
1690-
raise AssertionError("%s is not false")
1681+
raise AssertionError("%s is not false" % expression)
1682+
1683+
def assert_equal(self, first, second):
1684+
if first != second:
1685+
raise AssertionError("%s is not equal to %s" % (first, second))
1686+
1687+
def assert_not_equal(self, first, second):
1688+
if first == second:
1689+
raise AssertionError("%s is equal to %s" % (first, second))
1690+
1691+
def assert_in(self, first, second):
1692+
if first not in second:
1693+
raise AssertionError("%s is not in %s" % (first, second))
1694+
1695+
def assert_not_in(self, first, second):
1696+
if first in second:
1697+
raise AssertionError("%s is in %s" % (first, second))
16911698

16921699
def scroll_into_view(self, selector):
16931700
self.find_element(selector).scroll_into_view()

‎seleniumbase/fixtures/base_case.py

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ def click(
392392
original_by = by
393393
selector, by = self.__recalculate_selector(selector, by)
394394
if self.__is_cdp_swap_needed():
395-
self.cdp.click(selector)
395+
self.cdp.click(selector, timeout=timeout)
396396
return
397397
if delay and (type(delay) in [int, float]) and delay > 0:
398398
time.sleep(delay)
@@ -885,7 +885,7 @@ def update_text(
885885
timeout = self.__get_new_timeout(timeout)
886886
selector, by = self.__recalculate_selector(selector, by)
887887
if self.__is_cdp_swap_needed():
888-
self.cdp.type(selector, text)
888+
self.cdp.type(selector, text, timeout=timeout)
889889
return
890890
if self.__is_shadow_selector(selector):
891891
self.__shadow_type(selector, text, timeout)
@@ -1112,7 +1112,7 @@ def send_keys(self, selector, text, by="css selector", timeout=None):
11121112
def press_keys(self, selector, text, by="css selector", timeout=None):
11131113
"""Use send_keys() to press one key at a time."""
11141114
if self.__is_cdp_swap_needed():
1115-
self.cdp.press_keys(selector, text)
1115+
self.cdp.press_keys(selector, text, timeout=timeout)
11161116
return
11171117
self.wait_for_ready_state_complete()
11181118
element = self.wait_for_element_present(
@@ -1597,7 +1597,7 @@ def click_link_text(self, link_text, timeout=None):
15971597
"""This method clicks link text on a page."""
15981598
self.__check_scope()
15991599
if self.__is_cdp_swap_needed():
1600-
self.cdp.find_element(link_text).click()
1600+
self.cdp.find_element(link_text, timeout=timeout).click()
16011601
return
16021602
self.__skip_if_esc()
16031603
if not timeout:
@@ -3380,6 +3380,8 @@ def open_html_file(self, html_file):
33803380

33813381
def execute_script(self, script, *args, **kwargs):
33823382
self.__check_scope()
3383+
if self.__is_cdp_swap_needed():
3384+
return self.cdp.evaluate(script)
33833385
self._check_browser()
33843386
return self.driver.execute_script(script, *args, **kwargs)
33853387

@@ -6308,7 +6310,7 @@ def js_click(
63086310
If "all_matches" is False, only the first match is clicked.
63096311
If "scroll" is False, won't scroll unless running in Demo Mode."""
63106312
if self.__is_cdp_swap_needed():
6311-
self.cdp.click(selector)
6313+
self.cdp.click(selector, timeout=timeout)
63126314
return
63136315
self.wait_for_ready_state_complete()
63146316
if not timeout or timeout is True:
@@ -8245,7 +8247,7 @@ def enter_mfa_code(
82458247
timeout = settings.SMALL_TIMEOUT
82468248
if self.__is_cdp_swap_needed():
82478249
mfa_code = self.get_mfa_code(totp_key)
8248-
self.cdp.type(selector, mfa_code + "\n")
8250+
self.cdp.type(selector, mfa_code + "\n", timeout=timeout)
82498251
return
82508252
self.wait_for_element_visible(selector, by=by, timeout=timeout)
82518253
if self.recorder_mode and self.__current_url_is_recordable():
@@ -9003,7 +9005,7 @@ def wait_for_element_visible(
90039005
original_selector = selector
90049006
selector, by = self.__recalculate_selector(selector, by)
90059007
if self.__is_cdp_swap_needed():
9006-
return self.cdp.select(selector)
9008+
return self.cdp.select(selector, timeout=timeout)
90079009
if self.__is_shadow_selector(selector):
90089010
return self.__get_shadow_element(selector, timeout)
90099011
return page_actions.wait_for_element_visible(
@@ -9026,7 +9028,7 @@ def wait_for_element_clickable(
90269028
original_selector = selector
90279029
selector, by = self.__recalculate_selector(selector, by)
90289030
if self.__is_cdp_swap_needed():
9029-
return self.cdp.select(selector)
9031+
return self.cdp.select(selector, timeout=timeout)
90309032
elif self.__is_shadow_selector(selector):
90319033
# If a shadow selector, use visible instead of clickable
90329034
return self.__wait_for_shadow_element_visible(selector, timeout)
@@ -9427,7 +9429,7 @@ def wait_for_element_present(
94279429
original_selector = selector
94289430
selector, by = self.__recalculate_selector(selector, by)
94299431
if self.__is_cdp_swap_needed():
9430-
return self.cdp.select(selector)
9432+
return self.cdp.select(selector, timeout=timeout)
94319433
elif self.__is_shadow_selector(selector):
94329434
return self.__wait_for_shadow_element_present(selector, timeout)
94339435
return page_actions.wait_for_element_present(
@@ -9449,7 +9451,7 @@ def wait_for_element(self, selector, by="css selector", timeout=None):
94499451
original_selector = selector
94509452
selector, by = self.__recalculate_selector(selector, by)
94519453
if self.__is_cdp_swap_needed():
9452-
return self.cdp.select(selector)
9454+
return self.cdp.select(selector, timeout=timeout)
94539455
if self.recorder_mode and self.__current_url_is_recordable():
94549456
if self.get_session_storage_item("pause_recorder") == "no":
94559457
if by == By.XPATH:
@@ -9492,7 +9494,7 @@ def wait_for_query_selector(
94929494
timeout = self.__get_new_timeout(timeout)
94939495
css_selector = self.convert_to_css_selector(selector, by=by)
94949496
if self.__is_cdp_swap_needed():
9495-
return self.cdp.select(css_selector)
9497+
return self.cdp.select(css_selector, timeout=timeout)
94969498
return js_utils.wait_for_css_query_selector(
94979499
self.driver, css_selector, timeout
94989500
)
@@ -9713,7 +9715,7 @@ def wait_for_text_visible(
97139715
text = self.__get_type_checked_text(text)
97149716
selector, by = self.__recalculate_selector(selector, by)
97159717
if self.__is_cdp_swap_needed():
9716-
return self.cdp.find_element(selector)
9718+
return self.cdp.find_element(selector, timeout=timeout)
97179719
elif self.__is_shadow_selector(selector):
97189720
return self.__wait_for_shadow_text_visible(text, selector, timeout)
97199721
return page_actions.wait_for_text_visible(
@@ -10093,7 +10095,7 @@ def assert_link_text(self, link_text, timeout=None):
1009310095
if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT:
1009410096
timeout = self.__get_new_timeout(timeout)
1009510097
if self.__is_cdp_swap_needed():
10096-
self.cdp.find_element(link_text)
10098+
self.cdp.find_element(link_text, timeout=timeout)
1009710099
return
1009810100
self.wait_for_link_text_visible(link_text, timeout=timeout)
1009910101
if self.demo_mode:

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /