0

I've been playing around with Selenium and have been trying to get my automated checkout working. So far it's been pretty successful, but I've hit a snag and can't seem the end part of my code working. I've tried arranging my 'sleeps' and 'implicit_waits' in every way I can think of but to no success. I keep getting thrown "selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: //*[@id="creditCardNumber"]" If someone can help me get this going I would really appreciate it!

 from selenium.webdriver import Firefox from selenium import webdriver from selenium.webdriver.support.select import Select import time driver = Firefox() action = webdriver.ActionChains(driver) def get_nike(): driver.maximize_window() driver.get('https://www.nike.com/') men_shoes = driver.find_element_by_xpath('/html/body/div[1]/div[3]/header/div/div[1]/div[2]/nav/div[2]/ul/li[2]/a') action.move_to_element(men_shoes) action.perform() new_releases = driver.find_element_by_xpath('/html/body/div[1]/div[3]/header/div/div[1]/div[2]/nav/div[2]/ul/li[2]/div/div/div[1]/a[1]') avoid_wrong_selection = driver.find_element_by_xpath('/html/body/div[1]/div[3]/header/div/div[1]/div[2]/nav/div[2]/ul/li[2]/div/div/div[2]/a[2]') action.move_to_element(avoid_wrong_selection) action.move_to_element(new_releases) action.perform() new_releases.click() # you have to click the element itself driver.implicitly_wait(2) selected_shoes = driver.find_element_by_xpath('//*[@id="Wall"]/div/div[5]/div[2]/main/section/div/div[12]/div/figure/a[2]/div/div/img') #can also use linked text driver.execute_script("arguments[0].scrollIntoView();", selected_shoes) # scrolls to shoes selected_shoes.click() get_size = driver.find_element_by_xpath('/html/body/div[1]/div[2]/div/div/div[3]/div[3]/div[2]/div/div/div[4]/form/div[1]/fieldset/div/div[10]/label') action.move_to_element(get_size) # selects size get_size.click() time.sleep(1) add_bag = driver.find_element_by_xpath('/html/body/div[1]/div[2]/div/div/div[3]/div[3]/div[2]/div/div/div[4]/form/div[2]/div/div') #requires web element action.move_to_element(add_bag) # adds item to bag add_bag.click() to_checkout = driver.find_element_by_xpath('/html/body/div[1]/div[2]/div/div/div[4]/div/div/div/div/div/div/div/div/div/div[3]/div/button[2]') action.move_to_element(to_checkout) # brings you to cart to_checkout.click() first_name = driver.find_element_by_xpath('//*[@id="firstName"]') first_name.send_keys("Bingo") last_name = driver.find_element_by_xpath('//*[@id="lastName"]') last_name.send_keys("Bongo") transition_address = driver.find_element_by_xpath('//*[@id="search-address-input"]') transition_address.send_keys('1453 E curfluffle street') manual_address = driver.find_element_by_xpath('/html/body/div[1]/div/div[3]/div/div[2]/div/div/main/section[2]/div/div[2]/form/div/div/div/div[1]/div[4]/div/div[2]/div/div/ul/li[3]/a') manual_address.click() real_address = driver.find_element_by_xpath('//*[@id="address1"]') # types address real_address.send_keys('53 sterling street') city = driver.find_element_by_xpath('//*[@id="city"]') # types city city.send_keys('pittsburgh') state_dropdown = driver.find_element_by_xpath('//*[@id="state"]') selections = Select(state_dropdown) # selects state from the dropdown selections.select_by_value("PA") zip_code = driver.find_element_by_xpath('//*[@id="postalCode"]') zip_code.send_keys('15203') #sends zip code email = driver.find_element_by_xpath('//*[@id="email"]') email.send_keys('[email protected]') phone_number = driver.find_element_by_xpath('//*[@id="phoneNumber"]') phone_number.send_keys('456-906-2354') save_and_continue = driver.find_element_by_xpath('/html/body/div[1]/div/div[3]/div/div[2]/div/div/main/section[2]/div/div[2]/form/div/div/div/div[2]/button') action.move_to_element(save_and_continue) save_and_continue.click() time.sleep(1) continue_to_payment = driver.find_element_by_xpath('/html/body/div[1]/div/div[3]/div/div[2]/div/div/main/section[2]/div/div[3]/div/button') action.move_to_element(continue_to_payment) continue_to_payment.click() cc_number = driver.find_element_by_xpath('//*[@id="creditCardNumber"]') driver.implicitly_wait(5) #scroll down to card info and enter card info driver.execute_script("arguments[0].scrollIntoView();", cc_number) time.sleep(2) cc_number.send_keys('123456789101112') get_nike() 

