add test project

This commit is contained in:
Gijs Stuurman 2012-07-09 16:57:47 +02:00
parent c01759f5f6
commit 6616d1d452
5 changed files with 151 additions and 0 deletions

11
test/.gitignore vendored Normal file
View file

@ -0,0 +1,11 @@
/target
/lib
/classes
/checkouts
pom.xml
*.jar
*.class
.lein-deps-sum
.lein-failures
.lein-plugins
notes

24
test/README.md Normal file
View file

@ -0,0 +1,24 @@
# test
Beginnings of a test suite for [clj-browserchannel][1]. Uses the
[clj-webdriver][2] Selenium wrapper to launch and interact with
browsers. Actors send messages through the demo chat application and
may introduce connection failures. The test checks whether all messages
were still received.
[1]:https://github.com/thegeez/clj-browserchannel
[2]:https://github.com/semperos/clj-webdriver/
## About
Written by:
Gijs Stuurman / [@thegeez][twt] / [Blog][blog] / [GitHub][github]
[twt]: http://twitter.com/thegeez
[blog]: http://thegeez.github.com
[github]: https://github.com/thegeez
### License
Copyright (c) 2012 Gijs Stuurman and released under an MIT license.

3
test/project.clj Normal file
View file

@ -0,0 +1,3 @@
(defproject test "0.0.1-SNAPSHOT"
:dependencies [[org.clojure/clojure "1.4.0"]
[clj-webdriver "0.6.0-alpha8"]])

67
test/src/test/actors.clj Normal file
View file

@ -0,0 +1,67 @@
(ns test.actors
(require [clj-webdriver.core :as w]
[clj-webdriver.wait :as wait]))
(defmulti web-action (fn [driver action]
(:type action)))
(defmethod web-action :default [& args] nil)
(defmethod web-action :say [driver {:keys [msg]}]
(w/input-text (w/find-element driver {:id "msg-input"}) msg)
(w/click (w/find-element driver {:id "send-button"})))
(defmethod web-action :kill-get [driver action]
(w/execute-script driver "try{ bc.core.channel.backChannelRequest_.xmlHttp_.xhr_.abort(); } catch (err) {return true;}; return true;" ))
(defmethod web-action :wait [driver {:keys [time]}]
;; uhm ja, want to use Thread/sleep but this is handled by the driver
(try (wait/wait-until driver (constantly false) time time)
(catch Exception e ;; should be TimeOutException
true)))
(defn play-actors [actors]
(let [agents (map (fn [act]
(-> act
(assoc :to-do (:actions act))
(assoc :driver (w/new-driver (select-keys [:browser] act)))
agent)) actors)
;; broken down clojure.core/await, because we can't know when
;; all the sends will be done as they are not all done in this thread
done-talking-latch (java.util.concurrent.CountDownLatch. (count actors))]
;; launch web-drivers
(doseq [ag agents]
(send ag (fn [{:keys [driver url] :as a}]
(w/to driver url)
a)))
;; can't use await here, the send are fired from separate threads
;;(apply await actors)
(println "All launched")
(doseq [ag agents]
(send ag (fn send-msg [a]
(let [{:keys [driver name to-do]} a]
(if-let [action (first to-do)]
(do
(web-action driver action)
(send *agent* send-msg))
(.countDown done-talking-latch)))
(update-in a [:to-do] rest)))
)
(.await done-talking-latch)
(println "All done talking")
(Thread/sleep 10000)
(doseq [ag agents]
(send ag (fn [a]
(let [{:keys [driver name]} a]
;;(w/execute-script driver "alert(\"LOLOLO\");")
(let [seen-msgs (doall (map w/text (w/find-elements driver [{:id "room"} {:tag :div}])))]
(assoc a :seen-msgs seen-msgs))))))
(apply await agents)
(Thread/sleep 10000)
(doseq [ag agents]
(send ag (fn [a]
(let [{:keys [driver name]} a]
(w/quit driver)))))
(println "All quit")
(doall (map #(dissoc (deref %) :to-do :driver) agents))))

46
test/src/test/core.clj Normal file
View file

@ -0,0 +1,46 @@
(ns test.core
(require [test.actors :as actors]))
(def url "http://localhost:8080/index-dev.html")
(defn -main [& args]
(let [mario {:name "MARIO"
:actions (for [i (range 10)]
{:type :say :msg (str "MARIO says Hello world! " i)})
:url url
:browser :firefox}
luigi {:name "LUIGI"
:actions (concat (interleave (for [i (range 5)]
{:type :say :msg (str "LUIGI says Hello world! " i)})
(repeat {:type :kill-get}))
[{:type :kill-get}]
[{:type :wait :time 30000}]
(interleave (for [i (range 5 10)]
{:type :say :msg (str "LUIGI says Hello world! " i)})
(repeat {:type :kill-get}))
)
:url url
:browser :firefox}
actors [mario luigi]
done-actors (actors/play-actors actors)]
(doseq [act1 done-actors
act2 done-actors
:when (not= act1 act2)]
;; check if every msgs for act1 sort of appears in what act2
;; recv and is in the correct order
(loop [act1-said (->> act1
:actions
(filter (comp #{:say} :type))
(map :msg))
act2-recv (:seen-msgs act2)]
(let [a1 (first act1-said)]
(if (nil? a1)
(println "All messages accounted for" (:name act1) " to " (:name act2))
(let [[match & others] (drop-while #(not (re-find (re-pattern a1) %)) act2-recv)]
(if match
(do #_(println "act1 said: " a1 " recv by act2 as: " match)
(recur (rest act1-said) others))
(println "Msg from act1 " (:name act1) " not recv by act2" (:name act2) a1)))))))))