seleniumbase 4.33.5__py3-none-any.whl → 4.33.7__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
@@ -268,6 +268,7 @@ class CDPMethods():
268
268
  if number < 0:
269
269
  number = 0
270
270
  element = elements[number]
271
+ element.scroll_into_view()
271
272
  element.click()
272
273
 
273
274
  def click_nth_visible_element(self, selector, number):
@@ -284,6 +285,7 @@ class CDPMethods():
284
285
  if number < 0:
285
286
  number = 0
286
287
  element = elements[number]
288
+ element.scroll_into_view()
287
289
  element.click()
288
290
 
289
291
  def click_link(self, link_text):
@@ -311,6 +313,13 @@ class CDPMethods():
311
313
  return result
312
314
 
313
315
  def __flash(self, element, *args, **kwargs):
316
+ element.scroll_into_view()
317
+ if len(args) < 3 and "x_offset" not in kwargs:
318
+ x_offset = self.__get_x_scroll_offset()
319
+ kwargs["x_offset"] = x_offset
320
+ if len(args) < 3 and "y_offset" not in kwargs:
321
+ y_offset = self.__get_y_scroll_offset()
322
+ kwargs["y_offset"] = y_offset
314
323
  return (
315
324
  self.loop.run_until_complete(
316
325
  element.flash_async(*args, **kwargs)
@@ -382,9 +391,9 @@ class CDPMethods():
382
391
  )
383
392
 
384
393
  def __scroll_into_view(self, element):
385
- return (
386
- self.loop.run_until_complete(element.scroll_into_view_async())
387
- )
394
+ self.loop.run_until_complete(element.scroll_into_view_async())
395
+ self.__add_light_pause()
396
+ return None
388
397
 
389
398
  def __select_option(self, element):
390
399
  return (
@@ -431,6 +440,18 @@ class CDPMethods():
431
440
  self.loop.run_until_complete(element.get_js_attributes_async())
432
441
  )
433
442
 
443
+ def __get_x_scroll_offset(self):
444
+ x_scroll_offset = self.loop.run_until_complete(
445
+ self.page.evaluate("window.pageXOffset")
446
+ )
447
+ return x_scroll_offset or 0
448
+
449
+ def __get_y_scroll_offset(self):
450
+ y_scroll_offset = self.loop.run_until_complete(
451
+ self.page.evaluate("window.pageYOffset")
452
+ )
453
+ return y_scroll_offset or 0
454
+
434
455
  def tile_windows(self, windows=None, max_columns=0):
435
456
  """Tile windows and return the grid of tiled windows."""
436
457
  driver = self.driver
@@ -504,7 +525,7 @@ class CDPMethods():
504
525
  def click(self, selector, timeout=settings.SMALL_TIMEOUT):
505
526
  self.__slow_mode_pause_if_set()
506
527
  element = self.find_element(selector, timeout=timeout)
507
- self.__add_light_pause()
528
+ element.scroll_into_view()
508
529
  element.click()
509
530
  self.__slow_mode_pause_if_set()
510
531
  self.loop.run_until_complete(self.page.wait())
@@ -518,7 +539,9 @@ class CDPMethods():
518
539
 
519
540
  def click_if_visible(self, selector):
520
541
  if self.is_element_visible(selector):
521
- self.find_element(selector).click()
542
+ element = self.find_element(selector)
543
+ element.scroll_into_view()
544
+ element.click()
522
545
  self.__slow_mode_pause_if_set()
523
546
  self.loop.run_until_complete(self.page.wait())
524
547
 
@@ -545,9 +568,10 @@ class CDPMethods():
545
568
  except Exception:
546
569
  continue
547
570
  if (width != 0 or height != 0):
571
+ element.scroll_into_view()
548
572
  element.click()
549
573
  click_count += 1
550
- time.sleep(0.044)
574
+ time.sleep(0.042)
551
575
  self.__slow_mode_pause_if_set()
552
576
  self.loop.run_until_complete(self.page.wait())
553
577
  except Exception:
@@ -557,7 +581,7 @@ class CDPMethods():
557
581
  """(Attempt simulating a mouse click)"""
558
582
  self.__slow_mode_pause_if_set()
559
583
  element = self.find_element(selector, timeout=timeout)
560
- self.__add_light_pause()
584
+ element.scroll_into_view()
561
585
  element.mouse_click()
562
586
  self.__slow_mode_pause_if_set()
563
587
  self.loop.run_until_complete(self.page.wait())
@@ -579,6 +603,7 @@ class CDPMethods():
579
603
 
580
604
  def select_option_by_text(self, dropdown_selector, option):
581
605
  element = self.find_element(dropdown_selector)
606
+ element.scroll_into_view()
582
607
  options = element.query_selector_all("option")
583
608
  for found_option in options:
584
609
  if found_option.text.strip() == option.strip():
@@ -599,7 +624,10 @@ class CDPMethods():
599
624
  """Paint a quickly-vanishing dot over an element."""
600
625
  selector = self.__convert_to_css_if_xpath(selector)
601
626
  element = self.find_element(selector)
602
- element.flash(duration=duration, color=color)
627
+ element.scroll_into_view()
628
+ x_offset = self.__get_x_scroll_offset()
629
+ y_offset = self.__get_y_scroll_offset()
630
+ element.flash(duration, color, x_offset, y_offset)
603
631
  if pause and isinstance(pause, (int, float)):
604
632
  time.sleep(pause)
605
633
 
@@ -607,17 +635,22 @@ class CDPMethods():
607
635
  """Highlight an element with multi-colors."""
608
636
  selector = self.__convert_to_css_if_xpath(selector)
609
637
  element = self.find_element(selector)
610
- element.flash(0.46, "44CC88")
638
+ element.scroll_into_view()
639
+ x_offset = self.__get_x_scroll_offset()
640
+ y_offset = self.__get_y_scroll_offset()
641
+ element.flash(0.46, "44CC88", x_offset, y_offset)
611
642
  time.sleep(0.15)
612
- element.flash(0.42, "8844CC")
643
+ element.flash(0.42, "8844CC", x_offset, y_offset)
613
644
  time.sleep(0.15)
614
- element.flash(0.38, "CC8844")
645
+ element.flash(0.38, "CC8844", x_offset, y_offset)
615
646
  time.sleep(0.15)
616
- element.flash(0.30, "44CC88")
647
+ element.flash(0.30, "44CC88", x_offset, y_offset)
617
648
  time.sleep(0.30)
618
649
 
619
650
  def focus(self, selector):
620
- self.find_element(selector).focus()
651
+ element = self.find_element(selector)
652
+ element.scroll_into_view()
653
+ element.focus()
621
654
 
622
655
  def highlight_overlay(self, selector):
623
656
  self.find_element(selector).highlight_overlay()
@@ -646,7 +679,7 @@ class CDPMethods():
646
679
  def send_keys(self, selector, text, timeout=settings.SMALL_TIMEOUT):
647
680
  self.__slow_mode_pause_if_set()
648
681
  element = self.select(selector, timeout=timeout)
649
- self.__add_light_pause()
682
+ element.scroll_into_view()
650
683
  if text.endswith("\n") or text.endswith("\r"):
651
684
  text = text[:-1] + "\r\n"
652
685
  element.send_keys(text)
@@ -657,7 +690,7 @@ class CDPMethods():
657
690
  """Similar to send_keys(), but presses keys at human speed."""
658
691
  self.__slow_mode_pause_if_set()
659
692
  element = self.select(selector, timeout=timeout)
660
- self.__add_light_pause()
693
+ element.scroll_into_view()
661
694
  submit = False
662
695
  if text.endswith("\n") or text.endswith("\r"):
663
696
  submit = True
@@ -675,7 +708,7 @@ class CDPMethods():
675
708
  """Similar to send_keys(), but clears the text field first."""
676
709
  self.__slow_mode_pause_if_set()
677
710
  element = self.select(selector, timeout=timeout)
678
- self.__add_light_pause()
711
+ element.scroll_into_view()
679
712
  with suppress(Exception):
680
713
  element.clear_input()
681
714
  if text.endswith("\n") or text.endswith("\r"):
@@ -688,8 +721,8 @@ class CDPMethods():
688
721
  """Similar to send_keys(), but clears the text field first."""
689
722
  self.__slow_mode_pause_if_set()
690
723
  selector = self.__convert_to_css_if_xpath(selector)
691
- self.select(selector, timeout=timeout)
692
- self.__add_light_pause()
724
+ element = self.select(selector, timeout=timeout)
725
+ element.scroll_into_view()
693
726
  press_enter = False
694
727
  if text.endswith("\n"):
695
728
  text = text[:-1]
@@ -1019,6 +1052,10 @@ class CDPMethods():
1019
1052
  with suppress(Exception):
1020
1053
  self.loop.run_until_complete(self.page.evaluate(js_code))
1021
1054
 
1055
+ def __make_sure_pyautogui_lock_is_writable(self):
1056
+ with suppress(Exception):
1057
+ shared_utils.make_writable(constants.MultiBrowser.PYAUTOGUILOCK)
1058
+
1022
1059
  def __verify_pyautogui_has_a_headed_browser(self):
1023
1060
  """PyAutoGUI requires a headed browser so that it can
1024
1061
  focus on the correct element when performing actions."""
@@ -1039,6 +1076,8 @@ class CDPMethods():
1039
1076
  constants.PipInstall.FINDLOCK
1040
1077
  )
