seleniumbase 4.27.5__py3-none-any.whl → 4.28.0a1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
seleniumbase/__init__.py CHANGED
@@ -1,4 +1,5 @@
1
1
  import collections
2
+ import os
2
3
  import pdb
3
4
  try:
4
5
  import pdbp # (Pdb+) --- Python Debugger Plus
@@ -34,11 +35,13 @@ if sys.version_info[0] < 3 and "pdbp" in locals():
34
35
  pdb.DefaultConfig.truncate_long_lines = False
35
36
  pdb.DefaultConfig.sticky_by_default = True
36
37
  colored_traceback.add_hook()
38
+ os.environ["SE_AVOID_STATS"] = "true" # Disable Selenium Manager stats
37
39
  if sys.version_info >= (3, 7):
38
40
  webdriver.TouchActions = None # Lifeline for past selenium-wire versions
39
41
  if sys.version_info >= (3, 10):
40
42
  collections.Callable = collections.abc.Callable # Lifeline for nosetests
41
43
  del collections # Undo "import collections" / Simplify "dir(seleniumbase)"
44
+ del os # Undo "import os" / Simplify "dir(seleniumbase)"
42
45
  del sys # Undo "import sys" / Simplify "dir(seleniumbase)"
43
46
  del webdriver # Undo "import webdriver" / Simplify "dir(seleniumbase)"
44
47
 
@@ -1,2 +1,2 @@
1
1
  # seleniumbase package
2
- __version__ = "4.27.5"
2
+ __version__ = "4.28.0a1"
@@ -861,13 +861,14 @@ def get_configured_sb(context):
861
861
  and not sb.headless
862
862
  and not sb.headless2
863
863
  and not sb.xvfb
864
+ and not sb.undetectable
864
865
  ):
865
866
  print(
866
867
  '(Linux uses "-D headless" by default. '
867
868
  'To override, use "-D headed" / "-D gui". '
868
869
  'For Xvfb mode instead, use "-D xvfb". '
869
870
  "Or you can hide this info by using"
870
- '"-D headless" / "-D headless2".)'
871
+ '"-D headless" / "-D headless2" / "-D uc".)'
871
872
  )
872
873
  sb.headless = True
873
874
  # Recorder Mode can still optimize scripts in --headless2 mode.
@@ -11,6 +11,7 @@ import urllib3
11
11
  import warnings
12
12
  from selenium import webdriver
13
13
  from selenium.common.exceptions import ElementClickInterceptedException
14
+ from selenium.common.exceptions import InvalidSessionIdException
14
15
  from selenium.webdriver.chrome.service import Service as ChromeService
15
16
  from selenium.webdriver.common.options import ArgOptions
16
17
  from selenium.webdriver.common.service import utils as service_utils
@@ -28,6 +29,7 @@ from seleniumbase.core import proxy_helper
28
29
  from seleniumbase.core import sb_driver
29
30
  from seleniumbase.fixtures import constants
30
31
  from seleniumbase.fixtures import js_utils
32
+ from seleniumbase.fixtures import page_actions
31
33
  from seleniumbase.fixtures import shared_utils
32
34
 
33
35
  urllib3.disable_warnings()
@@ -130,9 +132,13 @@ def extend_driver(driver):
130
132
  page.assert_element_not_visible = DM.assert_element_not_visible
131
133
  page.assert_text = DM.assert_text
132
134
  page.assert_exact_text = DM.assert_exact_text
135
+ page.assert_non_empty_text = DM.assert_non_empty_text
136
+ page.assert_text_not_visible = DM.assert_text_not_visible
133
137
  page.wait_for_element = DM.wait_for_element
134
138
  page.wait_for_text = DM.wait_for_text
135
139
  page.wait_for_exact_text = DM.wait_for_exact_text
140
+ page.wait_for_non_empty_text = DM.wait_for_non_empty_text
141
+ page.wait_for_text_not_visible = DM.wait_for_text_not_visible
136
142
  page.wait_for_and_accept_alert = DM.wait_for_and_accept_alert
