Jump to content

Need help using regex or broad XPath values to interact with DOM elements in the webpage using webdriver utility


Recommended Posts

Posted

I am writing a generic script that can work for logging into most of the websites if not all. The only way I have got it working is by storing multiple xPath values in different variables and using If statement against web element field when one of the conditions are true.

For example: This works but expanding the search by adding more variables over the time isn't a practical solution.

Local $oUserName    = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "//*[@id='j_username']") ; CDP and CFM ClouderaManager username
   Local $oUserName1    = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "//*[@id='loginForm']/div/div[1]/div/input") ; Kafka ClouderaManager username
   Local $oUserName2    = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "//*[@id='username']") ; SMM, Ranger and NiFi Web UI username

   
   If ($oUserName) Then
        _WD_ElementAction($sSession, $oUserName, 'value', $TargetUsername)
    ElseIf ($oUsername1) Then
        _WD_ElementAction($sSession, $oUserName1, 'value', $TargetUsername)
    ElseIf ($oUsername2) Then
        _WD_ElementAction($sSession, $oUserName2, 'value', $TargetUsername)
    EndIf

I would like to use a smarter way of either defining regex against the single variable to interact with various web elements input field or broaden the xPath lookup. I have tried below but nothing happens. None of the actions are taken by script.

Local $oUserName, $sUserName, $oPassword, $sPassword, $oButton, $sButton
    
    $oUserName = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "//*[contains(@id,'user')]" or "//*[contains(@id,'j_username')]" or "//*[contains(@id,'username')]" or "//*[contains(@placeholder,'username')]")

   ; Loop through the elements found by the XPath query
    For $i = 0 To UBound($oUserName) - 1
            $sUserName = $oUserName[$i]
            _WD_ElementAction($sSession, $sUserName, 'value', $TargetUsername)
    Next
    
   $oPassword = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "//*[contains(@name,'password')]" or "//*[contains(@id,'password')]" or "//*[contains(@id,'j_password')]" or "//*[contains(@id,'pass')]" or "//*[contains(@placeholder,'password')]")

    For $i = 0 To UBound($oPassword) - 1
            $sPassword = $oPassword[$i]
            _WD_ElementAction($sSession, $sPassword, 'value', $TargetPassword)
    Next
   
    $oButton = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "//*[contains(@name,'submit')]" or "//*[contains(@id,'login-submission-button')]" or "//*[contains(@id,'signIn')]" or "//*[contains(@id,'loginForm')]" or "//*[contains(@name,'signIn')]")
   
    For $i = 0 To UBound($oButton) - 1
            $sButton = $oButton[$i]
            _WD_ElementAction($sSession, $sButton, 'click')
    Next

Any idea what am I doing wrong ? @Danp2

Thanks in advance.

Posted

Thanks @Danp2. So, in AutoIT it works with below syntax for @id but not with text(), name or placeholders. I'm sure I am missing the syntax somewhere.

 

Local $oUserName, $oPassword, $oButton
    
    $oUserName = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "//input[@id='username' or @id='j_username' or @id='user' or @id='loginForm']")
    _WD_ElementAction($sSession, $oUserName, 'value', $TargetUsername)
    
   $oPassword = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "//input[@id='password' or @id='j_password' or @id='pass' or @name='password']")
    _WD_ElementAction($sSession, $oPassword, 'value', $TargetPassword)
   
    $oButton = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "//*[@id='submit' or @id='login-submission-button' or @id='signIn' or @id='loginForm' or @text(),'Sign In']")
    _WD_ElementAction($sSession, $oButton, 'click')

 

Posted

Does it look correct syntax @Danp2 to cover login process for most of the websites ? I tried using all the different methods such as using Arrays , xPath mappings, regex but none of them returned positive outcome. 