1041
1078
  with pip_find_lock: # Prevent issues with multiple processes
1079
+ with suppress(Exception):
1080
+ shared_utils.make_writable(constants.PipInstall.FINDLOCK)
1042
1081
  try:
1043
1082
  import pyautogui
1044
1083
  with suppress(Exception):
@@ -1124,6 +1163,7 @@ class CDPMethods():
1124
1163
  constants.MultiBrowser.PYAUTOGUILOCK
1125
1164
  )
1126
1165
  with gui_lock:
1166
+ self.__make_sure_pyautogui_lock_is_writable()
1127
1167
  pyautogui.press(key)
1128
1168
  time.sleep(0.044)
1129
1169
  self.__slow_mode_pause_if_set()
@@ -1137,6 +1177,7 @@ class CDPMethods():
1137
1177
  constants.MultiBrowser.PYAUTOGUILOCK
1138
1178
  )
1139
1179
  with gui_lock:
1180
+ self.__make_sure_pyautogui_lock_is_writable()
1140
1181
  for key in keys:
1141
1182
  pyautogui.press(key)
1142
1183
  time.sleep(0.044)
@@ -1151,6 +1192,7 @@ class CDPMethods():
1151
1192
  constants.MultiBrowser.PYAUTOGUILOCK
1152
1193
  )
