Jump to content
Danp2

WebDriver UDF (W3C compliant version) - 04/28/2021

Recommended Posts

Hi, congratulations on your UDF, @Danp2 it's the first time I've used it,(I am not expert ) I wanted to know if it's possible to start the browser with the plugins already installed? because when firefox starts it's without any plugins. 

I hope I have written in the right section, if not, please excuse me.

 

bye

Share this post


Link to post
Share on other sites

Is there any debuggers that work with the WD Driver? I tried using the Graphical Debugger from here http://www.thefoolonthehill.net/drupal/AutoIt Debugger, but when I try to run it step by step, it just jumps between WinHttps and wd_core in a perpetual loop, after 20 minutes of this I stopped it.

Is there any good tutorials or videos on how to click on buttons, links and banners on the webpage for beginners? Wiki is not too descriptive and does not have syntax or examples. 

 

Share this post


Link to post
Share on other sites

Latest update just released. See below for change log.

Quote

    v0.4.0.3
    - Changed (_WD_HighlightElement): Option to remove highlight
    - Fix (_WD_SetElementValue): Corrected leftover $iMethod reference
    - Fix (_WD_FrameEnter) Properly handle Null index (mLipok)
    - Fix (_WD_SelectFiles) Properly set value of $sFuncName (mLipok)
    - Fix (_WD_ElementActionEx) Properly terminate JSON string
    - Chore (_WD_IsLatestRelease) Remove unneeded code for saving debug level (seadoggie01)
    - Chore (_WD_GetShadowRoot) Remove unused variable (seadoggie01)

 

Share this post


Link to post
Share on other sites

Good morning everyone, 

;Loading...
    _WD_WaitElement($sSession, $_WD_LOCATOR_ByXPath, "//div[@id='popups-loading']//div[contains(text(),'Loading...')]")
    $sElement = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "//div[@id='popups-loading']//div[contains(text(),'Loading...')]")
    If @error = $_WD_ERROR_NoMatch Then
        ;MsgBox($MB_SYSTEMMODAL, "Loading... message not found", "")
        ;MsgBox($MB_SYSTEMMODAL, "Click the Remove button", "//form[@id='s-library-template-unpublish-form']//input[@id='edit-submit']")
        _WD_WaitElement($sSession, $_WD_LOCATOR_ByXPath, "//div[(@class='title') and text() = 'Remove Public Version']", Default, 30*60*1000)
        ;_WD_WaitElement($sSession, $_WD_LOCATOR_ByXPath, "//form[@id='s-library-template-unpublish-form']//input[@id='edit-submit']")
        $sElement = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "//form[@id='s-library-template-unpublish-form']//input[@id='edit-submit']")
        _WD_ElementAction($sSession, $sElement, 'click')
        _WD_LoadWait($sSession, 2000)
    EndIf

Working in Schoology; optimizing a file uploader script. A window that says "Loading..." will appear on certain actions. I am trying to get the script to detect when this window appears and essentially wait until the window goes away until continuing the next action. The script above seems to work but also seems very delayed. I feel like I am not doing something correctly with the _WD_WaitElement and I am wondering how the "$lVisible" works. 

; #FUNCTION# ====================================================================================================================
; Name ..........: _WD_WaitElement
; Description ...: Wait for a element to be found  in the current tab before returning
; Syntax ........: _WD_WaitElement($sSession, $sStrategy, $sSelector[, $iDelay = Default[, $iTimeout = Default[, $lVisible = Default[,
;                                   $lEnabled = Default[, $lReturnElement = Default]]]]])
; Parameters ....: $sSession            - Session ID from _WD_CreateSession
;                  $sStrategy           - Locator strategy. See defined constant $_WD_LOCATOR_* for allowed values
;                  $sSelector           - Value to find
;                  $iDelay              - [optional] Milliseconds to wait before checking status
;                  $iTimeout            - [optional] Period of time to wait before exiting function
;                  $lVisible            - [optional] Check visibility of element?
;                  $lEnabled            - [optional] Check enabled status of element?
;                  $lReturnElement      - [optional] Return found element?
; Return values .: Success      - 1 or element ID
;                  Failure      - 0 and sets the @error flag to non-zero
;                  @error       - $_WD_ERROR_Success
;                               - $_WD_ERROR_Timeout
; Author ........: Dan Pollak
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: No
; ===============================================================================================================================

Thank you for your time and attention to this matter and please have a great day, 




Thomas

Share this post


Link to post
Share on other sites

