I am new to using python's selenium model and ran into a problem while trying to automate the checkout process for this store, https://bellevo.store/products/luna. I have python click buy now and fill out the information and it works well until it comes to the city field. I don't think it is seeing it as clickable and I am not sure why. Any help would be much appreciated. Here is my code
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
# Initialize a new browser instance
driver = webdriver.Chrome()
# Click "Buy It Now"
wait = WebDriverWait(driver, 10)
buy_now_button = wait.until(EC.element_to_be_clickable((By.XPATH, "//*[@id=\"product form-template--22164028883241__main\"]/div/div/dynamic-checkout")))
buy_now_button.click()
# Fill in contact and delivery fields
wait.until(EC.element_to_be_clickable((By.XPATH, "//*[@id=\"email\"]"))).send_keys(phone_number)
time.sleep(.5)
wait.until(EC.element_to_be_clickable((By.XPATH, "//*[@id=\"TextField0\"]"))).send_keys(first_name)
time.sleep(.5)
wait.until(EC.element_to_be_clickable((By.XPATH, "//*[@id=\"TextField1\"]"))).send_keys(last_name)
time.sleep(.5)
wait.until(EC.element_to_be_clickable((By.XPATH, "//*[@id=\"billing-address1\"]"))).send_keys(address + ", " + city + ", " + state + ", USA")
time.sleep(.5)
wait.until(EC.element_to_be_clickable((By.XPATH, "//label[@id=\"TextField6-label\"]"))).send_keys(city)
I have tried many different methods and have not been able to find a solution. As I said, I am new to selenium and probably don't have a great understanding of it.
You were pretty close. Your code is actually pretty good. I have some suggestions for improvement below.
This can be a tough scenario. I think the issue you were running into is you were trying to type in the City field but it wasn't visible at the time because the address suggestion dropdown was open. There are a couple ways to approach this...
I went with #2. I also cleaned up a few things...
If you are using an ID, use
By.ID()instead ofBy.XPATH().I removed the
time.sleep()s. You don't need them since you have proper waits. You haveWebDriverWaits which is good... it's a best practice to use them and avoidtime.sleep().In the future, if you have nested double quotes (
"), alternate them with single quotes ('), e.g. change"//*[@id=\"email\"]"to"//*[@id='email']". It makes it easier to read and removes the escape chars.If you are going to click an element, use
EC.element_to_be_clickable(). If you are going to otherwise interact with an element, e.g. send_keys(), useEC.visibility_of_element_located(). AvoidEC.presence_of_element_located()in most cases... it's just confirming the element is in the DOM, not that it's visible or ready to be clicked. I see a lot of people using that and then clicking, etc. the element... that' s just asking for intermittent issues that are hard to track down.You don't have to but I prefer
fstring literals to concatenate strings. I find them much easier to read and use. No more ensuring you have matching"s each time you insert a new variable, etc. See the docs for more info.becomes
Taking all my suggestions into account, the cleaned up code is below and working.