Scala DOM Test Utils provides a convenient, type-safe way to assert that a real Javascript DOM node matches a certain description using an extensible DSL.
"com.raquo" %%% "domtestutils" % "<version>" // Scala.js
You can use Scala DOM Test Utils either directly to make assertions, or you if you're writing a DOM construction / manipulation library, to power its own test utils package.
This project exists only to serve the needs of testing Laminar and the basic needs of testing Laminar applications. Emphasis on basic. This is not going to be a full fledged test kit, nor are there any guarantees of documentation or stability. If you want a something more, you'll need to fork this and/or create your own. It's a very small project anyway.
I am very unlikely to accept PRs on this project – please talk to me before spending your time.
import com.raquo.laminar.api.L._
// Create a JS DOM node that you want to test (example shows optional Laminar syntax)
val jsDomNode: org.scalajs.dom.Node = div(
rel := "yolo"
span("Hello, "),
p("bizzare ", a(href := "http://y2017.com", "2017"), span(" world")),
hr
).ref
// Mount the DOM node for testing
mount(jsDomNode, "optional clue to show on failure")
// Assert that the mounted node matches the provided description (this test will pass given the input above)
expectNode(
div.of(
rel is "yolo", // Ensure that rel attribute is "yolo". Note: assertions for properties and styles work similarly
span.of("Hello, "), // Ensure the this element contains just one text node: "Hello, "
p.of(
"bizzare ",
a.of(
href is "http://y2017.com",
title.isEmpty, // Ensure that title attribute is not set
"2017"
),
span.of(" world")
),
hr // Just check existence of element and tag name. Equivalent to `hr like ()`
)
)
The above example gets div
, rel
, href
, etc. from Laminar, and uses implicit conversions from these Laminar values to DOM TestUtils classes like ExpectedNode
and TestableHtmlAttr
.See more usage examples and glue code in Laminar tests
Laminar is not required to use Scala DOM TestUtils. You can integrate similarly with any other Scala.js UI library.
Canonical usage is to mount
one DOM node / tree (e.g. the output of your component) and then test it using the expectNode
method.
Alternative is to call expectNode(actualNode, expectedNode)
, for example if you only want to test a subtree of what you mounted.
If the mechanics of MountOps
do not work for you, you can bypass MountOps
altogether and just call ExpectedNode.checkNode(actualNode)
directly to get a list of errors.
With ScalaTest: Your test suite should extend the MountSpec
trait. Use mount
and expectNode
methods in your test code. You can call unmount
and then mount
again within one test if you want to test multiple unrelated nodes (e.g. different variations in a loop). See Laminar's test suite for an example.
Without ScalaTest: You could write a tiny adapter like MountSpec
for your test framework, which would:
MountOps
and provide doAssert
/ doFail
implementations specific to your test frameworkresetDOM
in the beginning of each test, and clearDOM
at the end of each test.source.Position
macro, but in the future the integration could be deepened.MountOps
and other such files and drop down to calling ExpectedNode.checkNode(actualNode)
to get a list of errors, and build your own test util around it.There is no promise of any backwards compatibility in this particular project. I roughly align versions with Scala DOM Types for my own convenience.
Nikita Gazarov – @raquo
License – MIT