1

I am working on a program to create new accounts on a website my company uses. I have been able to get through the entire webpage at this point the only issues I am having is the confirm password input. I keep getting a TimeoutException which doesn't make sense because I have created the correct angular xpath. The only thing I can think of is that the HTML for the element has compare-to="user.password. I have put the HTML for the password and confirm password HTML below, the section of script that is supposed to write to the confirm password element, and the full script. Any help is greatly appreciated!

HTML - Password Element:

<input ng-required="true" ng-pattern="/^[a-zA-Z0-9\p{P}\$\^\+=~`|]+$/" ng-model="user.password" type="password" name="password" maxlength="16" class="ng-pristine ng-untouched ng-invalid ng-invalid-required ng-valid-pattern ng-valid-maxlength" required="required">

HTML - Confirm Password Element

<input ng-required="true" ng-pattern="/^[a-zA-Z0-9\p{P}\$\^\+=~`|]+$/" ng-model="user.confirmPassword" type="password" compare-to="user.password" name="confirmPassword" maxlength="16" class="ng-pristine ng-untouched ng-isolate-scope ng-invalid ng-invalid-required ng-valid-pattern ng-valid-maxlength ng-valid-compare" required="required">

Selenium Python code that is supposed to send keys to confirm password element:

WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[@class='ng-pristine ng-untouched ng-invalid ng-invalid-required ng-valid-pattern ng-valid-maxlength' and @name='password']"))).send_keys("DaHawg")

The Full Python Script

from hashlib import new
from multiprocessing.connection import wait
from select import select
import time
from webbrowser import BaseBrowser, Chrome
from xml.etree.ElementPath import find
from selenium.webdriver.support.select import Select
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.common.exceptions import NoSuchElementException

driver = webdriver.Chrome()
driver.get('https://power.dat.com')

# chrome_optinons = webdriver.ChromeOptions()
# chrome_optinons.add_argument('--headless')
# chrome_optinons.add_argument('window-size=1920x1080')

#setup wait 
wait = WebDriverWait(driver, 10)

username = driver.find_element(By.XPATH, '//*[@id="mat-input-1"]')
username.send_keys('')

password = driver.find_element(By.XPATH, '//*[@id="mat-input-0"]')
password.send_keys('')


loginbutton = driver.find_element(By.XPATH, '//*[@id="submit-button"]')
loginbutton.click()

(time.sleep(2))

profiledrop = driver.find_element(By.XPATH, '//*[@id="user-salutation"]')
profiledrop.click()

#store original window ID
windows_before = driver.current_window_handle

# #checks no other windows open
# assert len(driver.window_handles) == 1


Adminbutton = driver.find_element(By.CSS_SELECTOR, '#userPreferencesUl > li:nth-child(5) > a')
Adminbutton.click()


# driver.switch_to.window(driver.window_handles[1])

#Wait for new window Tab
WebDriverWait(driver, 10).until(EC.number_of_windows_to_be(2))

windows_after = driver.window_handles

new_window = [x for x in windows_after if x != windows_before][0]

driver.switch_to.window(new_window)

#Tells program to wait till new window confirmed 
WebDriverWait(driver,20).until(EC.title_is("Admin"))

(time.sleep(5))

WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button.newUser.ng-scope[ng-if^='isTrustedAdmin'][ng-click^='onNewUser']"))).click()
#NewUsrBtn.click()

#User Name
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[@class='ng-pristine ng-untouched ng-invalid ng-invalid-required ng-valid-pattern ng-valid-maxlength' and @name='loginId']"))).send_keys("Dahawg")
#UsrNM.send_keys('justin')


#<input ng-required="true" ng-readonly="!hasPriviledgeToEdit(user)" ng-model="user.loginId" ng-pattern="/^[a-zA-Z0-9_]+$/" name="loginId" maxlength="16" class="ng-valid-pattern ng-valid-maxlength ng-dirty ng-valid-parse ng-valid ng-valid-required ng-touched" required="required">
#Password 
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[@class='ng-pristine ng-untouched ng-invalid ng-invalid-required ng-valid-pattern ng-valid-maxlength' and @name='password']"))).send_keys("DaHawg")


#Confirm Password
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[@class='ng-pristine ng-untouched ng-isolate-scope ng-invalid ng-invalid-required ng-valid-pattern ng-valid-maxlength ng-valid-compare' and @name='confirmPassword']"))).send_keys("DaHawg")

