Witam
cześć
siemka
uh, fajnie chociaż raz znaleźć polską aktywną grupę 😛
Próbuję napisać test dla componenta w Reagencie, ktoś wie jak sprawdzić funkcję :on-click
? Testy odpalamy z phantomjs, tam nie ma click()
więc próbuję użyć jQuery, ale ten nie odpala :on-click
'a w ogóle
nie jestem na bieżąco, ale powinieneś być w stanie wywołać (.onClick component)
zdarzenia w React są syntetyczne, nie są to typowe handlery w DOM
Jasne, robię to w mniej wiecej w sposób pożyczony z samego reagenta: https://github.com/reagent-project/reagent/blob/master/test/reagenttest/testreagent.cljs
Po wywołaniu with-mounted-component
mam dostęp do obiektu DOM js i na tym wołam jQuery.trigger('click')
. Ta sama funkcja jQuery działa oczywiście poprawnie w przeglądarce, a w phantomjs z jakiegoś powodu nic się nie dzieje
Tak zeby było jasniej, jeden prosty test (klik on <tr>
zaznacza checkbox'a gdzies w tym rzędzie:
(deftest service-component-test
(when browser?
(let [acme-service (->> acme-tenant :services rand-nth)
get-first-row (fn [div] (.querySelector div "tr:nth-child(2)"))
checkbox-checked? (fn [row] (.-checked (.querySelector row "td input")))
service-component (p/service-component acme-service p/toggle-row)]
(with-mounted-component service-component
(fn [c div]
(let [first-row (get-first-row div)]
(testing "Unchecked checkbox"
(is (not (checkbox-checked? first-row))))
(.trigger (js/jQuery first-row) "click")
(testing "Checked checkbox"
(is (checkbox-checked? first-row)))))))))
Nie mówię, że moje podejście do sprawy jest dobre oczyiście, ale już brakowalo mi pomysłów
bardziej jestem zdziwiony że trigger na click ci zadziałał... może czegoś nie wiem
Czemu miałby nie działać?
bo tam nie prawdziwego event listenera. Jest jeden event listener który zbiera wszystkie zdarzenia od "korzenia" i na podstawie przekazanego identyfikatora komponentu podejmuje akcję
no jasne, ale klikniecie jQuery odpala dokładnie to samo chyba co klikniecie myszką
w sensie, wszystkie dane zostają nadal przekazane
no ale sprawdzę dla pewności jeszcze raz, że napewno działa
no działa bez problemu
heh, no to widocznie moja wiedza zardzewiała :simple_smile: sorry, może ktoś bardziej obeznany się wypowie w tej kwestii. może spróbuj na #C0620C0C8, kanał jest dosyć aktywny
Będę próbował, dzięki!
dobra, już chyba wiem dlaczego to działa :simple_smile: , zdarzenia wywołane jQuery.trigger bąbelkują od 1.3 http://api.jquery.com/trigger/
Był czas kiedy nie bubble'owały? TIL
"As of jQuery 1.3, .trigger()ed events bubble up the DOM tree"
Tak, przeczytałem ten fragment, bardziej chodziło mi o to, że po prostu nie pamiętałem żeby tak nie było i mnie to trochę zdziwiło ; d
Może za młody jestem po prostu xD
:simple_smile:
@smogg: sprawdzałeś czy querySelector zwraca coś w phantomie?
Wydaje mi sie ze zwraca wszystko dobrze... Tutaj prosty przyklad:
(deftest click-test
(when browser?
(let [component (fn [] [:div {:class "someclass"
:on-click #(println "something")}])]
(with-mounted-component (component)
(fn [c div]
(let [d (.querySelector div ".someclass")]
;; :on-click println never fires
(.trigger (js/jQuery d) "click")))))))
Natomiast to działa:
(deftest click-checkbox-test
(when browser?
(let [component (fn [] [:input {:type :checkbox
:class "someclass"
:on-click #(println "something")}])]
(with-mounted-component (component)
(fn [c div]
(let [d (.querySelector div "input")]
;; :on-click is fired
(.trigger (js/jQuery d) "click")))))))
jesteś pewien, że w pierwszym przypadku nie dostajesz nulla?
w sensie czy d
jest puste?
Nie, napewno nie
wydaje mi sie, ze moze chodzic o niesynchroniczna funkcje
moze po prostu chwila mija od wywolania trigger()
do reakcji, a sprawdzam od razu
tylko nie wiem jak poczekac... Nie wiem czy sie da jakos to zrobic moze z core.async
?
probowalem js setTimeout
ale bez efektów
faktycznie, może tak być
osobiście postawiłbym na maksymalnie prosty handler który wywołuje jakąś zewnętrzną funkcję, którą można z ręki wyzwolić. wtedy w teście po odpaleniu funkcji, która modyfikuje stan renderujesz komponent i sprawdzasz
wtedy masz z bani zabawę z asynchronicznymi zdarzeniami. oczywiście nie zawsze się tak da
no ta funkcja jest sprawdzana swoją drogą, ale tutaj potrzebuje potwierdzić, że DOM reaguje tak jak trzeba na click'a
no i ogólnie ta wiedza wydaje mi się przydatna, więc chętnie się pomęczę z tym problemem jeszcze chwile
jak się nie uda, to będę kombinował
hm
chociaż jednak może nie; bo chciałem powiedzieć, że println
zwraca nil
a to oznacza zatrzymanie propagacji, ale to i tak się powinno wypisać
no na <input>
działa bez problemu, więc...
A co do testowania rzeczy asynchronicznych to jest to - https://github.com/clojure/clojurescript/wiki/Testing#async-testing (bazowane na tym - https://github.com/cemerick/clojurescript.test#asynchronous-testing)
Ale nie używałem więc nie wiem na ile pomoże
ok, sprawdzę, dzięki
Może też Cię zainteresować to
Oficjalne utilsy do testowania Reacta
Mają symulację klikania np.
o, to może być to!
Ehh, nadal dupa nawet z TestUtils
😛
parafrazując, lepiej mieć stosunek z jeżem, niż zajmować się webdevem 😆
😄