137
143
  page.wait_for_and_dismiss_alert = DM.wait_for_and_dismiss_alert
138
144
  page.is_element_present = DM.is_element_present
@@ -140,12 +146,20 @@ def extend_driver(driver):
140
146
  page.is_text_visible = DM.is_text_visible
141
147
  page.is_exact_text_visible = DM.is_exact_text_visible
142
148
  page.is_attribute_present = DM.is_attribute_present
149
+ page.is_non_empty_text_visible = DM.is_non_empty_text_visible
143
150
  page.get_text = DM.get_text
144
151
  page.find_element = DM.find_element
145
152
  page.find_elements = DM.find_elements
146
153
  page.locator = DM.locator
147
154
  page.get_page_source = DM.get_page_source
148
155
  page.get_title = DM.get_title
156
+ page.switch_to_default_window = DM.switch_to_default_window
157
+ page.switch_to_newest_window = DM.switch_to_newest_window
158
+ page.open_new_window = DM.open_new_window
159
+ page.open_new_tab = DM.open_new_tab
160
+ page.switch_to_window = DM.switch_to_window
161
+ page.switch_to_tab = DM.switch_to_tab
162
+ page.switch_to_frame = DM.switch_to_frame
149
163
  driver.page = page
150
164
  js = types.SimpleNamespace()
151
165
  js.js_click = DM.js_click
@@ -169,12 +183,16 @@ def extend_driver(driver):
169
183
  driver.assert_element_not_visible = DM.assert_element_not_visible
170
184
  driver.assert_text = DM.assert_text
171
185
  driver.assert_exact_text = DM.assert_exact_text
186
+ driver.assert_non_empty_text = DM.assert_non_empty_text
187
+ driver.assert_text_not_visible = DM.assert_text_not_visible
172
188
  driver.wait_for_element = DM.wait_for_element
173
189
  driver.wait_for_element_visible = DM.wait_for_element_visible
174
190
  driver.wait_for_element_present = DM.wait_for_element_present
175
191
  driver.wait_for_selector = DM.wait_for_selector
176
192
  driver.wait_for_text = DM.wait_for_text
177
193
  driver.wait_for_exact_text = DM.wait_for_exact_text
194
+ driver.wait_for_non_empty_text = DM.wait_for_non_empty_text
195
+ driver.wait_for_text_not_visible = DM.wait_for_text_not_visible
178
196
  driver.wait_for_and_accept_alert = DM.wait_for_and_accept_alert
179
197
  driver.wait_for_and_dismiss_alert = DM.wait_for_and_dismiss_alert
180
198
  driver.is_element_present = DM.is_element_present
@@ -182,8 +200,10 @@ def extend_driver(driver):
182
200
  driver.is_text_visible = DM.is_text_visible
183
201
  driver.is_exact_text_visible = DM.is_exact_text_visible
184
202
  driver.is_attribute_present = DM.is_attribute_present
185
- driver.get_text = DM.get_text
203
+ driver.is_non_empty_text_visible = DM.is_non_empty_text_visible
204
+ driver.is_online = DM.is_online
186
205
  driver.js_click = DM.js_click
206
+ driver.get_text = DM.get_text
187
207
  driver.get_active_element_css = DM.get_active_element_css
188
208
  driver.get_locale_code = DM.get_locale_code
189
209
  driver.get_origin = DM.get_origin
@@ -195,6 +215,12 @@ def extend_driver(driver):
195
215
  driver.get_attribute = DM.get_attribute
196
216
  driver.get_page_source = DM.get_page_source
197
217
  driver.get_title = DM.get_title
218
+ driver.switch_to_default_window = DM.switch_to_default_window
219
+ driver.switch_to_newest_window = DM.switch_to_newest_window
220
+ driver.open_new_window = DM.open_new_window
221
+ driver.open_new_tab = DM.open_new_tab
222
+ driver.switch_to_window = DM.switch_to_window
223
+ driver.switch_to_tab = DM.switch_to_tab
198
224
  driver.switch_to_frame = DM.switch_to_frame
