It is currently Sun Dec 16, 2018 6:42 pm

All times are UTC + 1 hour




Post new topic Reply to topic  [ 42 posts ]  Go to page Previous  1, 2, 3  Next
Author Message
 Post subject: Re: Driving a Web Browser with PureBasic
PostPosted: Thu Oct 25, 2018 9:44 am 
Offline
Addict
Addict
User avatar

Joined: Sun Nov 05, 2006 11:42 pm
Posts: 4349
Location: Lyon - France
Marc56 wrote:
I wonder if it would not be possible (and even easier) to use the new HTTP_Request() function
For the moment i not asked to me this style of question... :lol: with or without header....if by miracle FF open... 8)
But the road is open to you :mrgreen:

Marc56 wrote:
if KCC agrees
Your desire is orders for KCC :D

If someone understand a little bit the JSON, why the FRED lib say to me : "sessionId" not found and JSONMember = 0 ? :shock:

This is the return of "jsV"
jsV wrote:
{"value":{"sessionId":"09e9390e-583c-42cd-8c9e-bcf607e6e2e9","capabilities":{"acceptInsecureCerts":false,"browserName":"firefox","browserVersion":"62.0.2","moz:accessibilityChecks":false,"moz:geckodriverVersion":"0.22.0",
"moz:headless":false,"moz:processID":8008,"moz:profile":"C:\\Users\\Kcc\\AppData\\Local\\Temp\\rust_mozprofile.9JHFI8aLE2Gk",
"moz:useNonSpecCompliantPointerOrigin":false,"moz:webdriverClick":true,"pageLoadStrategy":"normal","platformName":"windows_nt",
"platformVersion":"6.1","rotatable":false,"timeouts":{"implicit":0,"pageLoad":300000,"script":30000}}}}

And JsGetItem is equal to "sessionId"
Code:
JSONMember = GetJSONMember(jsV, JsGetItem)
     
     If JSONMember
      Value$ = GetJSONString(JSONMember)
     Else
      Value$ = "The member ''" + JsGetItem + "'' is not found."
     EndIf

_________________
ImageThe happiness is a road...
Not a destination


Top
 Profile  
Reply with quote  
 Post subject: Re: Driving a Web Browser with PureBasic
PostPosted: Thu Oct 25, 2018 10:18 am 
Offline
Addict
Addict
User avatar

Joined: Sun Nov 05, 2006 11:42 pm
Posts: 4349
Location: Lyon - France
I answer myself, i never playing with JSON, it's the first time :oops:
The "sessionId" is a subkey of "value"...why ??? i don't know :mrgreen:
Is the reason why the CELTIC code crash :idea:

Code:
Json$ = "{|value|:{|sessionId|:|09e9390e-583c-42cd-8c9e-bcf607e6e2e9|,|capabilities|:{|acceptInsecureCerts|:false,"
Json$ + "|browserName|:|firefox|,|browserVersion|:|62.0.2|,|moz:accessibilityChecks|:false,|moz:geckodriverVersion|:|0.22.0|,"
Json$ + "|moz:headless|:false,|moz:processID|:8008,|moz:profile|:|C:\\Users\\Kcc\\AppData\\Local\\Temp\\rust_mozprofile.9JHFI8aLE2Gk|,"
Json$ + "|moz:useNonSpecCompliantPointerOrigin|:false,|moz:webdriverClick|:true,|pageLoadStrategy|:|normal|,|platformName|:|windows_nt|,|platformVersion|:|6.1|,"
Json$ + "|rotatable|:false,|timeouts|:{|implicit|:0,|pageLoad|:300000,|script|:30000}}}}"

Json$ = ReplaceString(Json$, "|", Chr(34))
Jid = ParseJSON(#PB_Any, Json$)
jsV  = JSONValue(Jid)
JSONMember1 = GetJSONMember(jsV, "value")
Debug JSONMember1
JSONMember2 = GetJSONMember(JSONMember1, "sessionId")
Value$ = GetJSONString(JSONMember2)
Debug Value$

_________________
ImageThe happiness is a road...
Not a destination


Top
 Profile  
Reply with quote  
 Post subject: Re: Driving a Web Browser with PureBasic
PostPosted: Thu Oct 25, 2018 12:51 pm 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Sat Jul 23, 2011 1:13 am
Posts: 164
Location: Germany
Use https://jsonlint.com/
It beautifies your JSON Data (and validates it, if you create it yourself with PB or manually)

Now, because of indentation, you can see what is a subkey of what.
Code:
{
   "value": {
      "sessionId": "09e9390e-583c-42cd-8c9e-bcf607e6e2e9",
      "capabilities": {
         "acceptInsecureCerts": false,
         "browserName": "firefox",
         "browserVersion": "62.0.2",
         "moz:accessibilityChecks": false,
         "moz:geckodriverVersion": "0.22.0",
         "moz:headless": false,
         "moz:processID": 8008,
         "moz:profile": "C:\\Users\\Kcc\\AppData\\Local\\Temp\\rust_mozprofile.9JHFI8aLE2Gk",
         "moz:useNonSpecCompliantPointerOrigin": false,
         "moz:webdriverClick": true,
         "pageLoadStrategy": "normal",
         "platformName": "windows_nt",
         "platformVersion": "6.1",
         "rotatable": false,
         "timeouts": {
            "implicit": 0,
            "pageLoad": 300000,
            "script": 30000
         }
      }
   }
}


Top
 Profile  
Reply with quote  
 Post subject: Re: Driving a Web Browser with PureBasic
PostPosted: Thu Oct 25, 2018 1:09 pm 
Offline
Addict
Addict
User avatar

Joined: Sun Nov 05, 2006 11:42 pm
Posts: 4349
Location: Lyon - France
Hello DERREN (4 in our island) :D

Waoooouuuhhh !!!!
You have right...nothing to see before and after use your "mixer" :D

Image

Super tips !!!! thanks a lot !!! 8) 8) 8)

_________________
ImageThe happiness is a road...
Not a destination


Top
 Profile  
Reply with quote  
 Post subject: Re: Driving a Web Browser with PureBasic
PostPosted: Thu Oct 25, 2018 1:33 pm 
Offline
Enthusiast
Enthusiast

