[Class]An application port of w3c's webdriver API client.

Post your working scripts, libraries and tools
devnullsp
Posts: 73
Joined: 21 Nov 2017, 09:00

[Class]An application port of w3c's webdriver API client.

30 Oct 2019, 16:45

Hi,

This is my newest release in GitHub of an application port of w3c's webdriver API client in Autohotkey language.

Support all WebDrive:
Download from:
https://github.com/devnullsp/ahkWebDrive

This is NOT a Selenium port.

This is intended for webscrapping purpose.

I hope this is helpfull,

Devnullsp.

changelog:
v1.0 First realease.
v1.1 switch to teadrinker'json.

Sample:

Code: Select all

; get Session (WebDriver is runing @ localhost:9515)
wd := new WDSession("http://localhost:9515")
; navigate to new site
wd.url("https://autohotkey.com")
; click over documentation
wd.element(WDSession.XPath,"//*[@id=""menu-0""]/div/div/div/div[3]/nav/div/ul/li[2]/a").click()
; or use
we :=wd.element(WDSession.XPath,"//*[@id=""menu-0""]/div/div/div/div[3]/nav/div/ul/li[2]/a")
we.click()
; using javascript
we := wd.element(WDSession.XPath,"//*[@id=""menu-0""]/div/div/div/div[3]/nav/div/ul/li[2]/a")
wd.execute("arguments[0].click()",[we])) 
Last edited by devnullsp on 31 Oct 2019, 16:16, edited 4 times in total.
malcev
Posts: 657
Joined: 12 Aug 2014, 12:37

Re: An application port of w3c's webdriver API client.

30 Oct 2019, 19:30

I suggest You do not use JXON parser by Coco, because it is very slow.
Instead of that use JSON class by teadrinker.
For example, test how much time needed to parse delfi.lv page source.

Code: Select all

setbatchlines -1
Run, geckodriver.exe
HTTP := ComObjCreate("WinHTTP.WinHTTPRequest.5.1")
HTTP.Open("POST", "http://127.0.0.1:4444/session", true)
HTTP.Send("{}")
HTTP.WaitForResponse()
sessionId := RegexReplace(HTTP.responseText, "^.+?sessionId"":""(.+?)"".+$", "$1")
HTTP.Open("POST", "http://127.0.0.1:4444/session/" sessionId "/url", true)
HTTP.Send("{""url"":""http://delfi.lv""}")
HTTP.WaitForResponse()
HTTP.Open("GET", "http://127.0.0.1:4444/session/" sessionId "/source", true)
HTTP.Send()
HTTP.WaitForResponse()
a := a_tickcount
responseText := JSON.Parse(http.responseText).value
msgbox % a_tickcount - a
msgbox % responseText


class JSON
{
   static JS := JSON._GetJScriptObject(), true := {}, false := {}, null := {}
   
   Parse(sJson, js := false)  {
      if jsObj := this.VerifyJson(sJson)
         Return js ? jsObj : this._CreateObject(jsObj)
   }
   
   Stringify(obj, js := false, indent := "") {
      if js
         Return this.JS.JSON.stringify(obj, "", indent)
      else {
         sObj := this._ObjToString(obj)
         Return this.JS.eval("JSON.stringify(" . sObj . ",'','" . indent . "')")
      }
   }
   
   GetKey(sJson, key, indent := "") {
      if !this.VerifyJson(sJson)
         Return
      
      try Return this.JS.eval("JSON.stringify((" . sJson . ")" . (SubStr(key, 1, 1) = "[" ? "" : ".") . key . ",'','" . indent . "')")
      catch
         MsgBox, Bad key:`n`n%key%
   }
   
   SetKey(sJson, key, value, indent := "") {
      if !this.VerifyJson(sJson)
         Return
      if !this.VerifyJson(value, true) {
         MsgBox, % "Bad value: " . value                      . "`n"
                 . "Must be a valid JSON string."             . "`n"
                 . "Enclose literal strings in quotes '' or """".`n"
                 . "As an empty string pass '' or """""
         Return
      }
      try {
         res := this.JS.eval( "var obj = (" . sJson . ");"
                            . "obj" . (SubStr(key, 1, 1) = "[" ? "" : ".") . key . "=" . value . ";"
                            . "JSON.stringify(obj,'','" . indent . "')" )
         this.JS.eval("obj = ''")
         Return res
      }
      catch
         MsgBox, Bad key:`n`n%key%
   }
   
   RemoveKey(sJson, key, indent := "") {
      if !this.VerifyJson(sJson)
         Return
      
      sign := SubStr(key, 1, 1) = "[" ? "" : "."
      try {
         if !RegExMatch(key, "(.*)\[(\d+)]$", match)
            res := this.JS.eval("var obj = (" . sJson . "); delete obj" . sign . key . "; JSON.stringify(obj,'','" . indent . "')")
         else
            res := this.JS.eval( "var obj = (" . sJson . ");" 
                               . "obj" . (match1 != "" ? sign . match1 : "") . ".splice(" . match2 . ", 1);"
                               . "JSON.stringify(obj,'','" . indent . "')" )
         this.JS.eval("obj = ''")
         Return res
      }
      catch
         MsgBox, Bad key:`n`n%key%
   }
   
