Jump to content

WebDriver UDF (W3C compliant version) - 2024/02/19


Danp2
 Share

Recommended Posts

@Danp2 Excellent thanks!

Before you responded, I got it to work using the 2nd element of the handles array:

$aHandles = _WD_Window($sSession,'handles')
_WD_Window($sSession, 'Switch', '{"handle":"' & $aHandles[1] & '"}')

Since the title of the new tab was the same as the other, I was successfully able to use the url option.
 

_WD_Attach($sSession, 'https://www.widgetold.com', 'url') ;or title or HTML
_WD_Navigate($sSession, "https://www.widgetnew.com")

 

That's a better idea to switch tabs and attach to the new tab created after clicking on the link. Thanks again!

Edited by NassauSky
Link to comment
Share on other sites

@finAC Here's a revised version of your code --

#include "wd_core.au3"
#include "wd_helper.au3"

$_WD_DEBUG = $_WD_DEBUG_Info

_WD_Option('Driver', 'geckodriver.exe')
_WD_Option('DriverParams', '--log trace')
_WD_Option('Port', 4444)

Local $sDesiredCapabilities = '{"capabilities": {"alwaysMatch": {"browserName": "firefox", "acceptInsecureCerts":true}}}'
Local $sTargetURL = "https://myerponline.de/demosystem/security/Menu.html"
Local $pWD
Local $sSession, $sElement, $sFrames, $sContent

$pWD = _WD_Startup()
If @error <> $_WD_ERROR_Success Then Exit -1

;Open Session
$sSession = _WD_CreateSession($sDesiredCapabilities)
_WD_Navigate($sSession, $sTargetURL)
_WD_WaitElement($sSession, $_WD_LOCATOR_ByXPath, "//frameset[@id='framesetMenu']", 1000, 5000)

MsgBox(0, "How many frames", _WD_GetFrameCount($sSession))

Local $sFrames = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "//frame", Default, True)
If VarGetType($sFrames) = "Array" Then
    For $i = 0 To UBound($sFrames) - 1
        MsgBox(0, "Frame " & $i, _WD_ElementAction($sSession, $sFrames[$i], 'attribute', 'src'))
        _WD_FrameEnter($sSession, $sFrames[$i])
        MsgBox(0, "", _WD_GetSource($sSession))
        _WD_FrameLeave($sSession)
    Next
EndIf

_WD_DeleteSession($sSession)
_WD_Shutdown($pWD)

 

Link to comment
Share on other sites

Hi,

Where can I find more information or an example of the function listed in wd_core.au3:  _WD_Window specifically the Rect parameter.  One post mentioned using winmove to resize the chrome window opened up by webdriver but that sounds like a bit more work if webdriver has something built in to handle that.

🙂

 

Link to comment
Share on other sites

@NassauSky If you look at the function DemoWindows in wd_demo, it shows how to retrieve the window's coordinates. The raw response from the webdriver looks like this --

{"height":1380,"width":1266,"x":10,"y":10}

Completely untested, but I suspect that something like this would work to set the window's coordinates --

_WD_Window($sSession, 'rect', '{"height":1000,"width":1000,"x":100,"y":100}')

 

Link to comment
Share on other sites

You're quick @Danp2!

That worked and I did read that it wasn't guaranteed to work :)

;--- RESIZE BROWSER WINDOW
;~    WinWait('[CLASS:Chrome_WidgetWin_1]')
;~    Local $aPos = WinGetPos('[CLASS:Chrome_WidgetWin_1]')
;~    Local $Handle = WinGetHandle('[CLASS:Chrome_WidgetWin_1]')
;~    WinMove($Handle, '', $aPos[0], $aPos[1], 100, 100) ;x,y
;~    ConsoleWrite("Chrome Handle for Resize: " & $Handle & @CRLF)
      _WD_Window($sSession, 'rect', '{"height":85,"width":100,"x":0,"y":0}')

