From a2ec8861cd8b37ec13ab6b128c0de720ff3818bc Mon Sep 17 00:00:00 2001 From: Mariano Montone Date: Mon, 3 May 2021 19:06:59 -0300 Subject: [PATCH] Sessions documentation. --- src/errors.lisp | 3 ++- src/package.lisp | 7 ++++++- src/selenium.lisp | 20 ++++++++++++++++++++ src/session.lisp | 16 ++++++++++++---- 4 files changed, 40 insertions(+), 6 deletions(-) diff --git a/src/errors.lisp b/src/errors.lisp index 702fda8..043e286 100644 --- a/src/errors.lisp +++ b/src/errors.lisp @@ -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) () diff --git a/src/package.lisp b/src/package.lisp index 2dbb610..383e8b5 100644 --- a/src/package.lisp +++ b/src/package.lisp @@ -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) diff --git a/src/selenium.lisp b/src/selenium.lisp index 8be739a..c867745 100644 --- a/src/selenium.lisp +++ b/src/selenium.lisp @@ -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") diff --git a/src/session.lisp b/src/session.lisp index 7183bc1..7282eaf 100644 --- a/src/session.lisp +++ b/src/session.lisp @@ -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? @@ -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) @@ -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 @@ -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)))