   Enum(sJson, key := "", indent := "") {
      if !this.VerifyJson(sJson)
         Return
      
      conc := key ? (SubStr(key, 1, 1) = "[" ? "" : ".") . key : ""
      try {
         jsObj := this.JS.eval("(" sJson ")" . conc)
         res := jsObj.IsArray()
         if (res = "")
            Return
         obj := {}
         if (res = -1) {
            Loop % jsObj.length
               obj[A_Index - 1] := this.JS.eval("JSON.stringify((" sJson ")" . conc . "[" . (A_Index - 1) . "],'','" . indent . "')")
         }
         else if (res = 0) {
            keys := jsObj.GetKeys()
            Loop % keys.length
               k := keys[A_Index - 1], obj[k] := this.JS.eval("JSON.stringify((" sJson ")" . conc . "['" . k . "'],'','" . indent . "')")
         }
         Return obj
      }
      catch
         MsgBox, Bad key:`n`n%key%
   }
   
   VerifyJson(sJson, silent := false) {
      try jsObj := this.JS.eval("(" sJson ")")
      catch {
         if !silent
            MsgBox, Bad JSON string:`n`n%sJson%
         Return
      }
      Return IsObject(jsObj) ? jsObj : true
   }
   
   _ObjToString(obj) {
      if IsObject( obj ) {
         for k, v in ["true", "false", "null"]
            if (obj = this[v])
               Return v
            
         isArray := true
         for key in obj {
            if IsObject(key)
               throw Exception("Invalid key")
            if !( key = A_Index || isArray := false )
               break
         }
         for k, v in obj
            str .= ( A_Index = 1 ? "" : "," ) . ( isArray ? "" : """" . k . """:" ) . this._ObjToString(v)

         Return isArray ? "[" str "]" : "{" str "}"
      }
      else if !(obj*1 = "" || RegExMatch(obj, "\s"))
         Return obj
      
      for k, v in [["\", "\\"], [A_Tab, "\t"], ["""", "\"""], ["/", "\/"], ["`n", "\n"], ["`r", "\r"], [Chr(12), "\f"], [Chr(08), "\b"]]
         obj := StrReplace( obj, v[1], v[2] )

      Return """" obj """"
   }

   _GetJScriptObject() {
      static doc
      doc := ComObjCreate("htmlfile")
      doc.write("<meta http-equiv=""X-UA-Compatible"" content=""IE=9"">")
      JS := doc.parentWindow
      JSON._AddMethods(JS)
      Return JS
   }

   _AddMethods(ByRef JS) {
      JScript =
      (
         Object.prototype.GetKeys = function () {
            var keys = []
            for (var k in this)
               if (this.hasOwnProperty(k))
                  keys.push(k)
            return keys
         }
         Object.prototype.IsArray = function () {
            var toStandardString = {}.toString
            return toStandardString.call(this) == '[object Array]'
         }
      )
      JS.eval(JScript)
   }

   _CreateObject(jsObj) {
      res := jsObj.IsArray()
      if (res = "")
         Return jsObj
      
      else if (res = -1) {
         obj := []
         Loop % jsObj.length
            obj[A_Index] := this._CreateObject(jsObj[A_Index - 1])
      }
      else if (res = 0) {
         obj := {}
         keys := jsObj.GetKeys()
         Loop % keys.length
            k := keys[A_Index - 1], obj[k] := this._CreateObject(jsObj[k])
      }
      Return obj
   }
}
devnullsp
Posts: 73
Joined: 21 Nov 2017, 09:00

Re: An application port of w3c's webdriver API client.

31 Oct 2019, 14:21

malcev wrote:
30 Oct 2019, 19:30
I suggest You do not use JXON parser by Coco, because it is very slow.
Instead of that use JSON class by teadrinker.
ok, but i have one little problem:

teadrinker json test :

Code: Select all

msgbox % json.stringify({capabilities:{}})
show

Code: Select all

 "{ "capabilities": [] }"
so this is not correct.

ok i know its very dificult know if one parameter is an object or an array.

Do json change all empty {} by [] in json.Stringify?

:(

TIA
teadrinker
Posts: 1827
Joined: 29 Mar 2015, 09:41
Contact:

Re: An application port of w3c's webdriver API client.

31 Oct 2019, 15:20

devnullsp wrote: so this is not correct.
IMO, it is correct. AHK doesn't distinguish {} and []. ["a", "b"] is the same as {1: "a", 2: "b"}.
devnullsp
Posts: 73
Joined: 21 Nov 2017, 09:00

Re: An application port of w3c's webdriver API client.

31 Oct 2019, 15:57

I changed from jxon to json. Work end!

yes i know, sorry for my bad english. NOT problem at all.

i know it's correct for autohotkey but i get one error from remote about they need to be one object not one array :(

so in remote server "[]" != "{}"

And thanks for json api ;)

Return to “Scripts and Functions”

Who is online

Users browsing this forum: neogna2 and 24 guests