0

On instagram you can use the Account center to change your password:

enter image description here

From there you can choose change password option to change your password in this screen:

enter image description here

I'm trying using selenium to fill the input boxes and click the Change password "button" (It's not a button) with no success.

I can fill the inputs without any issue but for the button I have tried 2 different approaches with same results

1 - Selecting the span that contains the text "Change password" and then clicking it. This closes the change password dialog but no password is changed

2 - Moving to the span (have tried some parents too) and then clicking it. Same result as before.

Here the code:

    print("Filling change password data")
    currentPassowrd= driver.find_element(By.XPATH, "//label[contains(text(),'Current password')]/preceding-sibling::input")
    newPassowrd = driver.find_element(By.XPATH, "//label[text()='New password']/preceding-sibling::input")
    reNewPassowrd = driver.find_element(By.XPATH, "//label[text()='Re-type new password']/preceding-sibling::input")
    changePasswordButton = driver.find_element(By.XPATH, "//span[text()='Change password']")

    ActionChains(driver) \
        .move_to_element(currentPassowrd).click() \
        .send_keys("old pass") \
        .move_to_element(newPassowrd).click() \
        .send_keys("new pass") \
        .move_to_element(reNewPassowrd).click() \
        .send_keys("re new pass") \
        .perform()

    time.sleep(3);
    ActionChains(driver).click(changePasswordButton).perform()
Notbad
  • 5,936
  • 12
  • 54
  • 100

2 Answers2

0

The locator strategy you have used identifies 3 elements within the HTML DOM:

ChangePassword

and none of them is the desired element.


Solution

To click on the element Change Password you can use the following locator strategy:

  • Using xpath:

    driver.find_element(By.XPATH, "//div[@role='button' and @tabindex='0']//span[text()='Change Password']").click()
    

However, the desired element is a dynamic element, so to click on the clickable element 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, "//div[@role='button' and @tabindex='0']//span[text()='Change Password']"))).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

After trying the solutions posted and checking they won't work for me I decided to post my method. It is pretty easy once you understand the page structure.

The main thing is that when you get to that Change password form you will have several elements with the string "Change password" as their text property. Some belong to the form itself and others to the page below. Some are hidden and some not.

If you look closely you will see that the only ones that you should care about are the ones at the bottom of the form. So there should be a way to isolate them and this is using the aria-hidden property. For the real button, one of its ancestors will have this property set to false when it is available to be clicked but for the other element that is over the real button it would stay as true. So I use this code in selenium to get that:

elements = driver.find_elements(By.XPATH, "//span[text()='Change password']/ancestor::div[@aria-hidden='false']")

The problem with that is that it will return 2 elements. One for the form root and the other for the element we really want. If we check the text property of each element one will contain all the form text but the other only the "Change password text". This is the one we need. So I added just that in python to detect the correct one:

element = None
for e in elements:
    if e.text == "Change password":
        element = e
        break;
element.click()

I have written all this in a hurry if anything is not clear let me know.

Notbad
  • 5,936
  • 12
  • 54
  • 100