@ThomasBennett You might be able to speed things up a bit by changing your call to _WD_WaitElement so that it returns the found element so that you don't need to call _WD_FindElement afterwards. It appears that you aren't using the latest UDF version, so you may want to update to benefit from the latest fixes.

FYI, @mLipok has proposed a change here that may benefit you once it gets approved / merged.

Share this post


Link to post
Share on other sites
Posted (edited)
6 hours ago, Danp2 said:

@ThomasBennett You might be able to speed things up a bit by changing your call to _WD_WaitElement so that it returns the found element so that you don't need to call _WD_FindElement afterwards. It appears that you aren't using the latest UDF version, so you may want to update to benefit from the latest fixes.

FYI, @mLipok has proposed a change here that may benefit you once it gets approved / merged.

@Danp2, Thank you for your help and I think the proposed change by @mLipok will be awesome. 

Code that resolved my issue:

While $x = 1
        _WD_WaitElement($sSession, $_WD_LOCATOR_ByXPath, "//div[@id='popups-loading']//div[contains(text(),'Loading...')]")
        $sElement = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "//div[@id='popups-loading']//div[contains(text(),'Loading...')]")
        If @error = $_WD_ERROR_Success Then
            ;MsgBox($MB_SYSTEMMODAL, "Waiting for the Loading... screen to go away.", "Autoclosing this MsgBox", 1)
        Else
            SetError($_WD_ERROR_NoMatch)
            ;MsgBox($MB_SYSTEMMODAL, "Exiting While Loop", "Autoclosing this MsgBox", 5)
            $x = $x + 1
        EndIf
    WEnd
    $x = 1

    _WD_LoadWait($sSession, 2000)

I have a new question; I am trying to read the text "30 of 31" from a Schoology Resources webpage. Once the text is read I will use StringSplit to put what's needed into individual variables and manipulate further from there. I am hung up on how to read the text into a variable. 

Xpath

//thead[@class='tableHeader-processed']//div[@class='collection-paging-info']/

I understand that the code below should allow for the text to be read into a variable

//thead[@class='tableHeader-processed']//div[@class='collection-paging-info']/text()

I am struggling on how to call this Xpath to read into a variable would I use "_WD_ExecuteScript" for this?

Thank you again for your time and consideration,



Thomas

Edited by ThomasBennett
I don't know how to use the @ :P

Share this post


Link to post
Share on other sites

@ThomasBennett I would have written the loop like this --

While True
        $nResult = _WD_WaitElement($sSession, $_WD_LOCATOR_ByXPath, "//div[@id='popups-loading']//div[contains(text(),'Loading...')]")
        
        If $nResult = 1 And @error = $_WD_ERROR_Timeout Then
            ExitLoop
        EndIf
WEnd

Obviously, this doesn't handle any other type of error that may occur and I didn't set @error like you did.

Yes, you could use _WD_ExecuteScript to retrieve the text, but a more traditional method would be like this --

$sElement = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "//thead[@class='tableHeader-processed']//div[@class='collection-paging-info']")

; Either of the following should work
$sValue1 = _WD_ElementAction($sSession, $sElement, 'property', 'value')
$sValue2 = _WD_ElementAction($sSession, $sElement, 'value')

 

Share this post


Link to post
Share on other sites

@Danp2, thank you for the optimized code!

I made a few modifications:

;Loading...
    While True
        $nResult = _WD_WaitElement($sSession, $_WD_LOCATOR_ByXPath, "//div[@id='popups-loading']//div[contains(text(),'Loading...')]")
        ;MsgBox($MB_SYSTEMMODAL, "nResult Value", $nResult, 1)
        If $nResult = 0 Or @error = $_WD_ERROR_Timeout Then
            ;MsgBox($MB_SYSTEMMODAL, "nResult Value", $nResult, 5)
            ExitLoop
        EndIf
    WEnd

I made a few modifications:

