Next: Introduction [Contents][Index]
CL Webdriver Client is client library for WebDriver.
WebDriver is a remote control interface that enables introspection and control of user agents. It provides a platform- and language-neutral wire protocol as a way for out-of-process programs to remotely instruct the behavior of web browsers.
Provided is a set of interfaces to discover and manipulate DOM elements in web documents and to control the behavior of a user agent. It is primarily intended to allow web authors to write tests that automate a user agent from a separate controlling process, but may also be used in such a way as to allow in-browser scripts to control a â possibly separate â browser.
See W3C Webdriver spec.
• Introduction | ||
• Usage | ||
• Installation | ||
• Utils | ||
• API | ||
• Index |
CL Webdriver Client is client library for WebDriver.
WebDriver is a remote control interface that enables introspection and control of user agents. It provides a platform- and language-neutral wire protocol as a way for out-of-process programs to remotely instruct the behavior of web browsers.
Provided is a set of interfaces to discover and manipulate DOM elements in web documents and to control the behavior of a user agent. It is primarily intended to allow web authors to write tests that automate a user agent from a separate controlling process, but may also be used in such a way as to allow in-browser scripts to control a â possibly separate â browser.
See W3C Webdriver spec.
Next: Installation, Previous: Introduction, Up: Top [Contents][Index]
• Sessions | ||
• Capabilities | ||
• Actions |
;; see examples/*.lisp and t/*.lisp (in-package :cl-user) (eval-when (:compile-toplevel :load-toplevel :execute) (ql:quickload :cl-webdriver-client)) (defpackage go-test (:use :cl :webdriver-client)) (in-package :go-test) (defparameter *code* " package main import \"fmt\" func main() { fmt.Print(\"Hello WebDriver!\") }") (with-session () (setf (url) "http://play.golang.org/?simple=1") (let ((elem (find-element "#code" :by :css-selector))) (element-clear elem) (element-send-keys elem *code*)) (let ((btn (find-element "#run"))) (element-click btn)) (loop with div = (find-element "#output") for ouput = (element-text div) while (equal ouput "Waiting for remote server...") do (sleep 0.1) finally (print ouput)))
Next: Capabilities, Up: Usage [Contents][Index]
A session is equivalent to a single instantiation of a particular user agent, including all its child browsers. WebDriver gives each session a unique session ID that can be used to differentiate one session from another, allowing multiple user agents to be controlled from a single HTTP server, and allowing sessions to be routed via a multiplexer (known as an intermediary node).
A WebDriver session represents the connection between a local end and a specific remote end.
A session is started when a New Session is invoked. It is an error to send any commands before starting a session, or to continue to send commands after the session has been closed. Maintaining session continuity between commands to the remote end requires passing a session ID.
A session is torn down at some later point; either explicitly by invoking Delete Session, or implicitly when Close Window is called at the last remaining top-level browsing context.
An intermediary node will maintain an associated session for each active session. This is the session on the upstream neighbor that is created when the intermediary node executes the New Session command. Closing a session on an intermediary node will also close the session of the associated session.
All commands, except New Session and Status, have an associated current session, which is the session in which that command will run.
Use START-INTERACTIVE-SESSION function to start an interactive session, and WITH-SESSION macro to evaluate WebDriver code in the context of a session.
WebDriver capabilities are used to communicate the features supported by a session. A client may also use capabilities to define which features it requires the driver to satisfy when creating a new session.
When a WebDriver session is created it returns a set of capabilities describing the negotiated, effective capabilities of the session. Some of the capabilities included in this set are standard and shared between all browsers, but the set may also contain browser-specific capabilities and these are always prefixed. Capabilities negotiation
Capabilities can be used to require a driver that supports a certain subset of features. This can be used to require certain browser features, such as the ability to resize the window dimensions, but is also used in distributed environments to select a particular browser configuration from a matrix of choices.
Selecting a particular web browser or platform only makes sense when you use a remote WebDriver. In this case the client makes contact with WebDriver through one or more intermediary nodes which negotiates which driver to return to you based on the capabilities it receives.
The capabilities object is a selection mechanism that limits which driver configurations the server will return. If you request a Firefox instance using browserName and Firefox is not installed on the remote, or macOS from a remote that only supports Linux, you may be out of luck. But occasionally you may not care which specific operating system or web browser your session has: you just want a session that has some capability.
The selection process, or the capabilities negotiation, is done through alwaysMatch and firstMatch.
In CL-WEBDRIVER-CLIENT capabilities are created using MAKE-CAPABILITIES. The key argument :always-match should be the ’alwaysMatch’ capabilities as an association list. The key argument :first-match are the ’firstMatch’ capabilities, a list of association lists.
Also, capabilities are constructed from arguments in MAKE-SESSION and WITH-SESSION.
• alwaysMatch | ||
• firstMatch | ||
• Combining alwaysMatch and firstMatch | ||
• List of capabilities | ||
• Vendor-specific capabilities |
Next: firstMatch, Up: Capabilities [Contents][Index]
As the name suggests, capabilities described inside the alwaysMatch capabilities object are features you require the session to have. If the server can not provide what features you require, it will fail.
If for example you ask for Firefox version 62 on a system that only has 60 installed, the session creation will fail:
(make-capabilities
:always-match '((:browser-name . "firefox")
(:browser-version . "60")))
or:
(with-session '(:always-match ((:browser-name . "firefox")
(:browser-version . "60")))
... )
Next: Combining alwaysMatch and firstMatch, Previous: alwaysMatch, Up: Capabilities [Contents][Index]
The firstMatch field accepts an array of capabilities objects which will be matched in turn until one matches what the server can provide, or it will fail.
This can be useful when you want a driver that runs on macOS or Linux, but not Windows:
(make-capabilities
:first-match (list
'((:platform-name . "macos"))
'((:platform-name . "linux"))))
Next: List of capabilities, Previous: firstMatch, Up: Capabilities [Contents][Index]
firstMatch can of course be combined with alwaysMatch to narrow down the selection. If for example you a driver that runs on macOS or Linux but it has to be Firefox:
(make-capabilities
:always-match '((:browser-name . "firefox"))
:first-match (list
'((:platform-name . "macos"))
'((:platform-name . "linux"))))
The previous example is exactly equivalent to putting the Firefox requirement in each firstMatch arm:
(make-capabilities
:first-match (list
'((:browser-name . "firefox") (:platform-name . "macos"))
'((:browser-name . "firefox") (:platform-name . "linux"))))
Which you choose of the two preceding examples is not important, but it can matter when pass along browser configuration. To avoid unnecessarily repeating data, such as profiles, it is advisable to make use of alwaysMatch so that this data is only transmitted across the wire once:
(make-capabilities
:always-match `((:browser-name . "firefox")
,(firefox-capabilities
:profile "<base64 encoded profile>"
:args #("--headless")
:prefs '(("dom.ipc.processCount" . 8))
:log '((:level . "trace"))))
:first-match (list
'((:platform-name . "macos"))
'((:platform-name . "linux"))))
Next: Vendor-specific capabilities, Previous: Combining alwaysMatch and firstMatch, Up: Capabilities [Contents][Index]
Reference: https://www.w3.org/TR/webdriver1/#capabilities.
Previous: List of capabilities, Up: Capabilities [Contents][Index]
In addition to the standard capabilities WebDriver allows third-parties to extend the set of capabilities to match their needs. Browser vendors and suppliers of drivers typically use extension capabilities to provide configuration to the browser, but they can also be used by intermediaries for arbitrary blobs of information.
You can use CHROME-CAPABILITIES and FIREFOX-CAPABILITIES for these.
Previous: Capabilities, Up: Usage [Contents][Index]
The Actions API provides a low-level interface for providing virtualised device input to the web browser. Conceptually, the Actions commands divide time into a series of ticks. The local end sends a series of actions which correspond to the change in state, if any, of each input device during each tick. For example, pressing a key is represented by an action sequence consisting of a single key input device and two ticks, the first containing a keyDown action, and the second a keyUp action, whereas a pinch-zoom input is represented by an action sequence consisting of three ticks and two pointer input devices of type touch, each performing a sequence of actions pointerDown, followed by pointerMove, and then pointerUp.
See https://www.w3.org/TR/webdriver/#actions for the whole explanation.
To perform actions in cl-webdriver-client use PERFORM-ACTIONS. That function implements a little language, with the following syntax:
actions ::= ({actions-input-source}*) actions-input-source ::= (input-source-type {action}*) input-source-type ::= :none | :pointer | :mouse | :pen | :touch | :key action ::= pause | pointer-move | pointer-down | pointer-up | key-down | key-up pause ::= (:pause duration) pointer-move ::= (:pointer-move x y) pointer-down ::= (:pointer-down button-number) pointer-up ::= (:pointer-up button-number) key-down ::= (:key-down key) key-up ::= (:key-up key)
(perform-actions `((:pen
(:pointer-move 22 33)
(:pause 2000)
(:pointer-move 23 54))))
git clone https://github.com/copyleft/cl-webdriver-client ~/quicklisp/local-projects/ (ql:quickload :cl-webdriver-client)
You need a running instance of selenium-server-standalone.
[Download](http://www.seleniumhq.org/download/) it and run:
curl -L0 https://goo.gl/SP94ZB -o selenium-server-standalone.jar java -jar selenium-server-standalone.jar
Next: API, Previous: Installation, Up: Top [Contents][Index]
There is a :webdriver-client-utils
package which should reduce boilerplate. For example:
(defpackage my-test (:use :cl :webdriver-client) (:import-from :webdriver-client-utils :send-keys :click :wait-for :classlist)) (in-package :my-test) (with-session () (setf (url) "http://google.com") (send-keys "cl-webdriver-client") (click "[name=btnK]") (wait-for "#resultStats"))
• Interactive session | ||
• Utils API conventions | ||
• Waiting for the reaction | ||
• Running tests |
Next: Utils API conventions, Up: Utils [Contents][Index]
You can just start the session and control it from your repl:
(in-package :my-test) (start-interactive-session) (setf (url) "http://google.com") (send-keys "cl-webdriver-client") (send-keys (key :enter)) (classlist "#slim_appbar") ; prints ("ab_tnav_wrp") (stop-interactive-session)
Next: Waiting for the reaction, Previous: Interactive session, Up: Utils [Contents][Index]
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 webdriver-client-utils:*default-element-func* (lambda () (find-element "input[type=submit]"))
Next: Running tests, Previous: Utils API conventions, Up: Utils [Contents][Index]
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 webdriver-client-utils:*timeout* 3)
Previous: Waiting for the reaction, Up: Utils [Contents][Index]
(ql:quickload '(:cl-selenium :prove)) (setf prove:*enable-colors* nil) (prove:run :cl-webdriver-client-test)
sh ./test.sh
• WEBDRIVER-CLIENT package | ||
• WEBDRIVER-CLIENT-UTILS package |
Next: WEBDRIVER-CLIENT-UTILS package, Up: API [Contents][Index]
This package exports functions for working with Selenium WebDriver.
For documentation see:
- https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol
- https://www.w3.org/TR/webdriver1
Returns the window handle associated with the current top-level browsing context.
See: https://www.w3.org/TR/webdriver1/#get-window-handle
Category: Contexts
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.
Category: Contexts
See: https://www.w3.org/TR/webdriver1/#switch-to-frame
Returns the window handles associated with ech top-level browsing context.
See: https://www.w3.org/TR/webdriver1/#get-window-handles
Category: Contexts
Switching window will select the current top-level browsing context used as the target for all subsequent commands. In a tabbed browser, this will typically make the tab containing the browsing context the selected tab.
WINDOW-HANDLE is the handle of the window obtained via GET-WINDOW-HANDLE.
See: https://www.w3.org/TR/webdriver1/#switch-to-window
Category: Contexts
Close the current window.
See: https://www.w3.org/TR/webdriver1/#close-window
Category: Contexts
Create a new top-level browsing context.
Category: Contexts
See: https://w3c.github.io/webdriver/#new-window
The Dismiss Alert command dismisses a simple dialog if present. A request to dismiss an alert user prompt, which may not necessarily have a dismiss button, has the same effect as accepting it.
Category: User prompts
See: https://www.w3.org/TR/webdriver1/#dismiss-alert
Accept Alert.
Category: User prompts
See: https://www.w3.org/TR/webdriver1/#dfn-accept-alert
Get Alert Text.
Category: User prompts
See: https://www.w3.org/TR/webdriver1/#get-alert-text
The Get Element Rect command returns the dimensions and coordinates of the given web element. The returned value is a dictionary with the following members:
x
X axis position of the top-left corner of the web element relative to the current browsing contextâs document element in CSS pixels.
y
Y axis position of the top-left corner of the web element relative to the current browsing contextâs document element in CSS pixels.
height
Height of the web elementâs bounding rectangle in CSS pixels.
width
Width of the web elementâs bounding rectangle in CSS pixels.
Category: Elements
Returns if ELEMENT is enabled.
Category: Elements
See: https://www.w3.org/TR/webdriver1/#is-element-enabled .
Return the ELEMENT’s attribute named NAME.
Category: Elements
Returns if ELEMENT is visible.
Category: Elements
See: https://www.w3.org/TR/webdriver1/#element-displayedness .
Return the ELEMENT’s tag name.
Category: Elements
Find elements that match VALUE using location strategy in BY.
Category: Elements
See FIND-ELEMENT.
See https://www.w3.org/TR/webdriver1/#find-elements .
The Get Element Text command intends to return an elementâs text âas renderedâ. An elementâs rendered text is also used for locating a elements by their link text and partial link text.
Category: Elements
See: https://www.w3.org/TR/webdriver1/#get-element-text .
The Find Element command is used to find an element in the current browsing context that can be used as the web element context for future element-centric commands.
For example, consider this pseudo code which retrieves an element with the #toremove ID and uses this as the argument for a script it injects to remove it from the HTML document:
let body ‘=’ session.find.css("#toremove");
session.execute("arguments[0].remove()", [body]);
The BY parameter represents the element location strategy.
It can be one of:
- :id : Finds element by id.
- :class-name : Finds element by class name.
- :css-selector : Returns element that matches css selector.
- :link-text : Returns element that matches <a> element text.
- :partial-link-text: Returns element that matches <a> element text partially.
- :tag-name: Returns element that matches tag name.
- :xpath: Returns element that matches the XPath expression.
If result is empty, a ‘HANDLE-FIND-ERROR’ is signaled.
Category: Elements
See: https://www.w3.org/TR/webdriver1/#dfn-find-element .
Return the active element of the current browsing contextâs document.
The active element is the Element within the DOM that currently has focus.
If there’s no active element, an error is signaled.
Category: Elements
See: https://www.w3.org/TR/webdriver2/#get-active-element.
See: https://developer.mozilla.org/en-US/docs/Web/API/Document/activeElement.
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.
Category: Document handling
See: https://www.w3.org/TR/webdriver1/#executing-script .
Clear the contents of ELEMENT (for example, a form field element).
Category: Element interaction
See: https://www.w3.org/TR/webdriver1/#dfn-element-clear.
The Element Click command scrolls into view the element if it is not already pointer-interactable, and clicks its in-view center point.
If the elementâs center point is obscured by another element, an element click intercepted error is returned. If the element is outside the viewport, an element not interactable error is returned.
Category: Element interaction
See: https://www.w3.org/TR/webdriver1/#element-click .
The Element Send Keys command scrolls into view the form control element and then sends the provided keys to the element. In case the element is not keyboard-interactable, an element not interactable error is returned.
KEYS should be a string or a list of characters or control character keywords.
For example:
(element-send-keys el (list :control #t))
See KEY and KEYS functions.
Category: Element interaction
See: https://www.w3.org/TR/webdriver1/#element-send-keys .
The Actions API provides a low-level interface for providing virtualised device input to the web browser.
Conceptually, the Actions commands divide time into a series of ticks. The local end sends a series of actions which correspond to the change in state, if any, of each input device during each tick. For example, pressing a key is represented by an action sequence consisting of a single key input device and two ticks, the first containing a keyDown action, and the second a keyUp action, whereas a pinch-zoom input is represented by an action sequence consisting of three ticks and two pointer input devices of type touch, each performing a sequence of actions pointerDown, followed by pointerMove, and then pointerUp.
Category: Actions
See: https://www.w3.org/TR/webdriver/#actions
Returns a string with characters and control keyword charcters in KEYS list.
Example:
(keys :control #t)
Category: Actions
See: https://www.w3.org/TR/webdriver/#keyboard-actions
Returns a string with KEY’s codepoint.
Category: Actions
See: https://www.w3.org/TR/webdriver/#keyboard-actions
Get the current url in session.
Category: Navigation
See: https://www.w3.org/TR/webdriver1/#dfn-get-current-url .
Refresh the current page.
Category: Navigation
Returns a string serialization of the DOM of the current browsing context active document.
Category: Navigation
See: https://www.w3.org/TR/webdriver1/#get-page-source
This command returns the document title of the current top-level browsing context, equivalent to calling document.title.
Category: Navigation
See: https://www.w3.org/TR/webdriver2/#get-title .
This command causes the browser to traverse one step backward in the joint session history of the current top-level browsing context. This is equivalent to pressing the back button in the browser chrome or invoking window.history.back.
Category: Navigation
See: https://www.w3.org/TR/webdriver1/#dfn-back .
A cookie is described in [RFC6265] by a name-value pair holding the cookieâs data, followed by zero or more attribute-value pairs describing its characteristics.
Category: Cookies
Class precedence list: cookie, standard-object, t
Slots:
name
— initarg: :name
The name of the cookie
value
— initarg: :value
The cookie value
path
— initarg: :path
The cookie path. Defaults to ’/’ if omitted when adding a cookie.
domain
— initarg: :domain
The domain the cookie is visible to. Defaults to the current browsing contextâs active documentâs URL domain if omitted when adding a cookie.
secure
— initarg: :secure
Whether the cookie is a secure cookie. Defaults to false if omitted when adding a cookie.
http-only
— initarg: :http-only
Whether the cookie is an HTTP only cookie. Defaults to false if omitted when adding a cookie.
expiry
— initarg: :expiry
When the cookie expires, specified in seconds since Unix Epoch. Must not be set if omitted when adding a cookie.
Retrieve all cookies visible to the current page.
Category: Cookies
See: https://www.w3.org/TR/webdriver1/#get-all-cookies .
See: https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol#sessionsessionidcookie .
Deletes all cookies
Category: Cookies
See: https://www.w3.org/TR/webdriver1/#delete-all-cookies
Create a cookie object.
Category: Cookies
Retrieve the cookie with name COOKIE-NAME.
Category: Cookies
See: https://www.w3.org/TR/webdriver1/#get-named-cookie
Delete the cookie with name COOKIE-NAME.
Category: Cookies
See: https://www.w3.org/TR/webdriver1/#delete-cookie
Creates a new WebDriver session with the endpoint node. If the creation fails, a session not created error is returned.
CAPABILITIES are the capabilities to negotate for the new session. If it is NIL, then *DEFAULT-CAPABILITIES* are used. If it is a list, then it is use as parameters for MAKE-CAPABILITIES to build a new CAPABILITIES object. Otherwise, it is assumed to be a CAPABILITIES object.
Category: Session
See: https://www.w3.org/TR/webdriver1/#new-session .
See: https://www.w3.org/TR/webdriver1/#capabilities .
Make SESSION the current session.
Category: Session
Start an interactive session. Use this to interact with Selenium driver from a REPL.
Category: Session
See: MAKE-SESSION
Stop an interactive session.
Sometimes ‘*SESSION*’ could be out of sync with Webdriver instance. In that case we may want to ignore errors when trying to delete the session. IGNORE-ERRORS argument controls that.
Category: Session
Starts a new session, and evaluates BODY in the context of that session.
The session is deleted when finished.
Category: Session
See: MAKE-SESSION
Delete the WebDriver SESSION.
Category: Session
Specify capabilities for Firefox browser.
Example usage:
(firefox-capabilities :args #("–headless"))
Category: Capabilities
See: https://developer.mozilla.org/en-US/docs/Web/WebDriver/Capabilities/firefoxOptions
The default capabilities.
Category: Capabilities
Specifies Chrome specific capabilities.
Category: Capabilities
https://chromedriver.chromium.org/capabilities#h.p_ID_102
Merge two capabilities
Category: Capabilities
The Take Element Screenshot command takes a screenshot of the visible region encompassed by the bounding rectangle of an element. If given a parameter argument scroll that evaluates to false, the element will not be scrolled into view.
Category: Screen capture
See: https://www.w3.org/TR/webdriver1/#take-element-screenshot .
Screenshots are a mechanism for providing additional visual diagnostic information. They work by dumping a snapshot of the initial viewportâs framebuffer as a lossless PNG image. It is returned to the local end as a Base64 encoded string.
Category: Screen capture
See: https://www.w3.org/TR/webdriver2/#screen-capture .
Return the logs of a particular TYPE.
See: LOG-TYPES.
Move the mouse by an offset of the specificed element. If no element is specified, the move is relative to the current mouse cursor. If an element is provided but no offset, the mouse will be moved to the center of the element. If the element is not visible, it will be scrolled into view.
See: https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol#sessionsessionidmoveto
Error signaled when no such element is found.
Class precedence list: no-such-element-error, find-error, error, serious-condition, condition, t
Click any mouse button (at the coordinates set by the last moveto command). Note that calling this command after calling buttondown and before calling button up (or any out-of-order interactions sequence) will yield undefined behaviour).
See: https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol#sessionsessionidclick
Get WebDriver status information
Return the types of logs supported by the WebDriver.
- browser: Javascript console logs from the browser.
- client: Logs from the client side implementation of the WebDriver protocol (e.g. the Java bindings).
- driver: Logs from the internals of the driver (e.g. FirefoxDriver internals).
- performance: Logs relating to the performance characteristics of the page under test (e.g. resource load timings).
- server: Logs from within the selenium server.
See: https://github.com/SeleniumHQ/selenium/wiki/Logging .
Previous: WEBDRIVER-CLIENT package, Up: API [Contents][Index]
Package with the purpose of reducing boilerplate.
The exported definitions work with an implicit element. The default implicit element is the current active element. So, it is not neccesary to pass the element you are working with around most of the time.
Default timeout value to use in selenium-utils functions.
Function used to get the ’default element’ by selenium-utils functions.
It is ACTIVE-ELEMENT function by default.
Get active element id.
Get value of COOKIE at NAME.
Find element by SELECTOR. Returns NIL if the element is not found.
Wait for an element that matches SELECTOR to appear on the screen.
TIMEOUT indicates how much time to wait (default is *TIMEOUT*).
Get active element classname.
Get active element’s text.
Send a key to active element.
Get active element class list.
Get acttive element attribute.
Send keys to active element.
If SELECTOR is given, wait for an element that matches the selector to appear.
Otherwise, call *DEFAULT-ELEMENT-FUNC* (the active element is returned by default).
Click on active element.
Jump to: | C |
---|
Index Entry | Section | ||
---|---|---|---|
| |||
C | |||
cl-webdriver-client: | Top | ||
cl-webdriver-client: | Top | ||
|
Jump to: | C |
---|
Jump to: | *
W |
---|
Jump to: | *
W |
---|
Jump to: | A B C D E F G I K L M N P R S T U W |
---|
Jump to: | A B C D E F G I K L M N P R S T U W |
---|