This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-02-07
Channels
- # announcements (32)
- # asami (11)
- # babashka (5)
- # babashka-sci-dev (4)
- # beginners (65)
- # biff (11)
- # calva (35)
- # clerk (2)
- # clj-kondo (14)
- # clj-on-windows (4)
- # clojars (4)
- # clojure (122)
- # clojure-canada (1)
- # clojure-europe (31)
- # clojure-italy (6)
- # clojure-nl (1)
- # clojure-norway (7)
- # clojure-spec (3)
- # clojure-uk (2)
- # clojurescript (3)
- # core-async (7)
- # core-logic (1)
- # data-science (13)
- # datalog (3)
- # datavis (3)
- # datomic (15)
- # deps-new (4)
- # emacs (34)
- # figwheel-main (1)
- # fulcro (1)
- # funcool (1)
- # holy-lambda (10)
- # lsp (41)
- # malli (24)
- # membrane (5)
- # midje (1)
- # off-topic (5)
- # polylith (3)
- # proletarian (6)
- # re-frame (6)
- # reitit (6)
- # remote-jobs (4)
- # sci (1)
- # shadow-cljs (96)
- # sql (31)
- # testing (23)
- # xtdb (49)
Hey @thheller for :target :esm
can we output each entry as a separate ESM file, much similar to :npm-modules
?
:app-esm {:target :esm
:modules {:main {:entries [app.mod1 app.mod2]}}}
:esm
also really expects exports, otherwise its pretty useless in an interop scenario
but you'd do it like this
{:target :esm
:modules {:base {:entries []}
:app.mod1 {:entries [app.mod1] :depends-on #{:base}}
:app.mod2 {:entries [app.mod2] :depends-on #{:base}}}}
Guess I could hack a bit with the build hooks to scan the -test$
namespaces, then rewrite the :modules
config to the above format
I have some time in a bit, so I can see if I can figure out your :npm-module
problem
I inspected the :worker-info key, and it's nil https://github.com/thheller/shadow-cljs/blob/756d3fc/src/main/shadow/build/targets/npm_module.clj#L69-L70
:npm-module
supports browsers, but only with more processing by third party tools as browser can't load commonjs files otherwise
So I uses the :npm-module
to output things like app.foo-test.cljs
to app.foo-test.js
and cypress test running would load it and execute it in the browser
I'm following the logic of the code to check why the browser page doesn't connect back to shadow-cljs as a runtime, maybe I'm looking at the wrong places
why do you want the runtime to connect back? tests and repls usually don't play well with each other
so, if you just want a REPL but let the tests run on their own I recommend running a separate shadow-cljs browser-repl
or so
> tests and repls usually don't play well with each other yeah most time they don't, but in my case it's a pretty good match. With the :esm target I can use shadow-cljs's reload for fast test-rerunning
preloads and runtimes are a bit more complicated with :npm-module
since there is no controlled entry point
which is much faster than the builtin liveReload of cypress (which comes from webpack)
so you'd have something like require("./cljs-out/your.preload")
in some prepended configuration or so
require("./cljs-out/shadow.cljs.devtools.client.browser")
is the ns for the REPL/hot-reload runtime
Thanks for the tips, I'll think about it. Maybe I'll simply go the way of using hooks to crunch the esm modules config like the one you mentioned above
{:target :esm
:modules {:base {:entries []}
:app.mod1 {:entries [app.mod1] :depends-on #{:base}}
:app.mod2 {:entries [app.mod2] :depends-on #{:base}}}}
probably not, cypress has its own tests runner (one based on mocha) so tests have to be defined with mocha's primitives
well you can define your own runner with :browser-test
. doesn't have to be cljs.test
but there would be a bunch of other stuff to wire up together, assertions, matchers, etc. so that's an another rabbit hole. Beside cypress is really a totally different beast in conducting the tests, so I'd rather avoid it.
I really know very little about cypress and how it loads things, so really can't comment much from the cypress side
:browser-test
just generates JS, with the assumption that it is executed in a browser environment
It's pretty fascinating for doing react component testing. Otherwiser shadow's builtin browser-test is great enough for normal frontend unit tests
Being a js land tool it's by nature not a native fit for cljs, e.g. assert matchers for cljs data structures has to be custom registered
but once these rough egdes are smoothed it would be like a dream land for component based TDD
oh right it was one of those things that expects files in certain locations and so on
can't see what you are pressing. do you just save the file and cypress triggers running it or how does cypress get the new results?
I can see shadow-cljs reloading something, but can't tell if cypress does anything 😛
Well it's a "customized" version of cypress. The official cypress would actually reload the page completely each time the test ns is rebuilt.
the bundler configuration seems hardcoded to webpack/vite and can't be extended/replaced
https://docs.cypress.io/guides/component-testing/component-framework-configuration#Custom-Dev-Server
(def cy js/parent.Cypress)
(.onSpecWindow cy js/window #js [])
(.action cy "app:window:before:load" js/window)
yes, I played with component tests but abandoned it after discovering that the same trick cannot be done for e2e
and I couldn't figure out how to tell cypress to re-run the test after a hot-reload. since there is no documentation for any of this, at least nothing I could find
For e2e it's simple
(defn ^:dev/before-load click-cypress-ui-restart-button
[]
(when-not (= js/window.parent js/window)
(-> (js/window.parent.document.querySelector "button.restart")
.click)))
IMHO it's okay for the app iframe to do a full reload in e2e tests, since most of the e2e tests takes much longer and the benefit of hot-reloading over full page reload is dwarfed.emm, on a second thought I agree it might have greater benefit than I have estimated if we have hot reloading in e2e tests, e.g. we can skip lots of time consuming fixtures like logins, cleanups etc. :thinking_face:
yeah it would be more complex than CT. In CT there are two windows: top (cypress UI) & specWindow (where it/describe etc. and app code runs)