While we clearly take inspiration from
DOM Testing Library
and
React Testing Library
,
and try to do our best to align as much as possible, there are some major
distinctions between the project's APIs.
While the DOM Testing Library
and it's descendants have a concept of both a
container
and element
, CLI Testing Library
only has a single concept to
replace them both: a TestInstance
.
This is because, while the DOM makes a clear distinction between different
elements (say,
HTMLBodyElement
and
HTMLDivElement
),
there is no such distinction between processes in the CLI as far as I'm aware.
While this may change in the future (maybe container
can be a sort of
TestProcess
of some kind), there are
unanswered questions around what that API looks like and whether we can meaningfully handle the distinction.
Similarly, HTMLElement
s provide clean lines between user input items.
Meanwhile, the CLI only has the concepts of stdin
, stdout
, and stderr
.
It's unclear how matching a single line of stdout
would help in a beneficial
matter, much less how APIs like fireEvent
would utilize this seemingly
extraneous metadata.
As a result, we don't have any *AllBy
queries that DOM Testing Library
does.
All of our queries are non-plural (*By
) and will simply return either the test
instance the query was called on, or null
depending on the query.
While we would be happy to reconsider, there are once again
lots of questions around what *AllBy
queries would like and whether we can meaningfully use that concept.
Another area where we diverge from the DOM is in our event system (as
implemented via fireEvent
and userEvent
).
Despite our APIs' naming indicating an actual event system (complete with bubbling and more, like the DOM), the CLI has no such concept.
This means that, while fireEvent
in the DOM Testing Library
has the ability
to inherent from all baked-into-browser events, we must hard-code a list of
"events" and actions a user may take.
We try our best to implement ones that make sense:
fireEvent.write({value: str})
to writestr
into stdinfireEvent.sigkill()
to send a sigkill to the processfireEvent.sigint()
to send a sigint to the process
There is a missing API for that might make sense in keypress
. It's unclear
what this behavior would do that write
wouldn't be able to.
There's also the API of userEvent
that allows us to implement a fairly similar
keyboard
event
to upstream.
However, there are a few differences here as well:
userEvent
can be bound to therender
output. This is due to limitations of not having ascreen
API. It's unclear how this would work in practice, due to a lack of thewindow
API.userEvent.keyboard
does not support modifier keys. It's only key-presses, no holding. This is because of API differences that would require us to figure out a manual binding system for every single key using ANSI AFAIK.- Relatedly, we've remove the
{
syntax support, since there is no standard keybinding for the CLI, like there is for the DOM. Instead, we only support[
and]
syntax.
While most of this document has been talking about DOM Testing Library
and
React Testing Library
, let's take a moment to talk about
jest-dom
matchers.
Usually, in a Testing Library testbed, you'd expect a getByText
to look
something like this:
const {getByText} = render(/* Something */)
expect(getByText('Hello World')).toBeInTheDocument()
In today's version of CLI Testing Library
, the same would look something like
this:
const {getByText} = render(/* Something */)
expect(getByText('Hello World')).toBeInTheConsole()
None of this is to say that we're not dedicated to being aligned with upstream. We would love to work with the broader Testing Library community to figure out these problems and adjust our usage.
This is the primary reason the library is still published as an @alpha
,
despite being stable enough to successfully power
a popular CLI application's testbed.
What's more, we're dedicated enough to making this happen that we've made sure to:
- Use the same source code organization (as much as possible) as
DOM Testing Library
andReact Testing Library
- Use the same deployment process as
DOM Testing Library
- Use similar documentation styles
And more!