Home > Software engineering >  How to send text into a angular input field after switching tabs using Selenium Python
How to send text into a angular input field after switching tabs using Selenium Python

Time:08-05

I am trying to input text into a Angular input field after switching tabs. I keep getting either:

AttributeError: 'tuple' object has no attribute 'send_keys'

error or

ElementClickInterceptedException

or

NoSuchElementException

I have also noticed that the click() command is no longer a method but say click: Any.

Below is the HTML for the input field I am trying to input text into:

<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"  required="required">
    4-16 chars; A-z, 0-9, _
    <!-- ngIf: userProfileForm.loginId.$error.required --><span ng-if="userProfileForm.loginId.$error.required" >Required</span><!-- end ngIf: userProfileForm.loginId.$error.required -->
    <!-- ngIf: userProfileForm.loginId.$error.pattern -->
</fieldset>

Below is the code:

from multiprocessing.connection import wait
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
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(5))

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

#store original window ID
original_window = 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
wait.until(EC.number_of_windows_to_be(2))

#loops through till new window is confirmed open
for window_handle in driver.window_handles:
    if window_handle != original_window:
        driver.switch_to.window(window_handle)
        break

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


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


UsrNM = driver.find_element(By.XPATH, "//input[@name='loginId']")
UsrNM.send_keys('justin')

If you can explain how to get the proper Xpath for this element and if there is anything I need to do to make sure the driver continues to point to the new tab.

I have tried the below paths:

//input[@name='loginId']

input[name='loginId']

//*[@id="data"]/div[3]/table/tbody[1]/tr/td[1]/ng-form/fieldset[1]/input

#data > div.fixed-table-container-inner > table > tbody:nth-child(2) > tr > td:nth-child(1) > ng-form > fieldset:nth-child(1) > input

CodePudding user response:

As per the HTML:

<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"  required="required">
    4-16 chars; A-z, 0-9, _
    ...
</fieldset>

the element is an Angular element, so ideally to send a character sequence to the 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, "input.ng-pristine.ng-untouched.ng-invalid.ng-invalid-required.ng-valid-pattern.ng-valid-maxlength[name='loginId']"))).send_keys("DaHawg")
    
  • Using XPATH:

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