; Taught how to do the below code:
    ; https://www.autoitscript.com/forum/topic/191990-webdriver-udf-w3c-compliant-version-04282021/page/50/#comments

    $sElement = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "//thead[@class='tableHeader-processed']//div[@class='collection-paging-info']")
    $sValue1 = _WD_ElementAction($sSession, $sElement, 'property', 'innerText')
    ;MsgBox($MB_SYSTEMMODAL, "sValue1", $sValue1, 5)

    $aLine2 = StringSplit($sValue1, ' ', 1)

    MsgBox($MB_SYSTEMMODAL, "", $aLine2[0], 5) ; Total number of cells in the array.
    MsgBox($MB_SYSTEMMODAL, "", $aLine2[1], 5) ; First Number
    MsgBox($MB_SYSTEMMODAL, "", $aLine2[2], 5) ; of
    MsgBox($MB_SYSTEMMODAL, "", $aLine2[3], 5) ; Second Number

    $a = $aLine2[1]
    $b = $aLine2[3]

    MsgBox($MB_SYSTEMMODAL, "", $a, 5)
    MsgBox($MB_SYSTEMMODAL, "", $b, 5)


    If $b <= 32 Then
        While True
            If $a == $b Then
                ExitLoop
            EndIf
            WinActivate ("Schoology - Google Chrome")
            Send("{PGDN}")
            Sleep(2000)
            _WD_LoadWait($sSession, 2000)
            $sElement = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "//thead[@class='tableHeader-processed']//div[@class='collection-paging-info']")
            $sValue1 = _WD_ElementAction($sSession, $sElement, 'property', 'innerText')
            $sLine2 = StringSplit($sValue1, ' ', 1)
            $a = $sLine2[1]
            $b = $sLine2[3]
        WEnd
    EndIf

Both are working correctly and everything is running much faster now. Thank you again!

Working on a few other things but going to call it a night for now. 

Thank you again for your time and consideration,




Thomas

Share this post


Link to post
Share on other sites
8 hours ago, ThomasBennett said:

thank you for the optimized code!

You're welcome!

8 hours ago, ThomasBennett said:

If $nResult = 0 Or @error = $_WD_ERROR_Timeout Then

I'm still not sure this logic is correct. I think you want an 'And' instead of 'Or' because you can't get @error = $_WD_ERROR_Timeout without $nResult = 0

 

Share this post


Link to post
Share on other sites

Good morning @Danp2,

If $nResult = 0 Or @error = $_WD_ERROR_Timeout Then

Please do not take what I am about to say as an attack or anything personal; this is only me explaining my logic at my level of understanding.

There will be flaws in my logic and explanation. 🤓

With some limited testing I found that when the "Loading..." popup window goes away $nResult flips to 0; but I was still in the WhileLoop because the @error never seemed to = $_WD_ERROR_Timeout. So I figured the "AND" was the problem and flipped it to "OR". I was thinking about dropping the @error part altogether but figured it wouldn't hurt to have in place. 

Please tell me if my logic is flawed and thank you again for your time and consideration on this. Now back to figuring out why the laptop can't find the numbers on the screen but the desktop can find the numbers on the screen and the script works correctly on the desktop. Both are running the same version of Google Chrome: Version 90.0.4430.93 (Official Build) (64-bit). Both are Windows 10 x64. 

Thank you again and again, 




Thomas

Share this post


Link to post
Share on other sites

@Danp2 past experience; so I tend to lead with apologies early in case of hurt feelings and text can cause confusion. 😇

It was late last night when I did this so I probably did it wrong. I outputted @error to a msgbox and would only receive a "7" as the output. I was expecting the see something like: "$_WD_ERROR_Timeout". 

Using the msgbox to show the value of $nResult is what taught me the flip from 1 to 0.

What's the best method to output the @error information?

Thank you




Thomas

Share this post


Link to post
Share on other sites
1 hour ago, ThomasBennett said:

I outputted @error to a msgbox and would only receive a "7" as the output. I was expecting the see something like: "$_WD_ERROR_Timeout". 

$_WD_ERROR_Timeout is an enum that happens to corelate to the number 7. So you were receiving $_WD_ERROR_Timeout, but you just didn't know it. 😄

Share this post


Link to post
Share on other sites

The UDF is really good. 


But I’m looking  for a function to get the Id of  a element.
I find the element by XPath, but I can’t found a function to get the id of this element.

I can’t believe, I think I not to see the forest for the trees. 
Can somebody give me a tip with that.

 

Share this post


Link to post
Share on other sites

@ReM You'll want _WD_ElementAction with either attribute or property as the command and id as the option... I don't remember which, but you can figure that out ;)


All my code provided is Public Domain... but it may not work. ;) Use it, change it, break it, whatever you want.

Spoiler

My Humble Contributions:
Personal Function Documentation - A personal HelpFile for your functions
Acro.au3 UDF - Automating Acrobat Pro
ToDo Finder - Find #ToDo: lines in your scripts

Share this post


Link to post
Share on other sites
Posted (edited)

I tried 

WD_ElementAction (Session,Element, “attribute”,“id” ) and it’s function.

Great!!!

I thought the option is only for setting an attribute value.

