Jump to content

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


Danp2
 Share

Recommended Posts

On 1/9/2019 at 7:33 AM, danylarson said:

I wanted to highlight a table and it does not seem to works properly in my examples

Finally got around to looking at this again. Found some issues with your code. The following works for me --

$sElement = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "/html/body/table")
    _WD_HighlightElement($sSession, $sElement, 3)

 

Link to comment
Share on other sites

Hi Dan,

Thanks for your review i noticed my mistake.

Here is an improved version of my fonction to get Table content :

Func _WD_GetTableContent($sSession, $aElements, $Separator, $ContainHeader = "")

    Local $BaseElement
    Local $LineNumber
    Local $ColNumber
    Local $i
    local $j
    Local $sValue
    Local $TmpValue
    Local $StartCell

    $BaseElement = $aElements

    $aElements = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, $BaseElement & "/tbody/tr", "", True)
    $LineNumber = UBound($aElements)

    $aElements = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, $BaseElement & "/tbody/tr[1]/td", "", True)
    $ColNumber = UBound($aElements)

    Local $sArray = [$LineNumber]

    $aElements = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, $BaseElement & "/tbody/tr/td", "", True)
;~     _ArrayDisplay($aElements)

    $CellNumber = UBound($aElements)

    If $ContainHeader = "" Then

        $StartCell = 0

    Else

        $StartCell = $ColNumber

    EndIf

    For $i = $StartCell To $CellNumber - 1

        $sElement = $aElements[$i]
        $TmpValue = _WD_ElementAction($sSession, $sElement, 'Text')
        $sValue = $sValue & "##" & $TmpValue

        $j = $j + 1

        If $j = $ColNumber Then

            _ArrayAdd($sArray, $sValue)
            $sValue = ""
            $j = ""

        EndIf

    Next

    For $i = 1 To UBound($sArray) - 1

        $TmpValue = $sArray[$i]
        $TmpValue = StringMid($TmpValue, 3)
        $TmpValue = StringReplace($TmpValue, "##", $Separator)

        $sArray[$i] = $TmpValue

    Next

    Return $sArray

EndFunc   ;==>_WD_GetTableContent

Link to comment
Share on other sites

I have been having problems loading any User profile with Chrome other than the newly generated temporary one that Webdriver creates by default. 

I am using a copy of the wd_demo code just as a starting point, only having edited the DriverParams section of SetupChrome()

Func SetupChrome()
_WD_Option('Driver', 'chromedriver.exe')
_WD_Option('Port', 9515)
_WD_Option('DriverParams', '--log-path="' & @ScriptDir & '\chrome.log" --user-data-dir="C:\Users\Jan\AppData\Local\Google\Chrome\User Data"')

$sDesiredCapabilities = '{"capabilities": {"alwaysMatch": {"goog:chromeOptions": {"w3c": true }}}}'
EndFunc

Despite adding (what I believe to be)the correct usage of --user-data-dir, chromedriver launches with the new temp Chrome profile every time. 

 

Console:

_WDStartup: OS: WIN_10 WIN32_NT 17134 
_WDStartup: AutoIt: 3.3.14.2
_WDStartup: WD.au3: 0.1.0.17
_WDStartup: Driver: chromedriver.exe
_WDStartup: Params: --user-data-dir="C:\Users\Jan\AppData\Local\Google\Chrome\User Data"
_WDStartup: Port:   9515
__WD_Post: URL=HTTP://127.0.0.1:9515/session; $sData={"capabilities": {"alwaysMatch": {"goog:chromeOptions": {"w3c": true }}}}
__WD_Post: StatusCode=200; ResponseText={"value":{"capabilities":{"acceptInsecureCerts":false,"browserName":"chrome","browserVersion":"71.0.3578.98","chrome":{"chromedriverVersion":"2.45.615291 (ec3682e3c9061c10f26ea9e5cdcf3c53f3f74387)","userDataDir":"C:\\Users\\Jan\\AppData\\Local\\Temp\\scoped_dir3068_9340"},"goog:chromeOptions":{"debuggerAddress":"localhost:64107"},"networkConnectionEnabled":false,"pageLoadStrategy":"normal","platformName":"windows nt","proxy":{},"setWindowRect":true,"strictFileInteractability":false,"timeouts":{"implicit":0,"pageLoad":300000,"script":30000},"unhandledPromptBehavior":"dismiss and notify"},"sessionId":"c2ecb7bc400269fa73565ab43480120d"}}
_WD_CreateSession: {"value":{"capabilities":{"acceptInsecureCerts":false,"browserName":"chrome","browserVersion":"71.0.3578.98","chrome":{"chromedriverVersion":"2.45.615291 (ec3682e3c9061c10f26ea9e5cdcf3c53f3f74387)","userDataDir":"C:\\Users\\Jan\\AppData\\Local\\Temp\\scoped_dir3068_9340"},"goog:chromeOptions":{"debuggerAddress":"localhost:64107"},"networkConnectionEnabled":false,"pageLoadStrategy":"normal","platformName":"windows nt","proxy":{},"setWindowRect":true,"strictFileInteractability":false,"timeouts":{"implicit":0,"pageLoad":300000,"script":30000},"unhandledPromptBehavior":"dismiss and notify"},"sessionId":"c2ecb7bc400269fa73565ab43480120d"}}