#State
state = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//select[@class='ng-pristine ng-untouched ng-invalid ng-invalid-required' and @name='state']")))
selectState = Select(state)
selectState.select_by_value('string:TX')

#First Name
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[@class='ng-pristine ng-untouched ng-invalid ng-invalid-required ng-valid-maxlength' and @name='firstName']"))).send_keys("DaHawg")

#Last Name
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[@class='ng-pristine ng-untouched ng-invalid ng-invalid-required ng-valid-maxlength' and @name='lastName']"))).send_keys("DaHawg")

#Workgroup ID
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[@class='ng-pristine ng-untouched ng-invalid ng-invalid-required ng-valid-maxlength' and @name='initials']"))).send_keys("DH")

#Phone Number 
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[@class='ng-pristine ng-untouched ng-invalid ng-invalid-required ng-valid-pattern ng-valid-maxlength' and @name='primaryPhone']"))).send_keys("8888888888")

#Extension
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[@class='ng-pristine ng-untouched ng-valid ng-valid-pattern ng-valid-maxlength' and @name='primaryExtension']"))).send_keys("12345")

#Email
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[@class='ng-pristine ng-untouched ng-valid-email ng-invalid ng-invalid-required ng-valid-maxlength' and @name='email']"))).send_keys("email@email.com")

#National Account: Combo Premium Pooling Subscription 
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//label[contains(text(),'National Account: Combo Premium Pooling Subscripti')]"))).click()

#National Account: Combo Premium Pooling Subscription 
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//label[normalize-space()='National Account: DAT Connexion Subscription']"))).click()

#National Account: Combo Premium Pooling Subscription 
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//label[normalize-space()='National Account: Power Broker Subscription']"))).click()

The Full HTML for all of the Inputs