@seadoggie01 @Danp2 Thank you 


 

Edited by ReM

Share this post


Link to post
Share on other sites

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

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By Hermes
      Hi, I have a site that has the following elements below: 
      <div>More element here</div> <div>More element here</div> <div>More element here</div> When I do this in Auto It:
      Local $oSelectDiv = _WD_FindElement($sSession, $_WD_LOCATOR_ByCSSSelector, "div") _WD_HighlightElement($sSession, $oSelectDiv, 1) I also tried to add [3], but it doesnt seems to work:
      Local $oSelectDiv = _WD_FindElement($sSession, $_WD_LOCATOR_ByCSSSelector, "div[3]") _WD_HighlightElement($sSession, $oSelectDiv, 1) It always highlight the first one, but I am trying to highlight the 3rd in the list. Is there anyway to select the 3rd div without having to add any class/id in the divs, and without using XPATH? The structure of the elements in that site were built that way.
    • By ReM
      Hallo Experts,
      Your testsite and the examples are very good. Thanks a lot.  
      I used your example with Chromewebdriver. The Chrome Browser open, the site will shown, but all other functions not executed.
      The Chomedriver.exe Windows shows this text:
      Starting ChromeDriver 90.0.4430.24 (4c6d850f087da467d926e8eddb76550aed655991-refs/branch-heads/4430@{#429}) on port 9515 Only local connections are allowed. Please see https://chromedriver.chromium.org/security-considerations for suggestions on keeping ChromeDriver safe. ChromeDriver was started successfully. DevTools listening on ws://127.0.0.1:54044/devtools/browser/3c17aefd-a104-43e7-8c17-318963cda872 [12848:3100:0501/153128.889:ERROR:device_event_log_impl.cc(214)] [15:31:28.888] USB: usb_device_handle_win.cc:1054 Failed to read descriptor from node connection: Ein an das System angeschlossenes Gerõt funktioniert nicht. (0x1F) [12848:3100:0501/153128.896:ERROR:device_event_log_impl.cc(214)] [15:31:28.896] USB: usb_device_handle_win.cc:1054 Failed to read descriptor from node connection: Ein an das System angeschlossenes Gerõt funktioniert nicht. (0x1F) The Error :  A devise connected to the systen does not work (0x1F)
      Win 10
      Chrome & Driver 90
      What i do wrong. Can you help me?
      Reiner
       
       
    • By TheOne23
      Hi Danp2,
       
      May I seek your a help and assistance why the page to download the chrome driver version 89 is not accessible.
      Getting below error page:

       
      Thanks in advance.
      TheOne23
    • By Hermes
      I have an html table that displays data along with an excel spreadsheet that has the same data as the html table. I am wanting to only match the Title column in my html table with the Title column in my Excel spreadsheet. If the titles match, click on the Edit hyperlink and continue to loop to next row. The issue I'm experience is its not matching correctly. So far  i've written the codes below:
      <table border="1" class="test"> <tr> <th> UniqueID</th> <th> Title</th> <th> UserID</th> <th> Address</th> <th> Gender </th> </tr> <tr> <td> 1 </td> <td> Title1 </td> <td> 12345 </td> <td> Manila </td> <td> <span> Male </span> </td> </tr> <tr> <td align="center" colspan="5"> <a href="#" class="testlink">Edit</a> </td> </tr> <tr> <td> 2 </td> <td> Title2 </td> <td> 67891 </td> <td> Valenzuela </td> <td> <span> Female </span> </td> </tr> <tr> <td align="center" colspan="5" > <a href="#" class="testlink">Edit</a> </td> </tr> <tr> <td> 3 </td> <td> Title3 </td> <td> 88888 </td> <td> Ohio </td> <td> <span> Male </span> </td> </tr> <tr> <td align="center" colspan="5" > <a href="#" class="testlink">Edit</a> </td> </tr> <tr> <td> 4 </td> <td> Title4 </td> <td> 77777 </td> <td> California </td> <td> <span> Female </span> </td> </tr> <tr> <td align="center" colspan="5" > <a href="#" class="testlink">Edit</a> </td> </tr> <tr> <td> 5 </td> <td> Title5 </td> <td> 33333 </td> <td> Arizona </td> <td> <span> Male </span> </td> </tr> <tr> <td align="center" colspan="5" > <a href="#" class="testlink">Edit</a> </td> </tr> </table> #Include "Chrome.au3" #Include "wd_core.au3" #Include "wd_helper.au3" #Include "Excel.au3" #Include "_HtmlTable2Array.au3" #Include "Array.au3" Local $sDesiredCapabilities, $sSession SetupChrome() _WD_Startup() $sSession = _WD_CreateSession($sDesiredCapabilities) _WD_LoadWait($sSession) _WD_Navigate($sSession, "index.html") Sleep(6000) Local $oExcel = _Excel_Open() Local $oWorkbook = _Excel_BookOpen($oExcel, "test.xlsx") ; Get the table element $sElement = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "//table[@class='test']") ; Retrieve HTML $sHTML = _WD_ElementAction($sSession, $sElement, "Property", "outerHTML") ;Local $aTable = _HtmlTableGetWriteToArray($sHTML) Local $aArray1 = _Excel_RangeRead($oWorkbook,1,$oWorkbook.ActiveSheet.Usedrange.Columns("B:B")) Local $aArray2 = _HtmlTableGetWriteToArray($sHTML) ;_ArrayDisplay($aArray1) ;_ArrayDisplay($aArray2) For $i = UBound($aArray1) - 1 To 0 step - 1 For $j = UBound($aArray2) - 1 to 0 step - 1 If $aArray1[$i][1] == $aArray2[$j][1] Then _WD_WaitElement($sSession, $_WD_LOCATOR_ByXPath, "//a[contains(@class,'testlink') or contains(text(),'Edit')]") $test1 = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "//a[contains(@class,'testlink') or contains(text(),'Edit')]") _WD_ElementAction($sSession, $test1, 'click') ;_ArrayDisplay($aArray1) ;_ArrayDelete($aArray1 , $i) ;exitloop EndIf Next Next _WD_Shutdown() Func SetupChrome() _WD_Option('Driver', 'chromedriver.exe') _WD_Option('Port', 9515) _WD_Option('DriverParams', '--log-path="' & @ScriptDir & '\chrome.log"') $sDesiredCapabilities = '{"capabilities": {"alwaysMatch": {"goog:chromeOptions": {"w3c": true, "args":["start-maximized","disable-infobars"]}}}}' EndFunc ;==>SetupChrome Would appreciate if anyone can provide tips, or point me in the right direction in doing it.
       
      test.xlsx
    • By goku200
      I'm having some issues with writing to column C when an element is found. It works on C2 but it does not continue to C3, C4, C5, etc..... I'm wanting to write "test" if the element //input[@id='username'] is found  $someUser = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "//input[@id='username']"). I have attached my HTML and Excel file along with my AutoIt code below:
      #Include "wd_core.au3" #Include "wd_helper.au3" #Include "wd_core.au3" #Include "File.au3" #Include "Array.au3" #Include "Excel.au3" Local $sDesiredCapabilities, $sSession _WD_Startup() $Ssession = _WD_CreateSession($sDesiredCapabilities) _WD_Navigate($sSession, "https://127.0.0.1/test.html") _WD_LoadWait($sSession) Local $oExcel = _Excel_Open() Local $oWorkbook = _Excel_BookOpen($oExcel, "C:\Users\<Username>\Downloads\test.xlsx") Local $aArrayTest1 = _Excel_RangeRead($oWorkbook, 1, $oWorkbook.ActiveSheet.Usedrange.Columns("A:A")) Local $aArrayTest2 = _Excel_RangeRead($oWorkbook, 1, $oWorkbook.ActiveSheet.Usedrange.Columns("B:B")) For $i = 0 To UBound($aArrayTest1) - 1 _WD_Navigate($Ssession, $aArrayTest1[$i]) _WD_LoadWait($sSession) $someUser = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "//input[@id='username']") _WD_SetElementValue($sSession, $someUser, $aArrayTest2[$i]) Local $sElement = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "//input[@type='submit'][@value='Submit']") _WD_ElementAction($sSession, $sElement, 'click') _WD_LoadWait($sSession) Sleep(5000) If $someUser Then Local $aArray2D[2] = ["test"] _Excel_RangeWrite($oWorkbook, $oWorkbook.ActiveSheet, $aArray2D, "C2") EndIf Next Func SetupChrome() _WD_Option('Driver', 'chromedriver.exe') _WD_Option('Port', 9515) _WD_Option('DriverParams', '--log-path="' & @ScriptDir & '\chrome.log"') $sDesiredCapabilities = '{"capabilities": {"alwaysMatch": {"goog:chromeOptions": {"w3c": true, "args":["start-maximized","disable-infobars"]}}}}' EndFunc ;==>SetupChrome  
      test.html test.xlsx
×
×
  • Create New...