I can see the temporary profile, but am unsure how to enforce that my -user-data-dir is followed.

What am I missing?

Thank you for your time.

Link to comment
Share on other sites

  • 2 weeks later...

Hi Dan, ty for this UDF, its GREAT!)

I have some trouble with switchin between windows in one session. I hope someone will point me to my mistake.

$cc=_WD_Window($sSession, 'handles')
_WD_Window($sSession, 'switch', $cc[1])

Have something like this in logs:

__WD_Get: URL=HTTP://127.0.0.1:9515/session/b114c034cc52582e3aff710eef0a2c70/window/handles
__WD_Get: StatusCode=200; $iResult = 0; $sResponseText={"value":["CDwindow-C6D0ED80ACD5E48CFA1D0FBCC846FF25","CDwindow-65036AA757116B3CFA74AD96F5026D08"]}...
_WD_Window: {"value":["CDwindow-C6D0ED80ACD5E48CFA1D0FBCC846FF25","CDwindow-65036AA757116B3CFA74AD96F5026D08"]}...
__WD_Post: URL=HTTP://127.0.0.1:9515/session/b114c034cc52582e3aff710eef0a2c70/window; $sData=CDwindow-65036AA757116B3CFA74AD96F5026D08
__WD_Post: StatusCode=400; ResponseText=missing command parameters
_WD_Window: missing command parameters...
_WD_Window ==> Webdriver Exception: HTTP status = 400

 

Link to comment
Share on other sites

Thanks for the direction.

 

Have another question,

Which function may I use to open a new separate window in the same session? Or perhaps something to pull an existing tab into its own window.

 

Thank you for all your efforts, Danp2.

Edited by Refus
Link to comment
Share on other sites

I'm not sure how you would programmatically detach an existing tab. You can create a new window by using the same technique as  _WD_NewTab, where we execute the window.open() command. This command supports optional parameters where you can specify the window position, size, etc. When these are given, the new window is separate rather than attached as a tab.

I suspect that we could update _WD_NewTab to allow you to specify these optional parameters, but it's not something I've looked into yet.

Link to comment
Share on other sites

  • 4 weeks later...

Awwwwww Snap! When Firefox changed to Quantum, the new version didn't support Mozrepl. This is key for a little program I made and because of this, I haven't upgraded my browser. Last year, I came to the forum looking for an alternative and found someone else already asked the question and everyone told him/her to use UI Automation. Well, I tried it and I couldn't get it to wait until the page fully loaded before going on with the script, so that didn't work for me. Just found this UDF and I think it will do everything I need. Danp2, great work. Now I have some code to re-write.

Link to comment
Share on other sites

  • 2 weeks later...

For websites having a lot of frames, I created this functions to look for elements without caring about frames. Sharing if this can be of any interest for someone :)

  • _WD_SearchTextInFrames is the simple one, you use it with any text keyword and returns 0 or 1
  • _WD_SearchInFrames with same format than _WD_FindElement except you don't care about the frames.
    • StayInFrameContainingResult is important there , by default it's false : Even if you find your element in your page, we go back to the page you were (leaving frame) so you won't be able to act with your element after without going back into your frame.
    • If true, we don't leave the frame, meaning you can interact with the element, but you'll have to manually leave the frame yourself after, using __WD_FrameLeave() and _WD_IsWindowTop()
;RETURN 0 si text not found, 1 if found
Func _WD_SearchTextInFrames($sSession,$KeyWord,$result=0)
    If $result = 1 Then return 1
    Local $nbFrames = _WD_GetFrameCount($sSession)
    If $nbFrames > 0 Then
        For $i = 0 to $nbFrames -1
            If $result = 0 Then
                _WD_FrameEnter($sSession, $i)
                $result =  _WD_SearchTextInFrames($sSession,$KeyWord,$result)
                _WD_FrameLeave($sSession)
            EndIf
        Next
    EndIf

    If $result = 0 Then $result = _WD_Search($sSession,$KeyWord)
    Return $result
EndFunc

