I'm trying to automate a website to automatically make user profiles. Have run into a NG button that I have not be able to select. I have tried XPATH, CSS, and Class Name. None to these seem to work. I keep getting "NoSuchElementException" with:
By.XPATH, '//button[normalize-space()="Create New User"]'
and
By.CSS_SELECTOR, '.newUser.ng-scope'
When I try to use Webdriverwait, I get a time out error.
Code trials:
import time
from webbrowser import Chrome
from xml.etree.ElementPath import find
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
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')
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('')
#(time.sleep(3))
loginbutton = driver.find_element(By.XPATH, '//*[@id="submit-button"]')
loginbutton.click()
(time.sleep(5))
profiledrop = driver.find_element(By.XPATH, '//*[@id="user-salutation"]')
profiledrop.click()
Adminbutton = driver.find_element(By.CSS_SELECTOR, '#userPreferencesUl > li:nth-child(5) > a')
Adminbutton.click()
# (time.sleep(10))
NewUsrBtn = driver.find_element(By.XPATH, '//button[normalize-space()="Create New User"]')
NewUsrBtn.click()
#WebDriverWait(driver , 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, '.newUser.ng-scope'))).click()`
The HTML
<header>
<ul>
<!-- ngRepeat: product in office.products --><!-- ngIf: product.seatCount --><li ng-repeat="product in office.products" ng-if="product.seatCount" class="ng-scope">
<span class="product ng-binding">National Account: Combo Premium Pooling Subscription</span> <span class="count ng-binding">999999841</span> seats out of <span class="total ng-binding">999999999</span> available
</li><!-- end ngIf: product.seatCount --><!-- end ngRepeat: product in office.products --><!-- ngIf: product.seatCount --><li ng-repeat="product in office.products" ng-if="product.seatCount" class="ng-scope">
<span class="product ng-binding">National Account: DAT Connexion Subscription</span> <span class="count ng-binding">999999181</span> seats out of <span class="total ng-binding">999999999</span> available
</li><!-- end ngIf: product.seatCount --><!-- end ngRepeat: product in office.products --><!-- ngIf: product.seatCount --><li ng-repeat="product in office.products" ng-if="product.seatCount" class="ng-scope">
<span class="product ng-binding">National Account: Power Broker Subscription</span> <span class="count ng-binding">999999182</span> seats out of <span class="total ng-binding">999999999</span> available
</li><!-- end ngIf: product.seatCount --><!-- end ngRepeat: product in office.products -->
</ul>
<h3 class="ng-binding">Total Quality Logistics INC</h3>
<p>Need help? Customer support is available 4AM-6PM Pacific weekdays and 5AM-12PM Pacific Saturdays at
<span class="supportPhone">1-800-848-2546.</span></p>
<!-- ngIf: isTrustedAdmin() -->
<button class="newUser ng-scope" type="button" ng-if="isTrustedAdmin()" ng-click="onNewUser();" ng-disabled="user.isInEditMode">
Create New User
</button><!-- end ngIf: isTrustedAdmin() -->
<button class="manageGroups" type="button" ng-click="onManageGroups();">
Manage Groups
</button>
</header>
I also attached a screen shot of more of the HTML if needed
The desired element is an Angular element, so to click on the clickable element you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following locator strategies:
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button.newUser.ng-scope[ng-if^='isTrustedAdmin'][ng-click^='onNewUser']"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[@class='newUser ng-scope' and contains(., 'Create New User')][starts-with(@ng-if, 'isTrustedAdmin') and starts-with(@ng-click, 'onNewUser')]"))).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
As a last resort to to click using execute_script()
as follows:
Using CSS_SELECTOR:
driver.execute_script("arguments[0].click();", driver.find_element(By.CSS_SELECTOR, "button.newUser.ng-scope[ng-if^='isTrustedAdmin'][ng-click^='onNewUser']"))
Using XPATH:
driver.execute_script("arguments[0].click();", driver.find_element(By.XPATH, "//button[@class='newUser ng-scope' and contains(., 'Create New User')][starts-with(@ng-if, 'isTrustedAdmin') and starts-with(@ng-click, 'onNewUser')]"))