def navigate(self, driver, timeout=20): log.info('Navigating ' + str(self)) self.waypoints_reached = 0 if remove_qs(driver.current_url) != self.route_start: log.info('Navigating to route start: {}'.format(self.route_start)) driver.get(self.route_start) for waypoint in self.waypoints: try: valid_dest = [ waypnt.dest for waypnt in self.waypoints[self.waypoints.index(waypoint) + 1:] ] if remove_qs(driver.current_url) == BASE_URL + waypoint.dest: log.warning("Already at dest: '{}'".format(waypoint.dest)) else: self.navigate_waypoint(driver, waypoint, timeout, valid_dest) except NavigationException: handle_redirect(driver, ignore_oos=self.args.ignore_oos, valid_dest=valid_dest, timeout=timeout, route=self) self.waypoints_reached += 1 log.info('Route complete')
def get_slots(driver, prefs, slot_route): if slot_route.waypoints[-1].dest not in remove_qs(driver.current_url): try: handle_redirect(driver, slot_route.args.ignore_oos) except UnhandledRedirect: log.warning('Unhandled redirect') slot_route.navigate(driver) log.info('Checking for available slots') preferred_slots = [] slot_container = wait_for_element(driver, config.Locators.SLOT_CONTAINER) slots = [ SlotElement(element) for element in slot_container.find_elements(*config.Locators.SLOT) ] if slots: log.info('Found {} slots: \n{}'.format( len(slots), '\n'.join([s.full_name for s in slots]))) if slots and prefs: log.info('Comparing available slots to prefs') for cmp in prefs: if cmp.startswith('any'): _pref = [ s for s in slots if cmp.replace('any', '') in clean_slotname(s) ] else: _pref = [s for s in slots if clean_slotname(s).startswith(cmp)] preferred_slots.extend(_pref) if preferred_slots: log.info('Found {} preferred slots: {}'.format( len(preferred_slots), '\n' + '\n'.join([p.full_name for p in preferred_slots]))) return preferred_slots else: return slots
def handle_redirect(driver, ignore_oos, valid_dest=None, timeout=None, route=None): current = remove_qs(driver.current_url) log.warning("Redirected to: '{}'".format(current)) if Patterns.AUTH_URL in current: wait_for_auth(driver) elif Patterns.OOS_URL in current: handle_oos(driver, ignore_oos) elif Patterns.THROTTLE_URL in current: handle_throttle(driver) raise RouteRedirect('Redirected after throttle') elif route and current == route.route_start: if not route.waypoints_reached: driver.refresh() raise RouteRedirect() elif valid_dest and timeout: log.warning( 'Handling unknown redirect (timeout in {}s)'.format(timeout)) try: WebDriverWait(driver, timeout).until(EC.url_matches('|'.join(valid_dest))) except TimeoutException: raise UnhandledRedirect( "Timed out waiting for redirect to a valid dest\n" "Current URL: '{}'".format(driver.current_url)) else: raise UnhandledRedirect()
def navigate_waypoint(self, driver, waypoint, timeout, valid_dest): log.info('Navigating ' + str(waypoint)) elem = wait_for_element(driver, waypoint.locator, timeout=timeout) jitter(.4) click_when_enabled(driver, elem) try: WebDriverWait(driver, timeout).until(EC.staleness_of(elem)) except TimeoutException: pass current = remove_qs(driver.current_url) if current == BASE_URL + waypoint.dest: log.info("Navigated to '{}'".format(waypoint.dest)) elif valid_dest and any(d in current for d in valid_dest): log.info("Navigated to valid dest '{}'".format(current)) else: raise NavigationException("Navigation to '{}' failed".format( waypoint.dest))
def handle_redirect(driver, ignore_oos, valid_dest=None, timeout=None, route=None): current = remove_qs(driver.current_url) log.warning("Redirected to: '{}'".format(current)) if Patterns.AUTH_URL in current: wait_for_auth(driver) elif Patterns.OOS_URL in current: try: save_removed_items(driver) except Exception: log.error('Could not save removed items') if ignore_oos: log.warning('Attempting to proceed through OOS alert') click_when_enabled(driver, wait_for_element(driver, Locators.OOS_CONTINUE)) else: raise ItemOutOfStock( 'Encountered OOS Alert. Use `ignore-oos` to bypass') elif route and current == route.route_start and route.waypoints_reached: raise RouteRedirect() elif valid_dest and timeout: log.warning( 'Handling unknown redirect (timeout in {}s)'.format(timeout)) try: WebDriverWait(driver, timeout).until(EC.url_matches('|'.join(valid_dest))) except TimeoutException: raise UnhandledRedirect( "Timed out waiting for redirect to a valid dest\n" "Current URL: '{}'".format(driver.current_url)) else: raise UnhandledRedirect()
def check_current(self, current_url): for d in self.dest: if d in remove_qs(current_url): return d
def current_url(self): return remove_qs(self.driver.current_url)