Home > Enterprise >  Selenium Automation Angular JS Button (Python) (Chrome)
Selenium Automation Angular JS Button (Python) (Chrome)

Time:08-04

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" >
                <span >National Account: Combo Premium Pooling Subscription</span> <span >999999841</span> seats out of <span >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" >
                <span >National Account: DAT Connexion Subscription</span> <span >999999181</span> seats out of <span >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" >
                <span >National Account: Power Broker Subscription</span> <span >999999182</span> seats out of <span >999999999</span> available
            </li><!-- end ngIf: product.seatCount --><!-- end ngRepeat: product in office.products -->
        </ul>
        <h3 >Total Quality Logistics INC</h3>
        <p>Need help? Customer support is available 4AM-6PM Pacific weekdays and 5AM-12PM Pacific Saturdays at 
<span >1-800-848-2546.</span></p>
        <!-- ngIf: isTrustedAdmin() -->
<button  type="button" ng-if="isTrustedAdmin()" ng-click="onNewUser();" ng-disabled="user.isInEditMode">
            Create New User
        </button><!-- end ngIf: isTrustedAdmin() -->

        <button  type="button" ng-click="onManageGroups();">
            Manage Groups
        </button>
    </header>

I also attached a screen shot of more of the HTML if needed

Full HTML

CodePudding user response:

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
    

Update

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')]"))
    
  • Related