I have a simple project in Kotlin JavaScript using React. I've added unit tests, but when I run them, they seem to call main method of production code, and fail on initialization, when trying to reach unexsistent DOM structure. Despite the fact that the tested class does not reference React or DOM in any way.
The error looks the same when run from Intelij IDEA or by gradlew build
(I've replaced the full path to my project with /APP/ for clarity):
Testing started at 17:51 ...
> Task :cleanBrowserTest
> Task :packageJson UP-TO-DATE
> Task :testPackageJson UP-TO-DATE
> Task :kotlinNodeJsSetup SKIPPED
> Task :kotlinNpmInstall
> Task :compileKotlinJs
> Task :processResources
> Task :mainClasses
> Task :compileTestKotlinJs
> Task :testProcessResources NO-SOURCE
> Task :testClasses
> Task :browserTest
(...)
Error: Target container is not a DOM element.
at render (http://localhost:9876/absoluteD:/APP/build/js/packages/example-test/adapter-browser.js?92ccabfdcfa982960828b65b2f4e2683080859b4:25359:13)
at render_0 (http://localhost:9876/absoluteD:/APP/build/js/packages/example-test/adapter-browser.js?92ccabfdcfa982960828b65b2f4e2683080859b4:29868:5)
at main (http://localhost:9876/absoluteD:/APP/build/js/packages/example-test/adapter-browser.js?92ccabfdcfa982960828b65b2f4e2683080859b4:146311:5)
at Object.<anonymous> (http://localhost:9876/absoluteD:/APP/build/js/packages/example-test/adapter-browser.js?92ccabfdcfa982960828b65b2f4e2683080859b4:146315:3)
at http://localhost:9876/absoluteD:/APP/build/js/packages/example-test/adapter-browser.js?92ccabfdcfa982960828b65b2f4e2683080859b4:146289:37
at Object.../example/kotlin/example.js (http://localhost:9876/absoluteD:/APP/build/js/packages/example-test/adapter-browser.js?92ccabfdcfa982960828b65b2f4e2683080859b4:146292:2)
at __webpack_require__ (http://localhost:9876/absoluteD:/APP/build/js/packages/example-test/adapter-browser.js?92ccabfdcfa982960828b65b2f4e2683080859b4:20:30)
at http://localhost:9876/absoluteD:/APP/build/js/packages/example-test/adapter-browser.js?92ccabfdcfa982960828b65b2f4e2683080859b4:146346:134
at Object../kotlin/example-test.js (http://localhost:9876/absoluteD:/APP/build/js/packages/example-test/adapter-browser.js?92ccabfdcfa982960828b65b2f4e2683080859b4:146351:2)
at __webpack_require__ (http://localhost:9876/absoluteD:/APP/build/js/packages/example-test/adapter-browser.js?92ccabfdcfa982960828b65b2f4e2683080859b4:20:30)
HeadlessChrome 81.0.4044 (Windows 10.0.0) ERROR
Uncaught Error: Target container is not a DOM element.
at d:/APP/build/js/node_modules/react-dom/cjs/react-dom.development.js:24828:1 <- D:/APP/build/js/packages/example-test/adapter-browser.js:25359:7
(...)
> Task :browserTest FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':browserTest'.
> command 'C:\Users\Arsen\.gradle\nodejs\node-v12.14.0-win-x64\node.exe' exited with errors (exit code: 1)
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Get more help at https://help.gradle.org
BUILD FAILED in 10s
8 actionable tasks: 6 executed, 2 up-to-date
./build.gradle.kts
plugins {
id("org.jetbrains.kotlin.js") version "1.3.70-eap-184"
}
group = "org.example"
version = "1.0-SNAPSHOT"
repositories {
maven { setUrl("https://dl.bintray.com/kotlin/kotlin-eap") }
maven("https://kotlin.bintray.com/kotlin-js-wrappers/")
mavenCentral()
jcenter()
}
dependencies {
implementation(kotlin("stdlib-js"))
implementation("org.jetbrains:kotlin-react:16.13.0-pre.94-kotlin-1.3.70")
implementation("org.jetbrains:kotlin-react-dom:16.13.0-pre.94-kotlin-1.3.70")
implementation(npm("react", "16.13.1"))
implementation(npm("react-dom", "16.13.1"))
testImplementation(kotlin("test-js"))
}
kotlin.target.browser {
}
./settings.gradle.kts
pluginManagement {
repositories {
maven { setUrl("https://dl.bintray.com/kotlin/kotlin-eap") }
mavenCentral()
maven { setUrl("https://plugins.gradle.org/m2/") }
}
}
rootProject.name = "example"
./src/main/resources/index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<div id="root"></div>
<script src="example.js"></script>
</body>
</html>
./src/main/kotlin/Main.kt
import react.dom.*
import kotlin.browser.document
fun main(args: Array<String>) {
render(document.getElementById("root")) {
}
}
./src/main/kotlin/DummyClass.kt
class DummyClass {
fun foo(): String {
return "foo"
}
}
./src/test/kotlin/ExampleTest.kt
import kotlin.test.*
class ExampleTest {
@Test
fun foo() {
assertEquals(DummyClass().foo(), "foo")
}
}
The error does not occur if I don't reference production code at all (remove DummyClass().foo()
from the test), or when main method does not call render(document.getElementById("root"))
.
PS: If it matters I run the code on Windows
This is not the right answer - but something that will unblock you immediately.
This answer pointed out that
the test environment doesn't supply the DOM with an app id.
So too is the case with our test framework - it is not supplying an element with id 'root'.
This led me to believe that the main/resources/index.html
is not being used by the test framework. The exception trace confirms that - notice how it starts from __webpack_require__
The ideal solution would be to either have karma or webpack supply our code with the correct index.html; but I don't know how to accomplish that.
In the meantime, you can
<div id="root"></div>
as part of index.html
Have your kotlin code generate it, as below:
./src/main/kotlin/Main.kt
fun main(args: Array<String>) {
document.body!!.insertAdjacentHTML("afterbegin", "<div id='root'></div>" )
render(document.getElementById("root")) {
}
}
Hope that helps
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