mirror of
https://github.com/User0332/rewards-farmer.git
synced 2026-09-16 09:31:36 +00:00
address review: scroll only when needed and smoothly, tighten the visual search needle
scrollIntoView re-centered every element unconditionally and instantly, which is the page jump between the daily set and explore on bing. The pointer move now scrolls only when the element is actually outside the viewport, smoothly, and polls the rect until the async scroll settles before computing the path. Visual search matches the full 'visual search streak' label. Plain 'visual search' can also hit a dashboard element that goes stale mid-interaction, and the guessed 'image search' needle is gone.
This commit is contained in:
@@ -22,7 +22,9 @@ class Labels:
|
||||
CLAIM = "claim" # exact label preferred, substring as fallback
|
||||
DAILY_SET_STREAK = "daily set streak"
|
||||
CARD_COMPLETED = "completed"
|
||||
VISUAL_SEARCH = ("visual search", "image search")
|
||||
# The full streak label on purpose: plain "visual search" also matches an
|
||||
# element on the dashboard, which can go stale mid-interaction.
|
||||
VISUAL_SEARCH_STREAK = "visual search streak"
|
||||
|
||||
|
||||
class ElementSelectionUtils:
|
||||
@@ -175,14 +177,11 @@ class ElementSelectionUtils:
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def get_open_visual_search_sidebar(self):
|
||||
for needle in Labels.VISUAL_SEARCH:
|
||||
try:
|
||||
return self._button_containing(needle)
|
||||
return self._button_containing(Labels.VISUAL_SEARCH_STREAK)
|
||||
except NoSuchElementException:
|
||||
continue
|
||||
|
||||
# Not every layout ships this entry point, and where it does the label is
|
||||
# not confirmed, so fall back to the original position in streaks.
|
||||
# Not every layout ships this entry point. Where it does but the
|
||||
# label differs, fall back to the original position in streaks.
|
||||
return self._streaks_button(5)
|
||||
|
||||
def get_search_now_link_from_visual_search_sidebar(self):
|
||||
|
||||
+32
-3
@@ -314,12 +314,41 @@ class MouseUtils:
|
||||
def move_to_element(self, element: WebElement, visualize: bool=True):
|
||||
# The pointer is moved to viewport coordinates, so an element below the
|
||||
# fold yields a target outside the window and the driver rejects the move
|
||||
# with MoveTargetOutOfBoundsException. Bring it into view first.
|
||||
# with MoveTargetOutOfBoundsException. Bring it into view first, but only
|
||||
# when it actually is out of view: unconditionally re-centering visible
|
||||
# elements is what caused the page to jump between tasks. When scrolling
|
||||
# is needed it is smooth, and since smooth scrolling is asynchronous, the
|
||||
# rect is polled until it stops moving before the path is computed.
|
||||
fully_in_view = self.driver.execute_script("""
|
||||
var r = arguments[0].getBoundingClientRect();
|
||||
return (
|
||||
r.top >= 0 && r.left >= 0 &&
|
||||
r.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
|
||||
r.right <= (window.innerWidth || document.documentElement.clientWidth)
|
||||
);
|
||||
""", element)
|
||||
|
||||
if not fully_in_view:
|
||||
self.driver.execute_script(
|
||||
"arguments[0].scrollIntoView({block: 'center', inline: 'center'});",
|
||||
"arguments[0].scrollIntoView({block: 'center', inline: 'center', behavior: 'smooth'});",
|
||||
element
|
||||
)
|
||||
time.sleep(0.4)
|
||||
|
||||
last_rect = None
|
||||
|
||||
for _ in range(20):
|
||||
time.sleep(0.15)
|
||||
|
||||
rect = self.driver.execute_script(
|
||||
"var r = arguments[0].getBoundingClientRect();"
|
||||
"return [Math.round(r.top), Math.round(r.left)];",
|
||||
element
|
||||
)
|
||||
|
||||
if rect == last_rect:
|
||||
break
|
||||
|
||||
last_rect = rect
|
||||
|
||||
current_mouse_position = self.get_current_mouse_position()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user