I am trying to migrate ClojureScript tests from "Chrome Headless" to jsdom using Karma and shadow-cljs as test runners.
The regular tests which require access to DOM or browser API work fine. But async test where cljs.core.async/go is used doesn't work. Basically, nothing inside go is executed.
Does anyone have some idea what could be wrong? Did I miss some configuration? Is it only jsdom issue or maybe it is cljs.core.async interoperability issue?
I have put a simple test example below
(ns async-tests
  (:require [cljs.test :refer [deftest async]]
            [cljs.core.async :refer [go <! timeout]]))
(deftest async-go-test
  (async done
    (.log js/console "Before go is printed")
    (go
      (.log js/console "After go is never printed")
      (<! (timeout 1))
      (done))))
The result I get in console is
LOG: 'Testing async-tests'
LOG: 'Before go is printed'
WebKit 537.36 (undefined 0.0.0): Executed 159 of 185 SUCCESS (0 secs / 0.589 secs)
WebKit 537.36 (undefined 0.0.0) ERROR
Disconnected, because no message in 30000 ms.
Versions of libraries which are used:
  "devDependencies": {
    "jsdom": "^16.4.0",
    "karma": "^5.2.3",
    "karma-cljs-test": "^0.1.0",
    "karma-jsdom-launcher": "^8.0.2",
    "shadow-cljs": "2.10.19"
  }
Karma configuration:
module.exports = function (config) {
    config.set({
        browsers: ['jsdom'],
        basePath: 'target',
        files: ['ci.js'],
        frameworks: ['cljs-test'],
        colors: true,
        logLevel: config.LOG_INFO,
        client: {
            args: ["shadow.test.karma.init"]
        },
        jsdomLauncher: {
            jsdom: {
                resources: "usable",
                runScripts: "dangerously",
                pretendToBeVisual: true
            }
        }
    })
};
                I would like to say "Thank you" to the Clojure community which helped me find a workaround for this issue and especially @thheller. The root cause is not found yet but probably that it is the result of using the range of different libraries.
You have to override goog.async.nextTick method for your tests with
js/setTimeout
Create jsdom-setup namespace
(ns jsdom-setup)
(set! (.. js/window -goog -async -nextTick) js/setTimeout)
and add it to the tests JS output inside 'shadow-cljs.edn'
:builds {:karma {:target :karma
                 :output-to  "output/tests-bundle.js"
                 :ns-regexp "(setup-jsdom|[.-]tests$)"}}
Clojure Slack discussion
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With