I originally was using the code above (which I'll use as a fall-back if I run into any issues)

 

Thanks again!

Link to comment
Share on other sites

I have a fun one 😕

How do I get rid of this chrome "Save password?" dialog after starting a webdriver session.

 

ChromeSavePasswordDialog.png.c9a678a5543b345876230f5b3d25bb2b.png


Update: Found it. 🙂

Local $aList = WinList()
    For $i = 1 To $aList[0][0]
        If $aList[$i][0] <> "" And BitAND(WinGetState($aList[$i][1]), 2) Then ; Displaying only visable windows with a title.
            ConsoleWrite("Title: " & $aList[$i][0] & @CRLF & "Handle: " & $aList[$i][1])
            If StringInStr($aList[$i][0],"Save password?") > 0 Then
               WinClose($aList[$i][1])
            EndIf
        EndIf
    Next

 

Link to comment
Share on other sites

Great @Danp2.  Sometimes knowing the right search terms helps so much.

OK that worked:

$sDesiredCapabilities = '{"capabilities": {"alwaysMatch": {"unhandledPromptBehavior": "ignore", ' & _
         '"goog:chromeOptions": {"w3c": true, "excludeSwitches": ["enable-automation"], "useAutomationExtension": false, ' & _
         '"prefs": {"credentials_enable_service": false}, "args": ["start-maximized"] }}}}'

Thanks

Edited by NassauSky
Link to comment
Share on other sites

Where might I be lucky enough to find some examples of Webdriver? Github didn't have any listed. If there is nice place, can you add the link to your first post in this thread?

The Wiki lists a thread as a source for examples but I was hoping to get them all in a zip file 🙂

Thanks!

Update: Found a way to click a checkbox in my own example but still looking for a bunch of examples for the future 🙂

$sElement = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "//input[@id='Checkbox3']")
_WD_ElementAction($sSession, $sElement, 'click')

 

Edited by NassauSky
Fixed typo
Link to comment
Share on other sites

I have 2 suggestions:

  1. WaitElement should simply return the element id if successful (no need to bother about multiple matches). I read it somewhere and i know damp asked in return, but didn't get a reply.
  2. And I feel, a list frame function is missing. Its easy to write by most users themselfs, but would make the UDF easier to understand if you encounter frames. 
    ListFrames($sSession, $sType = Default) ... $sType = frame (Default), iframe
    Or maybe write just an additional demo function which has a better frame use-case
    -> I'm more than happy to post the code snippets for demo function or Listframes()

And then i have another one, is this a bug for geckodriver?