1153
1194
  with gui_lock:
1195
+ self.__make_sure_pyautogui_lock_is_writable()
1154
1196
  pyautogui.write(text)
1155
1197
  self.__slow_mode_pause_if_set()
1156
1198
  self.loop.run_until_complete(self.page.wait())
@@ -1171,6 +1213,7 @@ class CDPMethods():
1171
1213
  constants.MultiBrowser.PYAUTOGUILOCK
1172
1214
  )
1173
1215
  with gui_lock: # Prevent issues with multiple processes
1216
+ self.__make_sure_pyautogui_lock_is_writable()
1174
1217
  pyautogui.moveTo(x, y, timeframe, pyautogui.easeOutQuad)
1175
1218
  if timeframe >= 0.25:
1176
1219
  time.sleep(0.056) # Wait if moving at human-speed
@@ -1191,6 +1234,7 @@ class CDPMethods():
1191
1234
  constants.MultiBrowser.PYAUTOGUILOCK
1192
1235
  )
1193
1236
  with gui_lock: # Prevent issues with multiple processes
1237
+ self.__make_sure_pyautogui_lock_is_writable()
1194
1238
  self.__install_pyautogui_if_missing()
1195
1239
  import pyautogui
1196
1240
  pyautogui = self.__get_configured_pyautogui(pyautogui)
@@ -1408,6 +1452,7 @@ class CDPMethods():
1408
1452
  constants.MultiBrowser.PYAUTOGUILOCK
