Chicken on a Raft
This commit is contained in:
parent
b956247c18
commit
654f4ebd54
9 changed files with 333 additions and 1368 deletions
6
Makefile
6
Makefile
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
# Tangling and weaving
|
# Tangling and weaving
|
||||||
|
|
||||||
webdriver.scm webdriver-impl.scm webdriver.md webdriver.egg webdriver.release-info tests/run.scm: webdriver.org vendor/htmlize.el
|
raft.scm raft-impl.scm raft.md raft.egg raft.release-info tests/run.scm: raft.org vendor/htmlize.el
|
||||||
emacs --batch \
|
emacs --batch \
|
||||||
--load "~/.config/emacs/early-init.el" \
|
--load "~/.config/emacs/early-init.el" \
|
||||||
--load "vendor/htmlize.el" \
|
--load "vendor/htmlize.el" \
|
||||||
|
@ -23,9 +23,9 @@ vendor/htmlize.el:
|
||||||
mkdir -p vendor
|
mkdir -p vendor
|
||||||
wget https://raw.githubusercontent.com/hniksic/emacs-htmlize/dd27bc3f26efd728f2b1f01f9e4ac4f61f2ffbf9/htmlize.el -O vendor/htmlize.el
|
wget https://raw.githubusercontent.com/hniksic/emacs-htmlize/dd27bc3f26efd728f2b1f01f9e4ac4f61f2ffbf9/htmlize.el -O vendor/htmlize.el
|
||||||
|
|
||||||
salmonella: webdriver.scm
|
salmonella: raft.scm
|
||||||
rm -rf report
|
rm -rf report
|
||||||
rm -f webdriver*.so
|
rm -f raft*.so
|
||||||
salmonella --keep-repo --repo-dir=./petri-dish; \
|
salmonella --keep-repo --repo-dir=./petri-dish; \
|
||||||
salmonella-html-report ./salmonella.log report
|
salmonella-html-report ./salmonella.log report
|
||||||
|
|
||||||
|
|
|
@ -1,66 +1,66 @@
|
||||||
;; [[file:webdriver.org::*Dependencies][Dependencies:4]]
|
;; [[file:raft.org::*Dependencies][Dependencies:4]]
|
||||||
(import r7rs
|
(import r7rs
|
||||||
(chicken base)
|
(chicken base)
|
||||||
(chicken string)
|
(chicken string)
|
||||||
(chicken process)
|
(chicken process)
|
||||||
(chicken gc)
|
(chicken gc)
|
||||||
srfi-34 ;;Exception Handling
|
alist-lib ;;Handling alists from JSON objects
|
||||||
srfi-35 ;;Exception Types
|
|
||||||
base64 ;;decoding screenshot data
|
base64 ;;decoding screenshot data
|
||||||
|
coops ;;Object system
|
||||||
http-client ;;API interaction
|
http-client ;;API interaction
|
||||||
intarweb ;;Supporting HTTP functionality
|
intarweb ;;Supporting HTTP functionality
|
||||||
uri-common ;;Supporting HTTP functionality
|
|
||||||
coops ;;Object system
|
|
||||||
alist-lib ;;Handling alists from JSON objects
|
|
||||||
medea ;;JSON handling
|
medea ;;JSON handling
|
||||||
|
srfi-34 ;;Exception Handling
|
||||||
|
srfi-35 ;;Exception Types
|
||||||
|
uri-common ;;Supporting HTTP functionality
|
||||||
)
|
)
|
||||||
;; Dependencies:4 ends here
|
;; Dependencies:4 ends here
|
||||||
|
|
||||||
;; Error Conditions
|
;; Error Conditions
|
||||||
|
|
||||||
;; #+name: wd-exception
|
;; #+name: raft-exception
|
||||||
|
|
||||||
;; [[file:webdriver.org::wd-exception][wd-exception]]
|
;; [[file:raft.org::raft-exception][raft-exception]]
|
||||||
(define-condition-type &wd-exception &error wd-exception?
|
(define-condition-type &raft-exception &error raft-exception?
|
||||||
(stacktrace wd-stacktrace)
|
(stacktrace raft-stacktrace)
|
||||||
(data wd-data))
|
(data raft-data))
|
||||||
;; wd-exception ends here
|
;; raft-exception ends here
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;; #+name: conditions
|
;; #+name: conditions
|
||||||
|
|
||||||
;; [[file:webdriver.org::conditions][conditions]]
|
;; [[file:raft.org::conditions][conditions]]
|
||||||
(define-condition-type &detached-shadow-root &wd-exception detached-shadow-root?)
|
(define-condition-type &detached-shadow-root &raft-exception detached-shadow-root?)
|
||||||
(define-condition-type &element-click-intercepted &wd-exception element-click-intercepted?)
|
(define-condition-type &element-click-intercepted &raft-exception element-click-intercepted?)
|
||||||
(define-condition-type &element-not-interactable &wd-exception element-not-interactable?)
|
(define-condition-type &element-not-interactable &raft-exception element-not-interactable?)
|
||||||
(define-condition-type &insecure-certificate &wd-exception insecure-certificate?)
|
(define-condition-type &insecure-certificate &raft-exception insecure-certificate?)
|
||||||
(define-condition-type &invalid-argument &wd-exception invalid-argument?)
|
(define-condition-type &invalid-argument &raft-exception invalid-argument?)
|
||||||
(define-condition-type &invalid-cookie-domain &wd-exception invalid-cookie-domain?)
|
(define-condition-type &invalid-cookie-domain &raft-exception invalid-cookie-domain?)
|
||||||
(define-condition-type &invalid-element-state &wd-exception invalid-element-state?)
|
(define-condition-type &invalid-element-state &raft-exception invalid-element-state?)
|
||||||
(define-condition-type &invalid-selector &wd-exception invalid-selector?)
|
(define-condition-type &invalid-selector &raft-exception invalid-selector?)
|
||||||
(define-condition-type &invalid-session-id &wd-exception invalid-session-id?)
|
(define-condition-type &invalid-session-id &raft-exception invalid-session-id?)
|
||||||
(define-condition-type &javascript-error &wd-exception javascript-error?)
|
(define-condition-type &javascript-error &raft-exception javascript-error?)
|
||||||
(define-condition-type &move-target-out-of-bounds &wd-exception move-target-out-of-bounds?)
|
(define-condition-type &move-target-out-of-bounds &raft-exception move-target-out-of-bounds?)
|
||||||
(define-condition-type &no-such-alert &wd-exception no-such-alert?)
|
(define-condition-type &no-such-alert &raft-exception no-such-alert?)
|
||||||
(define-condition-type &no-such-cookie &wd-exception no-such-cookie?)
|
(define-condition-type &no-such-cookie &raft-exception no-such-cookie?)
|
||||||
(define-condition-type &no-such-element &wd-exception no-such-element?)
|
(define-condition-type &no-such-element &raft-exception no-such-element?)
|
||||||
(define-condition-type &no-such-frame &wd-exception no-such-frame?)
|
(define-condition-type &no-such-frame &raft-exception no-such-frame?)
|
||||||
(define-condition-type &no-such-shadow-root &wd-exception no-such-shadow-root?)
|
(define-condition-type &no-such-shadow-root &raft-exception no-such-shadow-root?)
|
||||||
(define-condition-type &no-such-window &wd-exception no-such-window?)
|
(define-condition-type &no-such-window &raft-exception no-such-window?)
|
||||||
(define-condition-type &script-timeout &wd-exception script-timeout?)
|
(define-condition-type &script-timeout &raft-exception script-timeout?)
|
||||||
(define-condition-type &session-not-created &wd-exception session-not-created?)
|
(define-condition-type &session-not-created &raft-exception session-not-created?)
|
||||||
(define-condition-type &stale-element-reference &wd-exception stale-element-reference?)
|
(define-condition-type &stale-element-reference &raft-exception stale-element-reference?)
|
||||||
(define-condition-type &timeout &wd-exception timeout?)
|
(define-condition-type &timeout &raft-exception timeout?)
|
||||||
(define-condition-type &unable-to-capture-screen &wd-exception unable-to-capture-screen?)
|
(define-condition-type &unable-to-capture-screen &raft-exception unable-to-capture-screen?)
|
||||||
(define-condition-type &unable-to-set-cookie &wd-exception unable-to-set-cookie?)
|
(define-condition-type &unable-to-set-cookie &raft-exception unable-to-set-cookie?)
|
||||||
(define-condition-type &unexpected-alert-open &wd-exception unexpected-alert-open?)
|
(define-condition-type &unexpected-alert-open &raft-exception unexpected-alert-open?)
|
||||||
(define-condition-type &unknown-command &wd-exception unknown-command?)
|
(define-condition-type &unknown-command &raft-exception unknown-command?)
|
||||||
(define-condition-type &unknown-error &wd-exception unknown-error?)
|
(define-condition-type &unknown-error &raft-exception unknown-error?)
|
||||||
(define-condition-type &unknown-method &wd-exception unknown-method?)
|
(define-condition-type &unknown-method &raft-exception unknown-method?)
|
||||||
(define-condition-type &unsupported-operation &wd-exception unsupported-operation?)
|
(define-condition-type &unsupported-operation &raft-exception unsupported-operation?)
|
||||||
|
|
||||||
(define (wd-throw data)
|
(define (raft-throw data)
|
||||||
(case (alist-ref data 'error)
|
(case (alist-ref data 'error)
|
||||||
(("detached shadow root") (raise (make-condition &detached-shadow-root (alist-ref data 'stacktrace) data)))
|
(("detached shadow root") (raise (make-condition &detached-shadow-root (alist-ref data 'stacktrace) data)))
|
||||||
(("element click intercepted") (raise (make-condition &element-click-intercepted (alist-ref data 'stacktrace) data)))
|
(("element click intercepted") (raise (make-condition &element-click-intercepted (alist-ref data 'stacktrace) data)))
|
||||||
|
@ -90,19 +90,19 @@
|
||||||
(("unknown error") (raise (make-condition &unknown-error (alist-ref data 'stacktrace) data)))
|
(("unknown error") (raise (make-condition &unknown-error (alist-ref data 'stacktrace) data)))
|
||||||
(("unknown method") (raise (make-condition &unknown-method (alist-ref data 'stacktrace) data)))
|
(("unknown method") (raise (make-condition &unknown-method (alist-ref data 'stacktrace) data)))
|
||||||
(("unsupported operation") (raise (make-condition &unsupported-operation (alist-ref data 'stacktrace) data)))
|
(("unsupported operation") (raise (make-condition &unsupported-operation (alist-ref data 'stacktrace) data)))
|
||||||
(else (raise (make-condition &wd-exception (alist-ref data 'stacktrace) data)))
|
(else (raise (make-condition &raft-exception (alist-ref data 'stacktrace) data)))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
;; conditions ends here
|
;; conditions ends here
|
||||||
|
|
||||||
;; WebDriver
|
;; WebDriver
|
||||||
|
|
||||||
;; The core element of the library is the ~<WebDriver>~ class and its subclasses. The class has the following fields:
|
;; The core element of the library is the ~<Raft>~ class and its subclasses. The class has the following fields:
|
||||||
|
|
||||||
;; #+name: webdriver-class
|
;; #+name: webdriver-class
|
||||||
|
|
||||||
;; [[file:webdriver.org::webdriver-class][webdriver-class]]
|
;; [[file:raft.org::webdriver-class][webdriver-class]]
|
||||||
(define-class <WebDriver> ()
|
(define-class <Raft> ()
|
||||||
((browser #f)
|
((browser #f)
|
||||||
(active? #f)
|
(active? #f)
|
||||||
(browser-pid #f)
|
(browser-pid #f)
|
||||||
|
@ -119,33 +119,33 @@
|
||||||
|
|
||||||
;; #+name: webdriver-basics
|
;; #+name: webdriver-basics
|
||||||
|
|
||||||
;; [[file:webdriver.org::webdriver-basics][webdriver-basics]]
|
;; [[file:raft.org::webdriver-basics][webdriver-basics]]
|
||||||
(define-method (launch #:after (instance <WebDriver>) options)
|
(define-method (launch #:after (instance <Raft>) options)
|
||||||
(set-finalizer! instance (lambda (obj)
|
(set-finalizer! instance (lambda (obj)
|
||||||
(when (slot-value instance 'active?)
|
(when (slot-value instance 'active?)
|
||||||
(terminate instance)))))
|
(terminate instance)))))
|
||||||
|
|
||||||
(define-method (terminate (instance <WebDriver>))
|
(define-method (terminate (instance <Raft>))
|
||||||
(terminate-session instance)
|
(terminate-session instance)
|
||||||
(process-signal (slot-value instance 'browser-pid))
|
(process-signal (slot-value instance 'browser-pid))
|
||||||
(set! (slot-value instance 'browser-pid) #f)
|
(set! (slot-value instance 'browser-pid) #f)
|
||||||
(set! (slot-value instance 'active?) #f))
|
(set! (slot-value instance 'active?) #f))
|
||||||
|
|
||||||
(define-method (construct-capabilities (instance <WebDriver>) #!optional caps)
|
(define-method (construct-capabilities (instance <Raft>) #!optional caps)
|
||||||
(raise 'subclass-responsibility))
|
(raise 'subclass-responsibility))
|
||||||
|
|
||||||
(define-method (postprocess-result (instance <WebDriver>) result)
|
(define-method (postprocess-result (instance <Raft>) result)
|
||||||
result)
|
result)
|
||||||
;; webdriver-basics ends here
|
;; webdriver-basics ends here
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;; Main initialization is done by calling the ~make-WebDriver~ procedure with the respective class name and optionally an alist of options.
|
;; Main initialization is done by calling the ~make-Raft~ procedure with the respective class name and optionally an alist of options.
|
||||||
|
|
||||||
;; #+name: webdriver-init
|
;; #+name: webdriver-init
|
||||||
|
|
||||||
;; [[file:webdriver.org::webdriver-init][webdriver-init]]
|
;; [[file:raft.org::webdriver-init][webdriver-init]]
|
||||||
(define (make-WebDriver browser #!optional options)
|
(define (make-Raft browser #!optional options)
|
||||||
(let ((instance (make browser)))
|
(let ((instance (make browser)))
|
||||||
(launch instance options)
|
(launch instance options)
|
||||||
(sleep 1)
|
(sleep 1)
|
||||||
|
@ -158,8 +158,8 @@
|
||||||
|
|
||||||
;; #+name: geckodriver-basic
|
;; #+name: geckodriver-basic
|
||||||
|
|
||||||
;; [[file:webdriver.org::geckodriver-basic][geckodriver-basic]]
|
;; [[file:raft.org::geckodriver-basic][geckodriver-basic]]
|
||||||
(define-class <Gecko> (<WebDriver>)
|
(define-class <Gecko> (<Raft>)
|
||||||
((browser #:firefox)
|
((browser #:firefox)
|
||||||
(server "127.0.0.1")
|
(server "127.0.0.1")
|
||||||
(port 4444)))
|
(port 4444)))
|
||||||
|
@ -178,7 +178,7 @@
|
||||||
|
|
||||||
;; #+name: geckodriver-capabilities
|
;; #+name: geckodriver-capabilities
|
||||||
|
|
||||||
;; [[file:webdriver.org::geckodriver-capabilities][geckodriver-capabilities]]
|
;; [[file:raft.org::geckodriver-capabilities][geckodriver-capabilities]]
|
||||||
(define-method (construct-capabilities (instance <Gecko>))
|
(define-method (construct-capabilities (instance <Gecko>))
|
||||||
(let ((caps (or (slot-value instance 'capabilities) (list))))
|
(let ((caps (or (slot-value instance 'capabilities) (list))))
|
||||||
`((capabilities . ,caps))))
|
`((capabilities . ,caps))))
|
||||||
|
@ -190,7 +190,7 @@
|
||||||
|
|
||||||
;; #+name: geckodriver-postprocess
|
;; #+name: geckodriver-postprocess
|
||||||
|
|
||||||
;; [[file:webdriver.org::geckodriver-postprocess][geckodriver-postprocess]]
|
;; [[file:raft.org::geckodriver-postprocess][geckodriver-postprocess]]
|
||||||
(define-method (postprocess-result (instance <Gecko>) result)
|
(define-method (postprocess-result (instance <Gecko>) result)
|
||||||
(alist-ref/default result 'value result))
|
(alist-ref/default result 'value result))
|
||||||
;; geckodriver-postprocess ends here
|
;; geckodriver-postprocess ends here
|
||||||
|
@ -199,10 +199,10 @@
|
||||||
|
|
||||||
;; Data is sent to the API via a central class method. For convenience, there is a ~send-with-session~ variant that automatically adds the session id.
|
;; Data is sent to the API via a central class method. For convenience, there is a ~send-with-session~ variant that automatically adds the session id.
|
||||||
|
|
||||||
;; #+name: wd-send
|
;; #+name: raft-send
|
||||||
|
|
||||||
;; [[file:webdriver.org::wd-send][wd-send]]
|
;; [[file:raft.org::raft-send][raft-send]]
|
||||||
(define-method (send (instance <WebDriver>) data uri method)
|
(define-method (send (instance <Raft>) data uri method)
|
||||||
(let* ((remote (string-append "http://" (slot-value instance 'server) ":" (->string (slot-value instance 'port)) "/"))
|
(let* ((remote (string-append "http://" (slot-value instance 'server) ":" (->string (slot-value instance 'port)) "/"))
|
||||||
(result (postprocess-result instance
|
(result (postprocess-result instance
|
||||||
(with-input-from-request
|
(with-input-from-request
|
||||||
|
@ -212,51 +212,51 @@
|
||||||
(if data (json->string data) "")
|
(if data (json->string data) "")
|
||||||
read-json))))
|
read-json))))
|
||||||
(if (and (list? result) (alist-ref/default result 'error #f))
|
(if (and (list? result) (alist-ref/default result 'error #f))
|
||||||
(wd-throw result)
|
(raft-throw result)
|
||||||
result)))
|
result)))
|
||||||
|
|
||||||
(define-method (send-with-session (instance <WebDriver>) data uri method)
|
(define-method (send-with-session (instance <Raft>) data uri method)
|
||||||
(send instance data (string-append "session/" (slot-value instance 'session-id) "/" uri) method))
|
(send instance data (string-append "session/" (slot-value instance 'session-id) "/" uri) method))
|
||||||
;; wd-send ends here
|
;; raft-send ends here
|
||||||
|
|
||||||
;; Session management
|
;; Session management
|
||||||
|
|
||||||
;; Session management is very simple. There is just one method to initialize a new session. Everything else is handled automatically.
|
;; Session management is very simple. There is just one method to initialize a new session. Everything else is handled automatically.
|
||||||
|
|
||||||
;; #+name: wd-init-session
|
;; #+name: raft-init-session
|
||||||
|
|
||||||
;; [[file:webdriver.org::wd-init-session][wd-init-session]]
|
;; [[file:raft.org::raft-init-session][raft-init-session]]
|
||||||
(define-method (initialize-session (instance <WebDriver>))
|
(define-method (initialize-session (instance <Raft>))
|
||||||
(let ((result (send instance (construct-capabilities instance) "session" 'POST)))
|
(let ((result (send instance (construct-capabilities instance) "session" 'POST)))
|
||||||
(set! (slot-value instance 'session-id) (alist-ref result 'sessionId))))
|
(set! (slot-value instance 'session-id) (alist-ref result 'sessionId))))
|
||||||
;; wd-init-session ends here
|
;; raft-init-session ends here
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;; #+name: wd-term-session
|
;; #+name: raft-term-session
|
||||||
|
|
||||||
;; [[file:webdriver.org::wd-term-session][wd-term-session]]
|
;; [[file:raft.org::raft-term-session][raft-term-session]]
|
||||||
(define-method (terminate-session (instance <WebDriver>))
|
(define-method (terminate-session (instance <Raft>))
|
||||||
(when (slot-value instance 'session-id)
|
(when (slot-value instance 'session-id)
|
||||||
(send instance #f (string-append "session/" (slot-value instance 'session-id)) 'DELETE))
|
(send instance #f (string-append "session/" (slot-value instance 'session-id)) 'DELETE))
|
||||||
(set! (slot-value instance 'session-id) #f))
|
(set! (slot-value instance 'session-id) #f))
|
||||||
;; wd-term-session ends here
|
;; raft-term-session ends here
|
||||||
|
|
||||||
;; API Access Methods
|
;; API Access Methods
|
||||||
|
|
||||||
;; #+name: wd-url
|
;; #+name: raft-url
|
||||||
|
|
||||||
;; [[file:webdriver.org::wd-url][wd-url]]
|
;; [[file:raft.org::raft-url][raft-url]]
|
||||||
(define-method (set-url (instance <WebDriver>) url)
|
(define-method (set-url (instance <Raft>) url)
|
||||||
(send-with-session instance `((url . ,url)) "url" 'POST))
|
(send-with-session instance `((url . ,url)) "url" 'POST))
|
||||||
|
|
||||||
(define-method (url (instance <WebDriver>))
|
(define-method (url (instance <Raft>))
|
||||||
(send-with-session instance #f "url" 'GET))
|
(send-with-session instance #f "url" 'GET))
|
||||||
;; wd-url ends here
|
;; raft-url ends here
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;; #+RESULTS: wd-url-test
|
;; #+RESULTS: raft-url-test
|
||||||
;; : -- testing url ---------------------------------------------------------------
|
;; : -- testing url ---------------------------------------------------------------
|
||||||
;; : Initial state ........................................................ [ PASS]
|
;; : Initial state ........................................................ [ PASS]
|
||||||
;; : Navigating to the first website ...................................... [ PASS]
|
;; : Navigating to the first website ...................................... [ PASS]
|
||||||
|
@ -265,53 +265,53 @@
|
||||||
;; : -- done testing url ----------------------------------------------------------
|
;; : -- done testing url ----------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
;; [[file:webdriver.org::*API Access Methods][API Access Methods:3]]
|
;; [[file:raft.org::*API Access Methods][API Access Methods:3]]
|
||||||
(define-method (back (instance <WebDriver>))
|
(define-method (back (instance <Raft>))
|
||||||
(send-with-session instance #f "back" 'POST))
|
(send-with-session instance #f "back" 'POST))
|
||||||
;; API Access Methods:3 ends here
|
;; API Access Methods:3 ends here
|
||||||
|
|
||||||
;; [[file:webdriver.org::*API Access Methods][API Access Methods:4]]
|
;; [[file:raft.org::*API Access Methods][API Access Methods:4]]
|
||||||
(define-method (forward (instance <WebDriver>))
|
(define-method (forward (instance <Raft>))
|
||||||
(send-with-session instance #f "forward" 'POST))
|
(send-with-session instance #f "forward" 'POST))
|
||||||
;; API Access Methods:4 ends here
|
;; API Access Methods:4 ends here
|
||||||
|
|
||||||
;; [[file:webdriver.org::*API Access Methods][API Access Methods:5]]
|
;; [[file:raft.org::*API Access Methods][API Access Methods:5]]
|
||||||
(define-method (refresh (instance <WebDriver>))
|
(define-method (refresh (instance <Raft>))
|
||||||
(send-with-session instance #f "refresh" 'POST))
|
(send-with-session instance #f "refresh" 'POST))
|
||||||
;; API Access Methods:5 ends here
|
;; API Access Methods:5 ends here
|
||||||
|
|
||||||
;; [[file:webdriver.org::*API Access Methods][API Access Methods:6]]
|
;; [[file:raft.org::*API Access Methods][API Access Methods:6]]
|
||||||
(define-method (title (instance <WebDriver>))
|
(define-method (title (instance <Raft>))
|
||||||
(send-with-session instance #f "title" 'GET))
|
(send-with-session instance #f "title" 'GET))
|
||||||
;; API Access Methods:6 ends here
|
;; API Access Methods:6 ends here
|
||||||
|
|
||||||
;; [[file:webdriver.org::*API Access Methods][API Access Methods:7]]
|
;; [[file:raft.org::*API Access Methods][API Access Methods:7]]
|
||||||
(define-method (status (instance <WebDriver>))
|
(define-method (status (instance <Raft>))
|
||||||
(send-with-session instance #f "status" 'GET))
|
(send-with-session instance #f "status" 'GET))
|
||||||
;; API Access Methods:7 ends here
|
;; API Access Methods:7 ends here
|
||||||
|
|
||||||
;; [[file:webdriver.org::*API Access Methods][API Access Methods:8]]
|
;; [[file:raft.org::*API Access Methods][API Access Methods:8]]
|
||||||
(define-method (source (instance <WebDriver>))
|
(define-method (source (instance <Raft>))
|
||||||
(send-with-session instance #f "source" 'GET))
|
(send-with-session instance #f "source" 'GET))
|
||||||
;; API Access Methods:8 ends here
|
;; API Access Methods:8 ends here
|
||||||
|
|
||||||
;; [[file:webdriver.org::*API Access Methods][API Access Methods:9]]
|
;; [[file:raft.org::*API Access Methods][API Access Methods:9]]
|
||||||
(define-method (screenshot (instance <WebDriver>))
|
(define-method (screenshot (instance <Raft>))
|
||||||
(base64-decode (send-with-session instance #f "screenshot" 'GET)))
|
(base64-decode (send-with-session instance #f "screenshot" 'GET)))
|
||||||
;; API Access Methods:9 ends here
|
;; API Access Methods:9 ends here
|
||||||
|
|
||||||
;; [[file:webdriver.org::*API Access Methods][API Access Methods:10]]
|
;; [[file:raft.org::*API Access Methods][API Access Methods:10]]
|
||||||
(define-method (print-page (instance <WebDriver>))
|
(define-method (print-page (instance <Raft>))
|
||||||
(send-with-session instance #f "print" 'POST))
|
(send-with-session instance #f "print" 'POST))
|
||||||
;; API Access Methods:10 ends here
|
;; API Access Methods:10 ends here
|
||||||
|
|
||||||
;; [[file:webdriver.org::*API Access Methods][API Access Methods:11]]
|
;; [[file:raft.org::*API Access Methods][API Access Methods:11]]
|
||||||
(define-method (execute-async (instance <WebDriver>) script args)
|
(define-method (execute-async (instance <Raft>) script args)
|
||||||
(send-with-session instance `((script . ,script) (args . ,args)) "execute/async" 'POST))
|
(send-with-session instance `((script . ,script) (args . ,args)) "execute/async" 'POST))
|
||||||
;; API Access Methods:11 ends here
|
;; API Access Methods:11 ends here
|
||||||
|
|
||||||
;; [[file:webdriver.org::*API Access Methods][API Access Methods:12]]
|
;; [[file:raft.org::*API Access Methods][API Access Methods:12]]
|
||||||
(define-method (execute-sync (instance <WebDriver>) script args)
|
(define-method (execute-sync (instance <Raft>) script args)
|
||||||
(send-with-session instance `((script . ,script) (args . ,args)) "execute/sync" 'POST))
|
(send-with-session instance `((script . ,script) (args . ,args)) "execute/sync" 'POST))
|
||||||
;; API Access Methods:12 ends here
|
;; API Access Methods:12 ends here
|
||||||
|
|
||||||
|
@ -324,15 +324,15 @@
|
||||||
;; - =implicit=: defaults to 0, specifies a time to wait for the element location strategy to complete when locating an element.
|
;; - =implicit=: defaults to 0, specifies a time to wait for the element location strategy to complete when locating an element.
|
||||||
|
|
||||||
|
|
||||||
;; [[file:webdriver.org::*Timeouts][Timeouts:1]]
|
;; [[file:raft.org::*Timeouts][Timeouts:1]]
|
||||||
(define-class <WDTimeouts> ()
|
(define-class <RaftTimeouts> ()
|
||||||
((script 30000)
|
((script 30000)
|
||||||
(pageLoad 300000)
|
(pageLoad 300000)
|
||||||
(implicit 0)))
|
(implicit 0)))
|
||||||
;; Timeouts:1 ends here
|
;; Timeouts:1 ends here
|
||||||
|
|
||||||
;; [[file:webdriver.org::*Timeouts][Timeouts:2]]
|
;; [[file:raft.org::*Timeouts][Timeouts:2]]
|
||||||
(define-method (extract (instance <WDTimeouts>))
|
(define-method (extract (instance <RaftTimeouts>))
|
||||||
`((script . ,(slot-value instance 'script))
|
`((script . ,(slot-value instance 'script))
|
||||||
(pageLoad . ,(slot-value instance 'pageLoad))
|
(pageLoad . ,(slot-value instance 'pageLoad))
|
||||||
(implicit . ,(slot-value instance 'implicit))))
|
(implicit . ,(slot-value instance 'implicit))))
|
||||||
|
@ -341,13 +341,13 @@
|
||||||
;; Setting and getting timeouts
|
;; Setting and getting timeouts
|
||||||
|
|
||||||
|
|
||||||
;; [[file:webdriver.org::*Setting and getting timeouts][Setting and getting timeouts:1]]
|
;; [[file:raft.org::*Setting and getting timeouts][Setting and getting timeouts:1]]
|
||||||
(define-method (set-timeouts (instance <WebDriver>) (timeouts <WDTimeouts>))
|
(define-method (set-timeouts (instance <Raft>) (timeouts <RaftTimeouts>))
|
||||||
(send-with-session instance (extract timeouts) "timeouts" 'POST))
|
(send-with-session instance (extract timeouts) "timeouts" 'POST))
|
||||||
|
|
||||||
(define-method (timeouts (instance <WebDriver>))
|
(define-method (timeouts (instance <Raft>))
|
||||||
(let ((result (send-with-session instance #f "timeouts" 'GET)))
|
(let ((result (send-with-session instance #f "timeouts" 'GET)))
|
||||||
(make <WDTimeouts>
|
(make <RaftTimeouts>
|
||||||
'script (alist-ref result 'script)
|
'script (alist-ref result 'script)
|
||||||
'pageLoad (alist-ref result 'pageLoad)
|
'pageLoad (alist-ref result 'pageLoad)
|
||||||
'implicit (alist-ref result 'implicit))))
|
'implicit (alist-ref result 'implicit))))
|
||||||
|
@ -356,14 +356,14 @@
|
||||||
;; Element Class
|
;; Element Class
|
||||||
|
|
||||||
|
|
||||||
;; [[file:webdriver.org::*Element Class][Element Class:1]]
|
;; [[file:raft.org::*Element Class][Element Class:1]]
|
||||||
(define-class <WDElement> ()
|
(define-class <RaftElement> ()
|
||||||
((driver #f)
|
((driver #f)
|
||||||
(element #f)))
|
(element #f)))
|
||||||
;; Element Class:1 ends here
|
;; Element Class:1 ends here
|
||||||
|
|
||||||
;; [[file:webdriver.org::*Element Class][Element Class:2]]
|
;; [[file:raft.org::*Element Class][Element Class:2]]
|
||||||
(define-method (send-with-session (instance <WDElement>) data uri method)
|
(define-method (send-with-session (instance <RaftElement>) data uri method)
|
||||||
(send-with-session (slot-value instance 'driver) data
|
(send-with-session (slot-value instance 'driver) data
|
||||||
(string-append "element/" (slot-value instance 'element) "/" uri)
|
(string-append "element/" (slot-value instance 'element) "/" uri)
|
||||||
method))
|
method))
|
||||||
|
@ -372,7 +372,7 @@
|
||||||
;; Location Strategies
|
;; Location Strategies
|
||||||
|
|
||||||
|
|
||||||
;; [[file:webdriver.org::*Location Strategies][Location Strategies:1]]
|
;; [[file:raft.org::*Location Strategies][Location Strategies:1]]
|
||||||
(define css-selector "css selector")
|
(define css-selector "css selector")
|
||||||
(define link-text "link text")
|
(define link-text "link text")
|
||||||
(define partial-link-text "partial link text")
|
(define partial-link-text "partial link text")
|
||||||
|
@ -383,41 +383,41 @@
|
||||||
;; Accessor Methods
|
;; Accessor Methods
|
||||||
|
|
||||||
|
|
||||||
;; [[file:webdriver.org::*Accessor Methods][Accessor Methods:1]]
|
;; [[file:raft.org::*Accessor Methods][Accessor Methods:1]]
|
||||||
(define-method (find-element (instance <WebDriver>) strategy selector)
|
(define-method (find-element (instance <Raft>) strategy selector)
|
||||||
(let ((result (send-with-session instance `((using . ,strategy) (value . ,selector)) "element" 'POST)))
|
(let ((result (send-with-session instance `((using . ,strategy) (value . ,selector)) "element" 'POST)))
|
||||||
(make <WDElement> 'driver instance 'element (car (alist-values result)))))
|
(make <RaftElement> 'driver instance 'element (car (alist-values result)))))
|
||||||
;; Accessor Methods:1 ends here
|
;; Accessor Methods:1 ends here
|
||||||
|
|
||||||
;; [[file:webdriver.org::*Accessor Methods][Accessor Methods:2]]
|
;; [[file:raft.org::*Accessor Methods][Accessor Methods:2]]
|
||||||
(define-method (find-elements (instance <WebDriver>) strategy selector)
|
(define-method (find-elements (instance <Raft>) strategy selector)
|
||||||
(let ((result (send-with-session instance `((using . ,strategy) (value . ,selector)) "elements" 'POST)))
|
(let ((result (send-with-session instance `((using . ,strategy) (value . ,selector)) "elements" 'POST)))
|
||||||
(map
|
(map
|
||||||
(lambda (elem)
|
(lambda (elem)
|
||||||
(make <WDElement> 'driver instance 'element (car (alist-values elem))))
|
(make <RaftElement> 'driver instance 'element (car (alist-values elem))))
|
||||||
result)))
|
result)))
|
||||||
;; Accessor Methods:2 ends here
|
;; Accessor Methods:2 ends here
|
||||||
|
|
||||||
;; [[file:webdriver.org::*Accessor Methods][Accessor Methods:3]]
|
;; [[file:raft.org::*Accessor Methods][Accessor Methods:3]]
|
||||||
(define-method (find-element (instance <WDElement>) strategy selector)
|
(define-method (find-element (instance <RaftElement>) strategy selector)
|
||||||
(let ((result (send-with-session instance `((using . ,strategy) (value . ,selector)) "element" 'POST)))
|
(let ((result (send-with-session instance `((using . ,strategy) (value . ,selector)) "element" 'POST)))
|
||||||
(make <WDElement> 'driver (slot-value instance 'driver) 'element (car (alist-values result)))))
|
(make <RaftElement> 'driver (slot-value instance 'driver) 'element (car (alist-values result)))))
|
||||||
;; Accessor Methods:3 ends here
|
;; Accessor Methods:3 ends here
|
||||||
|
|
||||||
;; [[file:webdriver.org::*Accessor Methods][Accessor Methods:4]]
|
;; [[file:raft.org::*Accessor Methods][Accessor Methods:4]]
|
||||||
(define-method (find-elements (instance <WDElement>) strategy selector)
|
(define-method (find-elements (instance <RaftElement>) strategy selector)
|
||||||
(let ((result (send-with-session instance `((using . ,strategy) (value . ,selector)) "elements" 'POST)))
|
(let ((result (send-with-session instance `((using . ,strategy) (value . ,selector)) "elements" 'POST)))
|
||||||
(map
|
(map
|
||||||
(lambda (elem)
|
(lambda (elem)
|
||||||
(make <WDElement> 'driver (slot-value instance 'driver) 'element (car (alist-values elem))))
|
(make <RaftElement> 'driver (slot-value instance 'driver) 'element (car (alist-values elem))))
|
||||||
result)))
|
result)))
|
||||||
;; Accessor Methods:4 ends here
|
;; Accessor Methods:4 ends here
|
||||||
|
|
||||||
;; Working with Elements
|
;; Working with Elements
|
||||||
|
|
||||||
|
|
||||||
;; [[file:webdriver.org::*Working with Elements][Working with Elements:1]]
|
;; [[file:raft.org::*Working with Elements][Working with Elements:1]]
|
||||||
(define-method (attribute (instance <WDElement>) attribute)
|
(define-method (attribute (instance <RaftElement>) attribute)
|
||||||
(let ((result (send-with-session instance #f
|
(let ((result (send-with-session instance #f
|
||||||
(string-append "attribute/" attribute)
|
(string-append "attribute/" attribute)
|
||||||
'GET)))
|
'GET)))
|
||||||
|
@ -426,62 +426,62 @@
|
||||||
result)))
|
result)))
|
||||||
;; Working with Elements:1 ends here
|
;; Working with Elements:1 ends here
|
||||||
|
|
||||||
;; [[file:webdriver.org::*Working with Elements][Working with Elements:2]]
|
;; [[file:raft.org::*Working with Elements][Working with Elements:2]]
|
||||||
(define-method (property (instance <WDElement>) property)
|
(define-method (property (instance <RaftElement>) property)
|
||||||
(send-with-session instance #f (string-append "property/" property) 'GET))
|
(send-with-session instance #f (string-append "property/" property) 'GET))
|
||||||
;; Working with Elements:2 ends here
|
;; Working with Elements:2 ends here
|
||||||
|
|
||||||
;; [[file:webdriver.org::*Working with Elements][Working with Elements:3]]
|
;; [[file:raft.org::*Working with Elements][Working with Elements:3]]
|
||||||
(define-method (clear (instance <WDElement>))
|
(define-method (clear (instance <RaftElement>))
|
||||||
(send-with-session instance #f "clear" 'POST))
|
(send-with-session instance #f "clear" 'POST))
|
||||||
;; Working with Elements:3 ends here
|
;; Working with Elements:3 ends here
|
||||||
|
|
||||||
;; [[file:webdriver.org::*Working with Elements][Working with Elements:4]]
|
;; [[file:raft.org::*Working with Elements][Working with Elements:4]]
|
||||||
(define-method (click (instance <WDElement>))
|
(define-method (click (instance <RaftElement>))
|
||||||
(send-with-session instance #f "click" 'POST))
|
(send-with-session instance #f "click" 'POST))
|
||||||
;; Working with Elements:4 ends here
|
;; Working with Elements:4 ends here
|
||||||
|
|
||||||
;; [[file:webdriver.org::*Working with Elements][Working with Elements:5]]
|
;; [[file:raft.org::*Working with Elements][Working with Elements:5]]
|
||||||
(define-method (computed-label (instance <WDElement>))
|
(define-method (computed-label (instance <RaftElement>))
|
||||||
(send-with-session instance #f "computedlabel" 'GET))
|
(send-with-session instance #f "computedlabel" 'GET))
|
||||||
;; Working with Elements:5 ends here
|
;; Working with Elements:5 ends here
|
||||||
|
|
||||||
;; [[file:webdriver.org::*Working with Elements][Working with Elements:6]]
|
;; [[file:raft.org::*Working with Elements][Working with Elements:6]]
|
||||||
(define-method (computed-role (instance <WDElement>))
|
(define-method (computed-role (instance <RaftElement>))
|
||||||
(send-with-session instance #f "computedrole" 'GET))
|
(send-with-session instance #f "computedrole" 'GET))
|
||||||
;; Working with Elements:6 ends here
|
;; Working with Elements:6 ends here
|
||||||
|
|
||||||
;; [[file:webdriver.org::*Working with Elements][Working with Elements:7]]
|
;; [[file:raft.org::*Working with Elements][Working with Elements:7]]
|
||||||
(define-method (enabled? (instance <WDElement>))
|
(define-method (enabled? (instance <RaftElement>))
|
||||||
(send-with-session instance #f "enabled" 'GET))
|
(send-with-session instance #f "enabled" 'GET))
|
||||||
;; Working with Elements:7 ends here
|
;; Working with Elements:7 ends here
|
||||||
|
|
||||||
;; [[file:webdriver.org::*Working with Elements][Working with Elements:8]]
|
;; [[file:raft.org::*Working with Elements][Working with Elements:8]]
|
||||||
(define-method (selected? (instance <WDElement>))
|
(define-method (selected? (instance <RaftElement>))
|
||||||
(send-with-session instance #f "selected" 'GET))
|
(send-with-session instance #f "selected" 'GET))
|
||||||
;; Working with Elements:8 ends here
|
;; Working with Elements:8 ends here
|
||||||
|
|
||||||
;; [[file:webdriver.org::*Working with Elements][Working with Elements:9]]
|
;; [[file:raft.org::*Working with Elements][Working with Elements:9]]
|
||||||
(define-method (name (instance <WDElement>))
|
(define-method (name (instance <RaftElement>))
|
||||||
(send-with-session instance #f "name" 'GET))
|
(send-with-session instance #f "name" 'GET))
|
||||||
;; Working with Elements:9 ends here
|
;; Working with Elements:9 ends here
|
||||||
|
|
||||||
;; [[file:webdriver.org::*Working with Elements][Working with Elements:10]]
|
;; [[file:raft.org::*Working with Elements][Working with Elements:10]]
|
||||||
(define-method (rect (instance <WDElement>))
|
(define-method (rect (instance <RaftElement>))
|
||||||
(send-with-session instance #f "rect" 'GET))
|
(send-with-session instance #f "rect" 'GET))
|
||||||
;; Working with Elements:10 ends here
|
;; Working with Elements:10 ends here
|
||||||
|
|
||||||
;; [[file:webdriver.org::*Working with Elements][Working with Elements:11]]
|
;; [[file:raft.org::*Working with Elements][Working with Elements:11]]
|
||||||
(define-method (screenshot (instance <WDElement>))
|
(define-method (screenshot (instance <RaftElement>))
|
||||||
(base64-decode (send-with-session instance #f "screenshot" 'GET)))
|
(base64-decode (send-with-session instance #f "screenshot" 'GET)))
|
||||||
;; Working with Elements:11 ends here
|
;; Working with Elements:11 ends here
|
||||||
|
|
||||||
;; [[file:webdriver.org::*Working with Elements][Working with Elements:12]]
|
;; [[file:raft.org::*Working with Elements][Working with Elements:12]]
|
||||||
(define-method (text (instance <WDElement>))
|
(define-method (text (instance <RaftElement>))
|
||||||
(send-with-session instance #f "text" 'GET))
|
(send-with-session instance #f "text" 'GET))
|
||||||
;; Working with Elements:12 ends here
|
;; Working with Elements:12 ends here
|
||||||
|
|
||||||
;; [[file:webdriver.org::*Working with Elements][Working with Elements:13]]
|
;; [[file:raft.org::*Working with Elements][Working with Elements:13]]
|
||||||
(define-method (set-value (instance <WDElement>) value)
|
(define-method (set-value (instance <RaftElement>) value)
|
||||||
(send-with-session instance `((text . ,value)) "value" 'POST))
|
(send-with-session instance `((text . ,value)) "value" 'POST))
|
||||||
;; Working with Elements:13 ends here
|
;; Working with Elements:13 ends here
|
|
@ -1,14 +1,14 @@
|
||||||
;; About This Egg
|
;; About This Egg
|
||||||
|
|
||||||
|
|
||||||
;; [[file:webdriver.org::*About This Egg][About This Egg:1]]
|
;; [[file:raft.org::*About This Egg][About This Egg:1]]
|
||||||
;; -*- scheme -*-
|
;; -*- scheme -*-
|
||||||
((author "Daniel Ziltener")
|
((author "Daniel Ziltener")
|
||||||
(synopsis "A WebDriver API implementation for Chicken")
|
(synopsis "A WebDriver API implementation for Chicken")
|
||||||
(category web)
|
(category web)
|
||||||
(license "BSD")
|
(license "BSD")
|
||||||
(version "0.5")
|
(version "0.5")
|
||||||
(dependencies r7rs srfi-34 srfi-35 base64 http-client intarweb uri-common coops alist-lib medea)
|
(dependencies r7rs alist-lib base64 coops http-client intarweb medea srfi-34 srfi-35 uri-common)
|
||||||
(test-dependencies test)
|
(test-dependencies test)
|
||||||
|
|
||||||
(components
|
(components
|
|
@ -1,8 +1,7 @@
|
||||||
#+title: Webdriver implementation in Chicken Scheme
|
#+title: Raft - Webdriver implementation in Chicken Scheme
|
||||||
#+author: Daniel Ziltener
|
#+author: Daniel Ziltener
|
||||||
#+property: header-args:scheme :session *chicken* :comments both
|
#+property: header-args:scheme :session *chicken* :comments both
|
||||||
|
|
||||||
|
|
||||||
* Helpers :noexport:
|
* Helpers :noexport:
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
:header-args:scheme: :prologue "(import (chicken string))"
|
:header-args:scheme: :prologue "(import (chicken string))"
|
||||||
|
@ -35,15 +34,15 @@
|
||||||
#+name: dependencies
|
#+name: dependencies
|
||||||
| Dependency | Description |
|
| Dependency | Description |
|
||||||
|-------------+-----------------------------------|
|
|-------------+-----------------------------------|
|
||||||
| srfi-34 | Exception Handling |
|
| alist-lib | Handling alists from JSON objects |
|
||||||
| srfi-35 | Exception Types |
|
|
||||||
| base64 | decoding screenshot data |
|
| base64 | decoding screenshot data |
|
||||||
|
| coops | Object system |
|
||||||
| http-client | API interaction |
|
| http-client | API interaction |
|
||||||
| intarweb | Supporting HTTP functionality |
|
| intarweb | Supporting HTTP functionality |
|
||||||
| uri-common | Supporting HTTP functionality |
|
|
||||||
| coops | Object system |
|
|
||||||
| alist-lib | Handling alists from JSON objects |
|
|
||||||
| medea | JSON handling |
|
| medea | JSON handling |
|
||||||
|
| srfi-34 | Exception Handling |
|
||||||
|
| srfi-35 | Exception Types |
|
||||||
|
| uri-common | Supporting HTTP functionality |
|
||||||
|
|
||||||
#+name: dependencies-for-egg
|
#+name: dependencies-for-egg
|
||||||
#+begin_src emacs-lisp :var tbl=dependencies :colnames yes :results raw :exports none
|
#+begin_src emacs-lisp :var tbl=dependencies :colnames yes :results raw :exports none
|
||||||
|
@ -56,13 +55,13 @@
|
||||||
tbl "\n")
|
tbl "\n")
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+begin_src scheme :noweb yes :tangle webdriver.scm :exports none
|
#+begin_src scheme :noweb yes :tangle raft.scm :exports none
|
||||||
(import r7rs)
|
(import r7rs)
|
||||||
(define-library (webdriver)
|
(define-library (raft)
|
||||||
(import (scheme base))
|
(import (scheme base))
|
||||||
(export <WebDriver>
|
(export <Raft>
|
||||||
<Gecko>
|
<Gecko>
|
||||||
make-WebDriver
|
make-Raft
|
||||||
terminate
|
terminate
|
||||||
initialize-session
|
initialize-session
|
||||||
terminate-session
|
terminate-session
|
||||||
|
@ -78,10 +77,10 @@
|
||||||
print-page
|
print-page
|
||||||
execute-async
|
execute-async
|
||||||
execute-sync
|
execute-sync
|
||||||
<WDTimeouts>
|
<RaftTimeouts>
|
||||||
set-timeouts
|
set-timeouts
|
||||||
timeouts
|
timeouts
|
||||||
<WDElement>
|
<RaftElement>
|
||||||
css-selector
|
css-selector
|
||||||
link-text
|
link-text
|
||||||
partial-link-text
|
partial-link-text
|
||||||
|
@ -102,16 +101,16 @@
|
||||||
screenshot
|
screenshot
|
||||||
text
|
text
|
||||||
set-value
|
set-value
|
||||||
&wd-exception
|
&raft-exception
|
||||||
wd-exception?
|
raft-exception?
|
||||||
wd-stacktrace
|
raft-stacktrace
|
||||||
wd-data
|
raft-data
|
||||||
<<export-conditions()>>
|
<<export-conditions()>>
|
||||||
)
|
)
|
||||||
(include "webdriver-impl.scm"))
|
(include "raft-impl.scm"))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+begin_src scheme :noweb yes :tangle webdriver-impl.scm :exports none
|
#+begin_src scheme :noweb yes :tangle raft-impl.scm :exports none
|
||||||
(import r7rs
|
(import r7rs
|
||||||
(chicken base)
|
(chicken base)
|
||||||
(chicken string)
|
(chicken string)
|
||||||
|
@ -122,19 +121,19 @@
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+begin_src scheme :tangle tests/run.scm :exports none :mkdirp yes
|
#+begin_src scheme :tangle tests/run.scm :exports none :mkdirp yes
|
||||||
(include-relative "../webdriver-impl.scm")
|
(include-relative "../raft-impl.scm")
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
* Error Conditions
|
* Error Conditions
|
||||||
|
|
||||||
#+name: wd-exception
|
#+name: raft-exception
|
||||||
#+begin_src scheme :tangle webdriver-impl.scm
|
#+begin_src scheme :tangle raft-impl.scm
|
||||||
(define-condition-type &wd-exception &error wd-exception?
|
(define-condition-type &raft-exception &error raft-exception?
|
||||||
(stacktrace wd-stacktrace)
|
(stacktrace raft-stacktrace)
|
||||||
(data wd-data))
|
(data raft-data))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
Every API error code (key "error" in the returned JSON data) gets its own condition type, prefixed by ~&~. They all inherit from ~&wd-exception~.
|
Every API error code (key "error" in the returned JSON data) gets its own condition type, prefixed by ~&~. They all inherit from ~&raft-exception~.
|
||||||
|
|
||||||
#+name: error-code-table
|
#+name: error-code-table
|
||||||
| Name | API Error Code |
|
| Name | API Error Code |
|
||||||
|
@ -183,13 +182,13 @@ Every API error code (key "error" in the returned JSON data) gets its own condit
|
||||||
(lambda (row)
|
(lambda (row)
|
||||||
(let ((replace `((?n . ,(cl-first row))
|
(let ((replace `((?n . ,(cl-first row))
|
||||||
(?c . ,(cl-second row)))))
|
(?c . ,(cl-second row)))))
|
||||||
(format-spec "(define-condition-type &%n &wd-exception %n?)" replace)))
|
(format-spec "(define-condition-type &%n &raft-exception %n?)" replace)))
|
||||||
src "\n")
|
src "\n")
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+name: define-condition-thrower
|
#+name: define-condition-thrower
|
||||||
#+begin_src emacs-lisp :var src=error-code-table :exports none :results raw
|
#+begin_src emacs-lisp :var src=error-code-table :exports none :results raw
|
||||||
(concat "(define (wd-throw data)\n"
|
(concat "(define (raft-throw data)\n"
|
||||||
" (case (alist-ref data 'error)\n"
|
" (case (alist-ref data 'error)\n"
|
||||||
(mapconcat
|
(mapconcat
|
||||||
(lambda (row)
|
(lambda (row)
|
||||||
|
@ -198,13 +197,13 @@ Every API error code (key "error" in the returned JSON data) gets its own condit
|
||||||
(format-spec " ((\"%c\") (raise (make-condition &%n (alist-ref data 'stacktrace) data)))" replace)))
|
(format-spec " ((\"%c\") (raise (make-condition &%n (alist-ref data 'stacktrace) data)))" replace)))
|
||||||
src "\n")
|
src "\n")
|
||||||
"\n"
|
"\n"
|
||||||
" (else (raise (make-condition &wd-exception (alist-ref data 'stacktrace) data)))\n"
|
" (else (raise (make-condition &raft-exception (alist-ref data 'stacktrace) data)))\n"
|
||||||
" )\n"
|
" )\n"
|
||||||
")")
|
")")
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+name: conditions
|
#+name: conditions
|
||||||
#+begin_src scheme :tangle webdriver-impl.scm :noweb yes :exports none
|
#+begin_src scheme :tangle raft-impl.scm :noweb yes :exports none
|
||||||
<<define-conditions()>>
|
<<define-conditions()>>
|
||||||
|
|
||||||
<<define-condition-thrower()>>
|
<<define-condition-thrower()>>
|
||||||
|
@ -212,11 +211,11 @@ Every API error code (key "error" in the returned JSON data) gets its own condit
|
||||||
|
|
||||||
* WebDriver
|
* WebDriver
|
||||||
|
|
||||||
The core element of the library is the ~<WebDriver>~ class and its subclasses. The class has the following fields:
|
The core element of the library is the ~<Raft>~ class and its subclasses. The class has the following fields:
|
||||||
|
|
||||||
#+name: webdriver-class
|
#+name: webdriver-class
|
||||||
#+begin_src scheme :tangle webdriver-impl.scm
|
#+begin_src scheme :tangle raft-impl.scm
|
||||||
(define-class <WebDriver> ()
|
(define-class <Raft> ()
|
||||||
((browser #f)
|
((browser #f)
|
||||||
(active? #f)
|
(active? #f)
|
||||||
(browser-pid #f)
|
(browser-pid #f)
|
||||||
|
@ -230,30 +229,30 @@ The core element of the library is the ~<WebDriver>~ class and its subclasses. T
|
||||||
The parent class provides a handful of methods, but does not implement all of them; some are the sole responsibility of the subclass. The ~launch~ method, on the other hand, bears shared responsibility. It sets a finalizer to ensure termination of the web driver process in case the class is disposed of with a still-open driver.
|
The parent class provides a handful of methods, but does not implement all of them; some are the sole responsibility of the subclass. The ~launch~ method, on the other hand, bears shared responsibility. It sets a finalizer to ensure termination of the web driver process in case the class is disposed of with a still-open driver.
|
||||||
|
|
||||||
#+name: webdriver-basics
|
#+name: webdriver-basics
|
||||||
#+begin_src scheme :tangle webdriver-impl.scm
|
#+begin_src scheme :tangle raft-impl.scm
|
||||||
(define-method (launch #:after (instance <WebDriver>) options)
|
(define-method (launch #:after (instance <Raft>) options)
|
||||||
(set-finalizer! instance (lambda (obj)
|
(set-finalizer! instance (lambda (obj)
|
||||||
(when (slot-value instance 'active?)
|
(when (slot-value instance 'active?)
|
||||||
(terminate instance)))))
|
(terminate instance)))))
|
||||||
|
|
||||||
(define-method (terminate (instance <WebDriver>))
|
(define-method (terminate (instance <Raft>))
|
||||||
(terminate-session instance)
|
(terminate-session instance)
|
||||||
(process-signal (slot-value instance 'browser-pid))
|
(process-signal (slot-value instance 'browser-pid))
|
||||||
(set! (slot-value instance 'browser-pid) #f)
|
(set! (slot-value instance 'browser-pid) #f)
|
||||||
(set! (slot-value instance 'active?) #f))
|
(set! (slot-value instance 'active?) #f))
|
||||||
|
|
||||||
(define-method (construct-capabilities (instance <WebDriver>) #!optional caps)
|
(define-method (construct-capabilities (instance <Raft>) #!optional caps)
|
||||||
(raise 'subclass-responsibility))
|
(raise 'subclass-responsibility))
|
||||||
|
|
||||||
(define-method (postprocess-result (instance <WebDriver>) result)
|
(define-method (postprocess-result (instance <Raft>) result)
|
||||||
result)
|
result)
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
Main initialization is done by calling the ~make-WebDriver~ procedure with the respective class name and optionally an alist of options.
|
Main initialization is done by calling the ~make-Raft~ procedure with the respective class name and optionally an alist of options.
|
||||||
|
|
||||||
#+name: webdriver-init
|
#+name: webdriver-init
|
||||||
#+begin_src scheme :tangle webdriver-impl.scm
|
#+begin_src scheme :tangle raft-impl.scm
|
||||||
(define (make-WebDriver browser #!optional options)
|
(define (make-Raft browser #!optional options)
|
||||||
(let ((instance (make browser)))
|
(let ((instance (make browser)))
|
||||||
(launch instance options)
|
(launch instance options)
|
||||||
(sleep 1)
|
(sleep 1)
|
||||||
|
@ -265,8 +264,8 @@ Main initialization is done by calling the ~make-WebDriver~ procedure with the r
|
||||||
The Geckodriver is used to control Firefox.
|
The Geckodriver is used to control Firefox.
|
||||||
|
|
||||||
#+name: geckodriver-basic
|
#+name: geckodriver-basic
|
||||||
#+begin_src scheme :tangle webdriver-impl.scm
|
#+begin_src scheme :tangle raft-impl.scm
|
||||||
(define-class <Gecko> (<WebDriver>)
|
(define-class <Gecko> (<Raft>)
|
||||||
((browser #:firefox)
|
((browser #:firefox)
|
||||||
(server "127.0.0.1")
|
(server "127.0.0.1")
|
||||||
(port 4444)))
|
(port 4444)))
|
||||||
|
@ -282,7 +281,7 @@ The capabilities object for Geckodriver is of the form ={"capabilities": {...}}=
|
||||||
For more information on capabilities, see https://developer.mozilla.org/en-US/docs/Web/WebDriver/Capabilities.
|
For more information on capabilities, see https://developer.mozilla.org/en-US/docs/Web/WebDriver/Capabilities.
|
||||||
|
|
||||||
#+name: geckodriver-capabilities
|
#+name: geckodriver-capabilities
|
||||||
#+begin_src scheme :tangle webdriver-impl.scm
|
#+begin_src scheme :tangle raft-impl.scm
|
||||||
(define-method (construct-capabilities (instance <Gecko>))
|
(define-method (construct-capabilities (instance <Gecko>))
|
||||||
(let ((caps (or (slot-value instance 'capabilities) (list))))
|
(let ((caps (or (slot-value instance 'capabilities) (list))))
|
||||||
`((capabilities . ,caps))))
|
`((capabilities . ,caps))))
|
||||||
|
@ -291,7 +290,7 @@ For more information on capabilities, see https://developer.mozilla.org/en-US/do
|
||||||
Sometimes, Geckodriver returns the results of a command in a JSON object with the sole key ="value"=. We have to correct that before returning the data to the user.
|
Sometimes, Geckodriver returns the results of a command in a JSON object with the sole key ="value"=. We have to correct that before returning the data to the user.
|
||||||
|
|
||||||
#+name: geckodriver-postprocess
|
#+name: geckodriver-postprocess
|
||||||
#+begin_src scheme :tangle webdriver-impl.scm
|
#+begin_src scheme :tangle raft-impl.scm
|
||||||
(define-method (postprocess-result (instance <Gecko>) result)
|
(define-method (postprocess-result (instance <Gecko>) result)
|
||||||
(alist-ref/default result 'value result))
|
(alist-ref/default result 'value result))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
@ -299,7 +298,7 @@ Sometimes, Geckodriver returns the results of a command in a JSON object with th
|
||||||
#+name: prep-geckodriver-test
|
#+name: prep-geckodriver-test
|
||||||
#+begin_src scheme :noweb strip-tangle :exports none :post test-post(input=*this*) :results output
|
#+begin_src scheme :noweb strip-tangle :exports none :post test-post(input=*this*) :results output
|
||||||
<<prep-test>>
|
<<prep-test>>
|
||||||
<<wd-exception>>
|
<<raft-exception>>
|
||||||
<<conditions>>
|
<<conditions>>
|
||||||
<<webdriver-class>>
|
<<webdriver-class>>
|
||||||
<<webdriver-basics>>
|
<<webdriver-basics>>
|
||||||
|
@ -307,9 +306,9 @@ Sometimes, Geckodriver returns the results of a command in a JSON object with th
|
||||||
<<geckodriver-basic>>
|
<<geckodriver-basic>>
|
||||||
<<geckodriver-capabilities>>
|
<<geckodriver-capabilities>>
|
||||||
<<geckodriver-postprocess>>
|
<<geckodriver-postprocess>>
|
||||||
<<wd-send>>
|
<<raft-send>>
|
||||||
<<wd-init-session>>
|
<<raft-init-session>>
|
||||||
<<wd-term-session>>
|
<<raft-term-session>>
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
* WebDriver API
|
* WebDriver API
|
||||||
|
@ -318,9 +317,9 @@ Sometimes, Geckodriver returns the results of a command in a JSON object with th
|
||||||
|
|
||||||
Data is sent to the API via a central class method. For convenience, there is a ~send-with-session~ variant that automatically adds the session id.
|
Data is sent to the API via a central class method. For convenience, there is a ~send-with-session~ variant that automatically adds the session id.
|
||||||
|
|
||||||
#+name: wd-send
|
#+name: raft-send
|
||||||
#+begin_src scheme :tangle webdriver-impl.scm
|
#+begin_src scheme :tangle raft-impl.scm
|
||||||
(define-method (send (instance <WebDriver>) data uri method)
|
(define-method (send (instance <Raft>) data uri method)
|
||||||
(let* ((remote (string-append "http://" (slot-value instance 'server) ":" (->string (slot-value instance 'port)) "/"))
|
(let* ((remote (string-append "http://" (slot-value instance 'server) ":" (->string (slot-value instance 'port)) "/"))
|
||||||
(result (postprocess-result instance
|
(result (postprocess-result instance
|
||||||
(with-input-from-request
|
(with-input-from-request
|
||||||
|
@ -330,10 +329,10 @@ Data is sent to the API via a central class method. For convenience, there is a
|
||||||
(if data (json->string data) "")
|
(if data (json->string data) "")
|
||||||
read-json))))
|
read-json))))
|
||||||
(if (and (list? result) (alist-ref/default result 'error #f))
|
(if (and (list? result) (alist-ref/default result 'error #f))
|
||||||
(wd-throw result)
|
(raft-throw result)
|
||||||
result)))
|
result)))
|
||||||
|
|
||||||
(define-method (send-with-session (instance <WebDriver>) data uri method)
|
(define-method (send-with-session (instance <Raft>) data uri method)
|
||||||
(send instance data (string-append "session/" (slot-value instance 'session-id) "/" uri) method))
|
(send instance data (string-append "session/" (slot-value instance 'session-id) "/" uri) method))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
@ -341,33 +340,33 @@ Data is sent to the API via a central class method. For convenience, there is a
|
||||||
|
|
||||||
Session management is very simple. There is just one method to initialize a new session. Everything else is handled automatically.
|
Session management is very simple. There is just one method to initialize a new session. Everything else is handled automatically.
|
||||||
|
|
||||||
#+name: wd-init-session
|
#+name: raft-init-session
|
||||||
#+begin_src scheme :tangle webdriver-impl.scm
|
#+begin_src scheme :tangle raft-impl.scm
|
||||||
(define-method (initialize-session (instance <WebDriver>))
|
(define-method (initialize-session (instance <Raft>))
|
||||||
(let ((result (send instance (construct-capabilities instance) "session" 'POST)))
|
(let ((result (send instance (construct-capabilities instance) "session" 'POST)))
|
||||||
(set! (slot-value instance 'session-id) (alist-ref result 'sessionId))))
|
(set! (slot-value instance 'session-id) (alist-ref result 'sessionId))))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+name: wd-term-session
|
#+name: raft-term-session
|
||||||
#+begin_src scheme :tangle webdriver-impl.scm
|
#+begin_src scheme :tangle raft-impl.scm
|
||||||
(define-method (terminate-session (instance <WebDriver>))
|
(define-method (terminate-session (instance <Raft>))
|
||||||
(when (slot-value instance 'session-id)
|
(when (slot-value instance 'session-id)
|
||||||
(send instance #f (string-append "session/" (slot-value instance 'session-id)) 'DELETE))
|
(send instance #f (string-append "session/" (slot-value instance 'session-id)) 'DELETE))
|
||||||
(set! (slot-value instance 'session-id) #f))
|
(set! (slot-value instance 'session-id) #f))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+name: wd-session-test
|
#+name: raft-session-test
|
||||||
#+begin_src scheme :tangle tests/run.scm :noweb strip-tangle :exports results :post test-post(input=*this*) :results output
|
#+begin_src scheme :tangle tests/run.scm :noweb strip-tangle :exports results :post test-post(input=*this*) :results output
|
||||||
<<prep-geckodriver-test>>
|
<<prep-geckodriver-test>>
|
||||||
(test-group "session"
|
(test-group "session"
|
||||||
(let ((browser (make-WebDriver <Gecko>)))
|
(let ((browser (make-Raft <Gecko>)))
|
||||||
(test "Initial state" #f (slot-value browser 'session-id))
|
(test "Initial state" #f (slot-value browser 'session-id))
|
||||||
(test-assert "Session id check" (string? (begin (initialize-session browser) (slot-value browser 'session-id))))
|
(test-assert "Session id check" (string? (begin (initialize-session browser) (slot-value browser 'session-id))))
|
||||||
(test-assert "Session id after termination" (eq? #f (begin (terminate-session browser) (slot-value browser 'session-id))))
|
(test-assert "Session id after termination" (eq? #f (begin (terminate-session browser) (slot-value browser 'session-id))))
|
||||||
(terminate browser)))
|
(terminate browser)))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+RESULTS: wd-session-test
|
#+RESULTS: raft-session-test
|
||||||
: -- testing session -----------------------------------------------------------
|
: -- testing session -----------------------------------------------------------
|
||||||
: Initial state ........................................................ [ PASS]
|
: Initial state ........................................................ [ PASS]
|
||||||
: Session id check ..................................................... [ PASS]
|
: Session id check ..................................................... [ PASS]
|
||||||
|
@ -378,21 +377,21 @@ Session management is very simple. There is just one method to initialize a new
|
||||||
|
|
||||||
** API Access Methods
|
** API Access Methods
|
||||||
|
|
||||||
#+name: wd-url
|
#+name: raft-url
|
||||||
#+begin_src scheme :tangle webdriver-impl.scm
|
#+begin_src scheme :tangle raft-impl.scm
|
||||||
(define-method (set-url (instance <WebDriver>) url)
|
(define-method (set-url (instance <Raft>) url)
|
||||||
(send-with-session instance `((url . ,url)) "url" 'POST))
|
(send-with-session instance `((url . ,url)) "url" 'POST))
|
||||||
|
|
||||||
(define-method (url (instance <WebDriver>))
|
(define-method (url (instance <Raft>))
|
||||||
(send-with-session instance #f "url" 'GET))
|
(send-with-session instance #f "url" 'GET))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+name: wd-url-test
|
#+name: raft-url-test
|
||||||
#+begin_src scheme :tangle tests/run.scm :noweb strip-tangle :exports results :post test-post(input=*this*) :results output
|
#+begin_src scheme :tangle tests/run.scm :noweb strip-tangle :exports results :post test-post(input=*this*) :results output
|
||||||
<<prep-geckodriver-test>>
|
<<prep-geckodriver-test>>
|
||||||
<<wd-url>>
|
<<raft-url>>
|
||||||
(test-group "url"
|
(test-group "url"
|
||||||
(let ((browser (make-WebDriver <Gecko>)))
|
(let ((browser (make-Raft <Gecko>)))
|
||||||
(test "Initial state" #f (slot-value browser 'session-id))
|
(test "Initial state" #f (slot-value browser 'session-id))
|
||||||
(test "Navigating to the first website" "http://info.cern.ch/hypertext/WWW/TheProject.html"
|
(test "Navigating to the first website" "http://info.cern.ch/hypertext/WWW/TheProject.html"
|
||||||
(begin (initialize-session browser)
|
(begin (initialize-session browser)
|
||||||
|
@ -401,7 +400,7 @@ Session management is very simple. There is just one method to initialize a new
|
||||||
(terminate browser)))
|
(terminate browser)))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+RESULTS: wd-url-test
|
#+RESULTS: raft-url-test
|
||||||
: -- testing url ---------------------------------------------------------------
|
: -- testing url ---------------------------------------------------------------
|
||||||
: Initial state ........................................................ [ PASS]
|
: Initial state ........................................................ [ PASS]
|
||||||
: Navigating to the first website ...................................... [ PASS]
|
: Navigating to the first website ...................................... [ PASS]
|
||||||
|
@ -409,53 +408,53 @@ Session management is very simple. There is just one method to initialize a new
|
||||||
: 2 out of 2 (100%) tests passed.
|
: 2 out of 2 (100%) tests passed.
|
||||||
: -- done testing url ----------------------------------------------------------
|
: -- done testing url ----------------------------------------------------------
|
||||||
|
|
||||||
#+begin_src scheme :tangle webdriver-impl.scm
|
#+begin_src scheme :tangle raft-impl.scm
|
||||||
(define-method (back (instance <WebDriver>))
|
(define-method (back (instance <Raft>))
|
||||||
(send-with-session instance #f "back" 'POST))
|
(send-with-session instance #f "back" 'POST))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+begin_src scheme :tangle webdriver-impl.scm
|
#+begin_src scheme :tangle raft-impl.scm
|
||||||
(define-method (forward (instance <WebDriver>))
|
(define-method (forward (instance <Raft>))
|
||||||
(send-with-session instance #f "forward" 'POST))
|
(send-with-session instance #f "forward" 'POST))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+begin_src scheme :tangle webdriver-impl.scm
|
#+begin_src scheme :tangle raft-impl.scm
|
||||||
(define-method (refresh (instance <WebDriver>))
|
(define-method (refresh (instance <Raft>))
|
||||||
(send-with-session instance #f "refresh" 'POST))
|
(send-with-session instance #f "refresh" 'POST))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+begin_src scheme :tangle webdriver-impl.scm
|
#+begin_src scheme :tangle raft-impl.scm
|
||||||
(define-method (title (instance <WebDriver>))
|
(define-method (title (instance <Raft>))
|
||||||
(send-with-session instance #f "title" 'GET))
|
(send-with-session instance #f "title" 'GET))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+begin_src scheme :tangle webdriver-impl.scm
|
#+begin_src scheme :tangle raft-impl.scm
|
||||||
(define-method (status (instance <WebDriver>))
|
(define-method (status (instance <Raft>))
|
||||||
(send-with-session instance #f "status" 'GET))
|
(send-with-session instance #f "status" 'GET))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+begin_src scheme :tangle webdriver-impl.scm
|
#+begin_src scheme :tangle raft-impl.scm
|
||||||
(define-method (source (instance <WebDriver>))
|
(define-method (source (instance <Raft>))
|
||||||
(send-with-session instance #f "source" 'GET))
|
(send-with-session instance #f "source" 'GET))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+begin_src scheme :tangle webdriver-impl.scm
|
#+begin_src scheme :tangle raft-impl.scm
|
||||||
(define-method (screenshot (instance <WebDriver>))
|
(define-method (screenshot (instance <Raft>))
|
||||||
(base64-decode (send-with-session instance #f "screenshot" 'GET)))
|
(base64-decode (send-with-session instance #f "screenshot" 'GET)))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+begin_src scheme :tangle webdriver-impl.scm
|
#+begin_src scheme :tangle raft-impl.scm
|
||||||
(define-method (print-page (instance <WebDriver>))
|
(define-method (print-page (instance <Raft>))
|
||||||
(send-with-session instance #f "print" 'POST))
|
(send-with-session instance #f "print" 'POST))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+begin_src scheme :tangle webdriver-impl.scm
|
#+begin_src scheme :tangle raft-impl.scm
|
||||||
(define-method (execute-async (instance <WebDriver>) script args)
|
(define-method (execute-async (instance <Raft>) script args)
|
||||||
(send-with-session instance `((script . ,script) (args . ,args)) "execute/async" 'POST))
|
(send-with-session instance `((script . ,script) (args . ,args)) "execute/async" 'POST))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+begin_src scheme :tangle webdriver-impl.scm
|
#+begin_src scheme :tangle raft-impl.scm
|
||||||
(define-method (execute-sync (instance <WebDriver>) script args)
|
(define-method (execute-sync (instance <Raft>) script args)
|
||||||
(send-with-session instance `((script . ,script) (args . ,args)) "execute/sync" 'POST))
|
(send-with-session instance `((script . ,script) (args . ,args)) "execute/sync" 'POST))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
@ -467,15 +466,15 @@ The following timeouts are defined:
|
||||||
- =pageLoad=: defaults to 300'000, provides the timeout limit used to interrupt an explicit navigation attempt.
|
- =pageLoad=: defaults to 300'000, provides the timeout limit used to interrupt an explicit navigation attempt.
|
||||||
- =implicit=: defaults to 0, specifies a time to wait for the element location strategy to complete when locating an element.
|
- =implicit=: defaults to 0, specifies a time to wait for the element location strategy to complete when locating an element.
|
||||||
|
|
||||||
#+begin_src scheme :tangle webdriver-impl.scm
|
#+begin_src scheme :tangle raft-impl.scm
|
||||||
(define-class <WDTimeouts> ()
|
(define-class <RaftTimeouts> ()
|
||||||
((script 30000)
|
((script 30000)
|
||||||
(pageLoad 300000)
|
(pageLoad 300000)
|
||||||
(implicit 0)))
|
(implicit 0)))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+begin_src scheme :tangle webdriver-impl.scm
|
#+begin_src scheme :tangle raft-impl.scm
|
||||||
(define-method (extract (instance <WDTimeouts>))
|
(define-method (extract (instance <RaftTimeouts>))
|
||||||
`((script . ,(slot-value instance 'script))
|
`((script . ,(slot-value instance 'script))
|
||||||
(pageLoad . ,(slot-value instance 'pageLoad))
|
(pageLoad . ,(slot-value instance 'pageLoad))
|
||||||
(implicit . ,(slot-value instance 'implicit))))
|
(implicit . ,(slot-value instance 'implicit))))
|
||||||
|
@ -483,13 +482,13 @@ The following timeouts are defined:
|
||||||
|
|
||||||
*** Setting and getting timeouts
|
*** Setting and getting timeouts
|
||||||
|
|
||||||
#+begin_src scheme :tangle webdriver-impl.scm
|
#+begin_src scheme :tangle raft-impl.scm
|
||||||
(define-method (set-timeouts (instance <WebDriver>) (timeouts <WDTimeouts>))
|
(define-method (set-timeouts (instance <Raft>) (timeouts <RaftTimeouts>))
|
||||||
(send-with-session instance (extract timeouts) "timeouts" 'POST))
|
(send-with-session instance (extract timeouts) "timeouts" 'POST))
|
||||||
|
|
||||||
(define-method (timeouts (instance <WebDriver>))
|
(define-method (timeouts (instance <Raft>))
|
||||||
(let ((result (send-with-session instance #f "timeouts" 'GET)))
|
(let ((result (send-with-session instance #f "timeouts" 'GET)))
|
||||||
(make <WDTimeouts>
|
(make <RaftTimeouts>
|
||||||
'script (alist-ref result 'script)
|
'script (alist-ref result 'script)
|
||||||
'pageLoad (alist-ref result 'pageLoad)
|
'pageLoad (alist-ref result 'pageLoad)
|
||||||
'implicit (alist-ref result 'implicit))))
|
'implicit (alist-ref result 'implicit))))
|
||||||
|
@ -499,14 +498,14 @@ The following timeouts are defined:
|
||||||
|
|
||||||
*** Element Class
|
*** Element Class
|
||||||
|
|
||||||
#+begin_src scheme :tangle webdriver-impl.scm
|
#+begin_src scheme :tangle raft-impl.scm
|
||||||
(define-class <WDElement> ()
|
(define-class <RaftElement> ()
|
||||||
((driver #f)
|
((driver #f)
|
||||||
(element #f)))
|
(element #f)))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+begin_src scheme :tangle webdriver-impl.scm
|
#+begin_src scheme :tangle raft-impl.scm
|
||||||
(define-method (send-with-session (instance <WDElement>) data uri method)
|
(define-method (send-with-session (instance <RaftElement>) data uri method)
|
||||||
(send-with-session (slot-value instance 'driver) data
|
(send-with-session (slot-value instance 'driver) data
|
||||||
(string-append "element/" (slot-value instance 'element) "/" uri)
|
(string-append "element/" (slot-value instance 'element) "/" uri)
|
||||||
method))
|
method))
|
||||||
|
@ -516,7 +515,7 @@ The following timeouts are defined:
|
||||||
|
|
||||||
**** Location Strategies
|
**** Location Strategies
|
||||||
|
|
||||||
#+begin_src scheme :tangle webdriver-impl.scm
|
#+begin_src scheme :tangle raft-impl.scm
|
||||||
(define css-selector "css selector")
|
(define css-selector "css selector")
|
||||||
(define link-text "link text")
|
(define link-text "link text")
|
||||||
(define partial-link-text "partial link text")
|
(define partial-link-text "partial link text")
|
||||||
|
@ -526,40 +525,40 @@ The following timeouts are defined:
|
||||||
|
|
||||||
**** Accessor Methods
|
**** Accessor Methods
|
||||||
|
|
||||||
#+begin_src scheme :tangle webdriver-impl.scm
|
#+begin_src scheme :tangle raft-impl.scm
|
||||||
(define-method (find-element (instance <WebDriver>) strategy selector)
|
(define-method (find-element (instance <Raft>) strategy selector)
|
||||||
(let ((result (send-with-session instance `((using . ,strategy) (value . ,selector)) "element" 'POST)))
|
(let ((result (send-with-session instance `((using . ,strategy) (value . ,selector)) "element" 'POST)))
|
||||||
(make <WDElement> 'driver instance 'element (car (alist-values result)))))
|
(make <RaftElement> 'driver instance 'element (car (alist-values result)))))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+begin_src scheme :tangle webdriver-impl.scm
|
#+begin_src scheme :tangle raft-impl.scm
|
||||||
(define-method (find-elements (instance <WebDriver>) strategy selector)
|
(define-method (find-elements (instance <Raft>) strategy selector)
|
||||||
(let ((result (send-with-session instance `((using . ,strategy) (value . ,selector)) "elements" 'POST)))
|
(let ((result (send-with-session instance `((using . ,strategy) (value . ,selector)) "elements" 'POST)))
|
||||||
(map
|
(map
|
||||||
(lambda (elem)
|
(lambda (elem)
|
||||||
(make <WDElement> 'driver instance 'element (car (alist-values elem))))
|
(make <RaftElement> 'driver instance 'element (car (alist-values elem))))
|
||||||
result)))
|
result)))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+begin_src scheme :tangle webdriver-impl.scm
|
#+begin_src scheme :tangle raft-impl.scm
|
||||||
(define-method (find-element (instance <WDElement>) strategy selector)
|
(define-method (find-element (instance <RaftElement>) strategy selector)
|
||||||
(let ((result (send-with-session instance `((using . ,strategy) (value . ,selector)) "element" 'POST)))
|
(let ((result (send-with-session instance `((using . ,strategy) (value . ,selector)) "element" 'POST)))
|
||||||
(make <WDElement> 'driver (slot-value instance 'driver) 'element (car (alist-values result)))))
|
(make <RaftElement> 'driver (slot-value instance 'driver) 'element (car (alist-values result)))))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+begin_src scheme :tangle webdriver-impl.scm
|
#+begin_src scheme :tangle raft-impl.scm
|
||||||
(define-method (find-elements (instance <WDElement>) strategy selector)
|
(define-method (find-elements (instance <RaftElement>) strategy selector)
|
||||||
(let ((result (send-with-session instance `((using . ,strategy) (value . ,selector)) "elements" 'POST)))
|
(let ((result (send-with-session instance `((using . ,strategy) (value . ,selector)) "elements" 'POST)))
|
||||||
(map
|
(map
|
||||||
(lambda (elem)
|
(lambda (elem)
|
||||||
(make <WDElement> 'driver (slot-value instance 'driver) 'element (car (alist-values elem))))
|
(make <RaftElement> 'driver (slot-value instance 'driver) 'element (car (alist-values elem))))
|
||||||
result)))
|
result)))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
*** Working with Elements
|
*** Working with Elements
|
||||||
|
|
||||||
#+begin_src scheme :tangle webdriver-impl.scm
|
#+begin_src scheme :tangle raft-impl.scm
|
||||||
(define-method (attribute (instance <WDElement>) attribute)
|
(define-method (attribute (instance <RaftElement>) attribute)
|
||||||
(let ((result (send-with-session instance #f
|
(let ((result (send-with-session instance #f
|
||||||
(string-append "attribute/" attribute)
|
(string-append "attribute/" attribute)
|
||||||
'GET)))
|
'GET)))
|
||||||
|
@ -568,69 +567,69 @@ The following timeouts are defined:
|
||||||
result)))
|
result)))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+begin_src scheme :tangle webdriver-impl.scm
|
#+begin_src scheme :tangle raft-impl.scm
|
||||||
(define-method (property (instance <WDElement>) property)
|
(define-method (property (instance <RaftElement>) property)
|
||||||
(send-with-session instance #f (string-append "property/" property) 'GET))
|
(send-with-session instance #f (string-append "property/" property) 'GET))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+begin_src scheme :tangle webdriver-impl.scm
|
#+begin_src scheme :tangle raft-impl.scm
|
||||||
(define-method (clear (instance <WDElement>))
|
(define-method (clear (instance <RaftElement>))
|
||||||
(send-with-session instance #f "clear" 'POST))
|
(send-with-session instance #f "clear" 'POST))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+begin_src scheme :tangle webdriver-impl.scm
|
#+begin_src scheme :tangle raft-impl.scm
|
||||||
(define-method (click (instance <WDElement>))
|
(define-method (click (instance <RaftElement>))
|
||||||
(send-with-session instance #f "click" 'POST))
|
(send-with-session instance #f "click" 'POST))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+begin_src scheme :tangle webdriver-impl.scm
|
#+begin_src scheme :tangle raft-impl.scm
|
||||||
(define-method (computed-label (instance <WDElement>))
|
(define-method (computed-label (instance <RaftElement>))
|
||||||
(send-with-session instance #f "computedlabel" 'GET))
|
(send-with-session instance #f "computedlabel" 'GET))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+begin_src scheme :tangle webdriver-impl.scm
|
#+begin_src scheme :tangle raft-impl.scm
|
||||||
(define-method (computed-role (instance <WDElement>))
|
(define-method (computed-role (instance <RaftElement>))
|
||||||
(send-with-session instance #f "computedrole" 'GET))
|
(send-with-session instance #f "computedrole" 'GET))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+begin_src scheme :tangle webdriver-impl.scm
|
#+begin_src scheme :tangle raft-impl.scm
|
||||||
(define-method (enabled? (instance <WDElement>))
|
(define-method (enabled? (instance <RaftElement>))
|
||||||
(send-with-session instance #f "enabled" 'GET))
|
(send-with-session instance #f "enabled" 'GET))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+begin_src scheme :tangle webdriver-impl.scm
|
#+begin_src scheme :tangle raft-impl.scm
|
||||||
(define-method (selected? (instance <WDElement>))
|
(define-method (selected? (instance <RaftElement>))
|
||||||
(send-with-session instance #f "selected" 'GET))
|
(send-with-session instance #f "selected" 'GET))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+begin_src scheme :tangle webdriver-impl.scm
|
#+begin_src scheme :tangle raft-impl.scm
|
||||||
(define-method (name (instance <WDElement>))
|
(define-method (name (instance <RaftElement>))
|
||||||
(send-with-session instance #f "name" 'GET))
|
(send-with-session instance #f "name" 'GET))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+begin_src scheme :tangle webdriver-impl.scm
|
#+begin_src scheme :tangle raft-impl.scm
|
||||||
(define-method (rect (instance <WDElement>))
|
(define-method (rect (instance <RaftElement>))
|
||||||
(send-with-session instance #f "rect" 'GET))
|
(send-with-session instance #f "rect" 'GET))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+begin_src scheme :tangle webdriver-impl.scm
|
#+begin_src scheme :tangle raft-impl.scm
|
||||||
(define-method (screenshot (instance <WDElement>))
|
(define-method (screenshot (instance <RaftElement>))
|
||||||
(base64-decode (send-with-session instance #f "screenshot" 'GET)))
|
(base64-decode (send-with-session instance #f "screenshot" 'GET)))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+begin_src scheme :tangle webdriver-impl.scm
|
#+begin_src scheme :tangle raft-impl.scm
|
||||||
(define-method (text (instance <WDElement>))
|
(define-method (text (instance <RaftElement>))
|
||||||
(send-with-session instance #f "text" 'GET))
|
(send-with-session instance #f "text" 'GET))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+begin_src scheme :tangle webdriver-impl.scm
|
#+begin_src scheme :tangle raft-impl.scm
|
||||||
(define-method (set-value (instance <WDElement>) value)
|
(define-method (set-value (instance <RaftElement>) value)
|
||||||
(send-with-session instance `((text . ,value)) "value" 'POST))
|
(send-with-session instance `((text . ,value)) "value" 'POST))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
* About This Egg
|
* About This Egg
|
||||||
|
|
||||||
#+begin_src scheme :noweb yes :tangle webdriver.egg :exports none
|
#+begin_src scheme :noweb yes :tangle raft.egg :exports none
|
||||||
;; -*- scheme -*-
|
;; -*- scheme -*-
|
||||||
((author "Daniel Ziltener")
|
((author "Daniel Ziltener")
|
||||||
(synopsis "A WebDriver API implementation for Chicken")
|
(synopsis "A WebDriver API implementation for Chicken")
|
||||||
|
@ -651,7 +650,7 @@ The following timeouts are defined:
|
||||||
|
|
||||||
** Source
|
** Source
|
||||||
|
|
||||||
The source is available at [[https://fossil.lyrion.ch/chicken-webdriver]].
|
The source is available at [[https://gitea.lyrion.ch/Chicken/raft]].
|
||||||
|
|
||||||
** Author
|
** Author
|
||||||
|
|
||||||
|
@ -673,10 +672,10 @@ Daniel Ziltener
|
||||||
(number-to-string (caar vers))
|
(number-to-string (caar vers))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+begin_src scheme :noweb yes :tangle webdriver.release-info :exports none
|
#+begin_src scheme :noweb yes :tangle raft.release-info :exports none
|
||||||
;; -*- scheme -*-
|
;; -*- scheme -*-
|
||||||
(repo fossil "https://fossil.lyrion.ch/chicken-webdriver")
|
(repo git "https://gitea.lyrion.ch/Chicken/raft")
|
||||||
(uri targz "https://fossil.lyrion.ch/chicken-webdriver/tarball/{egg-release}/chicken-webdriver-{egg-release}.tar.gz")
|
(uri targz "https://gitea.lyrion.ch/Chicken/raft/archive/{egg-release}.tar.gz")
|
||||||
<<gen-releases()>>
|
<<gen-releases()>>
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
6
raft.release-info
Normal file
6
raft.release-info
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
;; [[file:raft.org::*Version History][Version History:3]]
|
||||||
|
;; -*- scheme -*-
|
||||||
|
(repo git "https://gitea.lyrion.ch/Chicken/raft")
|
||||||
|
(uri targz "https://gitea.lyrion.ch/Chicken/raft/archive/{egg-release}.tar.gz")
|
||||||
|
(release "0.5") ;; Initial Release
|
||||||
|
;; Version History:3 ends here
|
|
@ -1,10 +1,10 @@
|
||||||
;; [[file:webdriver.org::*Dependencies][Dependencies:3]]
|
;; [[file:raft.org::*Dependencies][Dependencies:3]]
|
||||||
(import r7rs)
|
(import r7rs)
|
||||||
(define-library (webdriver)
|
(define-library (raft)
|
||||||
(import (scheme base))
|
(import (scheme base))
|
||||||
(export <WebDriver>
|
(export <Raft>
|
||||||
<Gecko>
|
<Gecko>
|
||||||
make-WebDriver
|
make-Raft
|
||||||
terminate
|
terminate
|
||||||
initialize-session
|
initialize-session
|
||||||
terminate-session
|
terminate-session
|
||||||
|
@ -20,10 +20,10 @@
|
||||||
print-page
|
print-page
|
||||||
execute-async
|
execute-async
|
||||||
execute-sync
|
execute-sync
|
||||||
<WDTimeouts>
|
<RaftTimeouts>
|
||||||
set-timeouts
|
set-timeouts
|
||||||
timeouts
|
timeouts
|
||||||
<WDElement>
|
<RaftElement>
|
||||||
css-selector
|
css-selector
|
||||||
link-text
|
link-text
|
||||||
partial-link-text
|
partial-link-text
|
||||||
|
@ -44,10 +44,10 @@
|
||||||
screenshot
|
screenshot
|
||||||
text
|
text
|
||||||
set-value
|
set-value
|
||||||
&wd-exception
|
&raft-exception
|
||||||
wd-exception?
|
raft-exception?
|
||||||
wd-stacktrace
|
raft-stacktrace
|
||||||
wd-data
|
raft-data
|
||||||
&detached-shadow-root detached-shadow-root?
|
&detached-shadow-root detached-shadow-root?
|
||||||
&element-click-intercepted element-click-intercepted?
|
&element-click-intercepted element-click-intercepted?
|
||||||
&element-not-interactable element-not-interactable?
|
&element-not-interactable element-not-interactable?
|
||||||
|
@ -77,5 +77,5 @@
|
||||||
&unknown-method unknown-method?
|
&unknown-method unknown-method?
|
||||||
&unsupported-operation unsupported-operation?
|
&unsupported-operation unsupported-operation?
|
||||||
)
|
)
|
||||||
(include "webdriver-impl.scm"))
|
(include "raft-impl.scm"))
|
||||||
;; Dependencies:3 ends here
|
;; Dependencies:3 ends here
|
|
@ -5,52 +5,49 @@
|
||||||
(chicken string)
|
(chicken string)
|
||||||
(chicken process)
|
(chicken process)
|
||||||
(chicken gc)
|
(chicken gc)
|
||||||
srfi-34 ;;Exception Handling
|
alist-lib ;;Handling alists from JSON objects
|
||||||
srfi-35 ;;Exception Types
|
|
||||||
base64 ;;decoding screenshot data
|
base64 ;;decoding screenshot data
|
||||||
|
coops ;;Object system
|
||||||
http-client ;;API interaction
|
http-client ;;API interaction
|
||||||
intarweb ;;Supporting HTTP functionality
|
intarweb ;;Supporting HTTP functionality
|
||||||
uri-common ;;Supporting HTTP functionality
|
|
||||||
coops ;;Object system
|
|
||||||
alist-lib ;;Handling alists from JSON objects
|
|
||||||
medea ;;JSON handling
|
medea ;;JSON handling
|
||||||
|
srfi-34 ;;Exception Handling
|
||||||
|
srfi-35 ;;Exception Types
|
||||||
|
uri-common ;;Supporting HTTP functionality
|
||||||
)
|
)
|
||||||
|
|
||||||
;; [[file:../webdriver.org::*Dependencies][Dependencies:5]]
|
;; [[file:../raft.org::*Dependencies][Dependencies:5]]
|
||||||
(include-relative "../webdriver-impl.scm")
|
(include-relative "../raft-impl.scm")
|
||||||
;; Dependencies:5 ends here
|
;; Dependencies:5 ends here
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;; #+name: wd-session-test
|
;; #+name: raft-session-test
|
||||||
|
|
||||||
;; [[file:../webdriver.org::wd-session-test][wd-session-test]]
|
;; [[file:../raft.org::raft-session-test][raft-session-test]]
|
||||||
<<prep-geckodriver-test>>
|
|
||||||
(test-group "session"
|
(test-group "session"
|
||||||
(let ((browser (make-WebDriver <Gecko>)))
|
(let ((browser (make-Raft <Gecko>)))
|
||||||
(test "Initial state" #f (slot-value browser 'session-id))
|
(test "Initial state" #f (slot-value browser 'session-id))
|
||||||
(test-assert "Session id check" (string? (begin (initialize-session browser) (slot-value browser 'session-id))))
|
(test-assert "Session id check" (string? (begin (initialize-session browser) (slot-value browser 'session-id))))
|
||||||
(test-assert "Session id after termination" (eq? #f (begin (terminate-session browser) (slot-value browser 'session-id))))
|
(test-assert "Session id after termination" (eq? #f (begin (terminate-session browser) (slot-value browser 'session-id))))
|
||||||
(terminate browser)))
|
(terminate browser)))
|
||||||
;; wd-session-test ends here
|
;; raft-session-test ends here
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;; #+name: wd-url-test
|
;; #+name: raft-url-test
|
||||||
|
|
||||||
;; [[file:../webdriver.org::wd-url-test][wd-url-test]]
|
;; [[file:../raft.org::raft-url-test][raft-url-test]]
|
||||||
<<prep-geckodriver-test>>
|
|
||||||
<<wd-url>>
|
|
||||||
(test-group "url"
|
(test-group "url"
|
||||||
(let ((browser (make-WebDriver <Gecko>)))
|
(let ((browser (make-Raft <Gecko>)))
|
||||||
(test "Initial state" #f (slot-value browser 'session-id))
|
(test "Initial state" #f (slot-value browser 'session-id))
|
||||||
(test "Navigating to the first website" "http://info.cern.ch/hypertext/WWW/TheProject.html"
|
(test "Navigating to the first website" "http://info.cern.ch/hypertext/WWW/TheProject.html"
|
||||||
(begin (initialize-session browser)
|
(begin (initialize-session browser)
|
||||||
(set-url browser "http://info.cern.ch/hypertext/WWW/TheProject.html")
|
(set-url browser "http://info.cern.ch/hypertext/WWW/TheProject.html")
|
||||||
(url browser)))
|
(url browser)))
|
||||||
(terminate browser)))
|
(terminate browser)))
|
||||||
;; wd-url-test ends here
|
;; raft-url-test ends here
|
||||||
|
|
||||||
;; [[file:../webdriver.org::*About This Egg][About This Egg:2]]
|
;; [[file:../raft.org::*About This Egg][About This Egg:2]]
|
||||||
(test-exit)
|
(test-exit)
|
||||||
;; About This Egg:2 ends here
|
;; About This Egg:2 ends here
|
||||||
|
|
1031
webdriver.html
1031
webdriver.html
File diff suppressed because it is too large
Load diff
|
@ -1,6 +0,0 @@
|
||||||
;; [[file:webdriver.org::*Version History][Version History:3]]
|
|
||||||
;; -*- scheme -*-
|
|
||||||
(repo fossil "https://fossil.lyrion.ch/chicken-webdriver")
|
|
||||||
(uri targz "https://fossil.lyrion.ch/chicken-webdriver/tarball/{egg-release}/chicken-webdriver-{egg-release}.tar.gz")
|
|
||||||
(release "0.5") ;; Initial Release
|
|
||||||
;; Version History:3 ends here
|
|
Loading…
Reference in a new issue