; Return values .: Success      - Element ID(s) returned by web driver
;                  Failure      - ""
Func _WD_SearchInFrames($sSession, $sStrategy, $sSelector,$StayInFrameContainingResult=False, $sStartElement = "", $lMultiple = False,$result="")
    If $result <> "" Then return $result
    Local $nbFrames = _WD_GetFrameCount($sSession)
    If $nbFrames > 0 Then
        For $i = 0 to $nbFrames -1
            If $result = "" Then
                _WD_FrameEnter($sSession, $i)
                $result =  _WD_SearchInFrames($sSession,$sStrategy, $sSelector, $StayInFrameContainingResult, $sStartElement, $lMultiple,$result)

                If $result="" OR $StayInFrameContainingResult=False Then
                    _WD_FrameLeave($sSession)
                EndIf
            EndIf
        Next
    EndIf

    If $result = "" Then $result =  _WD_FindElement($sSession, $sStrategy, $sSelector, $sStartElement, $lMultiple)
    Return $result
EndFunc

;Look for any keyword in page source, can be anything including html
;RETURN 0 si non trouvé, 1 si trouvé
Func _WD_Search($sSession,$KeyWord)
    $html = _WD_GetSource($sSession)
    If StringInStr($html, $KeyWord) Then Return 1
    Return 0
EndFunc

 

Link to comment
Share on other sites

  • 3 weeks later...

I want to input something in an input field  to an already opened website in Chrome.

But I can't get a session handle for the already opened  Browser window:

 

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

SetupChrome()

_WD_Startup()

$my_sSession = _WD_CreateSession($sDesiredCapabilities)
ConsoleWrite("$my_sSession=" & $my_sSession & @LF) ; Output: $my_session=
$sSession = _WD_Attach($my_sSession, "WindowTitle") ; Is window title of Chrome browser the right string?
ConsoleWrite("$sSession=" & $sSession & @LF) ; Output: $sSession=

_WD_WaitElement($sSession,$_WD_LOCATOR_ByXPath,"//*[@id='input-design-name']")
$sElement = _WD_FindElement($sSession,$_WD_LOCATOR_ByXPath,"//*[@id='input-design-name']")

If @error = $_WD_ERROR_Success Then
    ;this code is executed (not the code at else)
    _WD_ElementAction($sSession, $sElement, 'click')
    _WD_ElementAction($sSession, $sElement, 'value','Hello')
    ConsoleWrite("Success") ; Output: Success
Else
    ConsoleWrite("Error") ; this part isn't reached
EndIf

_WD_DeleteSession($sSession)
_WD_Shutdown()

Func SetupChrome()
    ;_WD_Option('Driver', 'chromedriver.exe')
    _WD_Option('Driver', 'C:\AutoItIncludeFiles\chromedriver.exe')
    _WD_Option('Port', 9515)
    ;_WD_Option('DriverParams', '--log-path=' & @ScriptDir & '\chrome.log')
    _WD_Option('DriverParams', '--log-path=' & 'C:\AutoItIncludeFiles' & '\chrome.log')
    $sDesiredCapabilities = '{"capabilities": {"alwaysMatch": {"chromeOptions": {"w3c": true }}}}'
EndFunc   ;==>SetupChrome

Output of the program:

$my_session=
$sSession=
Success

I don't really know how to handle the chromedriver.exe

"At double click I get an DOS window with "Starting ChromeDriver 73.0.3683.68.

Only local connection is allowed.

Please protect ports used by ChromeDriver ..."

Is it right that the ChromeDriver DOS window has to be opened

everytime I run the script?

If I run the script the ChromeDriver DOS window closes automatically.

Is that the right behave or a hint of an error?

Why does my code not work?

Why don't I get a session handle and how can I get it?

If I would get a session handle: Is the rest of the code correct to

input "Hello" in the input field?

Link to comment
Share on other sites

2 hours ago, AI123 said:

I want to input something in an input field  to an already opened website in Chrome.

I don't believe that this is currently possible with Chrome.

Quote

$sDesiredCapabilities = '{"capabilities": {"alwaysMatch": {"chromeOptions": {"w3c": true }}}}'

If you check your call to _WD_CreateSession, it is likely failing because there was a recent change by Google to this area. Try changing "chromeOptions" to "goog:chromeOptions"

Quote

Is it right that the ChromeDriver DOS window has to be opened everytime I run the script?

Try changing $_WD_DEBUG to $_WD_DEBUG_None and the console window will be hidden

Quote

If I would get a session handle: Is the rest of the code correct to input "Hello" in the input field? 

Hard to say without further details, but you can likely remove the call to _WD_WaitElement and also the line

_WD_ElementAction($sSession, $sElement, 'click')
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...