199
225
  if hasattr(driver, "proxy"):
200
226
  driver.set_wire_proxy = DM.set_wire_proxy
@@ -409,7 +435,7 @@ def uc_open(driver, url):
409
435
  if (url.startswith("http:") or url.startswith("https:")):
410
436
  with driver:
411
437
  script = 'window.location.href = "%s";' % url
412
- js_utils.call_me_later(driver, script, 33)
438
+ js_utils.call_me_later(driver, script, 5)
413
439
  else:
414
440
  driver.default_get(url) # The original one
415
441
  return None
@@ -440,22 +466,28 @@ def uc_open_with_reconnect(driver, url, reconnect_time=None):
440
466
  url = "https://" + url
441
467
  if (url.startswith("http:") or url.startswith("https:")):
442
468
  script = 'window.open("%s","_blank");' % url
443
- js_utils.call_me_later(driver, script, 3)
469
+ js_utils.call_me_later(driver, script, 4)
444
470
  time.sleep(0.007)
445
471
  driver.close()
446
472
  if reconnect_time == "disconnect":
447
473
  driver.disconnect()
448
- time.sleep(0.007)
474
+ time.sleep(0.008)
449
475
  else:
450
476
  driver.reconnect(reconnect_time)
451
- driver.switch_to.window(driver.window_handles[-1])
477
+ time.sleep(0.004)
478
+ try:
479
+ driver.switch_to.window(driver.window_handles[-1])
480
+ except InvalidSessionIdException:
481
+ time.sleep(0.05)
482
+ driver.switch_to.window(driver.window_handles[-1])
452
483
  else:
453
484
  driver.default_get(url) # The original one
454
485
  return None
455
486
 
456
487
 
457
- def uc_open_with_disconnect(driver, url):
488
+ def uc_open_with_disconnect(driver, url, timeout=None):
458
489
  """Open a url and disconnect chromedriver.
490
+ Then waits for the duration of the timeout.
459
491
  Note: You can't perform Selenium actions again
460
492
  until after you've called driver.connect()."""
461
493
  if url.startswith("//"):
@@ -464,11 +496,16 @@ def uc_open_with_disconnect(driver, url):
464
496
  url = "https://" + url
465
497
  if (url.startswith("http:") or url.startswith("https:")):
466
498
  script = 'window.open("%s","_blank");' % url
467
- js_utils.call_me_later(driver, script, 3)
499
+ js_utils.call_me_later(driver, script, 4)
468
500
  time.sleep(0.007)
469
501
  driver.close()
470
502
  driver.disconnect()
471
- time.sleep(0.007)
503
+ min_timeout = 0.008
504
+ if timeout and not str(timeout).replace(".", "", 1).isdigit():
505
+ timeout = min_timeout
506
+ if not timeout or timeout < min_timeout:
507
+ timeout = min_timeout
508
+ time.sleep(timeout)
472
509
  else:
473
510
  driver.default_get(url) # The original one
474
511
  return None