The following script returns this error, because it obviously fails to access the entered frame: Webdriver Exception: {"value":{"error":"unknown error","message":"TypeError: can't access dead object"

#include <UDF/wd_core.au3>
#include <UDF/wd_helper.au3>
$_WD_DEBUG = $_WD_DEBUG_Info

_WD_Option('Driver', 'UDF/geckodriver.exe')
_WD_Option('DriverParams', '--log trace')
_WD_Option('Port', 4444)
$sDesiredCapabilities = '{"capabilities": {"alwaysMatch": {"browserName": "firefox", "acceptInsecureCerts":true}}}'

$pWD = _WD_Startup()
If @error <> $_WD_ERROR_Success Then Exit -1

;Open Session
$sSession = _WD_CreateSession($sDesiredCapabilities)
_WD_Navigate($sSession, "https://myerponline.de/demosystem/")
_WD_WaitElement($sSession, $_WD_LOCATOR_ByXPath, "//frameset", 500, 5000)

MsgBox(0, "How many frames", _WD_GetFrameCount($sSession))

$aFrames = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "//frame", Default, True)

_WD_FrameEnter($sSession, $aFrames[2])

MsgBox(0, "After FrameEnter: IsWindowTop", _WD_IsWindowTop($sSession))

_WD_FrameLeave($sSession)

MsgBox(0, "After FrameLeave: IsWindowTop", _WD_IsWindowTop($sSession))

;All works fine, now the hickup

_WD_FrameEnter($sSession, $aFrames[2])

MsgBox(0, "", "Entered 2nd frame and now you manually need to enter any URL which has no frames and wait till its loaded!")

MsgBox(0, "After loading a new URL: Is Window Top", _WD_IsWindowTop($sSession))

;Should not get to here without crashing

_WD_FrameLeave($sSession)

_WD_DeleteSession($sSession)
_WD_Shutdown($pWD)

 

 

Link to comment
Share on other sites

Hi Dan,

This is a continuation or extended post about the function _WD_DownloadFile we had previously.

I started noticing something interesting with downloading files. Every once in a while, one or 2 images seem to be "missed" when downloading.

Example: In several attempts to download images 1-10, a random one can be missed like 2nd image or maybe 6th image or even the 10th.

 

The only things I've changed in the script was modifying

@error

values to the appropriate Global Enum's in wd_core as you suggested.

Edited by Purity8
Link to comment
Share on other sites

On 10/4/2020 at 12:22 PM, finAC said:

WaitElement should simply return the element id if successful

Next release should offer this as an option

On 10/4/2020 at 12:22 PM, finAC said:

a list frame function is missing. Its easy to write by most users themselfs, but would make the UDF easier to understand if you encounter frames. 

Why don't you write a function (_WD_ListFrames) and submit it for inclusion in the UDF?

 

Link to comment
Share on other sites

Global Const $DownloadsDir = @UserProfileDir & "\Downloads\"
Global Const $Url_01 = "http://q1.xiongmaoya.com/2018/05/24/8883/"
Global $Download = _WD_DownloadFile, $Dest, $Link, $Img, $n1, $n2, $i = 1, $Format = ".jpg"


; Ask
Func Ask()
    ConsoleWrite(@CRLF & "Enter a number where image gallery begins." & @CRLF)
    $n1 = InputBox("Notice", "Which image number do you wish to START from?", "", " M3")
    If @error = 1 Then
        ConsoleWrite(@CRLF & "Cancelled!" & @CRLF)
        Exit
    EndIf

    ConsoleWrite($n1 & @CRLF)

    ConsoleWrite(@CRLF & "Enter a number where image gallery ends." & @CRLF)
    $n2 = InputBox("Notice", "Which image number do you wish to END?", "", " M3")
    If @error = 1 Then
        ConsoleWrite(@CRLF & "Cancelled!" & @CRLF)
        Exit
    EndIf
    ConsoleWrite($n2 & @CRLF)
EndFunc

; Download
Func DL()
    ConsoleWrite(@CRLF & "Silently downloading..." & @CRLF)

    ConsoleWrite("From: " & $Link & @CRLF & "To: " & $Dest & @CRLF)
    $Download($Link, $Dest & $Img)

    If @error = $_WD_ERROR_Success Then
        ConsoleWrite(@CRLF & "Download Complete." & @CRLF & @CRLF)
    ElseIf @error = $_WD_ERROR_GeneralError Then
        MsgBox($MB_SYSTEMMODAL, "Caution:", "1 = General Error - Directory doesn't exist, invalid/incomplete file path.")
        ConsoleWrite(@CRLF & "1 = General Error - Directory doesn't exist or incomplete file path." & @CRLF & @CRLF)
        Exit
    ElseIf @error = $_WD_ERROR_InvalidValue Then
        ;MsgBox($MB_SYSTEMMODAL, "Caution:", "4 = Invalid value - URL variable has an empty field and not assigned a base URL. Exitting script." & @CRLF)
        ;ConsoleWrite(@CRLF & "URL variable is empty. Exitting script." & @CRLF & @CRLF)
        ;Exit
    ElseIf @error = $_WD_ERROR_NotFound Then
        ConsoleWrite(@CRLF & "Download link not found or end of gallery." & @CRLF)
    ElseIf @error = $_WD_ERROR_SendRecv Then
        MsgBox($MB_SYSTEMMODAL, "Caution:", ("Send/Receive Error")
        ConsoleWrite(@CRLF & "Send/Receive Error" & @CRLF)
        Exit
    Else
        MsgBox($MB_SYSTEMMODAL, "Notice:", @CRLF & "Something else went wrong..." & @CRLF)
        ConsoleWrite(@CRLF & "Something else went wrong..." & @CRLF & @CRLF & $Link & @CRLF & $Dest & @CRLF)
        Exit
    EndIf
EndFunc

; For Loop
Func F_Loop()
    For $i = $n1 To $n2 ; n1 = user defined, beginning point of gallery , n2 = ending point of gallery
        ConsoleWrite(@CRLF & "For Looping..." & @CRLF) ; For Loop started

        $Img = $i & $Format  ; Allows $Img to loop along $i

        $Dest = $DownloadsDir
        $Link = $Url_01 & $Img ; This allows the image number to be saved matching the gallery image number
        DL()

    ConsoleWrite(@CRLF & "Looping up." & @CRLF)
Next    ; End of 'For' Loop
    ConsoleWrite(@CRLF & "End of For Loop" & @CRLF)

    MsgBox($MB_OK, "Notice:", "All Downloads complete!")
EndFunc


Ask()
F_Loop()

I know this is a bad example as you've mentioned before.

On 9/15/2020 at 10:52 AM, Danp2 said:

  First off, that's an awful example IMO. You could have demonstrated the issue with just a few lines, like this --

#include "webdriver-0.3.0.9\wd_helper.au3"

Global Const $DownloadsDir = @UserProfileDir & "\Downloads\"
Global Const $Url_01 = "http://q1.xiongmaoya.com/2018/05/24/8883/49.jpg"
Global Const $Url_02 = "http://q1.xiongmaoya.com/2018/05/24/8883/50.jpg"

_WD_DownloadFile($Url_01, $DownloadsDir & "Url_01.jpg", 0)
_WD_DownloadFile($Url_02, $DownloadsDir & "Url_02.jpg", 0)

 

I originally started from that format. Here's my beginning progress when I first started:

ConsoleWrite("Downloading files.. & @CRLF & @CRLF)
    $Download($Url, $Feilin & "/Vol.144" & "/1.jpg")
    $Download($Url_2, $HuaYang & "/Vol.053" & "/1.jpg")
    $Download($Url_3, $YouMi & "/Vol.178"  & "/1.jpg")
    $Download($Url_4, $YouMi & "/Vol.182"  & "/1.jpg")
    $Download($Url_5, $HuaYang & "/Vol.057" & "/1.jpg")
    MsgBox($MB_OK, "info:", "Downloaded 5 Different Images in 1 Loop"  & @CRLF & @CRLF)
ConsoleWrite("Downloads complete." & @CRLF & @CRLF)

I realized I'd have to code out over 200 lines if the gallery had over 200 images and I'd have to manually code in the different photography networks (which I've now separated into custom au3's)

The new format is the quickest method of "batch" downloading, with the least amount of coding. It allows defining beginning and end images. If it happens to "randomly skip" numbers, it can be defined manually.

When downloading images 1-10, and 2 & 7 are skipped, those skipped numbers can be entered individually in both n variables or simply entering 2 in n1, 7 in n2 to re-download again.

 

edit:
Here's what the console shows for example:

Silently downloading...
From: http://q1.xiongmaoya.com/2020/07/17/21240/5.jpg
To: C:\Users\Admin\Downloads\??? (Sugar)\[XiaoYu]\Vol.328\
_WD_DownloadFile: 4
_WD_DownloadFile ==> Invalid value

The link for 5.jpg exists and somehow it doesn't download properly and gives invalid value error.

Re-attempt (like a restart with ctrl+alt+break or re-run of F5) and it'll download properly the next time around.

Silently downloading...
From: http://q1.xiongmaoya.com/2020/07/17/21240/5.jpg
To: C:\Users\Admin\Downloads\??? (Sugar)\[XiaoYu]\Vol.328\
_WD_DownloadFile: 0
_WD_DownloadFile ==> Success

Download Complete.

 

Edited by Purity8
new info
Link to comment
Share on other sites

@Purity8 Here's the latest (to be released) version of _WD_DownloadFile --

; #FUNCTION# ====================================================================================================================
; Name ..........: _WD_DownloadFile
; Description ...: Download file and save to disk
; Syntax ........: _WD_DownloadFile($sURL, $sDest[, $iOptions = Default])
; Parameters ....: $sURL                - URL representing file to be downloaded
;                  $sDest               - Full path, including filename, of destination file
;                  $iOptions            - [optional] Download options
;
; Return values .: True      - Download succeeded
;                  False     - Download failed
;
;                  @ERROR       - $_WD_ERROR_Success
;                               - $_WD_ERROR_GeneralError
;                               - $_WD_ERROR_NotFound
;
; Author ........: Dan Pollak
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func _WD_DownloadFile($sURL, $sDest, $iOptions = Default)
    Local Const $sFuncName = "_WD_DownloadFile"
    Local $lResult = False

    If $iOptions = Default Then $iOptions = $INET_FORCERELOAD + $INET_IGNORESSL + $INET_BINARYTRANSFER

    Local $sData = InetRead($sURL, $iOptions)
    Local $iErr = @error

    If $iErr = $_WD_ERROR_Success Then
        Local $hFile = FileOpen($sDest, 18)

        If $hFile <> -1 Then
            FileWrite($hFile, $sData)
            FileClose($hFile)

            $lResult = True
        Else
            $iErr = $_WD_ERROR_GeneralError
        EndIf
    Else
        $iErr = $_WD_ERROR_NotFound
    EndIf

    If $_WD_DEBUG = $_WD_DEBUG_Info Then
        __WD_ConsoleWrite($sFuncName & ': ' & $iErr & @CRLF)
    EndIf

    Return SetError(__WD_Error($sFuncName, $iErr), 0, $lResult)
EndFunc

Please retest using this version and report back any issues.

P.S. Since your problem appears to be sporadic and not reproducible on demand, I can only assume that it is caused by external factors, such as internet issues, website issues, etc.

Link to comment
Share on other sites

Hi.;sorry for my english, hope you understant!!:

FIXED with the $option in format json

i am testing the UDF web driver, but i have read long post about the syntax of switch to frame?  i dont understant if there is a problem or not?

 

i dont see help about that, so is it possible to have the right syntax ,  i have an error in this piece of code: i dont arrive to have the pagesource content

#cs ----------------------------------------------------------------------------

 AutoIt Version: 3.3.14.5
 Author:         myName

 Script Function:
    Template AutoIt script.

#ce ----------------------------------------------------------------------------
#include <FileConstants.au3>
#include <Array.au3>
#include "wd_core.au3"
#include "wd_helper.au3"

Global $sDesiredCapabilities, $sSession, $sScriptName = "AUtoSaveAS", $aResult_All
Global $hSplash = SplashTextOn($sScriptName, "Running ... please be patient!", Default, 45, 0, 600)
Local $aArray = FileReadToArray("F:\Urls.txt")

$sDesiredCapabilities = '{"desiredCapabilities":{"javascriptEnabled":true,"nativeEvents":true,"acceptInsecureCerts":true}}'
; (1, 2) ----------------------------------------------------------------------
; Automate the website using FireFox. Start FF from a different location
; -----------------------------------------------------------------------------
Global $sDriver = "C:\Program Files (x86)\Mozilla Firefox\geckodriver.exe" ; <== Please modify this statement to your environment. Must be a local drive, network drives don't work!
; Setup Firefox
_WD_Option("Driver", $sDriver)
If @error Then Exit SetError(1, @error)
_WD_Option('DriverParams', '--log trace')
_WD_Option('Port', 4444)
$sDesiredCapabilities = '{"desiredCapabilities":{"javascriptEnabled":true,"nativeEvents":true,"acceptInsecureCerts":true}}'
; (1, 2) End ------------------------------------------------------------------

_WD_Startup()
If @error Then Exit SetError(2, @error)
$sSession = _WD_CreateSession($sDesiredCapabilities)
If @error Then Exit SetError(3, @error)

; (3) -------------------------------------------------------------------------
; Maximize browser window
; -----------------------------------------------------------------------------
_WD_Window($sSession, "Maximize")
If @error Then Exit SetError(4, @error)
; (3) End ---------------------------------------------------------------------

DispURL($aArray)
If @error Then Exit SetError(5, @error)
MsgBox($MB_ICONINFORMATION, "Demo complete!", "Click ok to shutdown the browser and console")
ControlSetText($hSplash, "", "Static1", "Shutting down WebDriver automation")
_WD_DeleteSession($sSession)
If @error Then Exit SetError(6, @error)
_WD_Shutdown()
If @error Then Exit SetError(7, @error)
SplashOff()

Func DispURL(ByRef $aArray)
    ControlSetText($hSplash, "", "Static1", "Opening website " & $aArray[2])

    ; Open website
    ConsoleWrite("Navigate" & @CRLF)
    _WD_Navigate($sSession, "https://openclassrooms.com/fr/courses/4670706-adoptez-une-architecture-mvc-en-php/4671501-isoler-lacces-aux-donnees")
    Sleep(5000)
    ;trap all iframes in array, i have 7 iframes in the array
    $aFrame = _WD_FindElement($sSession, $_WD_LOCATOR_ByTagName, "iframe", "", True)
    ;trap the right frame with th
    For $i = 0 To UBound($aFrame) - 1
        _WD_Window($sSession, "Frame", '{"id":' & $i & '}');format json!!
        $pagesource = _WD_GetSource($sSession)
                ;some tests
        If StringInStr($pagesource, '<a class="call"') > 0 Then
            $elt = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "//*[@class='call']")
            _WD_ElementAction($sSession, $elt, "click")
        EndIf
        _WD_Window($sSession, "Parent", "{}"); format json!!
    Next
EndFunc

 

 

 

Edited by Frenchy
Link to comment
Share on other sites

  • Danp2 changed the title to WebDriver UDF (W3C compliant version) - 2024/02/19
  • Melba23 pinned this topic

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
 Share

×
×
  • Create New...