1409
1453
  )
1410
1454
  with gui_lock:
1455
+ self.__make_sure_pyautogui_lock_is_writable()
1411
1456
  self.bring_active_window_to_front()
1412
1457
  self.gui_hover_element(hover_selector)
1413
1458
  time.sleep(0.15)
@@ -1643,17 +1688,24 @@ class CDPMethods():
1643
1688
  raise Exception(error % (expected, actual))
1644
1689
 
1645
1690
  def assert_text(
1646
- self, text, selector="html", timeout=settings.SMALL_TIMEOUT
1691
+ self, text, selector="body", timeout=settings.SMALL_TIMEOUT
1647
1692
  ):
1693
+ start_ms = time.time() * 1000.0
1694
+ stop_ms = start_ms + (timeout * 1000.0)
1648
1695
  text = text.strip()
1649
1696
  element = None
1650
1697
  try:
1651
1698
  element = self.find_element(selector, timeout=timeout)
1652
1699
  except Exception:
1653
1700
  raise Exception("Element {%s} not found!" % selector)
1654
- for i in range(30):
1701
+ for i in range(int(timeout * 10)):
1702
+ with suppress(Exception):
1703
+ element = self.find_element(selector, timeout=0.1)
1655
1704
  if text in element.text_all:
1656
1705
  return True
1706
+ now_ms = time.time() * 1000.0
1707
+ if now_ms >= stop_ms:
1708
+ break
1657
1709
  time.sleep(0.1)
1658
1710
  raise Exception(
1659
1711
  "Text {%s} not found in {%s}! Actual text: {%s}"
@@ -1661,20 +1713,27 @@ class CDPMethods():
1661
1713
  )
1662
1714
 
1663
1715
  def assert_exact_text(
1664
- self, text, selector="html", timeout=settings.SMALL_TIMEOUT
1716
+ self, text, selector="body", timeout=settings.SMALL_TIMEOUT
1665
1717
  ):
1718
+ start_ms = time.time() * 1000.0
1719
+ stop_ms = start_ms + (timeout * 1000.0)
1666
1720
  text = text.strip()
1667
1721
  element = None
1668
1722
  try:
1669
1723
  element = self.select(selector, timeout=timeout)
1670
1724
  except Exception:
1671
1725
  raise Exception("Element {%s} not found!" % selector)
1672
- for i in range(30):
1726
+ for i in range(int(timeout * 10)):
1727
+ with suppress(Exception):
1728
+ element = self.select(selector, timeout=0.1)
1673
1729
  if (
1674
1730
  self.is_element_visible(selector)
1675
1731
  and text.strip() == element.text_all.strip()
1676
1732
  ):
1677
1733
  return True
1734
+ now_ms = time.time() * 1000.0
1735
+ if now_ms >= stop_ms:
1736
+ break
1678
1737
  time.sleep(0.1)
1679
1738
  raise Exception(
1680
1739
  "Expected Text {%s}, is not equal to {%s} in {%s}!"
@@ -1715,26 +1774,31 @@ class CDPMethods():
1715
1774
  with suppress(Exception):
1716
1775
  self.loop.run_until_complete(self.page.evaluate(js_code))
1717
1776
  self.loop.run_until_complete(self.page.wait())
1777
+ self.__add_light_pause()
1718
1778
 
1719
1779
  def scroll_to_top(self):
1720
1780
  js_code = "window.scrollTo(0, 0);"
1721
1781
  with suppress(Exception):
1722
1782
  self.loop.run_until_complete(self.page.evaluate(js_code))
1723
1783
  self.loop.run_until_complete(self.page.wait())
1784
+ self.__add_light_pause()
1724
1785
 
1725
1786
  def scroll_to_bottom(self):
1726
1787
  js_code = "window.scrollTo(0, 10000);"
1727
1788
  with suppress(Exception):
1728
1789
  self.loop.run_until_complete(self.page.evaluate(js_code))
1729
1790
  self.loop.run_until_complete(self.page.wait())
1791
+ self.__add_light_pause()
1730
1792
 
1731
1793
  def scroll_up(self, amount=25):
1732
1794
  self.loop.run_until_complete(self.page.scroll_up(amount))
1733
1795
  self.loop.run_until_complete(self.page.wait())
1796
+ self.__add_light_pause()
1734
1797
 
1735
1798
  def scroll_down(self, amount=25):
1736
1799
  self.loop.run_until_complete(self.page.scroll_down(amount))
1737
1800
  self.loop.run_until_complete(self.page.wait())
1801
+ self.__add_light_pause()
1738
1802
 
1739
1803
  def save_screenshot(self, name, folder=None, selector=None):
1740
1804
  filename = name
@@ -1,4 +1,5 @@
1
1
  import sys
2
+ import textwrap
2
3
  from seleniumbase.fixtures import constants
3
4
 
4
5
 
@@ -116,6 +117,7 @@ def get_report_style():
116
117
  }
