mirror of
https://github.com/User0332/rewards-farmer.git
synced 2026-09-16 01:31:36 +00:00
keep the rewards tab when a task fails, and put it back on the rewards page
The cleanup after each task called close_all_other_tabs() with no arguments. That defaults `exceptions` to the currently focused handle, so when a task died with a Bing tab in focus the cleanup kept the Bing tab and closed the Rewards one. Every later task then looked for Rewards controls on a search results page and reported [SKIP] for a UI that was present and working the whole time. One failure cost the rest of the run. Measured in the container rather than reasoned about: with a Rewards tab and a Bing tab open and the Bing one focused, close_all_other_tabs() leaves ['https://www.bing.com/search?q=weather'] behind and the Rewards handle is gone. Two separate things have to hold before the next task can work, and they failed independently. The right tab has to survive, so restore_main_tab names the handle recorded at startup instead of trusting whatever happens to be focused. The surviving tab also has to be showing the right page, which the tab fix alone does not give you: run_search_batch navigates the main tab to bing.com itself, so a failure part way through that batch strands the main tab on a search page with no second tab involved at all. Navigating only happens when the step did not finish, and is skipped when the browser is already on the Rewards host, so a clean run navigates nowhere and a panel that merely failed to render does not cost a page load. Both recoveries swallow their own errors. Raising here would replace the real failure with the tidy-up's, which is why the close_all_other_tabs call was wrapped in the first place. End to end in a real browser: two tabs with the Bing one focused become one tab, the original handle, on rewards.bing.com/about (the logged out redirect), and a main tab stranded on bing.com recovers too. Fifteen unit tests cover the tab choice, the missing-main-tab fallback, the failure and skip paths, a clean run navigating nowhere, and a driver too broken to do either. Refs #63 Claude-Session: https://claude.ai/code/session_0113hp36oUBeMqG7twfuC8rE
This commit is contained in:
+67
-7
@@ -18,6 +18,8 @@ import element_selectors
|
||||
|
||||
VISUAL_SEARCH_IMAGE_PATH = os.path.abspath("visual_search.jpg")
|
||||
|
||||
REWARDS_HOME_URL = "https://rewards.bing.com/"
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -76,11 +78,16 @@ class RewardsTaskUtils:
|
||||
|
||||
self.driver.execute_cdp_cmd("Network.setExtraHTTPHeaders", {"headers": headers})
|
||||
|
||||
self.driver.get("https://rewards.bing.com/")
|
||||
self.driver.get(REWARDS_HOME_URL)
|
||||
|
||||
self.tab_utils = tab_utils.TabUtils(driver)
|
||||
self.tab_utils.ensure_focus()
|
||||
|
||||
# The tab the tasks work in. Recorded rather than looked up later,
|
||||
# because "the current tab" stops meaning this one the moment a task
|
||||
# opens a card in a new one.
|
||||
self.main_window = driver.current_window_handle
|
||||
|
||||
self.mouse = mouse_trajectory.MouseUtils(driver)
|
||||
self.keyboard = mimic_typing.KeyboardUtils(driver)
|
||||
self.elements = element_selectors.ElementSelectionUtils(driver)
|
||||
@@ -396,9 +403,57 @@ class RewardsTaskUtils:
|
||||
)
|
||||
self.wait_for_then_click(self.elements.get_clear_bing_search_query_button)
|
||||
|
||||
self.driver.get("https://rewards.bing.com/")
|
||||
self.driver.get(REWARDS_HOME_URL)
|
||||
self.tab_utils.ensure_focus()
|
||||
|
||||
def restore_main_tab(self):
|
||||
"""Close the stray tabs, keeping the one the tasks work in.
|
||||
|
||||
close_all_other_tabs with no arguments keeps whatever tab is focused
|
||||
right now. After a task that died on a Bing tab that is the Bing tab, so
|
||||
the cleanup closed the Rewards tab and kept the search results. Naming
|
||||
the tab to keep is the difference between tidying up and destroying the
|
||||
only tab the next task can use.
|
||||
|
||||
If the main tab is gone, whatever is left is better than nothing: the
|
||||
page fix below still has to run either way.
|
||||
"""
|
||||
try:
|
||||
handles = self.driver.window_handles
|
||||
|
||||
if not handles:
|
||||
return
|
||||
|
||||
keep = self.main_window if self.main_window in handles else handles[0]
|
||||
|
||||
self.tab_utils.close_all_other_tabs(exceptions=[keep])
|
||||
except Exception as exc:
|
||||
logger.warning(
|
||||
"Could not tidy the open tabs: %s", log_utils.exception_summary(exc)
|
||||
)
|
||||
|
||||
def return_to_rewards_home(self):
|
||||
"""Put the browser back on the Rewards home page.
|
||||
|
||||
Only called when a task did not finish. Navigating after every task
|
||||
would reload the page six times a run for no reason, and the tasks that
|
||||
succeed already leave the browser somewhere their successor can work
|
||||
from.
|
||||
"""
|
||||
try:
|
||||
if self.driver.current_url.startswith(REWARDS_HOME_URL):
|
||||
return
|
||||
|
||||
self.driver.get(REWARDS_HOME_URL)
|
||||
self.tab_utils.ensure_focus()
|
||||
except Exception as exc:
|
||||
# Recovery is best effort. If even this fails the next task will
|
||||
# report its own [SKIP], which is no worse than before.
|
||||
logger.warning(
|
||||
"Could not return to the Rewards home page: %s",
|
||||
log_utils.exception_summary(exc)
|
||||
)
|
||||
|
||||
def claim_bonus_points(self):
|
||||
self.switch_to_dashboard()
|
||||
|
||||
@@ -426,9 +481,12 @@ class RewardsTaskUtils:
|
||||
# The tags stay in the message rather than being folded into the
|
||||
# level, they are the per-task outcome summary and reading a run
|
||||
# means scanning for them.
|
||||
completed = False
|
||||
|
||||
try:
|
||||
step()
|
||||
logger.info("[OK] %s", name)
|
||||
completed = True
|
||||
except Exception as exc:
|
||||
tag, reason = task_failure_report(exc)
|
||||
|
||||
@@ -438,8 +496,10 @@ class RewardsTaskUtils:
|
||||
exc_info=logger.isEnabledFor(logging.DEBUG)
|
||||
)
|
||||
|
||||
# Leave a clean tab state behind for the next task.
|
||||
try:
|
||||
self.tab_utils.close_all_other_tabs()
|
||||
except Exception:
|
||||
pass
|
||||
# Leave a clean tab state behind for the next task. Both halves of
|
||||
# this matter, and they are separate failures: the right tab has to
|
||||
# survive, and it has to be showing the right page.
|
||||
self.restore_main_tab()
|
||||
|
||||
if not completed:
|
||||
self.return_to_rewards_home()
|
||||
Reference in New Issue
Block a user