Compare commits

...

6 commits

Author SHA1 Message Date
Dominik Picheta
a2be578271 Implements ability to press buttons. 2018-05-19 13:18:15 +01:00
Dominik Picheta
c51d51fd72
Merge pull request #3 from hlaaftana/patch-1
Traverse object once for nil checks
2017-12-07 10:38:36 +00:00
hlaaf
61aea333ae
Traverse object once for nil checks 2017-12-07 11:45:52 +03:00
Dominik Picheta
038b5c8c70
Create README.md 2017-11-29 22:16:33 +00:00
Dominik Picheta
bc9dd909a6 Merge pull request #2 from darkmusic/master
Added element.click() and element.sendKeys()
2017-10-23 14:20:04 +01:00
Thomas Johnson
ef844cd998 Added element.click() and element.sendKeys() 2017-10-15 15:38:04 -07:00
2 changed files with 88 additions and 6 deletions

7
README.md Normal file
View file

@ -0,0 +1,7 @@
# webdriver
A simple implementation of the pretty recent [W3C WebDriver spec](https://www.w3.org/TR/webdriver/).
Currently Firefox is just about the only browser that supports it.
I have coded this library during a livestream, do check that out to see how the library is used:
https://www.youtube.com/watch?v=583BwZ7uSro&index=1&list=PLm-fq5xBdPkrMuVkPWuho7XzszB6kJ2My

View file

@ -1,4 +1,6 @@
import httpclient, uri, json, tables, options
# For reference, this is brilliant: https://github.com/jlipps/simple-wd-spec
import httpclient, uri, json, tables, options, strutils, unicode
type
WebDriver* = ref object
@ -43,12 +45,13 @@ proc createSession*(self: WebDriver): Session =
# Check the readiness of the Web Driver.
let resp = self.client.getContent($(self.url / "status"))
let obj = parseJson(resp)
let ready = obj{"value", "ready"}
if obj{"value", "ready"}.isNil():
if ready.isNil():
let msg = "Readiness message does not follow spec"
raise newException(ProtocolException, msg)
if not obj{"value", "ready"}.getBool():
if not ready.getBool():
raise newException(WebDriverException, "WebDriver is not ready")
# Create our session.
@ -56,10 +59,11 @@ proc createSession*(self: WebDriver): Session =
let sessionResp = self.client.postContent($(self.url / "session"),
$sessionReq)
let sessionObj = parseJson(sessionResp)
if sessionObj{"value", "sessionId"}.isNil():
let sessionId = sessionObj{"value", "sessionId"}
if sessionId.isNil():
raise newException(ProtocolException, "No sessionId in response to request")
return Session(id: sessionObj["value"]["sessionId"].getStr(), driver: self)
return Session(id: sessionId.getStr(), driver: self)
proc close*(self: Session) =
let reqUrl = $(self.driver.url / "session" / self.id)
@ -110,6 +114,77 @@ proc getText*(self: Element): string =
return respObj["value"].getStr()
proc click*(self: Element) =
let reqUrl = $(self.session.driver.url / "session" / self.session.id /
"element" / self.id / "click")
let obj = %*{}
let resp = self.session.driver.client.post(reqUrl, $obj)
if resp.status != Http200:
raise newException(WebDriverException, resp.status)
discard checkResponse(resp.body)
# Note: There currently is an open bug in geckodriver that causes DOM events not to fire when sending keys.
# https://github.com/mozilla/geckodriver/issues/348
proc sendKeys*(self: Element, text: string) =
let reqUrl = $(self.session.driver.url / "session" / self.session.id /
"element" / self.id / "value")
let obj = %*{"text": text}
let resp = self.session.driver.client.post(reqUrl, $obj)
if resp.status != Http200:
raise newException(WebDriverException, resp.status)
discard checkResponse(resp.body)
type
# https://w3c.github.io/webdriver/#keyboard-actions
Key* = enum
Unidentified = 0,
Cancel,
Help,
Backspace,
Tab,
Clear,
Return,
Enter,
Shift,
Control,
Alt,
Pause,
Escape
proc toUnicode(key: Key): Rune =
Rune(0xE000 + ord(key))
proc press*(self: Session, keys: varargs[Key]) =
let reqUrl = $(self.driver.url / "session" / self.id / "actions")
let obj = %*{"actions": [
{
"type": "key",
"id": "keyboard",
"actions": []
}
]}
for key in keys:
obj["actions"][0]["actions"].elems.add(
%*{
"type": "keyDown",
"value": $toUnicode(key)
}
)
obj["actions"][0]["actions"].elems.add(
%*{
"type": "keyUp",
"value": $toUnicode(key)
}
)
let resp = self.driver.client.post(reqUrl, $obj)
if resp.status != Http200:
raise newException(WebDriverException, resp.status)
discard checkResponse(resp.body)
when isMainModule:
let webDriver = newWebDriver()
let session = webDriver.createSession()
@ -119,4 +194,4 @@ when isMainModule:
echo session.findElement("#priceblock_ourprice").get().getText()
session.close()
session.close()