<ng-form name="userProfileForm" class="userProfileContainer ng-pristine ng-invalid ng-invalid-required ng-valid-pattern ng-valid-maxlength ng-valid-email ng-valid-compare">
            <fieldset>
                <label>Username:</label>
                <input ng-required="true" ng-readonly="!hasPriviledgeToEdit(user)" ng-model="user.loginId" ng-pattern="/^[a-zA-Z0-9_]+$/" name="loginId" maxlength="16" class="ng-pristine ng-untouched ng-invalid ng-invalid-required ng-valid-pattern ng-valid-maxlength" required="required">
                4-16 chars; A-z, 0-9, _
                <!-- ngIf: userProfileForm.loginId.$error.required --><span ng-if="userProfileForm.loginId.$error.required" class="invalid warning ng-scope">Required</span><!-- end ngIf: userProfileForm.loginId.$error.required -->
                <!-- ngIf: userProfileForm.loginId.$error.pattern -->
            </fieldset>
            <fieldset>
                <label>Password:</label>
                <input ng-required="true" ng-pattern="/^[a-zA-Z0-9\p{P}\$\^\+=~`|]+$/" ng-model="user.password" type="password" name="password" maxlength="16" class="ng-pristine ng-untouched ng-invalid ng-invalid-required ng-valid-pattern ng-valid-maxlength" required="required">
                6-16 chars; A-z, 0-9, $ ^ + = ~ |
                <!-- ngIf: userProfileForm.password.$error.required --><span ng-if="userProfileForm.password.$error.required" class="invalid warning ng-scope">Required</span><!-- end ngIf: userProfileForm.password.$error.required -->
                <!-- ngIf: userProfileForm.password.$error.pattern -->
            </fieldset>
            <fieldset>
                <label>Confirm Password:</label>
                <input ng-required="true" ng-pattern="/^[a-zA-Z0-9\p{P}\$\^\+=~`|]+$/" ng-model="user.confirmPassword" type="password" compare-to="user.password" name="confirmPassword" maxlength="16" class="ng-pristine ng-untouched ng-isolate-scope ng-invalid ng-invalid-required ng-valid-pattern ng-valid-maxlength ng-valid-compare" required="required">
                <!-- ngIf: userProfileForm.confirmPassword.$error.required --><span ng-if="userProfileForm.confirmPassword.$error.required" class="invalid warning ng-scope">Required</span><!-- end ngIf: userProfileForm.confirmPassword.$error.required -->
                <!-- ngIf: userProfileForm.confirmPassword.$error.compare && !userProfileForm.confirmPassword.$error.required -->
            </fieldset>
            <fieldset>
                <label>Home State:</label>
                <select ng-model="user.state" ng-options="stateCode for stateCode in states" ng-required="true" name="state" class="ng-pristine ng-untouched ng-invalid ng-invalid-required" required="required"><option value="" class="" selected="selected"></option><option label="AB" value="string:AB">AB</option><option label="AG" value="string:AG">AG</option><option label="AK" value="string:AK">AK</option><option label="AL" value="string:AL">AL</option><option label="AR" value="string:AR">AR</option><option label="AS" value="string:AS">AS</option><option label="AZ" value="string:AZ">AZ</option><option label="BC" value="string:BC">BC</option><option label="BJ" value="string:BJ">BJ</option><option label="BS" value="string:BS">BS</option><option label="CA" value="string:CA">CA</option><option label="CH" value="string:CH">CH</option><option label="CI" value="string:CI">CI</option><option label="CL" value="string:CL">CL</option><option label="CO" value="string:CO">CO</option><option label="CP" value="string:CP">CP</option><option label="CT" value="string:CT">CT</option><option label="CU" value="string:CU">CU</option><option label="DC" value="string:DC">DC</option><option label="DE" value="string:DE">DE</option><option label="DF" value="string:DF">DF</option><option label="DG" value="string:DG">DG</option><option label="EM" value="string:EM">EM</option><option label="FL" value="string:FL">FL</option><option label="GA" value="string:GA">GA</option><option label="GJ" value="string:GJ">GJ</option><option label="GR" value="string:GR">GR</option><option label="GU" value="string:GU">GU</option><option label="HG" value="string:HG">HG</option><option label="HI" value="string:HI">HI</option><option label="IA" value="string:IA">IA</option><option label="ID" value="string:ID">ID</option><option label="IL" value="string:IL">IL</option><option label="IN" value="string:IN">IN</option><option label="JA" value="string:JA">JA</option><option label="KS" value="string:KS">KS</option><option label="KY" value="string:KY">KY</option><option label="LA" value="string:LA">LA</option><option label="MA" value="string:MA">MA</option><option label="MB" value="string:MB">MB</option><option label="MD" value="string:MD">MD</option><option label="ME" value="string:ME">ME</option><option label="MH" value="string:MH">MH</option><option label="MI" value="string:MI">MI</option><option label="MN" value="string:MN">MN</option><option label="MO" value="string:MO">MO</option><option label="MR" value="string:MR">MR</option><option label="MS" value="string:MS">MS</option><option label="MT" value="string:MT">MT</option><option label="NA" value="string:NA">NA</option><option label="NB" value="string:NB">NB</option><option label="NC" value="string:NC">NC</option><option label="ND" value="string:ND">ND</option><option label="NE" value="string:NE">NE</option><option label="NF" value="string:NF">NF</option><option label="NH" value="string:NH">NH</option><option label="NJ" value="string:NJ">NJ</option><option label="NL" value="string:NL">NL</option><option label="NM" value="string:NM">NM</option><option label="NS" value="string:NS">NS</option><option label="NT" value="string:NT">NT</option><option label="NU" value="string:NU">NU</option><option label="NV" value="string:NV">NV</option><option label="NY" value="string:NY">NY</option><option label="OA" value="string:OA">OA</option><option label="OH" value="string:OH">OH</option><option label="OK" value="string:OK">OK</option><option label="ON" value="string:ON">ON</option><option label="OR" value="string:OR">OR</option><option label="PA" value="string:PA">PA</option><option label="PE" value="string:PE">PE</option><option label="PQ" value="string:PQ">PQ</option><option label="PR" value="string:PR">PR</option><option label="PU" value="string:PU">PU</option><option label="QA" value="string:QA">QA</option><option label="QR" value="string:QR">QR</option><option label="RI" value="string:RI">RI</option><option label="SC" value="string:SC">SC</option><option label="SD" value="string:SD">SD</option><option label="SI" value="string:SI">SI</option><option label="SK" value="string:SK">SK</option><option label="SL" value="string:SL">SL</option><option label="SO" value="string:SO">SO</option><option label="TA" value="string:TA">TA</option><option label="TL" value="string:TL">TL</option><option label="TM" value="string:TM">TM</option><option label="TN" value="string:TN">TN</option><option label="TX" value="string:TX">TX</option><option label="UT" value="string:UT">UT</option><option label="VA" value="string:VA">VA</option><option label="VI" value="string:VI">VI</option><option label="VL" value="string:VL">VL</option><option label="VT" value="string:VT">VT</option><option label="WA" value="string:WA">WA</option><option label="WI" value="string:WI">WI</option><option label="WV" value="string:WV">WV</option><option label="WY" value="string:WY">WY</option><option label="YC" value="string:YC">YC</option><option label="YT" value="string:YT">YT</option><option label="ZT" value="string:ZT">ZT</option></select>
                <!-- ngIf: userProfileForm.state.$error.required --><span ng-if="userProfileForm.state.$error.required" class="invalid warning ng-scope">Required</span><!-- end ngIf: userProfileForm.state.$error.required -->
            </fieldset>
            <fieldset>
                <label>First Name:</label>
                <input ng-required="true" ng-readonly="!isTrustedAdmin()" ng-model="user.firstName" maxlength="30" name="firstName" class="ng-pristine ng-untouched ng-invalid ng-invalid-required ng-valid-maxlength" required="required">
                <!-- ngIf: userProfileForm.firstName.$error.required --><span ng-if="userProfileForm.firstName.$error.required" class="invalid warning ng-scope">Required</span><!-- end ngIf: userProfileForm.firstName.$error.required -->
            </fieldset>
            <fieldset>
                <label>Middle Name(s):</label>
                <input ng-readonly="!isTrustedAdmin()" ng-model="user.middleName" maxlength="30" class="ng-pristine ng-untouched ng-valid ng-valid-maxlength">
            </fieldset>
            <fieldset>
                <label>Last Name:</label>
                <input ng-required="true" ng-readonly="!isTrustedAdmin()" ng-model="user.lastName" maxlength="30" name="lastName" class="ng-pristine ng-untouched ng-invalid ng-invalid-required ng-valid-maxlength" required="required">
                <!-- ngIf: userProfileForm.lastName.$error.required --><span ng-if="userProfileForm.lastName.$error.required" class="invalid warning ng-scope">Required</span><!-- end ngIf: userProfileForm.lastName.$error.required -->
            </fieldset>
            <fieldset>
                <label class="wid">Workgroup ID:</label>
                <input ng-required="true" ng-model="user.initials" maxlength="3" name="initials" class="ng-pristine ng-untouched ng-invalid ng-invalid-required ng-valid-maxlength" required="required">
                <!-- ngIf: userProfileForm.initials.$error.required --><span ng-if="userProfileForm.initials.$error.required" class="invalid warning ng-scope">Required</span><!-- end ngIf: userProfileForm.initials.$error.required -->
            </fieldset>
            <fieldset>
                <label>Primary Phone:</label>
                <input ng-required="true" ng-readonly="!isTrustedAdmin()" ng-pattern="/^\d{8,10}$/" ng-model="user.primaryPhone" maxlength="10" name="primaryPhone" placeholder="8001112222" class="ng-pristine ng-untouched ng-invalid ng-invalid-required ng-valid-pattern ng-valid-maxlength" required="required">
                <!-- ngIf: userProfileForm.primaryPhone.$error.required --><span ng-if="userProfileForm.primaryPhone.$error.required" class="invalid warning ng-scope">Required</span><!-- end ngIf: userProfileForm.primaryPhone.$error.required -->
                <!-- ngIf: userProfileForm.primaryPhone.$error.pattern -->
                <label class="ext">Ext:</label>
                <input ng-pattern="/^\d{1,5}$/" ng-model="user.primaryExtension" maxlength="5" name="primaryExtension" placeholder="312" class="ng-pristine ng-untouched ng-valid ng-valid-pattern ng-valid-maxlength">
                <!-- ngIf: userProfileForm.primaryExtension.$error.pattern -->
            </fieldset>
            <fieldset ng-show="user.alternatePhone || isTrustedAdmin()">
                <label>Secondary Phone:</label>
                <input ng-readonly="!isTrustedAdmin()" ng-pattern="/^\d{8,10}$/" ng-model="user.alternatePhone" name="alternatePhone" maxlength="10" placeholder="8001112222" class="ng-pristine ng-untouched ng-valid ng-valid-pattern ng-valid-maxlength">
                <!-- ngIf: userProfileForm.alternatePhone.$error.pattern -->
                <label class="ext">Ext:</label>
                <input ng-pattern="/^\d{1,5}$/" ng-model="user.alternateExtension" name="alternateExtension" maxlength="5" placeholder="312" class="ng-pristine ng-untouched ng-valid ng-valid-pattern ng-valid-maxlength">
                <!-- ngIf: userProfileForm.alternateExtension.$error.pattern -->
            </fieldset>
            <fieldset>
                <label>Email:</label>
                <input name="email" maxlength="50" type="email" ng-model="user.email" ng-required="true" class="ng-pristine ng-untouched ng-valid-email ng-invalid ng-invalid-required ng-valid-maxlength" required="required">
                <!-- ngIf: userProfileForm.email.$error.required --><span ng-if="userProfileForm.email.$error.required" class="invalid warning ng-scope">Required</span><!-- end ngIf: userProfileForm.email.$error.required -->
                <!-- ngIf: userProfileForm.email.$error.email -->
            </fieldset>
            <fieldset>
                <label>Group:</label>
                <select ng-model="user.groupId" ng-change="onGroupChanged(user)" ng-options="item.id as item.name for item in office.groups" class="ng-pristine ng-untouched ng-valid"><option value="" class="" selected="selected">-- None --</option></select>
            </fieldset>
            <div class="formfield buttons">
                <button class="cancel" type="button" ng-click="cancelEdit(user)"></button>
                <button ng-show="!user.isNew &amp;&amp; user.isActive" class="save ng-hide" type="submit" ng-click="save(user, userProfileForm)">Save</button>
                <button ng-show="!user.isNew &amp;&amp; user.isActive" class="deactivate ng-hide" type="submit" ng-click="deactivate(user, userProfileForm)">Deactivate</button>
                <button ng-show="!user.isNew &amp;&amp; !user.isActive" class="activate ng-hide" type="submit" ng-click="activate(user, userProfileForm)">Activate</button>
                <button ng-show="user.isNew" class="save" type="submit" ng-click="create(user, userProfileForm)">Add User</button>
                <button ng-show="!user.isNew" class="delete ng-hide" type="submit" ng-click="delete(user, userProfileForm)">Delete</button>
            </div>
        </ng-form>