; References to HTML elements in the login process
   
    Local $oUserName  = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "//*[@id='j_username']")
    Local $oUserName1  = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "//*[@id='loginForm']/div/div[1]/div/input")
    Local $oUserName2  = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "//*[@id='username']")
    Local $oUsername3   =  _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "//input[@name, 'user']")
    Local $oUsername4   =  _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "//input[@text(), 'User name']")
    
    Local $oPassword    = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "//*[@id='j_password']")
    Local $oPassword1   = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "//*[@id='loginForm']/div/div[2]/div/input[3]")
    Local $oPassword2   = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "//*[@id='password']")
    Local $oPassword3   =  _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "//input[@name, 'pass']")
    Local $oPassword4   =  _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "//input[@text(), 'Password']")
    
    Local $SignIn   = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "//*[@id='main-page-content']/form/div[4]/button")
    Local $SignIn1 = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath,"//*[@id='loginForm']/div/div[4]/div/button")
    Local $SignIn2 = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath,"//*[@id='root']/div/div/div/div[2]/div/form/button")
    Local $SignIn3 = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath,"//*[@id='signIn']")
    Local $SignIn4 = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath,"//*[@id='login-submission-button']")
    Local $SignIn5 = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath,"//*[@text()='Sign In']")
    
    ;Interact with username field
     If ($oUserName) Then
        _WD_ElementAction($sSession, $oUserName, 'value', $TargetUsername)
    ElseIf ($oUsername1) Then
        _WD_ElementAction($sSession, $oUserName1, 'value', $TargetUsername)
    ElseIf ($oUsername2) Then
        _WD_ElementAction($sSession, $oUserName2, 'value', $TargetUsername)
    ElseIf ($oUsername3) Then
        _WD_ElementAction($sSession, $oUserName3, 'value', $TargetUsername)
    ElseIf ($oUsername4) Then
        _WD_ElementAction($sSession, $oUserName4, 'value', $TargetUsername)
    EndIf
    
    ;Interact with password field
    If ($oPassword) Then
        _WD_ElementAction($sSession, $oPassword, 'value', $TargetPassword)
    ElseIf ($oPassword1) Then
        _WD_ElementAction($sSession, $oPassword1, 'value', $TargetPassword)
    ElseIf ($oPassword2) Then
        _WD_ElementAction($sSession, $oPassword2, 'value', $TargetPassword)
    ElseIf ($oPassword3) Then
        _WD_ElementAction($sSession, $oPassword3, 'value', $TargetPassword)
    ElseIf ($oPassword4) Then
        _WD_ElementAction($sSession, $oPassword4, 'value', $TargetPassword)
    EndIf
    
    ;Interact with buttons
    If ($SignIn) Then
        _WD_ElementAction($sSession, $SignIn, 'click')
    ElseIf ($SignIn1) Then
        _WD_ElementAction($sSession, $SignIn1, 'click')
    ElseIf ($SignIn2) Then
        _WD_ElementAction($sSession, $SignIn2, 'click')
    ElseIf ($SignIn3) Then
        _WD_ElementAction($sSession, $SignIn3, 'click')
    ElseIf ($SignIn4) Then
        _WD_ElementAction($sSession, $SignIn4, 'click')
    ElseIf ($SignIn5) Then
        _WD_ElementAction($sSession, $SignIn5, 'click')
    EndIf

 

Posted

Thanks @Danp2. In theory, the first option you have mentioned is what exactly my current script does. When website is launched it looks for one of the webform elements defined in the script and takes necessary action unless you meant inspecting the elements based on ID, Xpath, name, text etc in real time as part of the script. 
I can think of something like that in powershell or python. AutoIT is a grey area for me when it comes to complex scripting.

Storing the xPaths in database or script is something I already wish to avoid as that leads to manual overhead of inspecting the element manually and updating the script or repo with a possible xpath.

The way script works is users login to a PAM solution where their credentials are vaulted. They search for their account, enter URL and hit connect after which credentials are fetched by AutoIT script and transparently passed to the DOM elements of webpage. 
So, I have got two options to get this working:

A. Write up a nice python script that handles the web insepction, variables etc and AutoIT simply works as a dispatcher to execute the webdriver.

B. Create an mssql DB where all the 100s of xPaths are stored and periodically updated for any new xpath. Call the separate powershell script within AutoIt that runs the stored procedures to filter xpaths, uses switch function, handles variables etc and AutoIT is just used to launch the initial webdriver session.

Posted
1 hour ago, abs said:

In theory, the first option you have mentioned is what exactly my current script does.

Not really IMO. Your script calls the webdriver repeatedly for all sites, which will be much slower than necessary. In my scenario, you can make a single call to _WD_Action to retrieve the current URL, and then make only the needed webdriver requests for the given website.

Quote

Storing the xPaths in database or script is something I already wish to avoid as that leads to manual overhead of inspecting the element manually and updating the script or repo with a possible xpath.

Well, you are already storing the xpath in the script. Using a database allows you to update the settings without having to stop or reload the script. There isn't any need to introduce Python or MSSQL to the mix. There are multiple database options that you could use that don't require these.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...