This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-09-27
Channels
- # beginners (54)
- # bitcoin (2)
- # boot (1)
- # calva (10)
- # cider (30)
- # cljs-dev (25)
- # cljsrn (17)
- # clojure (27)
- # clojure-dev (16)
- # clojure-estonia (3)
- # clojure-hk (1)
- # clojure-italy (8)
- # clojure-losangeles (1)
- # clojure-nl (17)
- # clojure-russia (1)
- # clojure-spec (15)
- # clojure-uk (45)
- # clojurebridge (1)
- # clojurescript (95)
- # clojurescript-ios (1)
- # core-async (5)
- # cursive (10)
- # datomic (8)
- # emacs (2)
- # figwheel-main (31)
- # fulcro (99)
- # hyperfiddle (3)
- # immutant (1)
- # jobs (13)
- # jobs-discuss (82)
- # keechma (6)
- # leiningen (3)
- # lumo (1)
- # nrepl (1)
- # off-topic (37)
- # onyx (1)
- # pedestal (6)
- # re-frame (7)
- # reitit (2)
- # remote-jobs (1)
- # ring-swagger (3)
- # rum (6)
- # shadow-cljs (14)
- # specter (4)
- # tools-deps (27)
- # yada (12)
@veddha.riady there is a mention in the docs (dom/style {:dangerouslySetInnerHTML {:__html (g/css (css/get-css component))}})
. Haven't tried, but should work across all dom
elements.
@veddha.riady you are pretty much always better off using :ref
and then setting the HTML manually
Hi, is there a way to check if any running ajax requests?
@kirill.salykin There is :ui/loading-data
http://book.fulcrologic.com/#_global_network_activity_marker , think currently this is only for df/load
thanks
is it possible to access this outside of the fuclro? I need to ensure that request done in integration testā¦
thanks!
is there recommended way to test UI interactions with fulcro?
w/o backend involved?
think this might be what you're looking for http://book.fulcrologic.com/#DevCards
i meant unit test
or the only way is to spin up browser and click everything with selenium?
ahh š haven't given it much thought. Maybe there is something helpfull in the fulcro tests https://github.com/fulcrologic/fulcro/tree/develop/src/test .
thanks, looking into this
seems for UI interactions I need to use a browser, https://github.com/fulcrologic/fulcro/tree/develop/src/test - seems are unit tests for fulcro logic
Or nodejs :) shadow-cljs makes it really easy to have node scripts & fulcro behaves like in the browser (including dl/load & remote mutations)
sounds interesting
Iāll dig into it
@kirill.salykin ui based tests are, in my experience, expensive, flaky, and not worth the effort. Bugs worth CI are in logic.
how do you recommend to test validation logic for instance
Write and test the logic. Your Ui has hookup points. Manually check the hooks, and call it good.
thanks
Ask yourself: is it really worth the time you're putting into the test? Where's the actual risk, and what is the cost/benefit of test. I've seen people spend days on tests that will never fail (for useful reasons), to protect logic that has little business risk... why???
But if you need a ui full stack smoke test (useful), then you Need something that can drive a browser.
wise words
thanks
fyi - this works pretty good fo rme
@tony.kay what are you're thoughts on a testing flow like
- create headless app with login page (nodejs)
- add invalid user-name values in the state
- run send-form! mutation that does validation
- check the state to see that the error messages are in the right place
?@claudiu what i said above. Look at the cost/benefit. Judge if it is really worth your time. If it is a smoke test or fragile part of the system, or was cheap and easy to write, then it's fine. I prefer tests that are a bit more sustainable. UI tests break for invalid, time-wasting reasons. Was the server a little slow? Did your test not wait long enough? Do you really want your test suite running for many many minutes just to test the login screen? I don't know maybe you do.
I almost never write ui driver tests. I've found them to cost way more than they help
š yep, almost never have time, so trying to think of ways that they can be cost efficient š
The other aspect of UI based testing is you cannot test any sorts of failure behavior easily. Also, you're very quickly going to hit combinatorial explosions of tests that can be factored apart and unit tested much more easily. Just tons and tons of problems with treating it as a general purpose testing solution.
One tool that I found interesting that might be worth the effort https://jestjs.io/docs/en/snapshot-testing
And then when your UI test fails, you have no idea why it failed. Was it an internal logic error? Did the test not wait long enough for a response? Was the database down for that test run? Did someone change the database schema? It's another time wasting effort of trying to figure out what the hell happened because your test really doesn't give you very much specificity. It just tells you something failed. Which is why I say they're great for smoke tests. They tell you "somethings wrong", but not really what
Sortha like image regression. State + component and test the tree against a previous version.
Thinking of devcards woth possible states & jest to automate the testing that they have not changed
@claudiu AdStage was doing thatā¦they wrote a blog about it here https://medium.com/adstage-engineering/how-we-test-our-full-stack-clojure-app-b18d79ee9e00
Visual regression testing can tell you something changedā¦but you get a lot of āfalse alarmsāā¦so you spend lots of time saying āyep, that still looks rightā. Again, cost/benefit. Try it, but measure objectively.
As a person running a startup: if it doesnāt lead to new features or protect me from breaking things that would cost me more money later than the tests cost, then it isnāt worth it.
The way I test, I write tests as I code against logic. The tests take no longer than the REPL playing that I would need to do anyway, but theyāre repeatable. Win-win. Zero additional cost, and CI protection.
Yep. In my case doing ui for personal projects. Dont have a time for tests (really slow as it is) but I am working aylt late hours so would really help to have sort of tests before deploys
tests are importantā¦the trick is to make testing affordable. Ideally leveraging current habits (e.g. REPL testing) into new ones (codified tests that are essentially your REPL examples).
One more note: At some point someone has to use the UI and make sure it all works. The idea is that most breakage doesnāt happen on the UI itself. It happens as you evolve logic. So, well-named and directed tests give you detection of breakage there, and high specificity for what exactly broke.
At one company I worked for we had a highy-used subsystem that was always getting bug reports. The logic was complex, and touching one thing typically caused another to break. The ātestingā was manual, and of course only the ānew fixā got checkedā¦a user would report the breakage after days or even weeks if it was a corner case. The structure of the code was horrible, and it had been patched so many times as to make it untenable. I rewrote it. The most important part of the rewrite was fixing the structure of the code. Making it simple was the first and most important step. I turned about 2000 lines of spaghetti into a few hundred. I also wrote tests around each new well-structured bit. I actually didnāt touch the UI the entire time I rewrote it, but the new simpler structure was easily testable, and was super-well covered as a result. When I ran it, it worked as expected. Zero bugs I could see (though I already had high confidence because of my tests). Release to production: one issue report: It turned out that our specification for how it was supposed to work was wrong in one case (and I had a test proving I āmiswroteā it). I fixed the test, fixed the logic. Released. A system that was the source of continual bug reports for years never caused a peep again, and there wasnāt a single UI test.
And, I seriously doubt I could have written it any faster without testsā¦the tests made it so I didnāt have to click in the UI and generate crap full-system test data, etc. Testing effectively was probably faster than doing it without tests.
but it took me 3 years of practice, making crappy tests, and throwing tons of stuff away before that to get good enough at it to get that resultā¦so thereās that š
:) my experience with tests hasnt been that great. Full integration (including in memory db) was the only thing I liked & made sense. For js I see a lot of time colegues spend testing redux "selectors" and other stuff like that. And in python I actually have a project where tests are the problem :)) they don't really catch any bugs, but break even for trivial changes (a lot nested mocking in folder path)
Might be tha oop & mutabillity make things a lot harder than they need to be. In cljs seems a lot nicer & simpler
IMO, especially after reading Tonyās tests in fuclro, testing is a skill that needs to be actively developed
not everyone writes tests of the same quality and most people write brittle tests that cost more than they give you
the problem is most people (including myself until recently) see writing tests as a chore/formality that they save until the end
Hello friends, I am currently testing fulcro
with pathom
as a front-only app with a rest api. I managed to make a network query (one tv show) and itās sub network query work. But as you can see on the :query
part, I have to declare a join for :episodes
but I only want it to load if a user click on a button, I am kind of lost if anyone can help š
(defsc Episode [this {:keys [tvmaze.episode/id tvmaze.episode/name]}]
{:ident [:tvmaze.episode/id :tvmaze.episode/id]
:query [:tvmaze.episode/id :tvmaze.episode/name]}
(dom/ul nil
(dom/li nil (str "Episode id : " id))
(dom/li nil (str "Episode name : " name ))))
(def ui-episode (prim/factory Episode {:keyfn :tvmaze.episode/id}))
(defsc TvShow [this {:keys [tvmaze.show/id tvmaze.show/name tvmaze.show/language tvmaze.show/episodes]}]
{:ident [:tvamaze.show/id :tvmaze.show/id]
:query [:tvmaze.show/id :tvmaze.show/name :tvmaze.show/language
{:tvmaze.show/episodes (prim/get-query Episode)}]}
(dom/ul nil
(dom/li nil (str "id : ") id)
(dom/li nil (str "name : " name))
(dom/li nil (str "language : " language))
(map ui-episode episodes)))
(def ui-tv-show (prim/factory TvShow {:keyfn :tvmaze.show/id}))
(defsc Root [this {:keys [ui/react-key list/one]}]
{:query [:ui/react-key
{:list/one (prim/get-query TvShow)}]}
(dom/div #js {:key react-key}
"List of all TvShows that we-ve seen this year !"
(ui-tv-show one)
(dom/button #js {:onClick (fn [_]
(df/load this [:tvmaze.show/id 1]
TvShow
{:target [:list/one]}))}
"Charger une tvShow")))
I was thinking about dynamic queries but I am not sure itās a āvalidā use case
@baptiste-from-paris I do some query post-processing for these kind of things, on the load
fn of fulcro it supports :update-query
, in which you get the query before it sends to the server and process as you wish
what I do is mark the fields I don't wanna load right away as lazy
(eg: [:eager (:lazy {:lazy-attribute true})]
)
in the query itself ?
then in my update-query function I strip all the lazy things (when I want to)
ok perfect, thanks a lot again, I am going to try that
this is how I end up writing, a real query example:
[:purchase/id :rewards/purchase-labels :abrams.api/shard
(db.h/lazy :purchase.points/label)
::db.h/mutation-response
{:ui/classify-dropdown (fp/get-query ui/Dropdown)}]
the db.h/lazy will add the lazy param
(defn lazy [x] (p/update-attribute-param x assoc ::lazy? true))
p
is from pathom
and this is my remove-lazy fn:
(defn remove-lazy [query]
(->> (p/query->ast query)
(p/transduce-children (remove (comp ::lazy? :params)))
(p/ast->query)))
so typically when you would do a prim/get-query
all fields would be loaded right ?
itās only on the request post-processing side that you remove all that ?
yeah, for loads you don't call get-query yourself right, fulcro does
and this processing happens before the query is sent to the server
so the server never sees the lazy fields on this case
okay, nice
looks like desfsc
is not finding param anymore nfo: defsc TvShow: [tvmaze.show/language] destructured in props but do(es) not appear in your query!
Ok working perfectly @wilkerlucio, thanks a lot.
would :without
http://book.fulcrologic.com/#_pruning_the_query work for these scenario also ?
@claudiu without is too simplistic, it just removes all of that, and when you have a complex query that can be very hard to target what you want
also, using without requires that the caller of load
to know about what needs to be pruned, using the lazy the component tells it so it's not a concern of load
caller anymore
transduce-children
is recursive it looked at all query params