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:
- Extend
MountOpsand providedoAssert/doFailimplementations specific to your test framework - Call
resetDOMin the beginning of each test, andclearDOMat the end of each test. - However, this project depends on ScalaTest, currently just for the
source.Positionmacro, but in the future the integration could be deepened. - So, long term, you might be better off forking this project if you want to use a different testing library.
- You could probably also forgo
MountOpsand other such files and drop down to callingExpectedNode.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.
- Laminar – Reactive UI library based on Scala DOM Types
- Scala DOM Types – Type definitions for all the HTML tags, attributes, properties, and styles, used by Laminar and a few other similar libraries
Nikita Gazarov – @raquo
License – MIT