This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

Merge pull request #94 from semperos/assoc-exceptions

Improve handling of nils and exceptions when working with elements of the page
  • Loading branch information...
2 parents 8ba9424 + eac6fa2 commit a45d70c83ff585f7f94788e798c6b2e476c55ec5 @semperos committed Feb 11, 2013
View
@@ -1,4 +1,4 @@
-(defproject clj-webdriver "0.6.0-beta2"
+(defproject clj-webdriver "0.6.0-SNAPSHOT"
:description "Clojure API for Selenium-WebDriver"
:url "https://github.com/semperos/clj-webdriver"
:license {:name "Eclipse Public License"
View
@@ -30,9 +30,7 @@
[org.openqa.selenium.firefox FirefoxDriver]
[org.openqa.selenium.ie InternetExplorerDriver]
[org.openqa.selenium.chrome ChromeDriver]
- ;; [com.opera.core.systems OperaDriver]
[org.openqa.selenium.htmlunit HtmlUnitDriver]
- ;; [org.openqa.selenium.security UserAndPassword]
[org.openqa.selenium.support.ui Select]
[org.openqa.selenium.interactions Actions CompositeAction]
[java.util Date]
@@ -133,7 +131,7 @@
(deselect-all [select-element] "Deselect all options for a given select list. Does not leverage WebDriver method because WebDriver's isMultiple method is faulty.")
(deselect-by-index [select-element idx] "Deselect the option at index `idx` for the select list described by `by`. Indeces begin at 0")
(deselect-by-text [select-element text] "Deselect all options with visible text `text` for the select list described by `by`")
- (deselect-by-value [select-element value] "Deselect all options with value `value` for the select list described by `by`")
+ (deselect-by-value [select-element value] "Deselect all options with value `value` for the select list described by `by`")
(first-selected-option [select-element] "Retrieve the first selected option (or the only one for single-select lists) from the given select list")
(multiple? [select-element] "Return true if the given select list allows for multiple selections")
(select-option [select-element attr-val] "Select an option from a select list, either by `:value`, `:index` or `:text`")
@@ -200,6 +198,15 @@
:profile profile})
:cache-spec cache-spec}))))
+;; Chrome binary, common location of Chromium on Linux
+(comment
+ (do
+ (import 'org.openqa.selenium.remote.DesiredCapabilities)
+ (let [cap (DesiredCapabilities/chrome)]
+ (.setCapability cap "chrome.binary" "/usr/lib/chromium-browser/chromium-browser")
+ (init-driver (ChromeDriver. cap))))
+)
+
(defn start
"Shortcut to instantiate a driver, navigate to a URL, and return the driver for further use"
([browser-spec url]
@@ -298,7 +305,7 @@
Unless you need to wait to execute your composite actions, you should prefer `->actions` to this macro."
[driver & body]
- `(let [acts# (doto (:actions ~driver)
+ `(let [acts# (doto (:actions ~driver)
~@body)]
(.build acts#)))
@@ -27,12 +27,15 @@
(let [this-handle (window-handle* (:webdriver driver))
idx (.indexOf handles this-handle)]
(cond
- (zero? idx) (do ; if first window, switch to next
- (.close (:webdriver driver))
- (switch-to-window driver (nth handles (inc idx))))
- :else (do ; otherwise, switch back one window
- (.close (:webdriver driver))
- (switch-to-window driver (nth handles (dec idx)))))
+ (zero? idx)
+ (do ; if first window, switch to next
+ (.close (:webdriver driver))
+ (switch-to-window driver (nth handles (inc idx))))
+
+ :else
+ (do ; otherwise, switch back one window
+ (.close (:webdriver driver))
+ (switch-to-window driver (nth handles (dec idx)))))
(cache/seed driver {}))
(do
(.close (:webdriver driver))
@@ -125,19 +128,28 @@
(switch-to-window [driver window]
(cond
- (string? window) (do
- (.window (.switchTo (:webdriver driver)) window)
- driver)
- (win/window? window) (do
- (.window (.switchTo (:driver window)) (:handle window))
- driver)
- (number? window) (do
- (switch-to-window driver (nth (windows driver) window))
- driver)
- (nil? window) (throw (RuntimeException. "No window can be found"))
- :else (do
- (.window (.switchTo (:webdriver driver)) window)
- driver)))
+ (string? window)
+ (do
+ (.window (.switchTo (:webdriver driver)) window)
+ driver)
+
+ (win/window? window)
+ (do
+ (.window (.switchTo (:driver window)) (:handle window))
+ driver)
+
+ (number? window)
+ (do
+ (switch-to-window driver (nth (windows driver) window))
+ driver)
+
+ (nil? window)
+ (throw (RuntimeException. "No window can be found"))
+
+ :else
+ (do
+ (.window (.switchTo (:webdriver driver)) window)
+ driver)))
(switch-to-other-window [driver]
(if (not= (count (windows driver)) 2)
@@ -158,23 +170,23 @@
(add-cookie [driver cookie-spec]
(.addCookie (.manage (:webdriver driver)) (:cookie (init-cookie cookie-spec)))
driver)
-
+
(delete-cookie-named [driver cookie-name]
(.deleteCookieNamed (.manage (:webdriver driver)) cookie-name)
driver)
-
+
(delete-cookie [driver cookie-spec]
(.deleteCookie (.manage (:webdriver driver)) (:cookie (init-cookie cookie-spec)))
driver)
-
+
(delete-all-cookies [driver]
(.deleteAllCookies (.manage (:webdriver driver)))
driver)
-
+
(cookies [driver]
(set (map #(init-cookie {:cookie %})
(.getCookies (.manage (:webdriver driver))))))
-
+
(cookie-named [driver cookie-name]
(let [cookie-obj (.getCookieNamed (.manage (:webdriver driver)) cookie-name)]
(init-cookie {:cookie cookie-obj})))
@@ -186,7 +198,7 @@
(alert-obj [driver]
(-> driver :webdriver .switchTo .alert))
-
+
(alert-text [driver]
(-> driver :webdriver .switchTo .alert .getText))
@@ -196,7 +208,7 @@
(dismiss [driver]
(-> driver :webdriver .switchTo .alert .dismiss))
-
+
;; Find Functions
IFind
(find-element-by [driver by-value]
@@ -212,7 +224,7 @@
els (.findElements (:webdriver driver) by-value)]
(if (seq els)
(lazy-seq (map init-element els))
- (lazy-seq (map init-element [nil])))))
+ (lazy-seq nil))))
(find-windows [driver attr-val]
(if (contains? attr-val :index)
@@ -307,17 +319,27 @@
([driver element]
(let [act (:actions driver)]
(.perform (.doubleClick act (:webelement element))))))
-
+
(drag-and-drop
[driver element-a element-b]
- (let [act (:actions driver)]
- (.perform (.dragAndDrop act (:webelement element-a) (:webelement element-b)))))
+ (cond
+ (nil? element-a) (throw-nse "The first element does not exist.")
+ (nil? element-b) (throw-nse "The second element does not exist.")
+ :else (let [act (:actions driver)]
+ (.perform (.dragAndDrop act
+ (:webelement element-a)
+ (:webelement element-b))))))
(drag-and-drop-by
[driver element x-y-map]
- (let [act (:actions driver)
- {:keys [x y] :or {x 0 y 0}} x-y-map]
- (.perform (.dragAndDropBy act (:webelement element) x y))))
+ (if (nil? element)
+ (throw-nse)
+ (let [act (:actions driver)
+ {:keys [x y] :or {x 0 y 0}} x-y-map]
+ (.perform
+ (.dragAndDropBy act
+ (:webelement element)
+ x y)))))
(key-down
([driver k]
@@ -436,11 +458,18 @@
(cond
;; Accept by-clauses
(not (or (vector? attr-val)
- (map? attr-val))) (find-elements-by driver attr-val)
- ;; Accept vectors for hierarchical queries
- (vector? attr-val) (find-by-hierarchy driver attr-val)
- ;; Build XPath dynamically
- :else (find-elements-by driver (by-query (build-query attr-val))))
+ (map? attr-val)))
+ (find-elements-by driver attr-val)
+
+ ;; Accept vectors for hierarchical queries
+ (vector? attr-val)
+ (find-by-hierarchy driver attr-val)
+
+ ;; Build XPath dynamically
+ :else
+ (find-elements-by driver (by-query (build-query attr-val))))
(catch org.openqa.selenium.NoSuchElementException e
- ;; NoSuchElementException caught here, so we can have functions like `exist?`
- (lazy-seq [(init-element nil)])))))
+ ;; NoSuchElementException caught here to mimic Clojure behavior like
+ ;; (get {:foo "bar"} :baz) since the page can be thought of as a kind of associative
+ ;; data structure with unique selectors as keys and HTML elements as values
+ (lazy-seq nil)))))
Oops, something went wrong.

0 comments on commit a45d70c

Please sign in to comment.