The problem in particular the end.

 continue_to_payment = driver.find_element_by_xpath('/html/body/div[1]/div/div[3]/div/div[2]/div/div/main/section[2]/div/div[3]/div/button') action.move_to_element(continue_to_payment) continue_to_payment.click() cc_number = driver.find_element_by_xpath('//*[@id="creditCardNumber"]') driver.implicitly_wait(5) #scroll down to card info and enter card info driver.execute_script("arguments[0].scrollIntoView();", cc_number) time.sleep(2) cc_number.send_keys('123456789101112') 
4
  • 1
    Can you post the html of the element in question. Also check if it is in any iframes. Commented Feb 13, 2021 at 2:53
  • Heres the innerhtml, is this what you mean? <input maxlength="20" class="mod-ncss-input ncss-input pt2-sm pr4-sm pb2-sm pl4-sm" id="creditCardNumber" onautocomplete="off" value="" type="tel" tabindex="0" data-shortname="cc"> Commented Feb 13, 2021 at 2:57
  • 1
    If it moves to another page add some wait prior to finding the element. <iframe> check if its in one of these and driver switch to it Commented Feb 13, 2021 at 3:31
  • The only thing is it doesn't move to another page. It just opens the bottom of the page up, where I would then have to scroll down and enter credit card info. This the part that keeps messing up as I can't get the page to move down and locate the credit card input Commented Feb 13, 2021 at 4:33

2 Answers 2

1

Just use webdriver wait to wait for the element to pop up and send keys.

wait.until(EC.element_to_be_clickable((By.ID, "creditCardNumber"))).send_keys("123456789101112") 

Fixing other code to make it more stable.

wait = WebDriverWait(driver, 10) action = webdriver.ActionChains(driver) def get_nike(): driver.maximize_window() driver.get('https://www.nike.com/') men_shoes = wait.until(EC.element_to_be_clickable((By.XPATH, "//a[@aria-label='Men']"))) action.move_to_element(men_shoes).perform() new_releases = driver.find_element_by_xpath("//a[@role='menuitem' and text()='New Releases']") action.move_to_element(new_releases).click().perform() selected_shoes = wait.until(EC.element_to_be_clickable((By.XPATH, "//a[@aria-label='Nike ZoomX Invincible Run Flyknit']//img"))) selected_shoes.click() get_size = wait.until(EC.element_to_be_clickable((By.XPATH, "//label[text()='US 10.5']"))) get_size.click() 

Import

from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC 
Sign up to request clarification or add additional context in comments.

2 Comments

This answer seems closer to the one I'm looking for, but when it runs the 'wait.until' it still will not scroll down to the credit card input.
@Jamesyt60 all you'd do is just use your scroll to the element.
0

Use this snippet to check if a WebElement is visible in viewport, do not use selenium waits, they are plenty of bugs.

public static Boolean isVisibleInViewport(WebElement element) { WebDriver driver = ((RemoteWebElement)element).getWrappedDriver(); return (Boolean)((JavascriptExecutor)driver).executeScript( "var elem = arguments[0], " + " box = elem.getBoundingClientRect(), " + " cx = box.left + box.width / 2, " + " cy = box.top + box.height / 2, " + " e = document.elementFromPoint(cx, cy); " + "for (; e; e = e.parentElement) { " + " if (e === elem) " + " return true; " + "} " + "return false; " , element); } 

Just convert the Java method to a python function and pass to it the WebElement you're looking for.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.