Here is the test code I started to write couple of months ago which did not work: I could not manage to trigger onChange event. Is it really not triggerable programatically?
(ns capital-match.users-test
(:require-macros [cemerick.cljs.test
:refer (is deftest with-test run-tests testing test-var done)]
[cljs.core.async.macros :refer [go]]
[dommy.macros :refer [node sel sel1]])
(:require [cemerick.cljs.test :as t]
[capital-match.user.registration :as u]
[om.core :as om :include-macros true]
[om.dom :as dom :include-macros true]
[cljs.core.async :refer [chan <! >! pub sub]]
[dommy.utils :as utils]
[dommy.core :as dommy]))
(defn simulate-click-event
[el]
(let [document (.-document js/window)]
(cond
(.-click el) (.click el)
(.-createEvent document) (let [e (.createEvent document "MouseEvents")]
(.initMouseEvent e "click" true true
js/window 0 0 0 0 0
false false false false 0 nil)
(.dispatchEvent el e))
:default (throw "Unable to simulate click event"))))
(defn simulate-change-event
[el]
(let [document (.-document js/window)]
(cond
(.-onChange el) (do (print "firing on change on " el) (.onChange el))
(.-createEvent document) (let [e (.createEvent document "HTMLEvents")]
(print "firing " e " on change on " (.-id el))
(.initEvent e "change" true true)
(.dispatchEvent el e))
:default (throw "Unable to simulate change event"))))
(def sink
"contains a channel that receives messages along with notification type"
(chan))
(def source
(pub sink #(:topic %)))
(defn change-field!
[id value]
(let [el (sel1 (keyword (str "#" id)))]
(dommy/set-value! el value)
(simulate-change-event el)
))
(deftest ^:async password-confirmation
(testing "do not submit if passwords are not equal"
(let [subscription (chan)]
(sub source :user-registration subscription)
(om/root
(partial u/registration-view source sink)
nil
{:target (sel1 :#view)})
(go
(let [m (<! subscription)]
(is (= :error (:state m)))
(done)
))
(change-field! "userRequestedPassword" "secret")
(change-field! "confirmPassword" "nosecret")
(simulate-click-event (sel1 :#submitRegistration))
)))
The component is mounted on a dedicated DOM node which is part of the test HTML.
I would like to be able to test this without a browser, e.g. using something like phantomjs, in order to run all tests as part of build of the system the UI is part of. We currently have setup ETE testing using selenium w/in docker components so it would not be a big deal to use that to run "unit" tests too but these kind of tests are slow and selenium is somewhat brittle (although it too has improved and seems a lot more stable now than it was couple of years ago...).
Do you have an example test available that I could get inspiration from? I am not using reagent but I guess it should be possible to use React testutils with Om, I simply don't seem to understand how to do this...