Joined: Sat Feb 08, 2014 3:26 pm
Posts: 528
:idea: You can also see JSON structure in readeable mode in PB with ShowLibraryViewer("json", value)
Try:
Code:
    Protected Jid = ParseJSON(#PB_Any, RepReq)
    ShowLibraryViewer("json", Jid)

:idea: For others tools: Notepad++ have a plugin to see/arrage JSON file (but not validate) JSToolNpp
http://www.sunjw.us/jstoolnpp/

:wink:


Top
 Profile  
Reply with quote  
 Post subject: Re: Driving a Web Browser with PureBasic
PostPosted: Thu Oct 25, 2018 3:40 pm 
Offline
Addict
Addict
User avatar

Joined: Sun Nov 05, 2006 11:42 pm
Posts: 4349
Location: Lyon - France
Thanks to this new tips Marc, i don't know it 8)

Now i can :

1/ open FF
2/ Sending url
3/ Apparently have the ID of link
But i'm stopped to the click :|

If someone can help me :wink:

Code:
; http://forums.purebasic.com/english/viewtopic.php?p=516646&sid=5c05a993efbf6365ec8d55235e2c9751#p516646

InitNetwork()

Macro Req(Method, Loc, Cleng)
 
 Method + " " + Loc + " HTTP/1.1" + #CRLF$ +
          "Connection: Keep-Alive" + #CRLF$ +
          "Content-Type: application/json;charset=utf-8" + #CRLF$ +
          "Accept: */*" + #CRLF$ +
          "User-Agent: Mozilla/4.0" + #CRLF$ +
          "Content-Length: " + Cleng + #CRLF$ +
          #CRLF$
 
EndMacro

Procedure.s Webdriver_Req(ConnectionID, url.s, sData.s, JsGetItem.s, JSONType = #PB_JSON_String, ReqType.s = "POST")

 Protected pReq$ = Req(ReqType,url,StringByteLength(sData,#PB_Ascii)) + sData
 Debug pReq$
 SendNetworkString(ConnectionID, pReq$, #PB_Ascii)
 Protected Size = 1024 * 1024 * 10
 Protected *pRepReq = AllocateMemory(Size)
 ReceiveNetworkData(ConnectionID,*pRepReq, Size)
 Protected RepReq.s = StringField(PeekS(*pRepReq, -1, #PB_Ascii), 2, #CRLF$ + #CRLF$)
 FreeMemory(*pRepReq)
 
 Protected Jid = ParseJSON(#PB_Any, RepReq)
 
 If Jid
 
  Protected jsV  = JSONValue(Jid)
 
  If jsV
   
   JSONMember = GetJSONMember(jsV, JsGetItem)
   
   Select JSONType
     
    Case #PB_JSON_Null
   
     Debug "null"
     
    Case #PB_JSON_String
     
     Debug "string"
     
     If JSONMember
      RepReq = GetJSONString(JSONMember)
     EndIf
     
    Case #PB_JSON_Number:  Debug  "number"
     
     If JSONMember
      RepReq = Str(GetJSONInteger(JSONMember))
     EndIf
     
    Case #PB_JSON_Boolean
     
     Debug "boolean"
     
    Case #PB_JSON_Array
     
     Debug "array"
     
    Case #PB_JSON_Object
   
     Debug "object"
     
   EndSelect
   
  EndIf
 
 Else
 
  Debug "JSON error : " + JSONErrorMessage()
 
 EndIf
 
 ProcedureReturn  RepReq
 
EndProcedure

Procedure.s Webdriver_FF_GetSessionId(JSONValeur.s)

 Protected Jid = ParseJSON(#PB_Any, JSONValeur)
 
 If Jid
 
  Protected jsV  = JSONValue(Jid)
 
  If jsV
     
   JSONMember1 = GetJSONMember(jsV, "value")
   
   If JSONMember1
   
    JSONMember2 = GetJSONMember(JSONMember1, "sessionId")
   
    If JSONMember2
     SessionId$ = GetJSONString(JSONMember2)
    Else
     SessionId$ = "The member ''SessionId'' is Not found."
    EndIf
   
   Else
     
    SessionId$ = "The member ''Value'' is not found." 
 
   EndIf
   
  Else
 
   Debug "JSON error : " + JSONErrorMessage()
   
  EndIf
 
  ProcedureReturn SessionId$
 
 EndIf
 
EndProcedure

default_driver_Port = 4444
driver_location$ = "geckodriver.exe"

RunProgram(driver_location$ ,"-v --binary " + Chr(34) + "D:/A/J/C/O/Firefox50.1.0/App/Firefox/Firefox.exe" + Chr(34) ,"",#PB_Program_Open)
Cid = OpenNetworkConnection("127.0.0.1", default_driver_Port)
 
Url$ = "{"
Url$ +   "|capabilities|: {"
Url$ +             "|browserName|: |firefox|,"
Url$ +             "|javascriptEnabled|: true,"
Url$ +             "|acceptInsecureCerts|: true,"
Url$ +             "|moz:firefoxOptions|: {"
Url$ +                 "|binary|: |D:/A/J/C/O/Firefox50.1.0/App/Firefox/Firefox.exe|"
Url$ +             "}"
Url$ +     "}"
Url$ + "}"

Answer$ = Webdriver_Req(Cid, "/session", ReplaceString(Url$, "|", Chr(34)), "")
Debug Answer$
SessionId$ = Webdriver_FF_GetSessionId(Answer$)
Debug SessionId$
;
Url$ = "{|url|:|https://www.purebasic.com/|}"
Webdriver_Req(Cid, "/session/" + SessionId$ + "/url", ReplaceString(Url$, "|", Chr(34)), "status", #PB_JSON_Number)

Debug Webdriver_Req(Cid, "/session/" + sessionID$ + "/title", "", "value", #PB_JSON_String, "GET")

xpath.s = "/html/body/table[1]/tbody/tr[2]/td/table/tbody/tr/td[1]/a"
json$ = "{"
json$ + "|using|:|xpath|,"
json$ + "|value|:|" + xpath + "|"
json$ + "}"
json$ = ReplaceString(json$, "|", Chr(34))
res$ = Webdriver_Req(Cid, "/session/" + sessionID$ + "/element", json$, "value", #PB_JSON_Object, "POST")

Jid = ParseJSON(#PB_Any, res$)
jsV  = JSONValue(Jid)
ObjectValue = GetJSONMember(jsV, "value")
MemberKey$ = JSONMemberKey(ObjectValue)
MemberValue = JSONMemberValue(ObjectValue)
MemberValue$ = GetJSONString(MemberValue)

Debug "Link ID = " + MemberKey$ + ":" + MemberValue$
Debug ""
Debug Webdriver_Req(Cid, "/session/" + sessionID$ + "/element/" + MemberKey$ + ":" + MemberValue$ + "/click", "", "", #PB_JSON_Null, "POST")

CloseNetworkConnection(Cid)

_________________
ImageThe happiness is a road...
Not a destination


Top
 Profile  
Reply with quote  
 Post subject: Re: Selenium in standalone mode
PostPosted: Fri Oct 26, 2018 9:17 am 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Thu Mar 25, 2004 2:15 pm
Posts: 639
Location: Spain
Kwai chang caine wrote:
Hello ZIKITRAKE :D
And WELCOME to the hell of remoting webbrowser !!!! :twisted:
Thank you!
Kwai chang caine wrote:
"I talk english.... like a SPANISH cow" :wink: :lol:
:lol: :lol: I didn't know that expression, I'll save it for my next excuse!

I just tried your last code with geckodriver.exe, but the ELEMENT ID retrieved has a different format used in Chromedriver. I did a Google search but I don't find nothing about it

PS: If I find anything about Geckodriver I'll let you know!
PS2: I'm big fan about your posts! :D

Marc56us wrote:
Nice code! zikitrake, :)
Thank you, I do what I can :D
Marc56us wrote:
(Work fine with ChromDriver but not with Firefox (invalid JSON value line 32), but that's another problem.)
Yes, Little change with great different results!
Marc56us wrote:
We are getting closer and closer to a solution and a simple and elegant solution like any PureBasic product 8)
Zeus hear you!
Marc56us wrote:
I had an idea last night. :idea: Since the requests IN and OUT are in JSON format and we have to send a header each time, I wonder if it would not be possible (and even easier) to use the new HTTP_Request() function? instead of SendNetworkString() ?
Please!!! If you do, let us know.
Marc56us wrote:
PS. I don't speak a word of English too, I use Deepl.com :P
We are TBTT: The Babel Tower Team :lol:


My last work with Chromedriver:
For now I have added proxy connection (IP:port), Get element ID, Click or send text to an element and run JS.

The last code with simple example:
Code:
; Chromedriver.exe from http://chromedriver.chromium.org
; Based on @CELTIC88 sample http://forums.purebasic.com/english/viewtopic.php?f=13&t=69905&p=516646#p516646
; PB FORUM MAIN THREAD: https://www.purebasic.fr/english/viewtopic.php?f=13&t=71582

EnableExplicit
InitNetwork()

;-============================
;- WD PROCEDURE DECLARES
;-============================
;{
Declare.s Webdriver_Header(Metod.s, Loc.s, Cleng)
Declare.s Webdriver_Req(ConnctionID ,url.s,sData.s,JsGetItem.s,JSONType = #PB_JSON_String,ReqType.s  = "POST")
Declare Webdriver_DesiredCapabilitiesAdd(param$, value$)
Declare Webdriver_ChromeOptionsAdd(param$, value$)
Declare.s Webdriver_NewSession(Cid, proxy.s = "")
Declare.s Webdriver_DeleteSession(Cid, sessionID$)
Declare Webdriver_Navigate(Cid, sessionID$, url$)
Declare Webdriver_NavigateBack(Cid, sessionID$)
Declare Webdriver_NavigateForward(Cid, sessionID$)
Declare Webdriver_Refresh(Cid, sessionID$)
Declare Webdriver_FullScreen(Cid, sessionID$, activated.b = #True)
Declare Webdriver_Resize(Cid, sessionID$, width.l, height.l)
Declare Webdriver_Embedded(Cid, sessionID$, PBParent.l, noHeader = #True, disableForUser = #False)
Declare Webdriver_Keys(Cid, sessionID$, sKeys.s, wdDelay.l = 300)
Declare.s Webdriver_GetUrl(Cid, sessionID$)
Declare.s Webdriver_Title(Cid, sessionID$)
Declare.s Webdriver_Source(Cid, sessionID$)
Declare.s Webdriver_ScreenShot(Cid, sessionID$)
Declare.s Webdriver_CookiesGetAll(Cid, sessionID$, List wdCookies())
Declare Webdriver_CookieAdd(Cid, sessionID$, *cookie)
Declare Webdriver_CookiesDelete(Cid, sessionID$, cookieName$)
Declare.s Webdriver_CookiesDeleteAll(Cid, sessionID$)
Declare.s Webdriver_ElementGetID(Cid, sessionID$, xpath.s)
Declare Webdriver_ElementClick(Cid, sessionID$, xpath.s, clickDelay.l = 300)
Declare Webdriver_ElementValue(Cid, sessionID$, xpath.s, sKeys.s, wdDelay.l = 300)
Declare.s Webdriver_ElementGetText(Cid, sessionID$, xpath.s, wdDelay.l = 500)
Declare.s Webdriver_Execute(Cid, sessionID$, sScript.s, sAsync.b = #False)
;}

;-============================
;- WD GLOBAL VARS
;-============================
Structure wdSTRdesiredCapabilities
  param$
  value$
EndStructure
  Global NewList desiredCapabilities.wdSTRdesiredCapabilities()
Structure wdSTRchromeoptions
  param$
  value$
EndStructure
  Global NewList chromeOptions.wdSTRchromeoptions()

Structure wdSTRcookie
  domain$
  expiry.l
  httpOnly.b
  name$
  path$
  secure.b
  value$   
EndStructure

Macro MacroReq(Method,Loc,Cleng)
  Method + " "+Loc+" HTTP/1.1" + #CRLF$ +
           "Connection: Keep-Alive" + #CRLF$ +
           "Content-Type: application/json;charset=utf-8" + #CRLF$ +
           "Accept: */*" + #CRLF$ +
           "User-Agent: Mozilla/4.0" + #CRLF$ +
           "Content-Length: " + Cleng + #CRLF$ +
           #CRLF$
EndMacro
Procedure.s Webdriver_Req(ConnctionID ,url.s,sData.s,JsGetItem.s,JSONType = #PB_JSON_String,ReqType.s  = "POST") 
  Protected pReq$ = MacroReq(ReqType,url,StringByteLength(sData,#PB_Ascii)) + sData
;   Debug "**pReq$**"
;   Debug pReq$
  SendNetworkString(ConnctionID,pReq$,#PB_Ascii)
  Protected Size = 1024*1024*10
  Protected *pRepReq = AllocateMemory(Size)
  ReceiveNetworkData(ConnctionID,*pRepReq,Size)
  Protected RepReq.s = StringField(PeekS(*pRepReq,-1,#PB_Ascii),2,#CRLF$ + #CRLF$)
  FreeMemory(*pRepReq)
;   Debug " "
;   Debug "**RepReq$**"
;   Debug RepReq
  Protected Jid = ParseJSON(#PB_Any, RepReq)
  If Jid
    Protected jsV  = JSONValue(Jid)
    If jsV
      Select JSONType
        Case #PB_JSON_Null:    Debug "null"
        Case #PB_JSON_String:  Debug  "string"
          RepReq = GetJSONString(GetJSONMember(jsV, JsGetItem))
        Case #PB_JSON_Number:  Debug  "number"
          RepReq = Str(GetJSONInteger(GetJSONMember(jsV, JsGetItem)))
        Case #PB_JSON_Boolean: Debug  "boolean"
        Case #PB_JSON_Array:   Debug  "array"
        Case #PB_JSON_Object:  Debug  "object"
      EndSelect
    EndIf
  Else
    Debug "JSON error : " + JSONErrorMessage()
  EndIf
 
  ProcedureReturn  RepReq
EndProcedure
;-============================
;- WD MAIN PROCEDURES
;-============================
Procedure Webdriver_DesiredCapabilitiesAdd(param$, value$)
  If param$ = "default" And param$ = "default"
    ClearList(desiredCapabilities())
    AddElement(desiredCapabilities()): desiredCapabilities()\param$ = "javascriptEnabled"   : desiredCapabilities()\value$ = "true"
    AddElement(desiredCapabilities()): desiredCapabilities()\param$ = "nativeEvents"        : desiredCapabilities()\value$ = "true"
    AddElement(desiredCapabilities()): desiredCapabilities()\param$ = "browserName"         : desiredCapabilities()\value$ = #DQUOTE$ +"chrome" + #DQUOTE$
    AddElement(desiredCapabilities()): desiredCapabilities()\param$ = "acceptInsecureCerts" : desiredCapabilities()\value$ = "true"   
  Else
    AddElement(desiredCapabilities())
    desiredCapabilities()\param$ = param$
    desiredCapabilities()\value$ = value$ 
  EndIf 
EndProcedure
Procedure Webdriver_ChromeOptionsAdd(param$, value$)
 
  AddElement(chromeOptions())
  chromeOptions()\param$ = param$
  chromeOptions()\value$ = value$ 
EndProcedure

Procedure.s Webdriver_NewSession(Cid, proxy.s = "")
  ;********************************************************************************
  ; Open a new session with/without proxy and return a new sesion ID
  ; proxy format: IP:PORT...  "10.20.30.40:5060"
  ; global list chromeOptions() used
  ;********************************************************************************
  Protected sessionID$
  Protected json$
  Protected desiredCap$ = ""
  Protected chromeParams$ = ""
 
  ;Read desiredCapabilities list
  If ListSize(desiredCapabilities()) = 0                 ; if desiredCapabilities() is empty, create a default options list
    Webdriver_DesiredCapabilitiesAdd("default", "default")
  EndIf 
  ResetList(desiredCapabilities())
  ForEach(desiredCapabilities())
    With desiredCapabilities()
      If Len(desiredCap$): desiredCap$ + ", " + #LF$: EndIf
      desiredCap$ + "'" + \param$
      If Len(\value$)
        desiredCap$ + "': " + \value$
      EndIf
    EndWith
  Next
  desiredCap$ = ReplaceString(desiredCap$, "'", #DQUOTE$)
 
  ;Fill chromeParams$ from chromeOptions() list
  ResetList(chromeOptions()) 
  ForEach(chromeOptions())
    With chromeOptions()
      If Len(chromeParams$): chromeParams$ + ", " + #LF$: EndIf
      chromeParams$ + "'" + \param$
      If Len(\value$)
        chromeParams$ + "=" + \value$
      EndIf
      chromeParams$ + "'"
    EndWith
  Next 
  chromeParams$ = ReplaceString(chromeParams$, "'", #DQUOTE$)
 
 
  json$ = ~"{" + #LF$
  json$ + ~"  |desiredCapabilities|: {" + #LF$
  json$ +       desiredCap$ + "," + #LF$
  json$ + ~"   |chromeOptions|: {" + #LF$
  json$ + ~"     |args|: [" + chromeParams$ + "]" + #LF$ 
  json$ + ~"     }" + #LF$ 
  ;   ;HAVE A PROXY?
  If proxy
    json$ + ~", |proxy|: {" + #LF$
    json$ + ~"    |proxyType|: |manual|," + #LF$
    json$ + ~"    |httpProxy|: |" + proxy + "|" + #LF$
    json$ + ~"   }" + #LF$
  EndIf
  ;END PROXY JSON
  json$ + ~" }" + #LF$ 
  json$ + ~"}"
 
  json$ = ReplaceString(json$, "|", #DQUOTE$)
 
;   ParseJSON(0, json$)
;   json$ = ComposeJSON(0, #PB_JSON_PrettyPrint)
 
  sessionID$  = Webdriver_Req(Cid,"/session", json$, "sessionId")
   
  ProcedureReturn sessionID$ 
EndProcedure
Procedure.s Webdriver_DeleteSession(Cid, sessionID$)
  ;******************************************************************************** 
  ; Close selected session
  ; Returns: {object} An object describing the session's capabilities. 
  ;********************************************************************************
  Protected res$
  res$ = Webdriver_Req(Cid,sessionID$+"", "", "status",#PB_JSON_Object,"DELETE") 
  ProcedureReturn res$
EndProcedure
;-============================
;- WD NAVIGATION PROCEDURES
;-============================
Procedure Webdriver_Navigate(Cid, sessionID$, url$)
  Protected json$
  json$ = ~"{"
  json$ + ~"\"url\":" + #DQUOTE$ + url$ + #DQUOTE$
  json$ + ~"}" 
  Webdriver_Req(Cid,sessionID$+"/url", json$, "",#PB_JSON_Null)
EndProcedure
Procedure Webdriver_NavigateBack(Cid, sessionID$)
  ;********************************************************************************
  ; Navigate backwards in the browser history, if possible.
  ;********************************************************************************
  Protected status
  status = Val(Webdriver_Req(Cid,sessionID$+"/back", "", "status",#PB_JSON_Number))
  ProcedureReturn status
EndProcedure
Procedure Webdriver_NavigateForward(Cid, sessionID$)
  ;********************************************************************************
  ; Navigate forwards in the browser history, if possible.
  ;********************************************************************************
  Protected status
  status = Val(Webdriver_Req(Cid,sessionID$+"/forward", "", "status",#PB_JSON_Number))
  ProcedureReturn status
EndProcedure
;-============================
;- WD WINDOWS PROCEDURES
;-============================
Procedure Webdriver_Refresh(Cid, sessionID$)
  ;********************************************************************************
  ; Refresh the current page
  ;********************************************************************************
  Protected status
  status = Val(Webdriver_Req(Cid,sessionID$+"/refresh", "", "status",#PB_JSON_Number))
  ProcedureReturn status
EndProcedure
Procedure Webdriver_FullScreen(Cid, sessionID$, activated.b = #True)
  ;********************************************************************************
  ; Maximize the specified window If Not already maximized.
  ; If the :windowHandle URL parameter is "current", the currently active window will be maximized. 
  ;********************************************************************************
  Protected wHandle.s   
  wHandle = Webdriver_Req(Cid,sessionID$+"/window_handle", "", "value",#PB_JSON_String,"GET")   
  Webdriver_Req(Cid,sessionID$+"/window/" + wHandle + "/maximize", "", "",#PB_JSON_Null) 
EndProcedure
Procedure Webdriver_Resize(Cid, sessionID$, width.l, height.l)
  Protected wHandle.s, json$
 
  wHandle = Webdriver_Req(Cid,sessionID$+"/window_handle", "", "value",#PB_JSON_String,"GET")
 
  If Len(wHandle)
    json$ = ~"{"
    json$ + ~"\"width\": " + Str(width) + ", "
    json$ + ~"\"height\": " + Str(height)
    json$ + ~"}"
   
    Webdriver_Req(Cid,sessionID$+"/window/" + wHandle + "/size", json$, "",#PB_JSON_Null)
  EndIf
 
EndProcedure
Procedure Webdriver_Embedded(Cid, sessionID$, PBParent.l, noHeader = #True, disableForUser = #False)
  ;********************************************************************************
  ; PBParent parameter must be a gadgetContainer or a Window
  ; noHeader = #true will hide chromeheader (Tabs, Search bar, Bookmarks bar)
  ; disableForUser = #true to disable parent Gadget/Window
  ;********************************************************************************
  Delay(500)
  Delay(500)
  Protected width.l, height.l
  Protected oldUrl.s
  Protected dataUrl.s
  Protected PBparentHwnd
  Protected chromeTitle.s, chromeHwnd
  Protected chromeChildTitle.s, chromeChildHwnd
  Protected rc.rect, chromeY, chromeChildY, chromeYrelative

  oldUrl = Webdriver_GetUrl(Cid, sessionID$)
  dataUrl = URLEncoder(~"data:text/html;charset=utf-8,<!DOCTYPE HTML><title>" + sessionID$ + "</title>")
  Webdriver_Navigate(Cid, sessionID$, dataUrl)

  ;If PBParent is a containerGadget and noHeader = #true then
  ;   create a new containerGadget As child of original PBParent
  ;   and replace PBParent with the new gadget
  If noHeader = #True And IsGadget(PBParent) And GadgetType(PBParent) = #PB_GadgetType_Container
    OpenGadgetList(PBParent)
      Define PBParentNew = ContainerGadget(#PB_Any, 0,0, GadgetWidth(PBParent), GadgetHeight(PBParent), #PB_Container_BorderLess)
    CloseGadgetList()
    If IsGadget(PBParentNew)
      PBParent = PBParentNew
    EndIf
  Else
    noHeader = #False
  EndIf

  ;Resize Chrome Session to PB Parent size 
  If IsGadget(PBParent) And GadgetType(PBParent) = #PB_GadgetType_Container
    width = GadgetWidth(PBParent): height = GadgetHeight(PBParent)
    PBparentHwnd = GadgetID(PBParent)
    HideGadget(PBParent,1)
  ElseIf IsWindow(PBParent)
    width = WindowWidth(PBParent): height = WindowHeight(PBParent)
    PBparentHwnd = WindowID(PBParent)
  Else
    MessageRequester("Error!", "PBParent parameter must be a gadgetContainer or a Window", #PB_MessageRequester_Error)
    ProcedureReturn
  EndIf
 
  Webdriver_Resize(Cid, sessionID$, 1, 1)
 
  ;Search hwnd of the chrome Window opened 
  chromeTitle      = sessionID$ + " - Google Chrome"
  chromeChildTitle = "Chrome_RenderWidgetHostHWND"
  chromeHwnd = FindWindow_(0, chromeTitle)
  If Not chromeHwnd
    MessageRequester("Error", chromeTitle + " must be running !")
    End
  Else
    chromeChildHwnd = FindWindowEx_(chromeHwnd, 0, chromeChildTitle, 0);
  EndIf   
 
  ; if noHeader = #true, we search Chrome Content part Y position and move up PB Parent Gadget/Window
  ; only works with containerGadget Parent, not when Parent is a windows
  If noHeader And chromeChildHwnd <> 0   
      GetWindowRect_(chromeHwnd,rc)
      chromeY = rc\top
      GetWindowRect_(chromeChildHwnd,rc)
      chromeChildY = rc\top               ; Y from top of screen
      chromeYrelative = chromeChildY-chromeY    ; Y from top of chrome window
     
      ResizeGadget(PBParent, #PB_Ignore, -chromeYrelative, #PB_Ignore, GadgetHeight(PBParent) + chromeYrelative)
    EndIf
   
  Webdriver_Navigate(Cid, sessionID$, oldUrl)
  Webdriver_Resize(Cid, sessionID$, width, height+chromeYrelative)
 
  Webdriver_Refresh(Cid, sessionID$)
 
 
  ; Set Chrome as child of PB Parent
  If PBparentHwnd         
    SetWindowLong_(chromeHwnd, #GWL_STYLE, GetWindowLong_(chromeHwnd, #GWL_STYLE) &(~(#WS_MAXIMIZE|#WS_SIZEBOX )))
    SetParent_(chromeHwnd, PBparentHwnd)
    SetWindowPos_(chromeHwnd, 0, 0, 0, 0, 0, #SWP_NOSIZE|#SWP_NOZORDER|#SWP_FRAMECHANGED)           
  EndIf
 
 
  If IsGadget(PBParent)
    DisableGadget(PBParent, disableForUser)
    HideGadget(PBParent,0)
  ElseIf IsWindow(PBParent)
    DisableWindow(PBParent, disableForUser)
  EndIf 
 
 
EndProcedure
;-============================
;- WD GENERAL PROCEDURES
;-============================
Procedure Webdriver_Keys(Cid, sessionID$, sKeys.s, wdDelay.l = 300)
  ;********************************************************************************
  ; Send keys to the session
  ; EXAMPLE:
  ;           xpath = "/html/body/div[1]/div[1]/div[1]/div[1]/div[2]/textarea"
  ;           Webdriver_ElementValue(Cid, sessionID$, xpath, "Hello, world!")
  ;********************************************************************************
  Protected json$

  Delay(wdDelay)
 
  json$ =  "{" + #LF$
  json$ + ~"\"value\": [" + #DQUOTE$ + sKeys + #DQUOTE$ + "]" + #LF$
  json$ + ~"}"
 
  Webdriver_Req(Cid,sessionID$ + "/keys", json$, "",#PB_JSON_Null)
EndProcedure
Procedure.s Webdriver_GetUrl(Cid, sessionID$)
  ;********************************************************************************
  ; Retrieve the URL of the current page.
  ;********************************************************************************
  Protected url$
  url$ = Webdriver_Req(Cid,sessionID$+"/url", "", "value",#PB_JSON_String, "GET")
  ProcedureReturn(url$)
EndProcedure
Procedure.s Webdriver_Title(Cid, sessionID$)
  ;********************************************************************************
  ; Get the current page title.
  ;********************************************************************************
  Protected title$
  title$ = Webdriver_Req(Cid,sessionID$ + "/title", "", "value",#PB_JSON_String,"GET") 
  ProcedureReturn(title$)
EndProcedure
Procedure.s Webdriver_Source(Cid, sessionID$)
  ;********************************************************************************
  ; Return the source code
  ;********************************************************************************
  ProcedureReturn Webdriver_Req(Cid,sessionID$+"/source", "", "value",#PB_JSON_String,"GET")
EndProcedure
Procedure.s Webdriver_ScreenShot(Cid, sessionID$)
  ;********************************************************************************
  ; Take a screenshot of the current page.
  ; Returns string with the screenshot As a base64 encoded PNG.
  ;********************************************************************************
  Protected status.l, value.s
  status = Val(Webdriver_Req(Cid,sessionID$+"/screenshot", "", "status",#PB_JSON_Number,"GET"))
  If status = 0
    value = Webdriver_Req(Cid,sessionID$+"/screenshot", "", "value",#PB_JSON_String,"GET")
  EndIf
 
  ProcedureReturn value
EndProcedure
Procedure.s Webdriver_CookiesGetAll(Cid, sessionID$, List wdCookies.wdSTRcookie())
  ;******************************************************************************** 
  ;  Retrieve all cookies visible to the current page 
  ;  Example:
  ;               NewList theCookies.wdSTRcookie()
  ;               Webdriver_CookiesGetAll(Cid, sessionID$, theCookies())
  ;               ForEach(theCookies())
  ;                 Debug theCookies()\name$
  ;                 Debug theCookies()\value$
  ;               Next 
  ;********************************************************************************
  Protected json$, jsO, jsV, objectValue.l
 
  json$ = Webdriver_Req(Cid,sessionID$+"/cookie", "", "value",#PB_JSON_Object,"GET") 
 
  jsO = ParseJSON(#PB_Any, json$)
  jsV  = JSONValue(jsO)
  objectValue = GetJSONMember(jsV, "value")
 
  ClearList(wdCookies())
  ExtractJSONList(objectValue, wdCookies())
 
EndProcedure
Procedure Webdriver_CookieAdd(Cid, sessionID$, *cookie.wdSTRcookie)
  ;******************************************************************************** 
  ; Set a cookie. If the cookie path is not specified, it should be set to "/".
  ; Likewise, If the domain is omitted, it should Default To the current page's domain. 
  ; Example:
  ;             myCookie.wdSTRcookie
  ;             myCookie\name$ = "pbcookie"
  ;             myCookie\value$ = "Webdriver in PB, yeah!"
  ;             Webdriver_CookieAdd(Cid, sessionID$, myCookie)
  ;********************************************************************************
  Protected json$, status
  Protected secure.s   = "false"
  Protected httpOnly.s = "false"
 
  With *cookie
    If \httpOnly: httpOnly = "true": EndIf
    If \secure: secure = "true": EndIf
   
    json$ = ~"{"
    json$ + ~"  \"cookie\": {"    + #LF$
    json$ + ~"    \"domain\":"    + #DQUOTE$ + \domain$   + #DQUOTE$ + "," + #LF$
    json$ + ~"    \"expiry\":"    + #DQUOTE$ + \expiry    + #DQUOTE$ + "," + #LF$
    json$ + ~"    \"httpOnly\":"  + httpOnly + "," + #LF$
    json$ + ~"    \"name\":"      + #DQUOTE$ + \name$     + #DQUOTE$ + "," + #LF$
    json$ + ~"    \"path\":"      + #DQUOTE$ + \path$     + #DQUOTE$ + "," + #LF$
    json$ + ~"    \"secure\":"    + secure + "," + #LF$
    json$ + ~"    \"value\":"     + #DQUOTE$ + \value$    + #DQUOTE$ + ""
    json$ + ~"  }"
    json$ + ~"}"
   
  EndWith
 
  status = Val( Webdriver_Req(Cid,sessionID$+"/cookie", json$, "status",#PB_JSON_Number,"POST")  )
  ProcedureReturn status
 
EndProcedure

Procedure Webdriver_CookiesDelete(Cid, sessionID$, cookieName$)
  ;********************************************************************************
  ; Delete the cookie with the given name
  ;********************************************************************************
  Protected status
  status = Val (Webdriver_Req(Cid,sessionID$+"/cookie/" + cookieName$, "", "status",#PB_JSON_Number,"DELETE"))
  ProcedureReturn status
EndProcedure
Procedure.s Webdriver_CookiesDeleteAll(Cid, sessionID$)
  ;********************************************************************************
  ; Delete all cookies visible to the current page.
  ;********************************************************************************
  Webdriver_Req(Cid,sessionID$+"/cookie", "", "",#PB_JSON_Null,"DELETE") 
EndProcedure
;-============================
;- WD ELEMENTS PROCEDURES
;-============================
Procedure.s Webdriver_ElementGetID(Cid, sessionID$, xpath.s)
  ;********************************************************************************
  ; Return ID of an element
  ;********************************************************************************
  Protected json$, nJS.l
  Protected status, value$
 
  json$ = ~"{"
  json$ + ~"\"using\":\"xpath\","
  json$ + ~"\"value\":" + #DQUOTE$ + xpath + #DQUOTE$
  json$ + ~"}"
 
  value$ = Webdriver_Req(Cid,sessionID$ + "/element", json$, "value",#PB_JSON_Object,"POST")
 
  nJS = ParseJSON(#PB_Any, value$)
 
  If IsJSON(nJS) 
    nJS = JSONValue(nJS)
    status = GetJSONInteger(GetJSONMember(nJS, "status"))
    If status = 0
      value$ = GetJSONString(GetJSONMember(GetJSONMember(nJS, "value"), "ELEMENT"))
    Else
      value$ = ""
    EndIf
  Else
    value$ = ""
  EndIf
 
  ProcedureReturn value$
EndProcedure
Procedure Webdriver_ElementClick(Cid, sessionID$, xpath.s, clickDelay.l = 300)
  ;********************************************************************************
  ; Click in element
  ; EXAMPLE:   
  ;           xpath = "/html/body/div[1]/div[1]/div[1]/div[1]/div[2]/textarea"
  ;           Webdriver_ElementClick(Cid, sessionID$, xpath)
  ;********************************************************************************
  Protected elementoID.s
 
  Delay(clickDelay) 
 
  elementoID = Webdriver_ElementGetID(Cid, sessionID$, xpath)   
  Webdriver_Req(Cid,sessionID$ + ~"/element/" + elementoID + "/click", "", "",#PB_JSON_Null,"POST") 
EndProcedure
Procedure Webdriver_ElementValue(Cid, sessionID$, xpath.s, sKeys.s, wdDelay.l = 300)
  ;********************************************************************************
  ; Type text in an element
  ; EXAMPLE:
  ;           xpath = "/html/body/div[1]/div[1]/div[1]/div[1]/div[2]/textarea"
  ;           Webdriver_ElementValue(Cid, sessionID$, xpath, "Hello, world!")
  ;********************************************************************************
  Protected json$, elementoID.s
   
  Delay(wdDelay)
 
  elementoID = Webdriver_ElementGetID(Cid, sessionID$, xpath) 
 
  json$ =  "{" + #LF$
  json$ + ~"\"value\": [" + #DQUOTE$ + sKeys + #DQUOTE$ + "]" + #LF$
  json$ + ~"}"
 
  Webdriver_Req(Cid,sessionID$ + ~"/element/" + elementoID + "/value", json$, "",#PB_JSON_Null)
EndProcedure
Procedure.s Webdriver_ElementGetText(Cid, sessionID$, xpath.s, wdDelay.l = 500)
  ;********************************************************************************
  ; Get text in an element
  ; EXAMPLE:
  ;           xpath = "/html/body/div[1]/div[1]/div[1]/div[1]/div[2]/textarea"
  ;           Webdriver_ElementValue(Cid, sessionID$, xpath, "Hello, world!")
  ;********************************************************************************
  Protected elementoID.s
  Protected status, value$
 
  Delay(wdDelay)
 
  status = 0
  value$  = ""
 
  elementoID = Webdriver_ElementGetID(Cid, sessionID$, xpath) 
 
  If elementoID
    status = Val( Webdriver_Req(Cid,sessionID$ + ~"/element/" + elementoID + "/text", "", "status",#PB_JSON_Number, "GET") )
    If status = 0 ; OK?
      value$ = Webdriver_Req(Cid,sessionID$ + ~"/element/" + elementoID + "/text", "", "value",#PB_JSON_String, "GET")
    EndIf
  EndIf
   
  ProcedureReturn value$
 
EndProcedure
;-============================
;- WD SCRIPTS PROCEDURES
;-============================
Procedure.s Webdriver_Execute(Cid, sessionID$, sScript.s, sAsync.b = #False)
  ;********************************************************************************
  ; Execute an script sync or async, depending of sAsync var value
  ; EXAMPLE:
  ;         Webdriver_Execute(Cid,sessionID$, "alert('hello');")
  ;         devuelve STATUS|MESSAGE
  ;********************************************************************************
  Protected json$, res$, nJS.l, Async$, status, message.s
 
  If sAsync
    Async$ = "_async"
  Else
    Async$ = ""
  EndIf
 
  json$ = ~"{" + #LF$
  json$ + ~"\"script\": " + #DQUOTE$ + sScript + #DQUOTE$ + #LF$
  json$ + ~", \"args\": []" + #LF$ 
  json$ + ~"}" + #LF$ 
 
  res$ = Webdriver_Req(Cid, sessionID$ + "/execute" + Async$, json$, "", #PB_JSON_Object)
 
  nJS = ParseJSON(#PB_Any, res$)
  If IsJSON(nJS)
    nJS = JSONValue(nJS)
    status = GetJSONInteger(GetJSONMember(nJS, "status"))
    If status = 0
      message = "OK"
    Else     
      message = GetJSONString(GetJSONMember(GetJSONMember(nJS, "value"), "message"))
    EndIf     
    res$ = Str(status) + "|" + message   
  EndIf
 
  ProcedureReturn res$
 
EndProcedure



;-============================
;- WEBDRIVER EXAMPLE
;-============================
CompilerIf #PB_Compiler_IsMainFile
  DisableExplicit
  InitNetwork()
 
  default_driver_Port = 9515
  driver_location$ = "chromedriver.exe"
  Wbid = RunProgram(driver_location$ ,"" ,"",#PB_Program_Open)
 
  Cid = OpenNetworkConnection("127.0.0.1",default_driver_Port)
 
  Webdriver_DesiredCapabilitiesAdd("default", "default")
  ClearList(chromeOptions())
  Webdriver_ChromeOptionsAdd("--window-size", "650,480") 
  sessionID$  = "/session/" + Webdriver_NewSession(Cid, "")
 
  Webdriver_Navigate(Cid, sessionID$, "https://www.purebasic.fr/english/")
 
  xpath.s = "//*[@id='menubar']/table/tbody/tr/td[1]/a[2]"
  Webdriver_ElementClick(Cid, sessionID$, xpath)
 
  xpath.s = "//*[@id='pagecontent']/form/table/tbody/tr[2]/td[2]/input[1]"
  Webdriver_ElementValue(Cid, sessionID$, xpath, "Chromedriver")
  Webdriver_ElementValue(Cid, sessionID$, xpath, "\n")
 
 
  Delay(2000)
  Webdriver_DeleteSession(Cid, sessionID$)
  CloseNetworkConnection(Cid)
  KillProgram(Wbid)
  CloseProgram(Wbid) 
  Delay(1000)
CompilerEndIf


;-============================
;- WEBDRIVER EMBEDDED EXAMPLE
;-============================
CompilerIf #PB_Compiler_IsMainFile
 
  DisableExplicit
  InitNetwork()
 
  ;Create a window with a container
  mainWindow = OpenWindow(#PB_Any, 0, 0, 800, 600, "PB WINDOWS with a containerGadget", #PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_SizeGadget)
  containerG = ContainerGadget(#PB_Any, 50,50, 700,500, #PB_Container_BorderLess) 
  CloseGadgetList() 
  SetGadgetColor(containerG, #PB_Gadget_BackColor, $BFBF3F)
  While WindowEvent(): Wend 
 
  default_driver_Port = 9515
  Wbid = RunProgram(driver_location$ ,"" ,"",#PB_Program_Open|#PB_Program_Hide)
   
  Cid = OpenNetworkConnection("127.0.0.1",default_driver_Port)
 
  Webdriver_DesiredCapabilitiesAdd("default", "default")
  ClearList(chromeOptions())
  Webdriver_ChromeOptionsAdd("--window-size", "100,100")
  Webdriver_ChromeOptionsAdd("--window-position", "-1000,-1000")
 
  sessionID$  = "/session/" + Webdriver_NewSession(Cid, "")
 
 
  Webdriver_Embedded(Cid, sessionID$, containerG, #True)
 
  Webdriver_Navigate(Cid, sessionID$, "https://www.purebasic.fr/english/")
 
  Repeat : Until WaitWindowEvent()=#PB_Event_CloseWindow
 
  Debug "Delete: " + Webdriver_DeleteSession(Cid, sessionID$)
 
  CloseNetworkConnection(Cid)
  KillProgram(Wbid)
  CloseProgram(Wbid)
 
CompilerEndIf

_________________
PB 5.6x, PureVision User.


Last edited by zikitrake on Sun Oct 28, 2018 11:05 pm, edited 1 time in total.

Top
 Profile  
Reply with quote  
 Post subject: Re: Driving a Web Browser with PureBasic
PostPosted: Sat Oct 27, 2018 12:02 pm 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Thu Mar 25, 2004 2:15 pm
Posts: 639
Location: Spain
Updated previous code with an example of embedded Chrome in a containerGagdet

_________________
PB 5.6x, PureVision User.


Top
 Profile  
Reply with quote  
 Post subject: Re: Driving a Web Browser with PureBasic
PostPosted: Sun Oct 28, 2018 8:37 pm 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Thu Sep 17, 2015 3:39 pm
Posts: 127
hi cck :D,

Quote:
PS: I love CELTIC too !!! :D

I love you too ahamm my friend :D

good job @zikitrake,
Currently I'm using "https://bitbucket.org/chromiumembedded/cef"
good luck for you :)

_________________
interested in Cybersecurity..


Top
 Profile  
Reply with quote  
 Post subject: Re: Driving a Web Browser with PureBasic
PostPosted: Sun Oct 28, 2018 11:08 pm 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Thu Mar 25, 2004 2:15 pm
Posts: 639
Location: Spain
CELTIC88 wrote:
hi cck :D,

Quote:
PS: I love CELTIC too !!! :D

I love you too ahamm my friend :D

good job @zikitrake,
Currently I'm using "https://bitbucket.org/chromiumembedded/cef"
good luck for you :)

Thank you, Celtic88 you inspired me with your code in the other thread!

I've been watching CEF for a while, but I'm afraid my knowledge doesn't allow me to know how to get started.

_________________
PB 5.6x, PureVision User.


Top
 Profile  
Reply with quote  
 Post subject: Re: Driving a Web Browser with PureBasic
PostPosted: Mon Oct 29, 2018 11:40 am 
Offline
Addict
Addict
User avatar

Joined: Sun Nov 05, 2006 11:42 pm
Posts: 4349
Location: Lyon - France
zikitrake wrote:
PS2: I'm big fan about your posts! :D
Thanks a lot for this kinds words go directly in my heart 8)
I try to put a little bit of good humor in all the programmers friends lifes, in exchange of all their precious and generous helps.
Programming is too much often hards after reflect numerous hours and not always have the morale :|
I always say, the humor is not the ennemy of the serious things :wink: and sometime take the things with a little bit more lightness can help to have new good ideas
Again thanks 8)

Excuse me for the late answer, i'm forcing to go far away of a PC in family by my wife :?

zikitrake wrote:
I just tried your last code with geckodriver.exe, but the ELEMENT ID retrieved has a different format used in Chromedriver
Yes you have right i see that :shock: :wink:
My answer is
Quote:
{"value":{"sessionId":"358f0cfd-d7cc-4b5b-be09-cf3cffb536a7","capabilities":{"acceptInsecureCerts":false,"browserName":"firefox","browserVersion":"63.0","moz:accessibilityChecks":false,
"moz:geckodriverVersion":"0.22.0","moz:headless":false,"moz:processID":7772,
"moz:profile":"C:\\Users\\kcc\\AppData\\Local\\Temp\\rust_mozprofile.CcZdw6OUdHlg","moz:useNonSpecCompliantPointerOrigin":false,
"moz:webdriverClick":true,"pageLoadStrategy":"normal","platformName":"windows","platformVersion":"10.0",
"rotatable":false,"setWindowRect":true,"timeouts":{"implicit":0,"pageLoad":300000,"script":30000},"unhandledPromptBehavior":"dismiss and notify"}}}
358f0cfd-d7cc-4b5b-be09-cf3cffb536a7
and i have try
Code:
/session/358f0cfd-d7cc-4b5b-be09-cf3cffb536a7/url
that not works :|

I have try your splendid code, and it works very well on W10 without proxy
I can't try it behind a PROXY, because i'm not in my enterprise this week, but as soon i can, i'm very interesting to try your code with a PROXY 8)

CHROME, CHROME..always CHROME ...ok talking about CHROME :? :lol: :lol:

Since only CHROME works for the moment, can you adding in your great code a remote for a CHROME portable ?
Like for Firefox, that can be usefull for use the RemoteBrowser on an USB key :wink:
Code:
Url$ +             "|moz:firefoxOptions|: {"
Url$ +                 "|binary|: |" + Firefox + "|"
Url$ +             "}"
Url$ +     "}"
I hate all the installing software :twisted:

Again thanks for your code, you help to move very much in this adventure 8)

CELTIC88 wrote:
I love you too ahamm my friend :D
Your kinds words are an honor MASTER, for little KCC 8)

Image

_________________
ImageThe happiness is a road...
Not a destination


Top
 Profile  
Reply with quote  
 Post subject: Re: Driving a Web Browser with PureBasic
PostPosted: Mon Oct 29, 2018 1:45 pm 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Thu Mar 25, 2004 2:15 pm
Posts: 639
Location: Spain
You don't have to excuse yourself, it's the weekend :!:

I also prefer portable applications (that's why I use purebasic and not .net).

Where do I download a portable version of Firefox? Isn't there an official version? :?:

(And if you know any reliable version of Chrome, I'd appreciate it too 8) )

_________________
PB 5.6x, PureVision User.


Top
 Profile  
Reply with quote  
 Post subject: Re: Driving a Web Browser with PureBasic
PostPosted: Mon Oct 29, 2018 2:40 pm 
Offline
Addict
Addict
User avatar

Joined: Sun Nov 05, 2006 11:42 pm
Posts: 4349
Location: Lyon - France
Quote:
You don't have to excuse yourself, it's the weekend :!:
Thanks to understand 8)
But even to go to the toilet ....

Image

the time is long without PB :cry:
Fortunaltely......there is phone portable


Quote:
I also prefer portable applications (that's why I use purebasic and not .net).
Exactely like me :D
Since i have see PB is standalone (And other advantages obviously :wink:), i have abandon the other langages
Before i use VB6, and now since VB6 is an old software,.. portable version exist (non official)
That proof, even a software like VB6 really integrating in BDR can works without installing :? :shock:

A site create versions (non official) of numerous software
It's not always the last version, but personally i use this versions since several years without problem
And i have see, even this portable version auto update alone and continue to be portable :shock:
Like this i can use old code, old addons, etc...when i want
Like PB, i play with the differentes versions besides, all that on a external DD 8)

Firefox
https://portableapps.com/apps/internet/firefox_portable

Chrome
https://portableapps.com/apps/internet/ ... e_portable

The portability...

Image

Is the freedom !!! :D

_________________
ImageThe happiness is a road...
Not a destination


Top
 Profile  
Reply with quote  
 Post subject: Re: Driving a Web Browser with PureBasic
PostPosted: Mon Oct 29, 2018 8:46 pm 
Offline
Addict
Addict
User avatar

Joined: Sun Nov 05, 2006 11:42 pm
Posts: 4349
Location: Lyon - France
I have again searching all the day without real succes :|
Always impossible to send the elementID and click on a link

Just learn apparently the ID of element is the second part after the ":"
Code:
element-6066-11e4-a52e-4f735466cecf:b3047924-f191-46b8-986b-aa767bd7bd95
so
Code:
b3047924-f191-46b8-986b-aa767bd7bd95
But after ...nothing works, when i send to GeckoDriver
Code:
POST /session/0bc877c3-7da2-44e8-b019-0b7a85b208ef/element/b3047924-f191-46b8-986b-aa767bd7bd95/click HTTP/1.1
Connection: Keep-Alive
Content-Type: application/json;charset=utf-8
Accept: */*
User-Agent: Mozilla/4.0
Content-Length: 0

always the same answer of Geckodriver
Quote:
{"value":{"error":"invalid argument","message":"Failed to decode request as JSON: ","stacktrace":"Syntax error at :1:0"}}
Perhaps also a FF bug, because they are several issue reporting about this subject

I'm desperate, i'm sure we are not really far of the solution, but it was too good to be true, i believe my search stop here, for again another method, more simple :cry:
Not enough example, nobody have really the good idea of directly command GeckoDriver
Everybody pass by Selenium, with PYTHON, RUBY, PHP, JAVASCRIPT....either use the simplicity with OOP langages :|

_________________
ImageThe happiness is a road...
Not a destination


Top
 Profile  
Reply with quote  
 Post subject: Re: Driving a Web Browser with PureBasic
PostPosted: Wed Oct 31, 2018 6:13 pm 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Thu Mar 25, 2004 2:15 pm
Posts: 639
Location: Spain
Kwai chang caine wrote:
I have again searching all the day without real succes :|
Always impossible to send the elementID and click on a link|


Hi, sorry for slow reply, finally, I got an example for Firefox Portable :)

For now, It only works with Navigate and Click Elements, but if you see the Click code you could try to make other commands :)

The code with Firefox example added:

Code:
; Chromedriver.exe from http://chromedriver.chromium.org
; Based on @CELTIC88 sample http://forums.purebasic.com/english/viewtopic.php?f=13&t=69905&p=516646#p516646
; PB FORUM MAIN THREAD: https://www.purebasic.fr/english/viewtopic.php?f=13&t=71582

EnableExplicit
InitNetwork()

;-============================
;- WD PROCEDURE DECLARES
;-============================
;{
Declare.s Webdriver_Header(Metod.s, Loc.s, Cleng)
Declare.s Webdriver_Req(ConnctionID ,url.s,sData.s,JsGetItem.s,JSONType = #PB_JSON_String,ReqType.s  = "POST")
Declare Webdriver_DesiredCapabilitiesAdd(param$, value$)
Declare Webdriver_ChromeOptionsAdd(param$, value$)
Declare.s Webdriver_NewSession(Cid, wdProxy.s = "")
Declare.s Webdriver_DeleteSession(Cid, sessionID$)
Declare Webdriver_Navigate(Cid, sessionID$, url$)
Declare Webdriver_NavigateBack(Cid, sessionID$)
Declare Webdriver_NavigateForward(Cid, sessionID$)
Declare Webdriver_Refresh(Cid, sessionID$)
Declare Webdriver_FullScreen(Cid, sessionID$, activated.b = #True)
Declare Webdriver_Resize(Cid, sessionID$, width.l, height.l)
Declare Webdriver_Embedded(Cid, sessionID$, PBParent.l, noHeader = #True, disableForUser = #False)
Declare Webdriver_Keys(Cid, sessionID$, sKeys.s, wdDelay.l = 300)
Declare.s Webdriver_GetUrl(Cid, sessionID$)
Declare.s Webdriver_Title(Cid, sessionID$)
Declare.s Webdriver_Source(Cid, sessionID$)
Declare.s Webdriver_ScreenShot(Cid, sessionID$)
Declare.s Webdriver_CookiesGetAll(Cid, sessionID$, List wdCookies())
Declare Webdriver_CookieAdd(Cid, sessionID$, *cookie)
Declare Webdriver_CookiesDelete(Cid, sessionID$, cookieName$)
Declare.s Webdriver_CookiesDeleteAll(Cid, sessionID$)
Declare.s Webdriver_ElementGetID(Cid, sessionID$, xpath.s)
Declare Webdriver_ElementClick(Cid, sessionID$, xpath.s, wdDelay.l = 300)
Declare Webdriver_ElementValue(Cid, sessionID$, xpath.s, sKeys.s, wdDelay.l = 300)
Declare.s Webdriver_ElementGetText(Cid, sessionID$, xpath.s, wdDelay.l = 500)
Declare.s Webdriver_Execute(Cid, sessionID$, sScript.s, arguments$, sAsync.b = #False)
Declare WebDriver_SetFocusByClassName (Cid, sessionID$, sFieldClassName.s, idxTag.s="0", valueAdd.b = #False, nuevoValue.s = "", innerHTML.s="", hacerClick.b=#False, TeclaEnter.b = #False, innerText.s = "")
Declare Webdriver_ElementClear(Cid, sessionID$, xpath.s, wdDelay.l = 300)
;}

;-============================
;- WD GLOBAL VARS
;-============================
Global wdBrowser.s = "chrome"
Structure wdSTRdesiredCapabilities
  param$
  value$
EndStructure
  Global NewList desiredCapabilities.wdSTRdesiredCapabilities()
Structure wdSTRchromeoptions
  param$
  value$
EndStructure
  Global NewList chromeOptions.wdSTRchromeoptions()

Structure wdSTRcookie
  domain$
  expiry.l
  httpOnly.b
  name$
  path$
  secure.b
  value$   
EndStructure

Procedure.s MacroReq(Method.s,Loc.s,Cleng)
  Method + " "+Loc+" HTTP/1.1" + #CRLF$ +
           "Connection: Keep-Alive" + #CRLF$ +
           "Content-Type: application/json;charset=utf-8" + #CRLF$ +
           "Accept: */*" + #CRLF$ +
           "User-Agent: Mozilla/4.0" + #CRLF$ +
           "Content-Length: " + Str(Cleng) + #CRLF$ +
           #CRLF$
  ProcedureReturn Method
EndProcedure
Procedure.s Webdriver_Req(ConnctionID ,url.s,sData.s,JsGetItem.s,JSONType = #PB_JSON_String,ReqType.s  = "POST") 
  Protected pReq$ = MacroReq(ReqType,url,StringByteLength(sData,#PB_Ascii)) + sData
;   Debug "**pReq$**"
;   Debug pReq$
  SendNetworkString(ConnctionID,pReq$,#PB_Ascii)
  Protected Size = 1024*1024*10
  Protected *pRepReq = AllocateMemory(Size)
  ReceiveNetworkData(ConnctionID,*pRepReq,Size)
  Protected RepReq.s = StringField(PeekS(*pRepReq,-1,#PB_Ascii),2,#CRLF$ + #CRLF$)
  FreeMemory(*pRepReq)
;   Debug " "
;   Debug "**RepReq$**"
;   Debug RepReq
  Protected Jid = ParseJSON(#PB_Any, RepReq)
  If Jid
    Protected jsV  = JSONValue(Jid)
    If jsV
      Select JSONType
        Case #PB_JSON_Null:    Debug "null"
        Case #PB_JSON_String:  Debug  "string"
          RepReq = GetJSONString(GetJSONMember(jsV, JsGetItem))
        Case #PB_JSON_Number:  Debug  "number"
          RepReq = Str(GetJSONInteger(GetJSONMember(jsV, JsGetItem)))
        Case #PB_JSON_Boolean: Debug  "boolean"
        Case #PB_JSON_Array:   Debug  "array"
        Case #PB_JSON_Object:  Debug  "object"
      EndSelect
    EndIf
  Else
    Debug "JSON error : " + JSONErrorMessage()
  EndIf
 
  ProcedureReturn  RepReq
EndProcedure
;-============================
;- WD MAIN PROCEDURES
;-============================
  Procedure Webdriver_DesiredCapabilitiesAdd(param$, value$)
  Protected replaced.b = #False
 
  If param$ = "default" And value$ = "default"
    ClearList(desiredCapabilities())
    AddElement(desiredCapabilities()): desiredCapabilities()\param$ = "javascriptEnabled"   : desiredCapabilities()\value$ = "true"
    AddElement(desiredCapabilities()): desiredCapabilities()\param$ = "nativeEvents"        : desiredCapabilities()\value$ = "true"
    AddElement(desiredCapabilities()): desiredCapabilities()\param$ = "browserName"         : desiredCapabilities()\value$ = #DQUOTE$ + wdBrowser + #DQUOTE$
    AddElement(desiredCapabilities()): desiredCapabilities()\param$ = "acceptInsecureCerts" : desiredCapabilities()\value$ = "true"   
  Else
    ResetList(desiredCapabilities())
    ForEach(desiredCapabilities())
      If desiredCapabilities()\param$ = param$
        desiredCapabilities()\value$ = value$
        replaced = #True
        Break
      EndIf
    Next
   
    If replaced = #False
      AddElement(desiredCapabilities())
      desiredCapabilities()\param$ = param$
      desiredCapabilities()\value$ = value$ 
    EndIf
   
  EndIf 
EndProcedure

Procedure Webdriver_ChromeOptionsAdd(param$, value$)
  Protected replaced.b = #False
 
  ResetList(chromeOptions())
  ForEach(chromeOptions())
    If chromeOptions()\param$ = param$
      chromeOptions()\value$ = value$
      replaced = #True
      Break
    EndIf
  Next
 
  If replaced = #False
    AddElement(chromeOptions())
    chromeOptions()\param$ = param$
    chromeOptions()\value$ = value$ 
  EndIf
 
EndProcedure

Procedure.s Webdriver_NewSession(Cid, wbProxy.s = "")
  ;********************************************************************************
  ; Open a new session with/without proxy and return a new sesion ID
  ; wbProxy format: IP:PORT...  "10.20.30.40:5060"
  ; global list chromeOptions() used
  ;********************************************************************************
  Protected sessionID$
  Protected json$, json
  Protected desiredCap$ = ""
  Protected chromeParams$ = ""
 
  ;Read desiredCapabilities list
  If ListSize(desiredCapabilities()) = 0                 ; if desiredCapabilities() is empty, create a default options list
    Webdriver_DesiredCapabilitiesAdd("default", "default")
  EndIf 
  ResetList(desiredCapabilities())
  ForEach(desiredCapabilities())
    With desiredCapabilities()
      If Len(desiredCap$): desiredCap$ + ", " + #LF$: EndIf
      desiredCap$ + "'" + \param$
      If Len(\value$)
        desiredCap$ + "': " + \value$
      EndIf
    EndWith
  Next
  desiredCap$ = ReplaceString(desiredCap$, "'", #DQUOTE$)
 
  ;Fill chromeParams$ from chromeOptions() list
  ResetList(chromeOptions()) 
  ForEach(chromeOptions())
    With chromeOptions()
      If Len(chromeParams$): chromeParams$ + ", " + #LF$: EndIf
      chromeParams$ + "'" + \param$
      If Len(\value$)
        chromeParams$ + "=" + \value$
      EndIf
      chromeParams$ + "'"
    EndWith
  Next 
  chromeParams$ = ReplaceString(chromeParams$, "'", #DQUOTE$)
 
 
  json$ = ~"{" + #LF$
  json$ + ~"  |desiredCapabilities|: {" + #LF$
  json$ +       desiredCap$ + #LF$
    ; IS CHROME? 
  If wdBrowser = "chrome"
    json$ + ~",   |chromeOptions|: {" + #LF$
    json$ + ~"     |args|: [" + chromeParams$ + "]" + #LF$ 
    json$ + ~"     }" + #LF$ 
  EndIf
 
    ; HAVE A PROXY?
  If wbProxy
    json$ + ~", |proxy|: {" + #LF$
    json$ + ~"    |proxyType|: |manual|," + #LF$
    json$ + ~"    |httpProxy|: |" + wbProxy + "|" + #LF$
    json$ + ~"   }" + #LF$
  EndIf
  ;END PROXY JSON
 
  json$ + ~" }" + #LF$ 
  json$ + ~"}"
 
  json$ = ReplaceString(json$, "|", #DQUOTE$)
 
   ParseJSON(0, json$)
   json$ = ComposeJSON(0, #PB_JSON_PrettyPrint)
   Debug json$
   
   Select wdBrowser
       
    Case "chrome"
      sessionID$  = Webdriver_Req(Cid,"/session", json$, "sessionId")
    Case "firefox"
      json$ = Webdriver_Req(Cid,"/session", json$, "value", #PB_JSON_Object)
      jSON = ParseJSON(#PB_Any, json$)
      sessionID$ = GetJSONString(GetJSONMember(GetJSONMember(JSONValue(jSON), "value"), "sessionId"))
  EndSelect
   
  ProcedureReturn sessionID$ 
EndProcedure
Procedure.s Webdriver_DeleteSession(Cid, sessionID$)
  ;******************************************************************************** 
  ; Close selected session
  ; Returns: {object} An object describing the session's capabilities. 
  ;********************************************************************************
  Protected res$
  res$ = Webdriver_Req(Cid,sessionID$+"", "", "status",#PB_JSON_Object,"DELETE") 
  ProcedureReturn res$
EndProcedure
;-============================
;- WD NAVIGATION PROCEDURES
;-============================
Procedure Webdriver_Navigate(Cid, sessionID$, url$)
  Protected json$, status.l
  json$ = ~"{"
  json$ + ~"\"url\":" + #DQUOTE$ + url$ + #DQUOTE$
  json$ + ~"}" 
  status = Val (Webdriver_Req(Cid,sessionID$+"/url", json$, "",#PB_JSON_Null))
  ProcedureReturn status 
EndProcedure
Procedure Webdriver_NavigateBack(Cid, sessionID$)
  ;********************************************************************************
  ; Navigate backwards in the browser history, if possible.
  ;********************************************************************************
  Protected status
  status = Val(Webdriver_Req(Cid,sessionID$+"/back", "", "status",#PB_JSON_Number))
  ProcedureReturn status
EndProcedure
Procedure Webdriver_NavigateForward(Cid, sessionID$)
  ;********************************************************************************
  ; Navigate forwards in the browser history, if possible.
  ;********************************************************************************
  Protected status
  status = Val(Webdriver_Req(Cid,sessionID$+"/forward", "", "status",#PB_JSON_Number))
  ProcedureReturn status
EndProcedure
;-============================
;- WD WINDOWS PROCEDURES
;-============================
Procedure Webdriver_Refresh(Cid, sessionID$)
  ;********************************************************************************
  ; Refresh the current page
  ;********************************************************************************
  Protected status
  status = Val(Webdriver_Req(Cid,sessionID$+"/refresh", "", "status",#PB_JSON_Number))
  ProcedureReturn status
EndProcedure
Procedure Webdriver_FullScreen(Cid, sessionID$, activated.b = #True)
  ;********************************************************************************
  ; Maximize the specified window If Not already maximized.
  ; If the :windowHandle URL parameter is "current", the currently active window will be maximized. 
  ;********************************************************************************
  Protected wHandle.s   
  wHandle = Webdriver_Req(Cid,sessionID$+"/window_handle", "", "value",#PB_JSON_String,"GET")   
  Webdriver_Req(Cid,sessionID$+"/window/" + wHandle + "/maximize", "", "",#PB_JSON_Null) 
EndProcedure
Procedure Webdriver_Resize(Cid, sessionID$, width.l, height.l)
  Protected wHandle.s, json$
 
  wHandle = Webdriver_Req(Cid,sessionID$+"/window_handle", "", "value",#PB_JSON_String,"GET")
 
  If Len(wHandle)
    json$ = ~"{"
    json$ + ~"\"width\": " + Str(width) + ", "
    json$ + ~"\"height\": " + Str(height)
    json$ + ~"}"
   
    Webdriver_Req(Cid,sessionID$+"/window/" + wHandle + "/size", json$, "",#PB_JSON_Null)
  EndIf
 
EndProcedure
Procedure Webdriver_Embedded(Cid, sessionID$, PBParent.l, noHeader = #True, disableForUser = #False)
  ;********************************************************************************
  ; PBParent parameter must be a gadgetContainer or a Window
  ; noHeader = #true will hide chromeheader (Tabs, Search bar, Bookmarks bar)
  ; disableForUser = #true to disable parent Gadget/Window
  ;********************************************************************************
  Delay(500)
  Delay(500)
  Protected width.l, height.l
  Protected oldUrl.s
  Protected dataUrl.s
  Protected PBparentHwnd
  Protected chromeTitle.s, chromeHwnd
  Protected chromeChildTitle.s, chromeChildHwnd
  Protected rc.rect, chromeY, chromeChildY, chromeYrelative

  oldUrl = Webdriver_GetUrl(Cid, sessionID$)
  dataUrl = URLEncoder(~"data:text/html;charset=utf-8,<!DOCTYPE HTML><title>" + sessionID$ + "</title>")
  Webdriver_Navigate(Cid, sessionID$, dataUrl)

  ;If PBParent is a containerGadget and noHeader = #true then
  ;   create a new containerGadget As child of original PBParent
  ;   and replace PBParent with the new gadget
  If noHeader = #True And IsGadget(PBParent) And GadgetType(PBParent) = #PB_GadgetType_Container
    OpenGadgetList(PBParent)
      Define PBParentNew = ContainerGadget(#PB_Any, 0,0, GadgetWidth(PBParent), GadgetHeight(PBParent), #PB_Container_BorderLess)
    CloseGadgetList()
    If IsGadget(PBParentNew)
      PBParent = PBParentNew
    EndIf
  Else
    noHeader = #False
  EndIf

  ;Resize Chrome Session to PB Parent size 
  If IsGadget(PBParent) And GadgetType(PBParent) = #PB_GadgetType_Container
    width = GadgetWidth(PBParent): height = GadgetHeight(PBParent)
    PBparentHwnd = GadgetID(PBParent)
    HideGadget(PBParent,1)
  ElseIf IsWindow(PBParent)
    width = WindowWidth(PBParent): height = WindowHeight(PBParent)
    PBparentHwnd = WindowID(PBParent)
  Else
    MessageRequester("Error!", "PBParent parameter must be a gadgetContainer or a Window", #PB_MessageRequester_Error)
    ProcedureReturn
  EndIf
 
  Webdriver_Resize(Cid, sessionID$, 1, 1)
  While WindowEvent():Wend
 
  ;Search hwnd of the chrome Window opened 
  chromeTitle      = sessionID$ + " - Google Chrome"
  chromeChildTitle = "Chrome_RenderWidgetHostHWND"
  chromeHwnd = FindWindow_(0, chromeTitle)
  If Not chromeHwnd
    MessageRequester("Error", chromeTitle + " must be running !")
    End
  Else
    chromeChildHwnd = FindWindowEx_(chromeHwnd, 0, chromeChildTitle, 0);
  EndIf   
 
  ; if noHeader = #true, we search Chrome Content part Y position and move up PB Parent Gadget/Window
  ; only works with containerGadget Parent, not when Parent is a windows
  If noHeader And chromeChildHwnd <> 0   
      GetWindowRect_(chromeHwnd,rc)
      chromeY = rc\top
      GetWindowRect_(chromeChildHwnd,rc)
      chromeChildY = rc\top               ; Y from top of screen
      chromeYrelative = chromeChildY-chromeY    ; Y from top of chrome window
     
      ResizeGadget(PBParent, #PB_Ignore, -chromeYrelative, #PB_Ignore, GadgetHeight(PBParent) + chromeYrelative)
    EndIf
   
  Webdriver_Navigate(Cid, sessionID$, oldUrl)
  While WindowEvent():Wend
  Webdriver_Resize(Cid, sessionID$, width, height+chromeYrelative)
 
 
 
 
  ; Set Chrome as child of PB Parent
  If PBparentHwnd         
    SetWindowLong_(chromeHwnd, #GWL_STYLE, GetWindowLong_(chromeHwnd, #GWL_STYLE) &(~(#WS_MAXIMIZE|#WS_SIZEBOX )))
    SetParent_(chromeHwnd, PBparentHwnd)
    SetWindowPos_(chromeHwnd, 0, 0, 0, 0, 0, #SWP_NOSIZE|#SWP_NOZORDER|#SWP_FRAMECHANGED)           
  EndIf
 While WindowEvent():Wend
 
  If IsGadget(PBParent)
    DisableGadget(PBParent, disableForUser)
    HideGadget(PBParent,0)
  ElseIf IsWindow(PBParent)
    DisableWindow(PBParent, disableForUser)
  EndIf 
 
 
EndProcedure
;-============================
;- WD GENERAL PROCEDURES
;-============================
Procedure Webdriver_Keys(Cid, sessionID$, sKeys.s, wdDelay.l = 300)
  ;********************************************************************************
  ; Send keys to the session
  ; EXAMPLE:
  ;           xpath = "/html/body/div[1]/div[1]/div[1]/div[1]/div[2]/textarea"
  ;           Webdriver_ElementValue(Cid, sessionID$, xpath, "Hello, world!")
  ;********************************************************************************
  Protected json$

  Delay(wdDelay)
 
  json$ =  "{" + #LF$
  json$ + ~"\"value\": [" + #DQUOTE$ + sKeys + #DQUOTE$ + "]" + #LF$
  json$ + ~"}"
 
  Webdriver_Req(Cid,sessionID$ + "/keys", json$, "",#PB_JSON_Null)
EndProcedure
Procedure.s Webdriver_GetUrl(Cid, sessionID$)
  ;********************************************************************************
  ; Retrieve the URL of the current page.
  ;********************************************************************************
  Protected url$
  url$ = Webdriver_Req(Cid,sessionID$+"/url", "", "value",#PB_JSON_String, "GET")
  ProcedureReturn(url$)
EndProcedure
Procedure.s Webdriver_Title(Cid, sessionID$)
  ;********************************************************************************
  ; Get the current page title.
  ;********************************************************************************
  Protected title$
  title$ = Webdriver_Req(Cid,sessionID$ + "/title", "", "value",#PB_JSON_String,"GET") 
  ProcedureReturn(title$)
EndProcedure
Procedure.s Webdriver_Source(Cid, sessionID$)
  ;********************************************************************************
  ; Return the source code
  ;********************************************************************************
  ProcedureReturn Webdriver_Req(Cid,sessionID$+"/source", "", "value",#PB_JSON_String,"GET")
EndProcedure
Procedure.s Webdriver_ScreenShot(Cid, sessionID$)
  ;********************************************************************************
  ; Take a screenshot of the current page.
  ; Returns string with the screenshot As a base64 encoded PNG.
  ;********************************************************************************
  Protected status.l, value.s
  status = Val(Webdriver_Req(Cid,sessionID$+"/screenshot", "", "status",#PB_JSON_Number,"GET"))
  If status = 0
    value = Webdriver_Req(Cid,sessionID$+"/screenshot", "", "value",#PB_JSON_String,"GET")
  EndIf
 
  ProcedureReturn value
EndProcedure
Procedure.s Webdriver_CookiesGetAll(Cid, sessionID$, List wdCookies.wdSTRcookie())
  ;******************************************************************************** 
  ;  Retrieve all cookies visible to the current page 
  ;  Example:
  ;               NewList theCookies.wdSTRcookie()
  ;               Webdriver_CookiesGetAll(Cid, sessionID$, theCookies())
  ;               ForEach(theCookies())
  ;                 Debug theCookies()\name$
  ;                 Debug theCookies()\value$
  ;               Next 
  ;********************************************************************************
  Protected json$, jsO, jsV, objectValue.l
 
  json$ = Webdriver_Req(Cid,sessionID$+"/cookie", "", "value",#PB_JSON_Object,"GET") 
 
  jsO = ParseJSON(#PB_Any, json$)
  jsV  = JSONValue(jsO)
  objectValue = GetJSONMember(jsV, "value")
 
  ClearList(wdCookies())
  ExtractJSONList(objectValue, wdCookies())
 
EndProcedure
Procedure Webdriver_CookieAdd(Cid, sessionID$, *cookie.wdSTRcookie)
  ;******************************************************************************** 
  ; Set a cookie. If the cookie path is not specified, it should be set to "/".
  ; Likewise, If the domain is omitted, it should Default To the current page's domain. 
  ; Example:
  ;             myCookie.wdSTRcookie
  ;             myCookie\name$ = "pbcookie"
  ;             myCookie\value$ = "Webdriver in PB, yeah!"
  ;             Webdriver_CookieAdd(Cid, sessionID$, myCookie)
  ;********************************************************************************
  Protected json$, status
  Protected secure.s   = "false"
  Protected httpOnly.s = "false"
 
  With *cookie
    If \httpOnly: httpOnly = "true": EndIf
    If \secure: secure = "true": EndIf
   
    json$ = ~"{"
    json$ + ~"  \"cookie\": {"    + #LF$
    json$ + ~"    \"domain\":"    + #DQUOTE$ + \domain$   + #DQUOTE$ + "," + #LF$
    json$ + ~"    \"expiry\":"    + #DQUOTE$ + \expiry    + #DQUOTE$ + "," + #LF$
    json$ + ~"    \"httpOnly\":"  + httpOnly + "," + #LF$
    json$ + ~"    \"name\":"      + #DQUOTE$ + \name$     + #DQUOTE$ + "," + #LF$
    json$ + ~"    \"path\":"      + #DQUOTE$ + \path$     + #DQUOTE$ + "," + #LF$
    json$ + ~"    \"secure\":"    + secure + "," + #LF$
    json$ + ~"    \"value\":"     + #DQUOTE$ + \value$    + #DQUOTE$ + ""
    json$ + ~"  }"
    json$ + ~"}"
   
  EndWith
 
  status = Val( Webdriver_Req(Cid,sessionID$+"/cookie", json$, "status",#PB_JSON_Number,"POST")  )
  ProcedureReturn status
 
EndProcedure

Procedure Webdriver_CookiesDelete(Cid, sessionID$, cookieName$)
  ;********************************************************************************
  ; Delete the cookie with the given name
  ;********************************************************************************
  Protected status
  status = Val (Webdriver_Req(Cid,sessionID$+"/cookie/" + cookieName$, "", "status",#PB_JSON_Number,"DELETE"))
  ProcedureReturn status
EndProcedure
Procedure.s Webdriver_CookiesDeleteAll(Cid, sessionID$)
  ;********************************************************************************
  ; Delete all cookies visible to the current page.
  ;********************************************************************************
  Webdriver_Req(Cid,sessionID$+"/cookie", "", "",#PB_JSON_Null,"DELETE") 
EndProcedure
;-============================
;- WD ELEMENTS PROCEDURES
;-============================
Procedure.s Webdriver_ElementGetID(Cid, sessionID$, xpath.s)
  ;********************************************************************************
  ; Return ID of an element
  ;********************************************************************************
  Protected json$, nJS.l, nJSv.l, ObjectValue.l, MemberKey$, MemberValue
  Protected status, value$
 
  json$ = ~"{"
  json$ + ~"\"using\":\"xpath\","
  json$ + ~"\"value\":" + #DQUOTE$ + xpath + #DQUOTE$
  json$ + ~"}"
 
  value$ = Webdriver_Req(Cid,sessionID$ + "/element", json$, "value",#PB_JSON_Object,"POST")
 
  nJS = ParseJSON(#PB_Any, value$)
  value$ = ""
 
  If IsJSON(nJS) 
    nJSv = JSONValue(nJS)
    If nJSv
      Select wdBrowser
        Case  "chrome"
          status = GetJSONInteger(GetJSONMember(nJSv, "status"))
          If status = 0
            value$ = GetJSONString(GetJSONMember(GetJSONMember(nJSv, "value"), "ELEMENT"))
          EndIf
        Case "firefox"
          ObjectValue = GetJSONMember(nJSv, "value")
          If ObjectValue
            MemberKey$ = JSONMemberKey(ObjectValue)
            MemberValue = JSONMemberValue(ObjectValue)
            If MemberValue
              value$ = GetJSONString(MemberValue)
            EndIf
          EndIf
      EndSelect
    EndIf 
  EndIf
 
  ProcedureReturn value$
EndProcedure
Procedure Webdriver_ElementClick(Cid, sessionID$, xpath.s, wdDelay.l = 300)
  ;********************************************************************************
  ; Click in element
  ; EXAMPLE:   
  ;           xpath = "/html/body/div[1]/div[1]/div[1]/div[1]/div[2]/textarea"
  ;           Webdriver_ElementClick(Cid, sessionID$, xpath)
  ;********************************************************************************
  Protected elementoID.s, sScript.s, args.s
 
  Delay(wdDelay) 
 
  elementoID = Webdriver_ElementGetID(Cid, sessionID$, xpath)
 
  Select wdBrowser
    Case "chrome"     
      Webdriver_Req(Cid,sessionID$ + ~"/element/" + elementoID + "/click", "", "",#PB_JSON_Null,"POST") 
    Case "firefox"     
      xpath = URLEncoder(xpath)
      sScript = "arguments[0].click();"     
      args = ~"{\"ELEMENT\":" + #DQUOTE$ + elementoID + #DQUOTE$ + "}"     
      Webdriver_Execute(Cid, sessionID$, sScript, args)
  EndSelect
 
EndProcedure
Procedure Webdriver_ElementValue(Cid, sessionID$, xpath.s, sKeys.s, wdDelay.l = 300)
  ;********************************************************************************
  ; Type text in an element
  ; EXAMPLE:
  ;           xpath = "/html/body/div[1]/div[1]/div[1]/div[1]/div[2]/textarea"
  ;           Webdriver_ElementValue(Cid, sessionID$, xpath, "Hello, world!")
  ;********************************************************************************
  Protected json$, elementoID.s
   
  Delay(wdDelay)
 
  elementoID = Webdriver_ElementGetID(Cid, sessionID$, xpath) 
 
  json$ =  "{" + #LF$
  json$ + ~"\"value\": [" + #DQUOTE$ + sKeys + #DQUOTE$ + "]" + #LF$
  json$ + ~"}"
 
  Webdriver_Req(Cid,sessionID$ + ~"/element/" + elementoID + "/value", json$, "",#PB_JSON_Null)
EndProcedure
Procedure.s Webdriver_ElementGetText(Cid, sessionID$, xpath.s, wdDelay.l = 500)
  ;********************************************************************************
  ; Get text in an element
  ; EXAMPLE:
  ;           xpath = "/html/body/div[1]/div[1]/div[1]/div[1]/div[2]/textarea"
  ;           Webdriver_ElementValue(Cid, sessionID$, xpath, "Hello, world!")
  ;********************************************************************************
  Protected elementoID.s
  Protected status, value$
 
  Delay(wdDelay)
 
  status = 0
  value$  = ""
 
  elementoID = Webdriver_ElementGetID(Cid, sessionID$, xpath) 
 
  If elementoID
    status = Val( Webdriver_Req(Cid,sessionID$ + ~"/element/" + elementoID + "/text", "", "status",#PB_JSON_Number, "GET") )
    If status = 0 ; OK?
      value$ = Webdriver_Req(Cid,sessionID$ + ~"/element/" + elementoID + "/text", "", "value",#PB_JSON_String, "GET")
    EndIf
  EndIf
   
  ProcedureReturn value$
 
EndProcedure
Procedure Webdriver_ElementClear(Cid, sessionID$, xpath.s, wdDelay.l = 300)
  ;********************************************************************************
  ; Clear visible text in textarea or other element
  ; EXAMPLE:   
  ;           xpath = "/html/body/div[1]/div[1]/div[1]/div[1]/div[2]/textarea"
  ;           Webdriver_ElementClear(Cid, sessionID$, xpath)
  ;********************************************************************************
  Protected elementoID.s
 
  Delay(wdDelay) 
 
  elementoID = Webdriver_ElementGetID(Cid, sessionID$, xpath)   
  Webdriver_Req(Cid,sessionID$ + ~"/element/" + elementoID + "/clear", "", "",#PB_JSON_Null,"POST") 
EndProcedure
;-============================
;- WD SCRIPTS PROCEDURES
;-============================
Procedure.s Webdriver_Execute(Cid, sessionID$, sScript.s, arguments$, sAsync.b = #False)
  ;********************************************************************************
  ; Execute an script sync or async, depending of sAsync var value
  ; EXAMPLE:
  ;         Webdriver_Execute(Cid,sessionID$, "alert('hello');")
  ;         devuelve STATUS|MESSAGE
  ;********************************************************************************
  Protected json$, res$, nJS.l, Async$, status, message.s
 
  Select wdBrowser
    Case "chrome"
      If sAsync: Async$ = "_async": Else: Async$ = "": EndIf
    Case "firefox"
      If sAsync: Async$ = "/async": Else: Async$ = "/sync": EndIf
  EndSelect
 
  json$ = ~"{" + #LF$
  json$ + ~"\"script\": " + #DQUOTE$ + sScript + #DQUOTE$ + #LF$
  json$ + ~", \"args\": [" + arguments$ + "]" + #LF$ 
  json$ + ~"}" + #LF$     
  res$ = Webdriver_Req(Cid, sessionID$ + "/execute" + Async$, json$, "", #PB_JSON_Object)
 
  Select wdBrowser
    Case "chrome"     
      nJS = ParseJSON(#PB_Any, res$)
      If IsJSON(nJS)
        nJS = JSONValue(nJS)
        status = GetJSONInteger(GetJSONMember(nJS, "status"))
        If status = 0
          message = "OK"
        Else     
          message = GetJSONString(GetJSONMember(GetJSONMember(nJS, "value"), "message"))
        EndIf     
        res$ = Str(status) + "|" + message   
      EndIf
    Case "firefox"
      res$ = "0|0"
  EndSelect
 
 
  ProcedureReturn res$
 
EndProcedure
;-============================
;- WEBDRIVER FIREFOX EXAMPLE
;-============================
CompilerIf #PB_Compiler_IsMainFile
  DisableExplicit
 
  ;global variable wdBrowser must be defined before all other commands (by default, wdBrowser = "chrome"
  wdBrowser = "firefox"
 
  default_driver_Port = 4444
  driver_location$ = "geckodriver.exe"
  Wbid = RunProgram(driver_location$ ,"-v" ,"",#PB_Program_Open)

 
  Cid = OpenNetworkConnection("127.0.0.1",default_driver_Port)
 
  Webdriver_DesiredCapabilitiesAdd("default", "default")
  Webdriver_DesiredCapabilitiesAdd("binary", #DQUOTE$ + "d:/FirefoxPortable_63.0_English.paf/App/Firefox64/firefox.exe"+#DQUOTE$)
;   Webdriver_DesiredCapabilitiesAdd("marionette", "true")
;   Webdriver_DesiredCapabilitiesAdd("goog:chromeOptions", ~"{\"w3c\": true}")

 
  sessionID$  = "/session/" + Webdriver_NewSession(Cid, "")
 
  Webdriver_Navigate(Cid, sessionID$, "https://www.purebasic.fr/english/")
 
  xpath.s = "//*[@id='menubar']/table/tbody/tr/td[1]/a[2]"
  Webdriver_ElementClick(Cid, sessionID$, xpath)
 
  Delay(2000)
  Webdriver_Execute(Cid,sessionID$, "alert('hello, PB user');", "")
 
  Delay(5000)
  Webdriver_DeleteSession(Cid, sessionID$)
  CloseNetworkConnection(Cid)
  KillProgram(Wbid)
  CloseProgram(Wbid) 
  Delay(1000)
CompilerEndIf


;-============================
;- WEBDRIVER CHROME EXAMPLE 1
;-============================
CompilerIf #PB_Compiler_IsMainFile
  DisableExplicit
 
  ;global variable wdBrowser must be defined before all other commands (by default, wdBrowser = "chrome"
  wdBrowser = "chrome"
 
  default_driver_Port = 9515
  driver_location$ = "chromedriver.exe"
  Wbid = RunProgram(driver_location$ ,"" ,"",#PB_Program_Open)
 
  Cid = OpenNetworkConnection("127.0.0.1",default_driver_Port)
 
  Webdriver_DesiredCapabilitiesAdd("default", "default")
  ClearList(chromeOptions())
  Webdriver_ChromeOptionsAdd("--window-size", "800,700") 
  sessionID$  = "/session/" + Webdriver_NewSession(Cid, "")
 
  Webdriver_Navigate(Cid, sessionID$, "https://www.purebasic.fr/english/")
 
  xpath.s = "//*[@id='menubar']/table/tbody/tr/td[1]/a[2]"
  Webdriver_ElementClick(Cid, sessionID$, xpath)
 
  xpath.s = "//*[@id='pagecontent']/form/table/tbody/tr[2]/td[2]/input[1]"
  Webdriver_ElementValue(Cid, sessionID$, xpath, "Chromedriver")
  Webdriver_ElementValue(Cid, sessionID$, xpath, "\n")
 
 
  Delay(2000)
  Webdriver_DeleteSession(Cid, sessionID$)
  CloseNetworkConnection(Cid)
  KillProgram(Wbid)
  CloseProgram(Wbid) 
  Delay(1000)
CompilerEndIf


;-============================
;- WEBDRIVER CHROME EMBEDDED EXAMPLE
;-============================
CompilerIf #PB_Compiler_IsMainFile
 
  DisableExplicit
 
  ;global variable wdBrowser must be defined before all other commands (by default, wdBrowser = "chrome"
  wdBrowser = "chrome"
   
  ;Create a window with a container
  mainWindow = OpenWindow(#PB_Any, 0, 0, 800, 600, "PB WINDOWS with a containerGadget", #PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_SizeGadget)
  containerG = ContainerGadget(#PB_Any, 50,50, 700,500, #PB_Container_BorderLess) 
  CloseGadgetList() 
  SetGadgetColor(containerG, #PB_Gadget_BackColor, $BFBF3F)
  While WindowEvent(): Wend 
 
  default_driver_Port = 9515
  Wbid = RunProgram(driver_location$ ,"" ,"",#PB_Program_Open|#PB_Program_Hide)
   
  Cid = OpenNetworkConnection("127.0.0.1",default_driver_Port)
 
  Webdriver_DesiredCapabilitiesAdd("default", "default")
  ClearList(chromeOptions())
  Webdriver_ChromeOptionsAdd("--window-size", "100,100")
  Webdriver_ChromeOptionsAdd("--window-position", "-1000,-1000")
 
  sessionID$  = "/session/" + Webdriver_NewSession(Cid, "")
 
 
  Webdriver_Embedded(Cid, sessionID$, containerG, #True)
 
  Webdriver_Navigate(Cid, sessionID$, "https://www.purebasic.fr/english/")
 
  Repeat : Until WaitWindowEvent()=#PB_Event_CloseWindow
 
  Debug "Delete: " + Webdriver_DeleteSession(Cid, sessionID$)
 
  CloseNetworkConnection(Cid)
  KillProgram(Wbid)
  CloseProgram(Wbid)
 
CompilerEndIf



I will try to make this code Gecko compatible, but it a hard work because documentation is scarce and confusing to me.

_________________
PB 5.6x, PureVision User.


Last edited by zikitrake on Thu Nov 01, 2018 9:32 am, edited 1 time in total.

Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 42 posts ]  Go to page Previous  1, 2, 3  Next

All times are UTC + 1 hour


Who is online

Users browsing this forum: mk-soft and 12 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye