diff --git a/Makefile b/Makefile index 270420e..52b415b 100644 --- a/Makefile +++ b/Makefile @@ -23,6 +23,12 @@ vendor/htmlize.el: mkdir -p vendor wget https://raw.githubusercontent.com/hniksic/emacs-htmlize/dd27bc3f26efd728f2b1f01f9e4ac4f61f2ffbf9/htmlize.el -O vendor/htmlize.el +salmonella: webdriver.scm + rm -rf report + rm -f webdriver*.so + salmonella --keep-repo --repo-dir=./petri-dish; \ + salmonella-html-report ./salmonella.log report + # Extension Rules .scm.so: csc5 -R r7rs -X r7rs -sJ ${.IMPSRC} diff --git a/tests/run.scm b/tests/run.scm index 20200b6..e955699 100644 --- a/tests/run.scm +++ b/tests/run.scm @@ -22,29 +22,9 @@ -;; #+name: prep-geckodriver-test - -;; [[file:../webdriver.org::prep-geckodriver-test][prep-geckodriver-test]] -<> -<> -<> -<> -<> -<> -<> -<> -<> -<> -<> -<> -;; prep-geckodriver-test ends here - - - ;; #+name: wd-session-test ;; [[file:../webdriver.org::wd-session-test][wd-session-test]] -<> (test-group "session" (let ((browser (new-WebDriver ))) (test "Initial state" #f (slot-value browser 'session-id)) @@ -58,8 +38,6 @@ ;; #+name: wd-url-test ;; [[file:../webdriver.org::wd-url-test][wd-url-test]] -<> -<> (test-group "url" (let ((browser (new-WebDriver ))) (test "Initial state" #f (slot-value browser 'session-id)) diff --git a/webdriver-impl.scm b/webdriver-impl.scm index 4b1f4d6..4d9d735 100644 --- a/webdriver-impl.scm +++ b/webdriver-impl.scm @@ -16,7 +16,9 @@ ) ;; Dependencies:4 ends here -;; Error Conditions + + +;; * Error Conditions ;; #+name: wd-exception @@ -95,7 +97,9 @@ ) ;; conditions ends here -;; WebDriver + + +;; * WebDriver ;; The core element of the library is the ~~ class and its subclasses. The class has the following fields: @@ -152,7 +156,9 @@ instance)) ;; webdriver-init ends here -;; Geckodriver + + +;; ** Geckodriver ;; The Geckodriver is used to control Firefox. @@ -195,7 +201,11 @@ (alist-ref/default result 'value result)) ;; geckodriver-postprocess ends here -;; Communication + + +;; * WebDriver API + +;; ** Communication ;; 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. @@ -219,7 +229,9 @@ (send instance data (string-append "session/" (slot-value instance 'session-id) "/" uri) method)) ;; wd-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. @@ -242,7 +254,18 @@ (set! (slot-value instance 'session-id) #f)) ;; wd-term-session ends here -;; API Access Methods + + +;; #+RESULTS: wd-session-test +;; : -- testing session ----------------------------------------------------------- +;; : Initial state ........................................................ [ PASS] +;; : Session id check ..................................................... [ PASS] +;; : Session id after termination ......................................... [ PASS] +;; : 3 tests completed in 3.788 seconds. +;; : 3 out of 3 (100%) tests passed. +;; : -- done testing session ------------------------------------------------------ + +;; ** API Access Methods ;; #+name: wd-url @@ -315,7 +338,7 @@ (send-with-session instance `((script . ,script) (args . ,args)) "execute/sync" 'POST)) ;; API Access Methods:12 ends here -;; Timeouts + ;; The following timeouts are defined: @@ -338,9 +361,6 @@ (implicit . ,(slot-value instance 'implicit)))) ;; Timeouts:2 ends here -;; Setting and getting timeouts - - ;; [[file:webdriver.org::*Setting and getting timeouts][Setting and getting timeouts:1]] (define-method (set-timeouts (instance ) (timeouts )) (send-with-session instance (extract timeouts) "timeouts" 'POST)) @@ -353,9 +373,6 @@ 'implicit (alist-ref result 'implicit)))) ;; Setting and getting timeouts:1 ends here -;; Element Class - - ;; [[file:webdriver.org::*Element Class][Element Class:1]] (define-class () ((driver #f) @@ -369,9 +386,6 @@ method)) ;; Element Class:2 ends here -;; Location Strategies - - ;; [[file:webdriver.org::*Location Strategies][Location Strategies:1]] (define css-selector "css selector") (define link-text "link text") @@ -380,14 +394,10 @@ (define xpath "xpath") ;; Location Strategies:1 ends here -;; Accessor Methods - - ;; [[file:webdriver.org::*Accessor Methods][Accessor Methods:1]] (define-method (find-element (instance ) strategy selector) (let ((result (send-with-session instance `((using . ,strategy) (value . ,selector)) "element" 'POST))) - (make 'driver instance 'element (car (alist-values result))) - element)) + (make 'driver instance 'element (car (alist-values result))))) ;; Accessor Methods:1 ends here ;; [[file:webdriver.org::*Accessor Methods][Accessor Methods:2]] @@ -402,8 +412,7 @@ ;; [[file:webdriver.org::*Accessor Methods][Accessor Methods:3]] (define-method (find-element (instance ) strategy selector) (let ((result (send-with-session instance `((using . ,strategy) (value . ,selector)) "element" 'POST))) - (make 'driver (slot-value instance 'driver) 'element (car (alist-values result))) - element)) + (make 'driver (slot-value instance 'driver) 'element (car (alist-values result))))) ;; Accessor Methods:3 ends here ;; [[file:webdriver.org::*Accessor Methods][Accessor Methods:4]] @@ -415,9 +424,6 @@ result))) ;; Accessor Methods:4 ends here -;; Working with Elements - - ;; [[file:webdriver.org::*Working with Elements][Working with Elements:1]] (define-method (attribute (instance ) attribute) (let ((result (send-with-session instance #f diff --git a/webdriver.egg b/webdriver.egg index e091a9a..d81e8bc 100644 --- a/webdriver.egg +++ b/webdriver.egg @@ -1,6 +1,3 @@ -;; About This Egg - - ;; [[file:webdriver.org::*About This Egg][About This Egg:1]] ;; -*- scheme -*- ((author "Daniel Ziltener") diff --git a/webdriver.html b/webdriver.html index 42be4ab..259c57c 100644 --- a/webdriver.html +++ b/webdriver.html @@ -191,38 +191,38 @@

