예제 #1
0
 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')
예제 #2
0
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
예제 #3
0
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()
예제 #4
0
 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))
예제 #5
0
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()
예제 #6
0
 def check_current(self, current_url):
     for d in self.dest:
         if d in remove_qs(current_url):
             return d
예제 #7
0
 def current_url(self):
     return remove_qs(self.driver.current_url)