def add_product_to_wish_list(browser: webdriver.WebDriver, li_element, task_data: TaskData): product_name = _open_product_details_page_and_get_product_name( browser, li_element) logging.info("Finding the add to wish list button") add_to_wish_list_button_xpath = "//span[contains(@class, 'wish_text')]" \ "/ancestor::div[contains(@class, 'addToWish')]" WebDriverWait(browser, 10).until( ec.presence_of_element_located( (By.XPATH, add_to_wish_list_button_xpath))) wait() add_to_wish_list_button_element = browser.find_element_by_xpath( add_to_wish_list_button_xpath) logging.info("Checking if the product is already in the wish list") if "add to wishlist" in add_to_wish_list_button_element.text.lower(): logging.info("Clicking the add to wish list button") add_to_wish_list_button_element.click() wait() _continue_shopping(browser, task_data, product_name) else: logging.info( "{} is already added to the wish list".format(product_name)) logging.warning( "Raising an exception. This is OK. By raising the exception this product will be skipped" ) raise ProductAlreadyInWishListException(product_name)
def _remove_one_product_from_wish_list(browser: webdriver.WebDriver, product: str): delete_core_xpath = "//div[contains(@class, 'wishlist-product')]" \ "//div[contains(@class, 'product-cnt')]" \ "//ul[contains(@class, 'product-list') and contains(@class, 'cf')]" delete_button_xpath = f"{delete_core_xpath}" \ f"//span[contains(@class, 'options')]//span[contains(@class, 'options-remove')]//i" delete_popup_yes_xpath = f"{delete_core_xpath}" \ f"//span[contains(@class, 'remove-pop')]//p[contains(@class, 'p-btn')]" \ f"//span[contains(@class, 'p-btn-yes')]" product_element = browser.find_element_by_xpath(f"{delete_core_xpath}//li") scroll_to_and_hover_over_element(browser, product_element) logging.info("Clicking on delete button") WebDriverWait(browser, 10).until( ec.presence_of_element_located((By.XPATH, delete_button_xpath))) WebDriverWait(browser, 10).until( ec.element_to_be_clickable((By.XPATH, delete_button_xpath))) browser.find_element_by_xpath(delete_button_xpath).click() wait() logging.info("Confirming deletion") WebDriverWait(browser, 10).until( ec.presence_of_element_located((By.XPATH, delete_popup_yes_xpath))) WebDriverWait(browser, 10).until( ec.element_to_be_clickable((By.XPATH, delete_popup_yes_xpath))) browser.find_element_by_xpath(delete_popup_yes_xpath).click() wait() logging.info(f"Product {product} deleted successfully from the wish list")
def _perform_navigation(browser: webdriver.WebDriver, url: str): try: browser.get(url) wait() except WebDriverException: logging.error(f"Something went wrong while executing the task") logging.error(traceback.format_exc())
def _set_shipto_info(browser: webdriver.WebDriver): # Explicitly switch to desired country and currency url_with_shipto_info = "https://www.banggood.com/index.php?com=account&DCC={}¤cy={}" \ .format(get_desired_country(), get_desired_currency()) logging.info("\n" "\tSetting country: {} \n" "\tSetting currency: {} \n " "\tWill navigate to URL: {}\n".format(get_desired_country(), get_desired_currency(), url_with_shipto_info)) _perform_navigation(browser, url_with_shipto_info) wait()
def add_product_to_cart(browser: webdriver.WebDriver, li_element, task_data: TaskData): product_name = _open_product_details_page_and_get_product_name( browser, li_element) logging.info("Finding the add to cart button") add_to_cart_button_xpath = "/html/body/div[8]/div/div[2]/form/div[5]/div[1]/a[1]" WebDriverWait(browser, 10).until( ec.presence_of_element_located((By.XPATH, add_to_cart_button_xpath))) wait() logging.info("Clicking the add to cart button") browser.find_element_by_xpath(add_to_cart_button_xpath).click() wait() _continue_shopping(browser, task_data, product_name)
def _search_for_product_in_wish_list_and_get_input_field_element( browser: webdriver.WebDriver, product: str) -> WebElement: logging.info("Finding the search button and clicking on it.") if "+" in product: logging.info("Invalid character '+' detected.") product = product.split("+")[0] logging.warning( f"Using {product} in the search. Potentially the wrong product can be returned..." ) logging.info( f"This hack was necessary as Banggood search on wish lists does not allow '+' character" ) search_component_xpath = "//li[contains(@class, 'wishlist-nav-search')]" search_span_xpath = f"{search_component_xpath}//span[contains(@class, 'search-inner')]" search_button_xpath = f"{search_span_xpath}" \ f"//span[contains(@class, 'icon-search_new') and contains(@class, 'search-btn')]" search_input_field_xpath = f"{search_span_xpath}//input[contains(@class, 'search-text')]" logging.info("Clicking on a search button to activate the input field") WebDriverWait(browser, 10).until( ec.presence_of_element_located((By.XPATH, search_button_xpath))) WebDriverWait(browser, 10).until( ec.element_to_be_clickable((By.XPATH, search_button_xpath))) search_button_element = browser.find_element_by_xpath(search_button_xpath) scroll_to_and_hover_over_element(browser, search_button_element) search_button_element.click() logging.info("Filling out the input field") WebDriverWait(browser, 10).until( ec.presence_of_element_located((By.XPATH, search_input_field_xpath))) WebDriverWait(browser, 10).until( ec.element_to_be_clickable((By.XPATH, search_input_field_xpath))) search_input_field_element = browser.find_element_by_xpath( search_input_field_xpath) search_input_field_element.send_keys(product) logging.info("Clicking on a search button again to perform the search") browser.find_element_by_xpath(search_button_xpath).click() wait() return search_input_field_element
def _receive_reward(browser: webdriver.WebDriver, task_data: TaskData): wait() logging.info("Clicking on \"Receive it\" button") receive_it_button_xpath = f"//div[contains(@class, '{task_data.modal_css_class}')] " \ "//a[(contains(" \ "translate(text(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), " \ "'receive it'))]" WebDriverWait(browser, 10).until( ec.presence_of_element_located((By.XPATH, receive_it_button_xpath))) receive_it_button_element = browser.find_element_by_xpath( receive_it_button_xpath) if receive_it_button_element.is_displayed(): receive_it_button_element.click() logging.info("Receiving points for completing the task") else: logging.info( "The \"Receive it\" button is not displayed. Not clicking on anything..." )
def cleanup_wish_list(browser: webdriver.WebDriver, task_data: TaskData): open_wish_list_page(browser) for product in task_data.products: logging.info(f"Working with product {product}") search_input_field_element = _search_for_product_in_wish_list_and_get_input_field_element( browser, product) try: _remove_one_product_from_wish_list(browser, product) except NoSuchElementException: logging.error( f"Product {product} not found in wish list. It was probably already deleted. Moving on..." ) logging.error(traceback.format_exc()) finally: task_data.products.remove(product) logging.info("Clearing text in input field") search_input_field_element.clear() wait()
def _continue_shopping(browser: webdriver.WebDriver, task_data: TaskData, product_name: str): wait( ) # Wait a little longer to ensure the product is added and popup is presented logging.info("Clicking on \"Continue Shopping\" button") continue_shopping_button_xpath = "//div[contains(@class, 'modal_container')] " \ "//a[(contains(translate(text(), " \ "'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), " \ "'continue shopping'))]" wait() # Wait a little longer to ensure the popup is presented WebDriverWait(browser, 10).until( ec.presence_of_element_located( (By.XPATH, continue_shopping_button_xpath))) WebDriverWait(browser, 10).until( ec.element_to_be_clickable((By.XPATH, continue_shopping_button_xpath))) browser.find_element_by_xpath(continue_shopping_button_xpath).click() wait() logging.info( "Adding product {} to list and closing the Product Details Page". format(product_name)) task_data.products.append(product_name) if len(task_data.products) >= 3: _receive_reward(browser, task_data) close_current_tab(browser)
def log_in(browser: webdriver.WebDriver): try: logging.info("Getting email input field in the login form") email_login_input_field = browser.find_element_by_xpath( "/html/body/div[1]/div/form[1]/ul/li[1]/label/div/input") logging.info("Getting password input field in the login form") password_login_input_field = browser.find_element_by_xpath( "/html/body/div[1]/div/form[1]/ul/li[2]/label/div/input") logging.info("Filling out the login form") email_login_input_field.send_keys(get_username()) password_login_input_field.send_keys(get_password()) logging.info("Performing login (getting the button and clicking it)") browser.find_element_by_xpath( "/html/body/div[1]/div/form[1]/ul/li[3]/input").click() wait() except WebDriverException: logging.error(f"Something went wrong while executing the task") logging.error(traceback.format_exc())
def _remove_one_product_from_cart(browser: webdriver.WebDriver, task_data: TaskData, product_row_xpath: str, product: str): product_quantity_xpath = ".//li[contains(@class, 'newcart_quantity')]//div[contains(@class, 'quantity_item')]" product_quantity_minus_xpath = ".//a[contains(text(), '-')]" product_options_xpath = ".//li[contains(@class, 'newcart_options')]" product_remove_button_xpath = f"{product_options_xpath}//span[contains(@data-title, 'Remove')]" product_remove_modal_xpath = f"{product_options_xpath}//div[contains(@class, 'item_remove_mask')]" product_remove_modal_yes_button_xpath = ".//a[contains(@class, 'item_mask_yes')]" target_product_link_xpath = f"{product_row_xpath}//li[contains(@class, 'newcart_product')]" \ f"//a[contains(@class, 'title') and contains(text(), '{product}')]" target_product_link_element = browser.find_element_by_xpath( target_product_link_xpath) product_row_ancestor_xpath = ".//ancestor::ul[contains(@class, 'newcart_list_items')]" product_row_element = target_product_link_element.find_element_by_xpath( product_row_ancestor_xpath) scroll_to_and_hover_over_element(browser, product_row_element) if product in task_data.products: logging.info(f"Product found! It's {product}") qty_element = product_row_element.find_element_by_xpath( product_quantity_xpath) quantity = int( qty_element.find_element_by_tag_name("input").get_attribute( "value")) if quantity > 1: logging.info( f"Decreasing qty for product {product} from {quantity} to {quantity - 1}" ) qty_element.find_element_by_xpath( product_quantity_minus_xpath).click() wait() else: logging.info(f"Removing product {product} from cart.") WebDriverWait(browser, 10). \ until(ec.presence_of_element_located((By.XPATH, product_remove_button_xpath))) WebDriverWait(browser, 10). \ until(ec.element_to_be_clickable((By.XPATH, product_remove_button_xpath))) product_row_element.find_element_by_xpath( product_remove_button_xpath).click() wait() product_row_element.find_element_by_xpath(product_remove_modal_xpath) \ .find_element_by_xpath(product_remove_modal_yes_button_xpath) \ .click() wait() task_data.products.remove(product)