Table of Contents

-
-

1. Dependencies

+
+

1. Dependencies

- +
@@ -297,11 +297,11 @@ -
-

2. Error Conditions

+
+

2. Error Conditions

-
(define-condition-type &wd-exception &error wd-exception?
+
(define-condition-type &wd-exception &error wd-exception?
   (stacktrace wd-stacktrace)
   (data wd-data))
 
@@ -311,7 +311,7 @@ Every API error code (key "error" in the returned JSON data) gets its own condition type, prefixed by &. They all inherit from &wd-exception.

-
+
@@ -470,15 +470,15 @@ Every API error code (key "error" in the returned JSON data) gets its own condit -
-

3. WebDriver

+
+

3. WebDriver

The core element of the library is the <WebDriver> class and its subclasses. The class has the following fields:

-
(define-class <WebDriver> ()
+
(define-class <WebDriver> ()
   ((browser #f)
    (active? #f)
    (browser-pid #f)
@@ -495,7 +495,7 @@ The parent class provides a handful of methods, but does not implement all of th
 

-
(define-method (launch #:after (instance <WebDriver>) options)
+
(define-method (launch #:after (instance <WebDriver>) options)
   (set-finalizer! instance (lambda (obj)
                              (when (slot-value instance 'active?)
                                (terminate instance)))))
@@ -519,7 +519,7 @@ Main initialization is done by calling the new-WebDriver procedure
 

-
(define (new-WebDriver browser #!optional options)
+
(define (new-WebDriver browser #!optional options)
   (let ((instance (make browser)))
     (launch instance options)
     (sleep 1)
@@ -528,15 +528,15 @@ Main initialization is done by calling the new-WebDriver procedure
 
-
-

3.1. Geckodriver

+
+

3.1. Geckodriver

-
-

4. WebDriver API

+
+

4. WebDriver API

-
-

4.1. Communication

+
+

4.1. Communication

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.

-
(define-method (send (instance <WebDriver>) data uri method)
+
(define-method (send (instance <WebDriver>) data uri method)
   (let* ((remote (string-append "http://" (slot-value instance 'server) ":" (->string (slot-value instance 'port)) "/"))
          (result (postprocess-result instance
                                      (with-input-from-request
@@ -606,22 +606,22 @@ Data is sent to the API via a central class method. For convenience, there is a
 
-
-

4.2. Session management

+
+

4.2. Session management

Session management is very simple. There is just one method to initialize a new session. Everything else is handled automatically.

-
(define-method (initialize-session (instance <WebDriver>))
+
(define-method (initialize-session (instance <WebDriver>))
  (let ((result (send instance (construct-capabilities instance) "session" 'POST)))
    (set! (slot-value instance 'session-id) (alist-ref result 'sessionId))))
 
-
(define-method (terminate-session (instance <WebDriver>))
+
(define-method (terminate-session (instance <WebDriver>))
   (when (slot-value instance 'session-id)
     (send instance #f (string-append "session/" (slot-value instance 'session-id)) 'DELETE))
   (set! (slot-value instance 'session-id) #f))
@@ -640,11 +640,11 @@ Session id after termination ......................................... [ PASS]
 
-
-

4.3. API Access Methods

+
+

4.3. API Access Methods

-
(define-method (set-url (instance <WebDriver>) url)
+
(define-method (set-url (instance <WebDriver>) url)
   (send-with-session instance `((url . ,url)) "url" 'POST))
 
 (define-method (url (instance <WebDriver>))
@@ -724,8 +724,8 @@ Navigating to the first website ...................................... [ PASS]
 
-
-

4.4. Timeouts

+
+

4.4. Timeouts

The following timeouts are defined: @@ -754,8 +754,8 @@ The following timeouts are defined:

-
-

4.4.1. Setting and getting timeouts

+
+

4.4.1. Setting and getting timeouts

(define-method (set-timeouts (instance <WebDriver>) (timeouts <WDTimeouts>))
@@ -773,12 +773,12 @@ The following timeouts are defined:
 
-
-

4.5. Elements

+
+

4.5. Elements

-
-

4.5.1. Element Class

+
+

4.5.1. Element Class

(define-class <WDElement> ()
@@ -797,12 +797,12 @@ The following timeouts are defined:
 
-
-

4.5.2. Finding Elements

+
+

4.5.2. Finding Elements

    -
  1. Location Strategies
    +
  2. Location Strategies
    (define css-selector "css selector")
    @@ -815,13 +815,12 @@ The following timeouts are defined:
     
  3. -
  4. Accessor Methods
    +
  5. Accessor Methods
    (define-method (find-element (instance <WebDriver>) strategy selector)
       (let ((result (send-with-session instance `((using . ,strategy) (value . ,selector)) "element" 'POST)))
    -    (make <WDElement> 'driver instance 'element (car (alist-values result)))
    -    element))
    +    (make <WDElement> 'driver instance 'element (car (alist-values result)))))
     
    @@ -838,8 +837,7 @@ The following timeouts are defined:
    (define-method (find-element (instance <WDElement>) strategy selector)
       (let ((result (send-with-session instance `((using . ,strategy) (value . ,selector)) "element" 'POST)))
    -    (make <WDElement> 'driver (slot-value instance 'driver) 'element (car (alist-values result)))
    -    element))
    +    (make <WDElement> 'driver (slot-value instance 'driver) 'element (car (alist-values result)))))
     
    @@ -857,8 +855,8 @@ The following timeouts are defined:
-
-

4.5.3. Working with Elements

+
+

4.5.3. Working with Elements

(define-method (attribute (instance <WDElement>) attribute)
@@ -947,12 +945,12 @@ The following timeouts are defined:
 
-
-

5. About This Egg

+
+

5. About This Egg

-
+
@@ -990,8 +988,8 @@ Daniel Ziltener -
-

5.4. License

+
+

5.4. License

diff --git a/webdriver.org b/webdriver.org index 96ae7de..1f5abaa 100644 --- a/webdriver.org +++ b/webdriver.org @@ -60,7 +60,49 @@ (import r7rs) (define-library (webdriver) (import (scheme base)) - (export ) + (export + + new-WebDriver + terminate + initialize-session + terminate-session + set-url + url + back + forward + refresh + title + status + source + screenshot + print-page + execute-async + execute-sync + + set-timeouts + timeouts + + find-element + find-elements + attribute + property + clear + click + computed-label + computed-role + enabled? + selected? + name + rect + screenshot + text + set-value + &wd-exception + wd-exception? + wd-stacktrace + wd-data + <> + ) (include "webdriver-impl.scm")) #+end_src @@ -121,6 +163,15 @@ Every API error code (key "error" in the returned JSON data) gets its own condit | unknown-method | unknown method | | unsupported-operation | unsupported operation | +#+name: export-conditions +#+begin_src emacs-lisp :var src=error-code-table :exports none :results raw +(mapconcat + (lambda (row) + (let ((replace `((?n . ,(cl-first row))))) + (format-spec "&%n %n?" replace))) + src "\n") +#+end_src + #+name: define-conditions #+begin_src emacs-lisp :var src=error-code-table :exports none :results raw (mapconcat @@ -241,7 +292,7 @@ Sometimes, Geckodriver returns the results of a command in a JSON object with th #+end_src #+name: prep-geckodriver-test -#+begin_src scheme :tangle tests/run.scm :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 <> <> <> @@ -473,8 +524,7 @@ The following timeouts are defined: #+begin_src scheme :tangle webdriver-impl.scm (define-method (find-element (instance ) strategy selector) (let ((result (send-with-session instance `((using . ,strategy) (value . ,selector)) "element" 'POST))) - (make 'driver instance 'element (car (alist-values result))) - element)) + (make 'driver instance 'element (car (alist-values result))))) #+end_src #+begin_src scheme :tangle webdriver-impl.scm @@ -489,8 +539,7 @@ The following timeouts are defined: #+begin_src scheme :tangle webdriver-impl.scm (define-method (find-element (instance ) strategy selector) (let ((result (send-with-session instance `((using . ,strategy) (value . ,selector)) "element" 'POST))) - (make 'driver (slot-value instance 'driver) 'element (car (alist-values result))) - element)) + (make 'driver (slot-value instance 'driver) 'element (car (alist-values result))))) #+end_src #+begin_src scheme :tangle webdriver-impl.scm diff --git a/webdriver.scm b/webdriver.scm index ce1786a..34ef11b 100644 --- a/webdriver.scm +++ b/webdriver.scm @@ -2,6 +2,75 @@ (import r7rs) (define-library (webdriver) (import (scheme base)) - (export ) + (export + + new-WebDriver + terminate + initialize-session + terminate-session + set-url + url + back + forward + refresh + title + status + source + screenshot + print-page + execute-async + execute-sync + + set-timeouts + timeouts + + find-element + find-elements + attribute + property + clear + click + computed-label + computed-role + enabled? + selected? + name + rect + screenshot + text + set-value + &wd-exception + wd-exception? + wd-stacktrace + wd-data + &detached-shadow-root detached-shadow-root? + &element-click-intercepted element-click-intercepted? + &element-not-interactable element-not-interactable? + &insecure-certificate insecure-certificate? + &invalid-argument invalid-argument? + &invalid-cookie-domain invalid-cookie-domain? + &invalid-element-state invalid-element-state? + &invalid-selector invalid-selector? + &invalid-session-id invalid-session-id? + &javascript-error javascript-error? + &move-target-out-of-bounds move-target-out-of-bounds? + &no-such-alert no-such-alert? + &no-such-cookie no-such-cookie? + &no-such-element no-such-element? + &no-such-frame no-such-frame? + &no-such-shadow-root no-such-shadow-root? + &no-such-window no-such-window? + &script-timeout script-timeout? + &session-not-created session-not-created? + &stale-element-reference stale-element-reference? + &timeout timeout? + &unable-to-capture-screen unable-to-capture-screen? + &unable-to-set-cookie unable-to-set-cookie? + &unexpected-alert-open unexpected-alert-open? + &unknown-command unknown-command? + &unknown-error unknown-error? + &unknown-method unknown-method? + &unsupported-operation unsupported-operation? + ) (include "webdriver-impl.scm")) ;; Dependencies:3 ends here