Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ClojureScript cljs.core.async/go doesn't work inside jsdom

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
            }
        }
    })
};
like image 937
Valdermeyder Hussar Avatar asked Oct 31 '25 09:10

Valdermeyder Hussar


1 Answers

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.

Workaround

You have to override goog.async.nextTick method for your tests with js/setTimeout

Example

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$)"}}

Links

Clojure Slack discussion

like image 95
Valdermeyder Hussar Avatar answered Nov 01 '25 23:11

Valdermeyder Hussar