Scala DOM Test Utils
"com.raquo" %%% "domtestutils" % "<version>" // Scala.js 1.13.0+ only
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
href, etc. from Laminar, and uses implicit conversions from these Laminar values to DOM TestUtils classes like
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
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
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:
doFailimplementations specific to your test framework
resetDOMin the beginning of each test, and
clearDOMat 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 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.
My Related Projects
- 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