Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Move protocols to top, functions beneath

  • Loading branch information...
commit 8b345ed1347d4d91520275a850d02bb050008b4a 1 parent c41b68b
@semperos semperos authored
Showing with 73 additions and 68 deletions.
  1. +73 −68 src/clj_webdriver/core.clj
View
141 src/clj_webdriver/core.clj
@@ -30,38 +30,9 @@
[java.util Date]
[java.io File]))
+;; ## Protocols for clj-webdriver API ##
-;; ## Driver Management ##
-(def webdriver-drivers
- {:firefox FirefoxDriver
- :ie InternetExplorerDriver
- :chrome ChromeDriver
- :htmlunit HtmlUnitDriver})
-
-(defn new-webdriver*
- "Return a Selenium-WebDriver WebDriver instance, optionally configured to leverage a custom FirefoxProfile."
- ([browser-spec]
- (let [{:keys [browser profile] :or {browser :firefox
- profile nil}} browser-spec]
- (if-not profile
- (.newInstance (webdriver-drivers (keyword browser)))
- (FirefoxDriver. profile)))))
-
-(defn new-driver
- "Start a new Driver instance. The `browser-spec` can include `:browser`, `:profile`, and `:cache-spec` keys.
-
- The `:browser` can be one of `:firefox`, `:ie`, `:chrome` or `:htmlunit`.
- The `:profile` should be an instance of FirefoxProfile you wish to use.
- The `:cache-spec` can contain `:strategy`, `:args`, `:include` and/or `:exclude keys. See documentation on caching for more details."
- ([browser-spec]
- (let [{:keys [browser profile cache-spec] :or {browser :firefox
- profile nil
- cache-spec {}}} browser-spec]
- (init-driver {:webdriver (new-webdriver* {:browser browser
- :profile profile})
- :cache-spec cache-spec}))))
-
-;;; Protocols for API ;;;
+;; ### Driver/Browser Functions ###
(defprotocol IDriver
"Basics of driver handling"
(back [driver] "Go back to the previous page in \"browsing history\"")
@@ -76,41 +47,7 @@
(title [driver] "Retrieve the title of the current page as defined in the `head` tag")
(to [driver url] "Navigate to a particular URL. Arg `url` can be either String or java.net.URL. Equivalent to the `get` function, provided here for compatibility with WebDriver API."))
-;; (with-drivers) for spooling up multiple, probably not good idea, but...
-;; Borrowed from core Clojure
-(defmacro with-driver
- "bindings => [name init ...]
-
- Evaluates body in a try expression with names bound to the values
- of the inits, and a finally clause that calls (.close name) on each
- name in reverse order."
- [bindings & body]
- (assert-args
- (vector? bindings) "a vector for its binding"
- (even? (count bindings)) "an even number of forms in binding vector")
- (cond
- (= (count bindings) 0) `(do ~@body)
- (symbol? (bindings 0)) `(let ~(subvec bindings 0 2)
- (try
- (with-driver ~(subvec bindings 2) ~@body)
- (finally
- (quit ~(bindings 0)))))
- :else (throw (IllegalArgumentException.
- "with-driver only allows Symbols in bindings"))))
-
-;; alias for with-driver
-(defmacro with-browser
- "Alias for with-driver
-
- bindings => [name init ...]
-
- Evaluates body in a try expression with names bound to the values
- of the inits, and a finally clause that calls (.close name) on each
- name in reverse order."
- [& args]
- `(with-driver ~@args))
-
-;;; ## Windows and Frames ##
+;; ### Windows and Frames ###
(defprotocol ITargetLocator
"Functions that deal with browser windows and frames"
(window-handle [driver] "Get the only (or first) window handle, return as a WindowHandler record")
@@ -122,14 +59,15 @@
(switch-to-default [driver] "Switch focus to the first first frame of the page, or the main document if the page contains iframes")
(switch-to-active [driver] "Switch to element that currently has focus, or to the body if this cannot be detected"))
+;; ### Finding Elements on Page ###
(defprotocol IFind
"Functions used to locate elements on a given page"
(find-element [driver by] "Retrieve the element object of an element described by `by`")
(find-elements [driver by] "Retrieve a seq of element objects described by `by`")
(find-elements-by-regex-alone [driver tag attr-val] "Given an `attr-val` pair with a regex value, find the elements that match")
(find-elements-by-regex [driver tag attr-val])
- (find-windows [driver attr-val] "Given a browser `driver` and a map of attributes, return the WindowHandles that matche")
- (find-window [driver attr-val] "Given a browser `driver` and a map of attributes, return the WindowHandles that matche")
+ (find-windows [driver attr-val] "Given a browser `driver` and a map of attributes, return the WindowHandles that match")
+ (find-window [driver attr-val] "Given a browser `driver` and a map of attributes, return the WindowHandles that match")
(find-semantic-buttons [driver attr-val] "Find HTML element that is either a `<button>` or an `<input>` of type submit, reset, image or button")
(find-semantic-buttons-by-regex [driver attr-val] "Semantic buttons are things that look or behave like buttons but do not necessarily consist of a `<button>` tag")
(find-checkables-by-text [driver attr-val] "Finding the 'text' of a radio or checkbox is complex. Handle it here.")
@@ -139,6 +77,7 @@
(find-them [driver attr-val] "Find all elements that match the parameters supplied in the `attr-val` map. Also provides a shortcut to `find-by-hierarchy` if a vector is supplied instead of a map.")
(find-it [driver attr-val] "Call (first (find-them args))"))
+;; ### Acting on Elements ###
(defprotocol IElement
"Basic actions on elements"
(attribute [element attr] "Retrieve the value of the attribute of the given element object")
@@ -159,6 +98,7 @@
(visible? [element] "Returns true if the given element object is visible/displayed")
(xpath [element] "Retrieve the XPath of an element"))
+;; ### Acting on Form-Specific Elements ###
(defprotocol IFormElement
"Actions for form elements"
(clear [element] "Clear the contents of the given element object")
@@ -171,6 +111,7 @@
(send-keys [element s] "Type the string of keys into the element object")
(toggle [element] "If the given element object is a checkbox, this will toggle its selected/unselected state. In Selenium 2, `.toggle()` was deprecated and replaced in usage by `.click()`."))
+;; ### Acting on Select Elements ###
(defprotocol ISelectElement
"Actions specific to select lists"
(all-options [select-element] "Retrieve all options from the given select list")
@@ -189,6 +130,37 @@
(select-by-value [select-element value] "Select all options with value `value` in the select list described by `by`"))
+;; ## Starting Driver/Browser ##
+(def ^{:doc "Map of keywords to available WebDriver classes."}
+ webdriver-drivers
+ {:firefox FirefoxDriver
+ :ie InternetExplorerDriver
+ :chrome ChromeDriver
+ :htmlunit HtmlUnitDriver})
+
+(defn new-webdriver*
+ "Return a Selenium-WebDriver WebDriver instance, optionally configured to leverage a custom FirefoxProfile."
+ ([browser-spec]
+ (let [{:keys [browser profile] :or {browser :firefox
+ profile nil}} browser-spec]
+ (if-not profile
+ (.newInstance (webdriver-drivers (keyword browser)))
+ (FirefoxDriver. profile)))))
+
+(defn new-driver
+ "Start a new Driver instance. The `browser-spec` can include `:browser`, `:profile`, and `:cache-spec` keys.
+
+ The `:browser` can be one of `:firefox`, `:ie`, `:chrome` or `:htmlunit`.
+ The `:profile` should be an instance of FirefoxProfile you wish to use.
+ The `:cache-spec` can contain `:strategy`, `:args`, `:include` and/or `:exclude keys. See documentation on caching for more details."
+ ([browser-spec]
+ (let [{:keys [browser profile cache-spec] :or {browser :firefox
+ profile nil
+ cache-spec {}}} browser-spec]
+ (init-driver {:webdriver (new-webdriver* {:browser browser
+ :profile profile})
+ :cache-spec cache-spec}))))
+
(defn start
"Shortcut to instantiate a driver, navigate to a URL, and return the driver for further use"
([browser-spec url]
@@ -196,6 +168,39 @@
(get-url driver url)
driver)))
+;; Borrowed from core Clojure
+(defmacro with-driver
+ "bindings => [name init ...]
+
+ Evaluates body in a try expression with names bound to the values
+ of the inits, and a finally clause that calls (.close name) on each
+ name in reverse order."
+ [bindings & body]
+ (assert-args
+ (vector? bindings) "a vector for its binding"
+ (even? (count bindings)) "an even number of forms in binding vector")
+ (cond
+ (= (count bindings) 0) `(do ~@body)
+ (symbol? (bindings 0)) `(let ~(subvec bindings 0 2)
+ (try
+ (with-driver ~(subvec bindings 2) ~@body)
+ (finally
+ (quit ~(bindings 0)))))
+ :else (throw (IllegalArgumentException.
+ "with-driver only allows Symbols in bindings"))))
+
+;; alias for with-driver
+(defmacro with-browser
+ "Alias for with-driver
+
+ bindings => [name init ...]
+
+ Evaluates body in a try expression with names bound to the values
+ of the inits, and a finally clause that calls (.close name) on each
+ name in reverse order."
+ [& args]
+ `(with-driver ~@args))
+
;; TODO: verify these functions' necessity
(defn window-handle*
"For WebDriver API compatibility: this simply wraps `.getWindowHandle`"
Please sign in to comment.
Something went wrong with that request. Please try again.