{"id":29097387,"url":"https://github.com/lambdaisland/kaocha-cljs","last_synced_at":"2025-07-31T02:04:01.820Z","repository":{"id":33788227,"uuid":"159824278","full_name":"lambdaisland/kaocha-cljs","owner":"lambdaisland","description":"ClojureScript support for Kaocha","archived":false,"fork":false,"pushed_at":"2023-04-17T21:28:27.000Z","size":217,"stargazers_count":43,"open_issues_count":5,"forks_count":9,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-07-22T02:41:14.404Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"epl-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lambdaisland.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2018-11-30T13:01:48.000Z","updated_at":"2025-05-01T13:53:41.000Z","dependencies_parsed_at":"2024-04-17T14:20:41.621Z","dependency_job_id":"9182d000-1b6b-4c85-a311-8aba98747426","html_url":"https://github.com/lambdaisland/kaocha-cljs","commit_stats":{"total_commits":137,"total_committers":14,"mean_commits":9.785714285714286,"dds":0.3065693430656934,"last_synced_commit":"ddcdd7bc8df2482d107da73f1b921a27c9576bd9"},"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"purl":"pkg:github/lambdaisland/kaocha-cljs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lambdaisland%2Fkaocha-cljs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lambdaisland%2Fkaocha-cljs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lambdaisland%2Fkaocha-cljs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lambdaisland%2Fkaocha-cljs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lambdaisland","download_url":"https://codeload.github.com/lambdaisland/kaocha-cljs/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lambdaisland%2Fkaocha-cljs/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267975207,"owners_count":24174666,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-31T02:00:08.723Z","response_time":66,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-06-28T13:42:05.784Z","updated_at":"2025-07-31T02:04:01.812Z","avatar_url":"https://github.com/lambdaisland.png","language":"Clojure","funding_links":["http://opencollective.com/lambda-island"],"categories":[],"sub_categories":[],"readme":"# kaocha-cljs\n\n\u003c!-- badges --\u003e\n[![CircleCI](https://circleci.com/gh/com.lambdaisland/kaocha-cljs.svg?style=svg)](https://circleci.com/gh/com.lambdaisland/kaocha-cljs) [![cljdoc badge](https://cljdoc.org/badge/com.lambdaisland/kaocha-cljs)](https://cljdoc.org/d/com.lambdaisland/kaocha-cljs) [![Clojars Project](https://img.shields.io/clojars/v/com.lambdaisland/kaocha-cljs.svg)](https://clojars.org/com.lambdaisland/kaocha-cljs)\n\u003c!-- /badges --\u003e\n\nClojureScript support for Kaocha\n\n## Features\n\nKaocha-cljs provides basic ClojureScript support for the Kaocha test runner. It\ncan run tests in the browser or in Node.js. It does this under the hood using\nthe built-in ClojureScript REPL implementations for the browser or for node.\n\nThis approach makes it fairly easy to set up, but also fairly limited and\ninflexible.\n\n- Your code has to be compatible with vanilla ClojureScript\n- Shadow-cljs is not supported\n- We can only run tests with `:optimizations :none`\n- You have little to no control over the compiler settings\n- We don't support other runtimes besides Node and browser\n- Each run opens a new tab/process, we can't reconnect to existing JS runtimes\n- The `repl-env` abstraction is a black box which provide very little diagnostics\n\nTo get around these limitations we created\n[kaocha-cljs2](https://github.com/lambdaisland/kaocha-cljs2), which is\ninfinitely flexible, but significantly harder to set up. For simple projects and\nlibraries kaocha-cljs v1 can still be a valid choice. If it no longer serves\nyour needs, you can try your hand at kaocha-cljs2.\n\nKaocha-cljs requires Clojure and ClojureScript 1.10 or later.\n\n\u003c!-- installation --\u003e\n## Installation\n\nTo use the latest release, add the following to your `deps.edn` ([Clojure CLI](https://clojure.org/guides/deps_and_cli))\n\n```\ncom.lambdaisland/kaocha-cljs {:mvn/version \"1.5.154\"}\n```\n\nor add the following to your `project.clj` ([Leiningen](https://leiningen.org/))\n\n```\n[com.lambdaisland/kaocha-cljs \"1.5.154\"]\n```\n\u003c!-- /installation --\u003e\n\nFor Node.js support also install the `ws` npm package, you can add something\nlike this to `bin/kaocha` to this for you.\n\n```sh\n#!/usr/bin/env sh\n\n[ -d \"node_modules/ws\" ] || npm install ws\nclojure -A:dev:test -M -m kaocha.runner \"$@\"\n```\n\nTo configure your kaocha-cljs test suite:\n\n``` clojure\n;; tests.edn\n#kaocha/v1\n{:tests [{:id :unit-cljs\n          :type :kaocha.type/cljs\n          ;; :test-paths [\"test\"]\n          ;; :cljs/timeout 10000                        ; 10 seconds, the default\n          ;; :cljs/repl-env cljs.repl.node/repl-env     ; node is the default\n          ;; :cljs/repl-env cljs.repl.browser/repl-env\n          }]}\n```\n\nAnd run your tests\n\n```\nbin/kaocha unit-cljs\n```\n\n## Configuration\n\n- `:kaocha/source-paths` (or `:source-paths` when using `#kaocha/v1`) \u003cbr\u003e\n  The location of your ClojureScript source paths (vector)\n- `:kaocha/test-paths` (or `:test-paths` when using `#kaocha/v1`) \u003cbr\u003e\n  The location of your ClojureScript test paths (vector)\n- `:cljs/timeout` \u003cbr\u003e Time in milliseconds before timing out. This timeout gets\n  reset whenever we receive an event from the ClojureScript environment, like a\n  cljs.test event, or something being written to stdout. Once there is no\n  activity for `:cljs/timeout` seconds, the test fails. This also causes\n  subsequent tests to be skipped, because we assume the ClojureScript runtime is\n  no longer responsive.\n- `:cljs/repl-env` \u003cbr\u003e A function (var) name which takes ClojureScript Compiler\n  options, and returns a REPL environment. Values you can use include\n  - `cljs.repl.node/repl-env`\n  - `cljs.repl.browser/repl-env`\n  - `figwheel.repl/repl-env`\n- `:cljs/compiler-options` \u003cbr\u003e Additional compiler options, defaults to `{}`.\n- `:cljs/precompile?` \u003cbr\u003e Invoke `cljs.build.api/build` before launching the\n  REPL. Certain REPL types like Figwheel REPL require an initial build before\n  the REPL is able to connect. If this is the case you can set this to `true`.\n  Defaults to `false`.\n\n## Configuration for npm dependency\n\nWhen using kaocha-cljs with `:npm-deps`, you need to:\n\n- enable precompilation\n- make sure `:main`, `:install-deps`, `:npm-deps` are all set in the compiler options\n\nFor example, if we want to compile the left-pad npm library as an npm dependency, the \n`tests.edn` should look like:\n\n```\n#kaocha/v1\n    {:bindings        {kaocha.type.cljs/*debug* true}\n     :capture-output? false\n     :tests           [{:id                    :unit-cljs\n                        :type                  :kaocha.type/cljs\n                        :cljs/precompile?      true\n                        :cljs/compiler-options {:main         npm_deps.main\n                                                :verbose      true\n                                                :install-deps true\n                                                :npm-deps     {:left-pad \"1.1.3\"}}\n                        :source-paths          [\"src\"]\n                        :test-paths            [\"test\"]}]}\n```\nNote: We use the compiler options twice `(if :cljs/precompile? is true)`: once to do the \n      precompilation, and another once to start a REPL to communicate with.\n\n## Known issues\n\n- The `:test-paths` do not get automatically added to the classpath (at least not\nin a way that makes the sources visible to ClojureScript), so you need to also\nhave any `:test-paths` in your `project.clj`/`deps.edn`/`build.boot`.\n\n  This is a discrepancy with regular Kaocha, where you only need to specify the\ntest paths once.\n\n- On Linux the `cljs.repl.browser/repl-env` requires the browser process to already be started\n  before running Kaocha (see: \u003chttps://clojure.atlassian.net/browse/CLJ-2493\u003e).\n\n  To support running browser tests on CircleCI add an early config step like:\n\n  ```\n  - run:\n      command: /usr/bin/google-chrome-stable --no-first-run\n      background: true\n  ```\n\n- You can not pass the `:advanced` optimization setting to the to the clojurescript compiler options, which is very important to run tests against a real build.\n  If this feature is important you should consider using [kaocha-cljs2 instead](https://github.com/lambdaisland/kaocha-cljs2).\n\n### Common Errors\n\n- `\"Kaocha ClojureScript client failed connecting back.\"`\n\nThis is the most common problem you'll encounter. Unfortunately it's a symptom\nthat can have many underlying causes. What it means is this: Kaocha-cljs has\ncreated a ClojureScript repl-env, and asked it to evaluate the code which loads\nour websocket client. At this point Kaocha has to wait until that client is\nloaded, and has connected back to Kaocha, so we know we're in business.\n\nFor some reason this didn't happen in time, and so we time out and provide this\nerror. What this really means is that the `repl-env` misbehaved. Maybe the JS\nruntime didn't start up properly (check your node process for instance), maybe\nthe compiles CLJS caused an error (anything in the browser console)? Maybe it's\na networking issue... We handed over control, and never got it back.\n\n- `\"Execution error (ReferenceError) at (\u003ccljs repl\u003e:1).\\ndocument is not defined\\n\"`\n\nThis usually means you're using libraries that expect a DOM (i.e., they expect to \nfind `js/document`), but you are using them in an environment where there is no DOM,\ntypically Node. \n\nThere are two ways to fix it:\n\n1. Instruct kaocha-cljs to use a browser REPL.\n2. Prepare a DOM for Node environment. For example, `(js/require \"global-jsdom\")` \n   in a pre-test hook\n\n## Architecture\n\n### Kaocha's execution model\n\nMost ClojureScript testing tools work by building a big blob of JavaScript that\ncontains both the compiled tests and a test runner, and then handing that over\nto a JavaScript runtime.\n\nKaocha, however, enforces a specific execution model on all its test types.\n\n```\n[config] --(load)--\u003e [test-plan] --(run)--\u003e [result]\n```\n\nStarting from a test configuration (e.g., `tests.edn`) Kaocha will recursively\n`load` the tests, building up a hierarchical test plan. For instance\n`clojure.test` will have a test suite containing test namespaces containing test\nvars.\n\nBased on the test plan Kaocha recursively invokes run on these \"testables\",\nproducing a final result.\n\nDuring these process various \"hooks\" are invoked (pre-test, post-test, pre-load,\npost-load), which can be implemented by plugins, and test events\n(begin-test-var, pass, fail, summary) are generated, which are handled by a\nreporter to provide real-time progress.\n\nKaocha's built-in features, plugins and reporters rely on this model of\nexecution, so any test type must adhere to it. Note that all of this is on the\nClojure side. Kaocha's own core, as well as plugins and reporters are all\nimplemented in (JVM-based) Clojure, not in ClojureScript, so even in the case of\nClojureScript tests the main coordination still happens from Clojure.\n\n### PREPL + Websocket\n\nTo make this work kaocha-cljs makes use of a ClojureScript PREPL (a programmable\nREPL). Given a certain repl environment function (e.g. `browser/repl-env` or\n`node/repl-env`) Kaocha will boot up a ClojureScript environment ready to\nevaluate code, and load a websocket client that connects back to Kaocha-cljs, so\nwe have a channel to send data back from ClojureScript to Kaocha. It will then\nsend code to the PREPL to load the test namespaces, and to invoke the tests.\n\nAnything written on stderr or stdout will be forwarded to Clojure's out/err\nstreams, and possibly captured by the output capturing plugin.\n\nThe test events produced by `cljs.test` (pass, fail, error) are sent back over\nthe websocket, and ultimately handled by whichever Kaocha reporter you are using.\n\nEvents received from the PREPL and the websocket are all placed on a queue,\nwhich ultimately drives a state machine, which coordinates what needs to happen\nnext, and gathers up the test results.\n\n## Debugging\n\nIf you're having issues, first try running with `--no-capture-output`. There may\nbe relevant information that's being hidden.\n\nTo see all messages coming in over the PREPL and Websocket you can set\n`kaocha.type.cljs/*debug*` to `true`. You can do this directly from `tests.edn`.\n\n``` clojure\n#kaocha/v1\n{:tests [,,,]\n :bindings {kaocha.type.cljs/*debug* true}}\n```\n\nThis will also set the `goog.log` root logger, and the\n`kaocha.cljs.websocket-client` logger both to the `DEBUG` level. Have a look at\n[glogi](https://github.com/lambdaisland/glogi) for more information about Google\nClosure's logging facilities.\n\nWhen not using `*debug*` you can still set these log levels separately through\n`:closure-defines`.\n\n``` clojure\n#kaocha/v1\n{:tests [{:type :kaocha.type/cljs\n          :cljs/compiler-options {:closure-defines {kaocha.type.cljs/log-level \"ALL\"\n                                                    kaocha.type.cljs/root-log-level \"INFO\"}}}]}\n;; Log levels:\n;; OFF SHOUT SEVERE WARNING INFO CONFIG FINE FINER FINEST ALL\n```\n\n\u003c!-- opencollective --\u003e\n## Lambda Island Open Source\n\n\u003cimg align=\"left\" src=\"https://github.com/lambdaisland/open-source/raw/master/artwork/lighthouse_readme.png\"\u003e\n\n\u0026nbsp;\n\nkaocha-cljs is part of a growing collection of quality Clojure libraries created and maintained\nby the fine folks at [Gaiwan](https://gaiwan.co).\n\nPay it forward by [becoming a backer on our Open Collective](http://opencollective.com/lambda-island),\nso that we may continue to enjoy a thriving Clojure ecosystem.\n\nYou can find an overview of our projects at [lambdaisland/open-source](https://github.com/lambdaisland/open-source).\n\n\u0026nbsp;\n\n\u0026nbsp;\n\u003c!-- /opencollective --\u003e\n\n\u003c!-- contributing --\u003e\n## Contributing\n\nEveryone has a right to submit patches to kaocha-cljs, and thus become a contributor.\n\nContributors MUST\n\n- adhere to the [LambdaIsland Clojure Style Guide](https://nextjournal.com/lambdaisland/clojure-style-guide)\n- write patches that solve a problem. Start by stating the problem, then supply a minimal solution. `*`\n- agree to license their contributions as MPL 2.0.\n- not break the contract with downstream consumers. `**`\n- not break the tests.\n\nContributors SHOULD\n\n- update the CHANGELOG and README.\n- add tests for new functionality.\n\nIf you submit a pull request that adheres to these rules, then it will almost\ncertainly be merged immediately. However some things may require more\nconsideration. If you add new dependencies, or significantly increase the API\nsurface, then we need to decide if these changes are in line with the project's\ngoals. In this case you can start by [writing a pitch](https://nextjournal.com/lambdaisland/pitch-template),\nand collecting feedback on it.\n\n`*` This goes for features too, a feature needs to solve a problem. State the problem it solves, then supply a minimal solution.\n\n`**` As long as this project has not seen a public release (i.e. is not on Clojars)\nwe may still consider making breaking changes, if there is consensus that the\nchanges are justified.\n\u003c!-- /contributing --\u003e\n\n\u003c!-- license --\u003e\n## License\n\nCopyright \u0026copy; 2018-2021 Arne Brasseur and Contributors\n\nLicensed under the term of the Mozilla Public License 2.0, see LICENSE.\n\u003c!-- /license --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flambdaisland%2Fkaocha-cljs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flambdaisland%2Fkaocha-cljs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flambdaisland%2Fkaocha-cljs/lists"}