Skip to content

Commit

Permalink
Sessions documentation.
Browse files Browse the repository at this point in the history
  • Loading branch information
mmontone committed May 3, 2021
1 parent bfa5a9a commit a2ec886
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 6 deletions.
3 changes: 2 additions & 1 deletion src/errors.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
()
(:report (lambda (condition stream)
(with-slots (value by) condition
(format stream "No such element: ~a (by ~a)" value by)))))
(format stream "No such element: ~a (by ~a)" value by))))
(:documentation "Error signaled when no such element is found."))

(define-condition stale-element-reference (find-error)
()
Expand Down
7 changes: 6 additions & 1 deletion src/package.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,12 @@
:no-such-element-error)
(:import-from :alexandria
:with-gensyms
:assoc-value))
:assoc-value)
(:documentation "This package exports functions for working with Selenium WebDriver.
For documentation see:
- https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol#sessionsessionidframe
- https://www.w3.org/TR/webdriver1."))

(defpackage cl-selenium-utils
(:use :cl :cl-selenium)
Expand Down
20 changes: 20 additions & 0 deletions src/selenium.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -210,19 +210,39 @@ See: https://www.w3.org/TR/webdriver2/#screen-capture."
(http-post-check (session-path session "/cookie") `(:cookie ,cookie)))

(defun cookie (&key (session *session*))
"Retrieve all cookies visible to the current page.
See: https://www.w3.org/TR/webdriver1/#get-all-cookies.
See: https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol#sessionsessionidcookie."
(http-get-value (session-path session "/cookie")))

(defun refresh (&key (session *session*))
"Refresh the current page."
(http-post (session-path session "/refresh")))

(defun switch-to-frame (id &key (session *session*))
"Change focus to another frame on the page. If the frame id is null, the server
should switch to the page's default content.
In the context of a web browser, a frame is a part of a web page or browser window which displays content independent of its container, with the ability to load content independently.
See: https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol#sessionsessionidframe.
See: https://en.wikipedia.org/wiki/Frame_(World_Wide_Web)."
(http-post-check (session-path session "/frame")
`(:id ,id)))

(defun close-current-window (&key (session *session*))
"Close the current window."
(http-delete (session-path session "/window")))

(defun execute-script (script args &key (session *session*))
"Inject a snippet of JavaScript into the page for execution in the context of the currently selected frame. The executed script is assumed to be synchronous and the result of evaluating the script is returned to the client.
The script argument defines the script to execute in the form of a function body. The value returned by that function will be returned to the client. The function will be invoked with the provided args array and the values may be accessed via the arguments object in the order specified.
Arguments may be any JSON-primitive, array, or JSON object. JSON objects that define a WebElement reference will be converted to the corresponding DOM element. Likewise, any WebElements in the script result will be returned to the client as WebElement JSON objects.
See: https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol#sessionsessionidexecute."
(check-type script string)
(check-type args list)
(http-post-value (session-path session "/execute")
Expand Down
16 changes: 12 additions & 4 deletions src/session.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@
(defclass session ()
((id :initarg :id
:initform (error "Must supply an id")
:reader session-id)))
:reader session-id))
(:documentation "A Selenium Webdriver session.
(defvar *session* nil)
The server should maintain one browser per session. Commands sent to a session will be directed to the corresponding browser."))

(defvar *session* nil "The current Selenium WebDriver session.")

(defun make-session (&key
(browser-name :chrome) ; TODO: autodetect?
Expand All @@ -14,6 +17,7 @@
platform-version
accept-ssl-certs
additional-capabilities)
"Creates a new WebDriver session with the endpoint node. If the creation fails, a session not created error is returned."
(let ((response (http-post "/session"
`(:session-id nil
:desired-capabilities ((browser-name . ,browser-name)
Expand All @@ -27,13 +31,15 @@
:id (assoc-value response :session-id))))

(defun delete-session (session)
"Delete the WebDriver SESSION."
(http-delete-check (session-path session "")))

;; TODO: make eldoc-friendly
(defun use-session(session)
(defun use-session (session)
"Make SESSION the current session."
(setf *session* session))

(defmacro with-session ((&rest capabilities) &body body)
"Execute BODY inside a Selenium session."
(with-gensyms (session)
`(let (,session)
(unwind-protect
Expand All @@ -45,11 +51,13 @@
(delete-session ,session))))))

(defun start-interactive-session (&rest capabilities)
"Start an interactive session. Use this to interact with Selenium driver from a REPL."
(when *session*
(delete-session *session*))
(setf *session* (apply #'make-session capabilities)))

(defun stop-interactive-session ()
"Stop an interactive session."
(when *session*
(delete-session *session*)
(setf *session* nil)))
Expand Down

0 comments on commit a2ec886

Please sign in to comment.