@@ -490,7 +527,7 @@ def uc_click(
490
527
  pass
491
528
  element = driver.wait_for_selector(selector, by=by, timeout=timeout)
492
529
  tag_name = element.tag_name
493
- if not tag_name == "span": # Element must be "visible"
530
+ if not tag_name == "span" and not tag_name == "input": # Must be "visible"
494
531
  element = driver.wait_for_element(selector, by=by, timeout=timeout)
495
532
  try:
496
533
  element.uc_click(
@@ -509,7 +546,143 @@ def uc_click(
509
546
  driver.reconnect(reconnect_time)
510
547
 
511
548
 
512
- def uc_switch_to_frame(driver, frame, reconnect_time=None):
549
+ def install_pyautogui_if_missing():
550
+ pip_find_lock = fasteners.InterProcessLock(
551
+ constants.PipInstall.FINDLOCK
552
+ )
553
+ with pip_find_lock: # Prevent issues with multiple processes
554
+ try:
555
+ import pyautogui
556
+ try:
557
+ use_pyautogui_ver = constants.PyAutoGUI.VER
558
+ if pyautogui.__version__ != use_pyautogui_ver:
559
+ shared_utils.pip_install(
560
+ "pyautogui", version=use_pyautogui_ver
561
+ )
562
+ del pyautogui
563
+ except Exception:
564
+ pass
565
+ except Exception:
566
+ print("\nPyAutoGUI required! Installing now...")
567
+ shared_utils.pip_install(
568
+ "pyautogui", version=constants.PyAutoGUI.VER
569
+ )
570
+
571
+
572
+ def get_configured_pyautogui(pyautogui_copy):
573
+ if (
574
+ IS_LINUX
575
+ and hasattr(pyautogui_copy, "_pyautogui_x11")
576
+ and "DISPLAY" in os.environ.keys()
577
+ ):
578
+ if (
579
+ hasattr(sb_config, "_pyautogui_x11_display")
580
+ and sb_config._pyautogui_x11_display
581
+ and hasattr(pyautogui_copy._pyautogui_x11, "_display")
582
+ and (
583
+ sb_config._pyautogui_x11_display
584
+ == pyautogui_copy._pyautogui_x11._display
585
+ )
586
+ ):
587
+ pass
588
+ else:
589
+ import Xlib.display
590
+ pyautogui_copy._pyautogui_x11._display = (
591
+ Xlib.display.Display(os.environ['DISPLAY'])
592
+ )
593
+ sb_config._pyautogui_x11_display = (
594
+ pyautogui_copy._pyautogui_x11._display
595
+ )
596
+ return pyautogui_copy
597
+
598
+
599
+ def uc_gui_press_key(driver, key):
600
+ install_pyautogui_if_missing()
601
+ import pyautogui
602
+ pyautogui = get_configured_pyautogui(pyautogui)
603
+ gui_lock = fasteners.InterProcessLock(
604
+ constants.MultiBrowser.PYAUTOGUILOCK
605
+ )
606
+ with gui_lock:
607
+ pyautogui.press(key)
608
+
609
+
610
+ def uc_gui_press_keys(driver, keys):
611
+ install_pyautogui_if_missing()
612
+ import pyautogui
613
+ pyautogui = get_configured_pyautogui(pyautogui)
614
+ gui_lock = fasteners.InterProcessLock(
615
+ constants.MultiBrowser.PYAUTOGUILOCK
616
+ )
617
+ with gui_lock:
618
+ for key in keys:
619
+ pyautogui.press(key)
620
+
621
+
622
+ def uc_gui_write(driver, text):
623
+ install_pyautogui_if_missing()
624
+ import pyautogui
625
+ pyautogui = get_configured_pyautogui(pyautogui)
626
+ gui_lock = fasteners.InterProcessLock(
627
+ constants.MultiBrowser.PYAUTOGUILOCK
628
+ )
629
+ with gui_lock:
630
+ pyautogui.write(text)
631
+
632
+
633
+ def uc_gui_handle_cf(driver, frame="iframe"):
634
+ source = driver.get_page_source()
635
+ if (
636
+ "//challenges.cloudflare.com" not in source
637
+ and 'aria-label="Cloudflare"' not in source
638
+ ):
639
+ return
640
+ install_pyautogui_if_missing()
641
+ import pyautogui
642
+ pyautogui = get_configured_pyautogui(pyautogui)
643
+ gui_lock = fasteners.InterProcessLock(
644
+ constants.MultiBrowser.PYAUTOGUILOCK
645
+ )
646
+ with gui_lock: # Prevent issues with multiple processes
647
+ needs_switch = False
648
+ is_in_frame = js_utils.is_in_frame(driver)
649
+ if is_in_frame and driver.is_element_present("#challenge-stage"):
650
+ driver.switch_to.parent_frame()
651
+ needs_switch = True
652
+ is_in_frame = js_utils.is_in_frame(driver)
653
+ if not is_in_frame:
654
+ # Make sure the window is on top
655
+ page_actions.switch_to_window(
656
+ driver,
657
+ driver.current_window_handle,
658
+ timeout=settings.SMALL_TIMEOUT,
659
+ )
660
+ if not is_in_frame or needs_switch:
661
+ # Currently not in frame (or nested frame outside CF one)
662
+ try:
663
+ driver.switch_to_frame(frame)
664
+ except Exception:
665
+ if driver.is_element_present("iframe"):
666
+ driver.switch_to_frame("iframe")
667
+ else:
668
+ return
669
+ try:
670
+ driver.execute_script('document.querySelector("input").focus()')
671
+ except Exception:
672
+ try:
673
+ driver.switch_to.default_content()
674
+ except Exception:
675
+ return
676
+ driver.disconnect()
677
+ try:
678
+ pyautogui.press(" ")
679
+ except Exception:
680
+ pass
681
+ reconnect_time = (float(constants.UC.RECONNECT_TIME) / 2.0) + 0.5
682
+ driver.reconnect(reconnect_time)
683
+
684
+
685
+ def uc_switch_to_frame(driver, frame="iframe", reconnect_time=None):
513
686
  from selenium.webdriver.remote.webelement import WebElement
514
687
  if isinstance(frame, WebElement):
515
688
  if not reconnect_time:
@@ -847,7 +1020,7 @@ def _set_chrome_options(
847
1020
  prefs["download.prompt_for_download"] = False
848
1021
  prefs["credentials_enable_service"] = False
849
1022
  prefs["local_discovery.notifications_enabled"] = False
850
- prefs["safebrowsing.enabled"] = False
1023
+ prefs["safebrowsing.enabled"] = True
851
1024
  prefs["safebrowsing.disable_download_protection"] = True
852
1025
  prefs["omnibox-max-zero-suggest-matches"] = 0
853
1026
  prefs["omnibox-use-existing-autocomplete-client"] = 0
@@ -1145,6 +1318,7 @@ def _set_chrome_options(
1145
1318
  chrome_options.add_argument("--auto-open-devtools-for-tabs")
1146
1319
  if user_agent:
1147
1320
  chrome_options.add_argument("--user-agent=%s" % user_agent)
1321
+ chrome_options.add_argument("--safebrowsing-disable-download-protection")
1148
1322
  chrome_options.add_argument("--disable-browser-side-navigation")
1149
1323
  chrome_options.add_argument("--disable-save-password-bubble")
1150
1324
  chrome_options.add_argument("--disable-single-click-autofill")
@@ -1183,10 +1357,9 @@ def _set_chrome_options(
1183
1357
  included_disabled_features.append("DownloadBubbleV2")
1184
1358
  included_disabled_features.append("InsecureDownloadWarnings")
1185
1359
  included_disabled_features.append("InterestFeedContentSuggestions")
1186
- if user_data_dir:
1187
- included_disabled_features.append("PrivacySandboxSettings4")
1188
- if not is_using_uc(undetectable, browser_name) or user_data_dir:
1189
- included_disabled_features.append("SidePanelPinning")
1360
+ included_disabled_features.append("PrivacySandboxSettings4")
1361
+ included_disabled_features.append("SidePanelPinning")
1362
+ included_disabled_features.append("UserAgentClientHint")
1190
1363
  for item in extra_disabled_features:
1191
1364
  if item not in included_disabled_features:
1192
1365
  included_disabled_features.append(item)
@@ -1374,7 +1547,7 @@ def _set_firefox_options(
1374
1547
  f_pref_value = False
1375
1548
  elif f_pref_value.isdigit():
1376
1549
  f_pref_value = int(f_pref_value)
1377
- elif f_pref_value.isdecimal():
1550
+ elif f_pref_value.replace(".", "", 1).isdigit():
1378
1551
  f_pref_value = float(f_pref_value)
1379
1552
  else:
1380
1553
  pass # keep as string
@@ -2438,7 +2611,7 @@ def get_local_driver(
2438
2611
  "credentials_enable_service": False,
2439
2612
  "local_discovery.notifications_enabled": False,
2440
2613
  "safebrowsing.disable_download_protection": True,
2441
- "safebrowsing.enabled": False,
2614
+ "safebrowsing.enabled": True,
2442
2615
  "omnibox-max-zero-suggest-matches": 0,
2443
2616
  "omnibox-use-existing-autocomplete-client": 0,
2444
2617
  "omnibox-trending-zero-prefix-suggestions-on-ntp": 0,
@@ -2707,6 +2880,7 @@ def get_local_driver(
2707
2880
  edge_options.add_argument(
2708
2881
  "--disable-autofill-keyboard-accessory-view[8]"
2709
2882
  )
2883
+ edge_options.add_argument("--safebrowsing-disable-download-protection")
2710
2884
  edge_options.add_argument("--disable-browser-side-navigation")
2711
2885
  edge_options.add_argument("--disable-translate")
2712
2886
  if not enable_ws:
@@ -2848,10 +3022,9 @@ def get_local_driver(
2848
3022
  included_disabled_features.append("OptimizationGuideModelDownloading")
2849
3023
  included_disabled_features.append("InsecureDownloadWarnings")
2850
3024
  included_disabled_features.append("InterestFeedContentSuggestions")
2851
- if user_data_dir:
2852
- included_disabled_features.append("PrivacySandboxSettings4")
2853
- if not is_using_uc(undetectable, browser_name) or user_data_dir:
2854
- included_disabled_features.append("SidePanelPinning")
3025
+ included_disabled_features.append("PrivacySandboxSettings4")
3026
+ included_disabled_features.append("SidePanelPinning")
3027
+ included_disabled_features.append("UserAgentClientHint")
2855
3028
  for item in extra_disabled_features:
2856
3029
  if item not in included_disabled_features:
2857
3030
  included_disabled_features.append(item)
@@ -3822,6 +3995,26 @@ def get_local_driver(
3822
3995
  driver.uc_click = lambda *args, **kwargs: uc_click(
3823
3996
  driver, *args, **kwargs
3824
3997
  )
3998
+ driver.uc_gui_press_key = (
3999
+ lambda *args, **kwargs: uc_gui_press_key(
4000
+ driver, *args, **kwargs
4001
+ )
4002
+ )
4003
+ driver.uc_gui_press_keys = (
4004
+ lambda *args, **kwargs: uc_gui_press_keys(
4005
+ driver, *args, **kwargs
4006
+ )
4007
+ )
4008
+ driver.uc_gui_write = (
4009
+ lambda *args, **kwargs: uc_gui_write(
4010
+ driver, *args, **kwargs
4011
+ )
4012
+ )
4013
+ driver.uc_gui_handle_cf = (
4014
+ lambda *args, **kwargs: uc_gui_handle_cf(
4015
+ driver, *args, **kwargs
4016
+ )
4017
+ )
3825
4018
  driver.uc_switch_to_frame = (
3826
4019
  lambda *args, **kwargs: uc_switch_to_frame(
3827
4020
  driver, *args, **kwargs
@@ -94,6 +94,16 @@ class DriverMethods():
94
94
  def assert_exact_text(self, *args, **kwargs):
95
95
  page_actions.assert_exact_text(self.driver, *args, **kwargs)
96
96
 
97
+ def assert_non_empty_text(self, *args, **kwargs):
98
+ return page_actions.assert_non_empty_text(
99
+ self.driver, *args, **kwargs
100
+ )
101
+
102
+ def assert_text_not_visible(self, *args, **kwargs):
103
+ return page_actions.assert_text_not_visible(
104
+ self.driver, *args, **kwargs
105
+ )
106
+
97
107
  def wait_for_element(self, *args, **kwargs):
98
108
  return page_actions.wait_for_element(self.driver, *args, **kwargs)
99
109
 
@@ -112,6 +122,16 @@ class DriverMethods():
112
122
  def wait_for_exact_text(self, *args, **kwargs):
113
123
  return page_actions.wait_for_exact_text(self.driver, *args, **kwargs)
114
124
 
125
+ def wait_for_non_empty_text(self, *args, **kwargs):
126
+ return page_actions.wait_for_non_empty_text(
127
+ self.driver, *args, **kwargs
128
+ )
129
+
130
+ def wait_for_text_not_visible(self, *args, **kwargs):
131
+ return page_actions.wait_for_text_not_visible(
132
+ self.driver, *args, **kwargs
133
+ )
134
+
115
135
  def wait_for_and_accept_alert(self, *args, **kwargs):
116
136
  return page_actions.wait_for_and_accept_alert(
117
137
  self.driver, *args, **kwargs
@@ -134,14 +154,22 @@ class DriverMethods():
134
154
  def is_exact_text_visible(self, *args, **kwargs):
135
155
  return page_actions.is_exact_text_visible(self.driver, *args, **kwargs)
136
156
 
137
- def get_text(self, *args, **kwargs):
138
- return page_actions.get_text(self.driver, *args, **kwargs)
157
+ def is_attribute_present(self, *args, **kwargs):
158
+ return page_actions.has_attribute(self.driver, *args, **kwargs)
159
+
160
+ def is_non_empty_text_visible(self, *args, **kwargs):
161
+ return page_actions.is_non_empty_text_visible(
162
+ self.driver, *args, **kwargs
163
+ )
164
+
165
+ def is_online(self):
166
+ return self.driver.execute_script("return navigator.onLine;")
139
167
 
140
168
  def js_click(self, *args, **kwargs):
141
169
  return page_actions.js_click(self.driver, *args, **kwargs)
142
170
 
143
- def is_attribute_present(self, *args, **kwargs):
144
- return page_actions.has_attribute(self.driver, *args, **kwargs)
171
+ def get_text(self, *args, **kwargs):
172
+ return page_actions.get_text(self.driver, *args, **kwargs)
145
173
 
146
174
  def get_active_element_css(self, *args, **kwargs):
147
175
  return js_utils.get_active_element_css(self.driver, *args, **kwargs)
@@ -182,7 +210,32 @@ class DriverMethods():
182
210
  if self.is_element_visible(selector, by=by):
183
211
  self.highlight(selector, by=by, loops=loops, scroll=scroll)
184
212
 
185
- def switch_to_frame(self, frame):
213
+ def switch_to_default_window(self):
214
+ self.driver.switch_to.window(self.driver.window_handles[0])
215
+
216
+ def switch_to_newest_window(self):
217
+ self.driver.switch_to.window(self.driver.window_handles[-1])
218
+
219
+ def open_new_window(self, switch_to=True):
220
+ if switch_to:
221
+ try:
222
+ self.driver.switch_to.new_window("tab")
223
+ except Exception:
224
+ self.driver.execute_script("window.open('');")
225
+ self.switch_to_newest_window()
226
+ else:
227
+ self.driver.execute_script("window.open('');")
228
+
229
+ def open_new_tab(self, switch_to=True):
230
+ self.open_new_window(switch_to=switch_to)
231
+
232
+ def switch_to_window(self, *args, **kwargs):
233
+ page_actions.switch_to_window(self.driver, *args, **kwargs)
234
+
235
+ def switch_to_tab(self, *args, **kwargs):
236
+ self.switch_to_window(*args, **kwargs)
237
+
238
+ def switch_to_frame(self, frame="iframe"):
186
239
  if isinstance(frame, WebElement):
187
240
  self.driver.switch_to.frame(frame)
188
241
  else:
Binary file