Skip to content
Go to file
Cannot retrieve contributors at this time
139 lines (110 sloc) 3.11 KB

CL Selenium WebDriver

CL Selenium WebDriver is a binding library to the Selenium 2.0


This software is in development. The APIs will be likely to change.


;; see examples/*.lisp and t/*.lisp
(in-package :cl-user)

(eval-when (:compile-toplevel :load-toplevel :execute)
  (ql:quickload :cl-selenium))

(defpackage go-test
  (:use :cl :cl-selenium))

(in-package :go-test)

(defparameter *code* "
package main
import \"fmt\"

func main() {
    fmt.Print(\"Hello WebDriver!\")

(with-session ()
  (setf (url) "")
  (let ((elem (find-element "#code" :by :css-selector)))
    (element-clear elem)
    (element-send-keys elem *code*))
  (let ((btn (find-element "#run")))
    (element-click btn))

     with div = (find-element "#output")
     for ouput = (element-text div)
     while (equal ouput "Waiting for remote server...")
     do (sleep 0.1)
     finally (print ouput)))


git clone ~/quicklisp/local-projects/
(ql:quickload :cl-selenium)

You need a running instance of selenium-server-standalone.

Download it and run:

curl -L0 -o selenium-server-standalone.jar
java -jar selenium-server-standalone.jar


There is a :cl-selenium-utils package which should reduce boilerplate. For example:

(defpackage my-test
  (:use :cl :cl-selenium)
  (:import-from :cl-selenium-utils

(in-package :my-test)

(with-session ()
  (setf (url) "")
  (send-keys "cl-selenium-webdriver")
  (click "[name=btnK]")
  (wait-for "#resultStats"))

Interactive session

You can just start the session and control it from your repl:

(in-package :my-test)


(setf (url) "")
(send-keys "cl-selenium-webdriver")
(send-keys (key :enter))
(classlist "#slim_appbar") ; prints ("ab_tnav_wrp")


Utils API conventions

If utility function needs an element to work on it defaults to (active-element).

(click) ; click on the current active element.

You can also pass a css selector as a last parameter.

(print (id "#submit")) ; print id the of matched element

(assert (= (first (classlist "div")) "first-div-ever"))

To change default element you can:

(setf cl-selenium-utils:*default-element-func* (lambda () (find-element "input[type=submit]"))

Waiting for the reaction

Often you need to wait for some action to be done. For example if you do a (click) on the button to load search results, you need to wait them to load.

(wait-for ".search-result" :timeout 10) ; wait 10 seconds

Timeout defaults to 30 seconds. You can globally change it:

(setf cl-selenium-utils:*timeout* 3)

Running tests


(ql:quickload '(:cl-selenium :prove))
(setf prove:*enable-colors* nil)
(prove:run :cl-selenium-test)




Licensed under the MIT License.

You can’t perform that action at this time.