Where I am trying to input data

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
DaHawg
  • 73
  • 5

1 Answers1

0

Unlike the Password Element element, the Confirm Password Element contains different set of classnames as follows:

<input class="ng-pristine ng-untouched ng-isolate-scope ng-invalid ng-invalid-required ng-valid-pattern ng-valid-maxlength ng-valid-compare" ...>

which your locator strategy doesn't identifies. Hence you see TimeoutException.


Solution

To identify the Confirm Password Element you can use either of the following locator strategies:

  • Using CSS_SELECTOR:

    element = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input.ng-pristine.ng-untouched.ng-isolate-scope.ng-invalid.ng-invalid-required.ng-valid-pattern.ng-valid-maxlength.ng-valid-compare[name='confirmPassword']")))
    
  • Using XPATH:

    element = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[@class='ng-pristine ng-untouched ng-isolate-scope ng-invalid ng-invalid-required ng-valid-pattern ng-valid-maxlength ng-valid-compare' and @name='confirmPassword']")))
    
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
  • Using the script you provided still provides a Timeoutexception error – DaHawg Aug 08 '22 at 20:35
  • I don't find the **Confirm Password Element** within the [webpage](https://power.dat.com). Am I missing something? – undetected Selenium Aug 08 '22 at 20:38
  • It is behind a admin account login. I will add a picture of what the page looks like. – DaHawg Aug 08 '22 at 20:39
  • Instead of picture, we'd prefer the text based formatted HTML. – undetected Selenium Aug 08 '22 at 20:44
  • Just added the full HTML for the entire section I am trying to write to. – DaHawg Aug 08 '22 at 20:52
  • Still don't have an explaination. One last time check if the element is within an [` – undetected Selenium Aug 08 '22 at 21:06
  • It is not in a iframe or shadow-root. It is in a ng-form but so is every other element and I have been able to access all of them. – DaHawg Aug 08 '22 at 21:36
  • Let's discuss the issue in [Selenium](https://chat.stackoverflow.com/rooms/223360/selenium) room. – undetected Selenium Aug 08 '22 at 21:38
  • 1
    So I actually just got it working. I switched the XPATH to element = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[@name='confirmPassword']"))) and it worked don't know why when every other element need the type of xpath you provided – DaHawg Aug 08 '22 at 21:44