Skip to content

Commit 90ec01c

Browse files
authored
docs: update marko examples with new apis (testing-library#861)
1 parent 0c13e94 commit 90ec01c

File tree

3 files changed

+109
-72
lines changed

3 files changed

+109
-72
lines changed

docs/marko-testing-library/api.mdx

Lines changed: 86 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@ as these methods:
1414
- [`debug`](#debug)
1515
- [`rerender`](#rerender)
1616
- [`emitted`](#emitted)
17+
- [`cleanup`](#cleanup)
1718
- [`container`](#container-1)
18-
- [`cleanup`](#cleanup)
19+
- [`cleanup`](#cleanup-1)
1920

2021
---
2122

@@ -39,34 +40,26 @@ render(MyTemplate)
3940
```
4041

4142
```javascript
42-
import { render, cleanup } from '@marko/testing-library'
43-
import '@testing-library/jest-dom/extend-expect'
43+
import { render, screen } from '@marko/testing-library'
4444
import Greeting from './greeting.marko'
4545

46-
afterEach(cleanup)
47-
4846
test('renders a message', async () => {
49-
const { container, getByText } = await render(Greeting, { name: 'Marko' })
50-
expect(getByText(/Marko/)).toBeInTheDocument()
47+
const { container } = await render(Greeting, { name: 'Marko' })
48+
expect(screen.getByText(/Marko/)).toBeInTheDocument()
5149
expect(container.firstChild).toMatchInlineSnapshot(`
5250
<h1>Hello, Marko!</h1>
5351
`)
5452
})
5553
```
5654

57-
> Note
58-
>
59-
> The [cleanup](#cleanup) function should be called between tests to remove the
60-
> created DOM nodes and keep the tests isolated.
61-
6255
### `render` Options
6356

6457
You won't often need to specify options, but if you ever do, here are the
65-
available options which you could provide as the third argument to `render`.
58+
available options which you can provide as the third argument to `render`.
6659

6760
#### `container`
6861

69-
By default for client side tests, `Marko Testing Library` will create a `div`
62+
By default for client-side tests, `Marko Testing Library` will create a `div`
7063
and append that `div` to the `document.body` and this is where your component
7164
will be rendered. If you provide your own HTMLElement `container` via this
7265
option, it will not be appended to the `document.body` automatically.
@@ -90,18 +83,28 @@ few properties:
9083
### `...queries`
9184

9285
The most important feature of `render` is that the queries from
93-
[DOM Testing Library](dom-testing-library/api-queries.mdx) are automatically
94-
returned with their first argument bound to the results of rendering your
95-
component.
86+
[DOM Testing Library](queries/about.mdx) are automatically returned with their
87+
first argument bound to the results of rendering your component.
9688

97-
See [Queries](dom-testing-library/api-queries.mdx) for a complete list.
89+
See [Queries](queries/about.mdx) for a complete list.
9890

9991
**Example**
10092

10193
```javascript
10294
const { getByLabelText, queryAllByTestId } = await render(MyTemplate)
10395
```
10496

97+
Alternatively, you can use the
98+
[top-level `screen` method](queries/about.mdx#screen) to query into all
99+
currently rendered components in the `document.body`, eg:
100+
101+
```javascript
102+
import { render, screen } from "@marko/testing-library"
103+
104+
await render(MyTemplate)
105+
const el = screen.getByText(...)
106+
```
107+
105108
### `debug`
106109

107110
This method is a shortcut for logging the `prettyDOM` for all children inside of
@@ -119,13 +122,13 @@ debug()
119122
```
120123

121124
This is a simple wrapper around `prettyDOM` which is also exposed and comes from
122-
[`DOM Testing Library`](https://github.com/testing-library/dom-testing-library/blob/master/README.md#prettydom).
125+
[`DOM Testing Library`](dom-testing-library/api-debugging.mdx#prettydom).
123126

124127
### `rerender`
125128

126129
A Marko components `input` can change at any time from a parent component.
127130
Although often this input is passed through your component declaratively,
128-
sometimes it is necessary to ensure that your components reacts appropriately to
131+
sometimes it is necessary to ensure that your components react appropriately to
129132
new data. You can simulate your component receiving new `input` by passing new
130133
data to the `rerender` helper.
131134

@@ -160,13 +163,13 @@ const { getByText, emitted } = await render(Counter)
160163

161164
const button = getByText('Increment')
162165

163-
fireEvent.click(button)
164-
fireEvent.click(button)
166+
await fireEvent.click(button)
167+
await fireEvent.click(button)
165168

166169
// Assuming the `Counter` component forwards these button clicks as `increment` events
167170
expect(emitted('increment')).toHaveProperty('length', 2)
168171

169-
fireEvent.click(button)
172+
await fireEvent.click(button)
170173

171174
// Note: the tracked events are cleared every time you read them.
172175
// Below we are snapshoting the events after our last assertion,
@@ -212,11 +215,37 @@ expect(emitted()).toMatchInlineSnapshot(`
212215
`)
213216
```
214217

218+
### `cleanup`
219+
220+
Like the [top-level cleanup method](#cleanup-1), this allows you to remove and
221+
destroy the currently rendered component before the test has been completed.
222+
223+
This can be useful to validate that a component properly cleans up any DOM
224+
mutations once it has been destroyed.
225+
226+
```javascript
227+
import { render, screen, getRoles } from '@marko/testing-library'
228+
import Main from './main.marko'
229+
import Dialog from './dialog.marko'
230+
231+
await render(Main)
232+
233+
const main = screen.getByRole('main')
234+
expect(main).not.toHaveAttribute('aria-hidden')
235+
236+
const { cleanup } = await render(Dialog)
237+
expect(main).toHaveAttribute('aria-hidden') // assert added attribute
238+
239+
cleanup() // destroy the dialog
240+
241+
expect(main).not.toHaveAttribute('aria-hidden') // assert attribute removed
242+
```
243+
215244
### `container`
216245

217-
The containing DOM node of your rendered Marko Component. For server side tests
246+
The containing DOM node of your rendered Marko Component. For server-side tests
218247
this is a [JSDOM.fragment](https://github.com/jsdom/jsdom#fragment), and for
219-
client side tests this will be whatever is passed as the `container` render
248+
client-side tests this will be whatever is passed as the `container` render
220249
option.
221250

222251
> Tip: To get the root element of your rendered element, use
@@ -227,30 +256,47 @@ option.
227256
> changes that will be made to the component you're testing. Avoid using
228257
> `container` to query for elements!
229258
259+
## `fireEvent`
260+
261+
Because Marko batches DOM updates to avoid unnecessary re-renders, the
262+
[fireEvent](dom-testing-library/api-events.mdx) helpers are re-exported as
263+
`async` functions. Awaiting this ensures that the DOM has properly updated in
264+
response to the event triggered in the test.
265+
266+
```js
267+
await fireEvent.click(getByText('Click me'))
268+
```
269+
230270
## `cleanup`
231271

232-
With client side tests your components are rendered into a placeholder
272+
With client-side tests your components are rendered into a placeholder
233273
HTMLElement. To ensure that your components are properly removed, and destroyed,
234-
you can call `cleanup` at any time which will remove any attached components.
274+
after each test the `cleanup` method is called for you automatically by hooking
275+
into `afterEach` in supported test frameworks. You can also manually call
276+
`cleanup` at any time which will remove all attached components.
235277

236278
```javascript
237-
import { cleanup } from '@marko/testing-library'
238-
// automatically unmount and cleanup DOM after the test is finished.
239-
afterEach(cleanup)
240-
```
279+
import { render, cleanup, screen } from '@marko/testing-library'
280+
import Greeting from './greeting.marko'
241281

242-
To save some typing, you could also import a file with the above.
282+
await render(Greeting, { name: 'Marko' })
243283

244-
```javascript
245-
import '@marko/testing-library/cleanup-after-each'
284+
expect(screen.getByText(/Marko/)).toBeInTheDocument()
285+
286+
// manually cleanup the component before the test is finished
287+
cleanup()
288+
expect(screen.queryByText(/Marko/)).toBeNull()
246289
```
247290

248-
If you are using Jest, you can simply include the following to your Jest config
249-
to avoid doing this in each file.
291+
You can turn off the automatic test cleanup by importing the following module:
250292

251293
```javascript
252-
module.exports = {
253-
...,
254-
setupFilesAfterEnv: ['@marko/testing-library/cleanup-after-each']
255-
}
294+
import '@marko/testing-library/dont-cleanup-after-each'
256295
```
296+
297+
With mocha you can use `mocha -r @marko/testing-library/dont-cleanup-after-each`
298+
as a shorthand.
299+
300+
If you are using Jest, you can include
301+
`setupFilesAfterEnv: ["@marko/testing-library/dont-cleanup-after-each"]` in your
302+
Jest config to avoid doing this in each file.

docs/marko-testing-library/intro.mdx

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,9 @@ title: Marko Testing Library
44
sidebar_label: Introduction
55
---
66

7-
The [`Marko Testing Library`](https://github.com/marko-js/testing-library) is a
8-
very lightweight solution for testing Marko components. It provides light
9-
utility functions on top of
10-
[`@testing-library/dom`](https://github.com/testing-library/dom-testing-library)
11-
in a way that encourages better testing practices.
7+
[`Marko Testing Library`](https://github.com/marko-js/testing-library) builds on
8+
top of [`DOM Testing Library`](dom-testing-library/intro.mdx) by adding APIs for
9+
working with Marko components.
1210

1311
```
1412
npm install --save-dev @marko/testing-library
@@ -19,7 +17,7 @@ npm install --save-dev @marko/testing-library
1917
You want to write maintainable tests for your Marko components. As a part of
2018
this goal, you want your tests to avoid including implementation details of your
2119
components and rather focus on making your tests give you the confidence for
22-
which they are intended. As part of this, you want your testbase to be
20+
which they are intended. As part of this, you want your test suite to be
2321
maintainable in the long run so refactors of your components (changes to
2422
implementation but not functionality) don't break your tests and slow you and
2523
your team down.
@@ -28,9 +26,8 @@ your team down.
2826

2927
The `@marko/testing-library` is a very lightweight solution for testing Marko
3028
components. It provides light utility functions on top of
31-
[`@testing-library/dom`](https://github.com/testing-library/dom-testing-library)
32-
in a way that encourages better testing practices. Its primary guiding principle
33-
is:
29+
[`@testing-library/dom`](dom-testing-library/intro.mdx) in a way that encourages
30+
better testing practices. Its primary guiding principle is:
3431

3532
> [The more your tests resemble the way your software is used, the more confidence they can give you.](guiding-principles.mdx)
3633
@@ -39,7 +36,7 @@ will work with actual DOM nodes. The utilities this library provides facilitate
3936
querying the DOM in the same way the user would. Finding for elements by their
4037
label text (just like a user would), finding links and buttons from their text
4138
(like a user would). It contains a small targeted API and can get out of your
42-
way if absolutely needed with some built in escape hatches.
39+
way if needed with some built-in escape hatches.
4340

4441
This library encourages your applications to be more accessible and allows you
4542
to get your tests closer to using your components the way a user will, which

docs/marko-testing-library/setup.mdx

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ title: Setup
44
sidebar_label: Setup
55
---
66

7-
`Marko Testing Library` is not dependent on any test runner, however it is
7+
`Marko Testing Library` is not dependent on any test runner. However, it is
88
dependent on the test environment. This package works for testing both server
9-
side, and client side Marko templates and provide a slightly different
10-
implementation for each. This is done using a
9+
side, and client-side Marko templates and provides a slightly different
10+
implementation optimized for each. This is done using a
1111
[browser shim](https://github.com/defunctzombie/package-browser-field-spec),
1212
just like in Marko.
1313

@@ -29,36 +29,32 @@ will tell Jest to resolve the
2929
[browser shim](https://github.com/defunctzombie/package-browser-field-spec)
3030
version of all modules as mentioned above.
3131

32-
To test components rendered in the client side, be sure to enable both the
32+
To test components rendered on the client-side, be sure to enable both the
3333
`browser` option and the preset and you are good to go!
3434

3535
**jest.config.js**
3636

3737
```javascript
3838
module.exports = {
39-
preset: '@marko/jest',
40-
browser: true, // Tells Jest to resolve browser shims.
39+
preset: '@marko/jest/preset/browser',
4140
}
4241
```
4342

44-
For testing components rendered server side we can omit the `browser` option,
45-
however ideally you should also set the
46-
[`testEnvironment option`](https://jestjs.io/docs/en/configuration#testenvironment-string)
47-
to `node` which will disable loading JSDOM globally.
43+
For testing components rendered on the server-side we can instead use
44+
`@marko/jest/preset/node` as our jest preset.
4845

4946
**jest.config.js**
5047

5148
```javascript
5249
module.exports = {
53-
preset: '@marko/jest',
54-
testEnvironment: 'node', // Tells Jest not to load a global JSDOM for server side.
50+
preset: '@marko/jest/preset/node',
5551
}
5652
```
5753

5854
A Jest configuration can also have multiple
5955
[projects](https://jestjs.io/docs/en/configuration#projects-array-string-projectconfig)
60-
which we can use to create a combined configuration for server side tests, and
61-
browser side tests, like so:
56+
which we can use to create a combined configuration for server-side tests, and
57+
client-side tests, like so:
6258

6359
**jest.config.js**
6460

@@ -67,14 +63,12 @@ module.exports = {
6763
projects: [
6864
{
6965
displayName: 'server',
70-
testEnvironment: 'node',
71-
preset: '@marko/jest',
66+
preset: '@marko/jest/preset/node',
7267
testRegex: '/__tests__/[^.]+\\.server\\.js$',
7368
},
7469
{
7570
displayName: 'browser',
76-
preset: '@marko/jest',
77-
browser: true,
71+
preset: '@marko/jest/preset/browser',
7872
testRegex: '/__tests__/[^.]+\\.browser\\.js$',
7973
},
8074
],
@@ -86,9 +80,9 @@ module.exports = {
8680
Mocha also works great for testing Marko components. Mocha, however, has no
8781
understanding of
8882
[browser shims](https://github.com/defunctzombie/package-browser-field-spec)
89-
which means out of the box it can only work with server side Marko components.
83+
which means out of the box it can only work with server-side Marko components.
9084

91-
To run server side Marko tests with `mocha` you can simply run the following
85+
To run server-side Marko tests with `mocha` you can simply run the following
9286
command:
9387

9488
```console
@@ -97,9 +91,9 @@ mocha -r marko/node-require
9791

9892
This enables the
9993
[Marko require hook](https://markojs.com/docs/installing/#require-marko-views)
100-
and allows you to require server side Marko templates directly in your tests.
94+
and allows you to require server-side Marko templates directly in your tests.
10195

102-
For client side testing of your components with Mocha often you will use a
96+
For client-side testing of your components with Mocha often you will use a
10397
bundler to build your tests (this will properly resolve the browser shims
10498
mentioned above) and then you can load these tests in some kind of browser
10599
context.

0 commit comments

Comments
 (0)