0

I am trying to create an Account on Walmart using selenium python. I successfully opened https://www.walmart.com/ and successfully go to create an account button under Sign In tab. Moreover, I also successfully entered the details of First name, Last name, Email Address and Password. However, once I clicked on Create account button, I got TimeoutException error despite using EC.visibility_of_element_located().click () method.

Can anyone kindly guide me what is wrong with my approach. Thanks in advance.

The source code of the website for Create Account button is as follows:

<button class="button m-margin-top text-inherit" type="submit" data-automation-id="signup-submit-btn" data-tl-id="signup-submit-btn" aria-label="Create Account, By clicking Create Account, the user is acknowledging that they have read and agreed to the Terms of Use and Privacy Policy">Create account</button>

My Python code is as follows:

import time
import requests
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.action_chains import ActionChains

url = "https://www.walmart.com/"

first_name = "chuza"
last_name = "123"
email_id = "chuza123@gmail.com"
password = "Eureka1@"

options = Options()
s=Service('C:/Users/Samiullah/.wdm/drivers/chromedriver/win32/96.0.4664.45/chromedriver.exe')
driver = webdriver.Chrome(service=s, options=options)
driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})")
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
    "source":
        "const newProto = navigator.__proto__;"
        "delete newProto.webdriver;"
        "navigator.__proto__ = newProto;"
})
wait = WebDriverWait(driver, 20)
actions = ActionChains(driver)
driver.get(url)
sign_in_btn = wait.until(EC.visibility_of_element_located((By.XPATH, "//div[text()='Sign In']")))
actions.move_to_element(sign_in_btn).perform()
time.sleep(0.5)
wait.until(EC.visibility_of_element_located((By.XPATH, '//button[normalize-space()="Create an account"]'))).click()

f_name = driver.find_element(By.ID, 'first-name-su')
l_name = driver.find_element(By.ID, 'last-name-su')
email = driver.find_element(By.ID, 'email-su')  
pswd = driver.find_element(By.ID, 'password-su')
f_name.send_keys(first_name)
driver.implicitly_wait(2)
l_name.send_keys(last_name)
driver.implicitly_wait(1.5)
email.send_keys(email_id)
driver.implicitly_wait(2)
pswd.send_keys(password)
driver.implicitly_wait(0.5)
### 
wait.until(EC.visibility_of_element_located((By.XPATH, '//button[normalize-space()="Create account"]'))).click()

Prophet
  • 32,350
  • 22
  • 54
  • 79
salman dinani
  • 47
  • 1
  • 5

5 Answers5

1

//button[normalize-space()="Create account"] locator matches 3 elements on that page, you need to use more precise locator.
This locator is unique: //form[@id='sign-up-form']//button[@data-tl-id='signup-submit-btn']
So, this should work:

wait.until(EC.visibility_of_element_located((By.XPATH, "//form[@id='sign-up-form']//button[@data-tl-id='signup-submit-btn']"))).click()
Prophet
  • 32,350
  • 22
  • 54
  • 79
1

I see this css selector that represent the desired webelement:

button[data-automation-id='signup-submit-btn']

and xpath would be:

//button[@data-automation-id='signup-submit-btn']

there are 3 matching nodes for each CSS and XPath and Selenium will look for the first match, the CSS and XPath basically are first matching node.

wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[data-automation-id='signup-submit-btn']"))).click()

or

wait.until(EC.element_to_be_clickable((By.XPATH, "//button[@data-automation-id='signup-submit-btn']"))).click()

It makes more sense to use element_to_be_clickable when trying to click on a web element instead of visibility_of_element_located. Also, CSS are much better locator as compared to XPath.

cruisepandey
  • 28,520
  • 6
  • 20
  • 38
1

This xpath based Locator Strategy...

//button[normalize-space()="Create account"]

...identifies three(3) elements within the DOM Tree and your desired element is the second in the list.

walmart_create_an_account


Solution

The desired element is a dynamic element so to click on the clickable element instead of visibility_of_element_located() you need to induce WebDriverWait for the element_to_be_clickable() and you can use the following Locator Strategy:

  • Using XPATH:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//form[@id='sign-up-form']//button[normalize-space()='Create account']"))).click()
    
  • Note: You have to add the following imports :

    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
0

This issue is because of selenium, you can fix this by creating it manually, follow the steps:

Create an account on Walmart IO platform here by clicking on the man icon just before the search box.

Login to the account and accept "Terms of Use"

Click on "Create Your Application" to create a new application and fill in appropriate details.

You can follow this tutorial to generate two sets of public/private keys -one set will be used for production and the other set will be used for stage.

Upload both public keys using this: https://walmart.io/key-upload?app_name=<your app name>

Consumer ID will be generated for both sets for prod and stage which can be seen on the dashboard

Click on "Request Access" for OPD APIs at here and fill out the form

MD Mushfirat Mohaimin
  • 1,966
  • 3
  • 10
  • 22
IOSupport
  • 11
  • 1
0

use the below code and replace "variable" and "idname"

variable = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, '//*[@id="idname"]/button'))).click()

if that doesn't work right click the webpage, click inspect then use the arrow icon to click on the button that they want to interact with. after that the right click the source code of the button and hover over copy then click on copy xpath or whatever is needed

D-Rey
  • 3
  • 2