117
118
  </style>"""
118
119
  )
120
+ style = textwrap.dedent(style)
119
121
  Saved.report_style = style
120
122
  return style
121
123
 
@@ -132,6 +134,7 @@ def get_bt_backdrop_style():
132
134
  box-shadow: 0 0 0 88422px rgba(0, 0, 0, 0.42);
133
135
  pointer-events: auto !important;
134
136
  }"""
137
+ bt_backdrop_style = textwrap.dedent(bt_backdrop_style)
135
138
  Saved.bt_backdrop_style = bt_backdrop_style
136
139
  return bt_backdrop_style
137
140
 
@@ -150,6 +153,7 @@ def get_dt_backdrop_style():
150
153
  button.driver-prev-btn.driver-disabled {
151
154
  visibility: hidden;
152
155
  }"""
156
+ dt_backdrop_style = textwrap.dedent(dt_backdrop_style)
153
157
  Saved.dt_backdrop_style = dt_backdrop_style
154
158
  return dt_backdrop_style
155
159
 
@@ -167,6 +171,7 @@ def get_messenger_style():
167
171
  box-shadow: 2px 2px 9px 4px rgba(32, 142, 120, 0.28),
168
172
  2px 2px 9px 4px rgba(200, 240, 80, 0.34) !important;
169
173
  }""" % font_family
174
+ messenger_style = textwrap.dedent(messenger_style)
170
175
  Saved.messenger_style = messenger_style
171
176
  return messenger_style
172
177
 
@@ -181,6 +186,7 @@ def get_sh_style_test():
181
186
  scrollTo: true
182
187
  }
183
188
  });"""
189
+ sh_style_test = textwrap.dedent(sh_style_test)
184
190
  Saved.sh_style_test = sh_style_test
185
191
  return sh_style_test
186
192
 
@@ -193,6 +199,7 @@ def get_hops_backdrop_style():
193
199
  .hopscotch-bubble-container {
194
200
  font-size: 110%;
195
201
  }"""
202
+ hops_backdrop_style = textwrap.dedent(hops_backdrop_style)
196
203
  Saved.hops_backdrop_style = hops_backdrop_style
197
204
  return hops_backdrop_style
198
205
 
@@ -227,6 +234,7 @@ def get_introjs_style():
227
234
  box-sizing: content-box;
228
235
  position: absolute;
229
236
  }"""
237
+ introjs_style = textwrap.dedent(introjs_style)
230
238
  Saved.introjs_style = introjs_style
231
239
  return introjs_style
232
240
 
@@ -261,6 +269,7 @@ def get_sh_backdrop_style():
261
269
  body.shepherd-active {
262
270
  pointer-events: none !important;
263
271
  }"""
272
+ sh_backdrop_style = textwrap.dedent(sh_backdrop_style)
264
273
  Saved.sh_backdrop_style = sh_backdrop_style
265
274
  return sh_backdrop_style
266
275
 
@@ -387,5 +396,6 @@ def get_pytest_style():
387
396
  .desc.active .sort-icon {
388
397
  border-top: 8px solid #999;
389
398
  }"""
399
+ pytest_style = textwrap.dedent(pytest_style)
390
400
  Saved.pytest_style = pytest_style
391
401
  return pytest_style