Skip to content

Commit 288b86f

Browse files
authored
docs(svelte-testing-library): update API docs for v5 release (#1369)
1 parent 882dff9 commit 288b86f

File tree

1 file changed

+247
-90
lines changed

1 file changed

+247
-90
lines changed

docs/svelte-testing-library/api.mdx

+247-90
Original file line numberDiff line numberDiff line change
@@ -4,149 +4,306 @@ title: API
44
sidebar_label: API
55
---
66

7-
- [`@testing-library/dom`](#testing-library-dom)
7+
`@testing-library/svelte` re-exports everything from
8+
[`@testing-library/dom`][@testing-library/dom], as well as:
9+
810
- [`render`](#render)
11+
- [`act`](#act)
912
- [`cleanup`](#cleanup)
10-
- [`act`](#act-async)
11-
- [`fireEvent`](#fireevent-async)
12-
13-
---
13+
- [`fireEvent` (async)](#fireevent-async)
1414

15-
## `@testing-library/dom`
16-
17-
This library re-exports everything from the DOM Testing Library
18-
(`@testing-library/dom`). See the [documentation](queries/about.mdx) to see what
19-
goodies you can use.
20-
21-
📝 `fireEvent` is an `async` method when imported from
22-
`@testing-library/svelte`. This is because it calls [`tick`][svelte-tick] which
23-
tells Svelte to apply any new changes to the DOM.
15+
[@testing-library/dom]: ../dom-testing-library/api.mdx
2416

2517
## `render`
2618

19+
Render your component to the DOM with Svelte. By default, the component will be
20+
rendered into a `<div>` appended to `document.body`.
21+
2722
```js
2823
import {render} from '@testing-library/svelte'
24+
import MyComponent from './MyComponent.svelte'
2925

30-
const view = render(YourComponent, {ComponentOptions}, {RenderOptions})
26+
const result = render(MyComponent, componentOptions, renderOptions)
3127
```
3228

3329
### Component Options
3430

35-
These are the options you pass when instantiating your Svelte `Component`.
36-
Please refer to the
37-
[Client-side component API](https://svelte.dev/docs#run-time-client-side-component-api-creating-a-component).
31+
You may customize how the component is created and mounted. These options are
32+
passed directly to Svelte.
3833

39-
📝 If the only option you're passing in is `props`, then you can just pass them
40-
in directly.
34+
If you only need to send props to your component, you may pass props directly,
35+
as long as those props don't share a name with a component option.
4136

4237
```js
43-
// With options.
44-
const view = render(YourComponent, {
45-
target: MyTarget,
38+
// pass props to the component
39+
render(YourComponent, {myProp: 'value'})
40+
41+
// pass props and other options to the component
42+
render(YourComponent, {
4643
props: {myProp: 'value'},
44+
context: new Map([[('theme': 'dark')]]),
4745
})
48-
49-
// Props only.
50-
const view = render(YourComponent, {myProp: 'value'})
5146
```
5247

48+
The most common options you will need are:
49+
50+
| Option | Description | Default |
51+
| --------- | ------------------------------------------------------- | ----------------------------------- |
52+
| `props` | Props to pass to the component. | N/A |
53+
| `context` | A `Map` of context values to render the component with. | N/A |
54+
| `target` | An `HTMLElement` to render the component into. | `<div>` appended to `document.body` |
55+
56+
If you specify the `target` option, the `target` element will _not_ be appended
57+
to `document.body` automatically, and it will be used as the base element for
58+
[bound queries](#queries) and [`debug`](#debug).
59+
60+
Refer to the [Svelte client-side component API docs][svelte-component-api] for
61+
all available options.
62+
63+
[svelte-component-api]: https://svelte.dev/docs/client-side-component-api
64+
5365
### Render Options
5466

55-
| Option | Description | Default |
56-
| ----------- | ----------------------------------------------------------------------------------- | --------------- |
57-
| `container` | The HTML element the component is mounted into. | `document.body` |
58-
| `queries` | Queries to bind to the container. See [within](dom-testing-library/api-within.mdx). | `null` |
67+
You may also customize how Svelte Testing Library renders your component. Most
68+
of the time, you shouldn't need to modify these options.
69+
70+
:::caution
71+
72+
Prior to `@testing-library/[email protected]`, the `baseElement` option was named
73+
`container`.
74+
75+
:::
76+
77+
| Option | Description | Default |
78+
| ------------- | --------------------------------------------------- | ------------------------------------------ |
79+
| `baseElement` | The base element for queries and [`debug`](#debug). | `componentOptions.target ?? document.body` |
80+
| `queries` | [Custom Queries][custom-queries]. | N/A |
81+
82+
[custom-queries]: ../dom-testing-library/api-custom-queries.mdx
83+
84+
### Render Results
85+
86+
| Result | Description |
87+
| ----------------------------- | ---------------------------------------------------------- |
88+
| [`baseElement`](#baseelement) | The base DOM element used for queries. |
89+
| [`component`](#component) | The mounted Svelte component. |
90+
| [`container`](#container) | The DOM element the component is mounted to. |
91+
| [`debug`](#debug) | Log elements using [`prettyDOM`][pretty-dom]. |
92+
| [`rerender`](#rerender) | Update the component's props. |
93+
| [`unmount`](#unmount) | Unmount and destroy the component. |
94+
| [`...queries`](#queries) | [Query functions][query-functions] bound to `baseElement`. |
95+
96+
[pretty-dom]: ../dom-testing-library/api-debugging.mdx#prettydom
97+
[query-functions]: ../queries/about.mdx
98+
99+
#### `baseElement`
100+
101+
_Added in `@testing-library/[email protected]`_
102+
103+
The base DOM element that queries are bound to. Corresponds to
104+
`renderOptions.baseElement`. If you do not use `componentOptions.target` nor
105+
`renderOptions.baseElement`, this will be `document.body`.
106+
107+
#### `container`
108+
109+
The DOM element the component is mounted in. Corresponds to
110+
`componentOptions.target`. In general, avoid using `container` directly to query
111+
for elements; use [testing-library queries][query-functions] instead.
112+
113+
:::tip
114+
115+
Use `container.firstChild` to get the first rendered element of your component.
116+
117+
:::
118+
119+
:::caution
120+
121+
Prior to `@testing-library/[email protected]`, `container` was set to the base
122+
element. Use `container.firstChild.firstChild` to get the first rendered element
123+
of the component in earlier versions.
124+
125+
:::
126+
127+
#### `component`
128+
129+
The Svelte component instance. See the [Svelte component
130+
API][svelte-component-api] for more details.
131+
132+
:::tip
133+
134+
Avoid using `component` except to test developer-facing APIs, like exported
135+
functions. Instead, interact with the DOM. Read [Avoid the Test User][test-user]
136+
by Kent C. Dodds to understand the difference between the **end user** and
137+
**developer user**.
138+
139+
:::
140+
141+
[test-user]: https://kentcdodds.com/blog/avoid-the-test-user
142+
143+
#### `debug`
144+
145+
Log the `baseElement` or a given element using [`prettyDOM`][pretty-dom].
146+
147+
:::tip
148+
149+
If your `baseElement` is the default `document.body`, we recommend using
150+
[`screen.debug`][screen-debug].
151+
152+
:::
153+
154+
```js
155+
import {render, screen} from '@testing-library/svelte'
156+
157+
const {debug} = render(MyComponent, {myProp: 'value'})
158+
159+
const button = screen.getByRole('button')
59160

60-
### Results
161+
// log `document.body`
162+
screen.debug()
61163

62-
| Result | Description |
63-
| ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
64-
| `container` | The HTML element the component is mounted into. |
65-
| `component` | The newly created Svelte component. Generally, this should only be used when testing exported functions, or when you're testing developer facing API's. Outside of said cases avoid using the component directly to build tests, instead of interacting with the rendered Svelte component, work with the DOM. Have a read of [Avoid the Test User](https://kentcdodds.com/blog/avoid-the-test-user) by Kent C. Dodds to understand the difference between the **end user** and **developer user**. |
66-
| `debug` | Logs the `container` using [prettyDom](dom-testing-library/api-debugging.mdx/#prettydom). |
67-
| `unmount` | Unmounts the component from the `target` by calling `component.$destroy()`. |
68-
| `rerender` | Calls render again destroying the old component, and mounting the new component on the original `target` with any new options passed in. |
69-
| `...queries` | Returns all [query functions](queries/about.mdx) that are bound to the `container`. If you pass in `query` arguments than this will be those, otherwise all. |
164+
// log your custom `target` or `baseElement`
165+
debug()
166+
167+
// log a specific element
168+
screen.debug(button)
169+
debug(button)
170+
```
171+
172+
[screen-debug]: ../dom-testing-library/api-debugging.mdx#screendebug
173+
174+
#### `rerender`
175+
176+
Update one or more of the component's props and wait for Svelte to update.
177+
178+
```js
179+
const {rerender} = render(MyComponent, {myProp: 'value'})
180+
181+
await rerender({myProp: 'new value'}))
182+
```
183+
184+
:::caution
185+
186+
Prior to `@testing-library/[email protected]`, calling `rerender` would destroy and
187+
remount the component. Use `component.$set` and [`act`](#act) to update props in
188+
earlier versions:
189+
190+
```js
191+
const {component} = render(MyComponent, {myProp: 'value'})
192+
193+
await act(() => component.$set({myProp: 'new value'}))
194+
```
195+
196+
:::
197+
198+
#### `unmount`
199+
200+
Unmount and destroy the Svelte component.
201+
202+
```js
203+
const {unmount} = render(MyComponent, {myProp: 'value'})
204+
205+
unmount()
206+
```
207+
208+
#### Queries
209+
210+
[Query functions][query-functions] bound to the [`baseElement`](#baseelement).
211+
If you passed [custom queries][custom-queries] to `render`, those will be
212+
available instead of the default queries.
213+
214+
:::tip
215+
216+
If your [`baseElement`](#baseelement) is the default `document.body`, we
217+
recommend using [`screen`][screen] rather than bound queries.
218+
219+
:::
220+
221+
```js
222+
import {render, screen} from '@testing-library/svelte'
223+
224+
const {getByRole} = render(MyComponent, {myProp: 'value'})
225+
226+
// query `document.body`
227+
const button = screen.getByRole('button')
228+
229+
// query using a custom `target` or `baseElement`
230+
const button = getByRole('button')
231+
```
232+
233+
[screen]: ../queries/about.mdx#screen
70234

71235
## `cleanup`
72236

73-
> This is called automatically if your testing framework (such as mocha, Jest or
74-
> Jasmine) injects a global `afterEach()` function into the testing environment.
75-
> If not, you will need to call `cleanup()` after each test.
237+
Destroy all components and remove any elements added to `document.body`.
238+
239+
:::info
240+
241+
`cleanup` is called automatically if your testing framework adds a global
242+
`afterEach` method (e.g. Mocha, Jest, or Jasmine), or if you use
243+
`import '@testing-library/svelte/vitest'` in your [Vitest setup
244+
file][vitest-setup]. Usually, you shouldn't need to call `cleanup` yourself.
76245

77-
Unmounts the component from the container and destroys the container.
246+
If you'd like to disable automatic cleanup in a framework that uses a global
247+
`afterEach` method, set `process.env.STL_SKIP_AUTO_CLEANUP`.
78248

79-
📝 When you import anything from the library, this automatically runs after each
80-
test. If you'd like to disable this then set `process.env.STL_SKIP_AUTO_CLEANUP`
81-
to true or import `dont-clean-up-after-each` from the library.
249+
:::
82250

83251
```js
84252
import {render, cleanup} from '@testing-library/svelte'
85253

254+
// Default: runs after each test
86255
afterEach(() => {
87256
cleanup()
88-
}) // Default on import: runs it after each test.
257+
})
89258

90259
render(YourComponent)
91260

92-
cleanup() // Or like this for more control.
261+
// Called manually for more control
262+
cleanup()
93263
```
94264

95-
## `act` (`async`)
96-
97-
An `async` helper method that takes in a `function` or `Promise` that is
98-
immediately called/resolved, and then calls [`tick`][svelte-tick] so all pending
99-
state changes are flushed, and the view now reflects any changes made to the
100-
DOM.
265+
[vitest-setup]: ./setup.mdx#vitest
101266

102-
## `fireEvent` (`async`)
267+
## `act`
103268

104-
Calls `@testing-library/dom` [fireEvent](dom-testing-library/api-events.mdx). It
105-
is an `async` method due to calling [`tick`][svelte-tick] which tells Svelte to
106-
flush all pending state changes, basically it updates the DOM to reflect the new
107-
changes.
269+
Ensure all pending updates from Svelte are applied to the DOM. Optionally, you
270+
may pass a function to be called before updates are applied. If the function
271+
returns a `Promise`, it will be resolved first.
108272

109-
**Component**
273+
Uses Svelte's [`tick`][svelte-tick] method to apply updates.
110274

111-
```html
112-
<script>
113-
let count = 0
275+
```js
276+
import {act, render} from '@testing-library/svelte'
114277

115-
function handleClick() {
116-
count += 1
117-
}
118-
</script>
278+
const {component} = render(MyComponent)
119279

120-
<button on:click="{handleClick}">Count is {count}</button>
280+
await act(() => {
281+
component.updateSomething()
282+
})
121283
```
122284

123-
**Test**
285+
[svelte-tick]: https://svelte.dev/docs/svelte#tick
124286

125-
```js
126-
import '@testing-library/jest-dom'
287+
## `fireEvent` (async)
127288

128-
import {render, fireEvent, screen} from '@testing-library/svelte'
289+
Fire an event and wait for Svelte to update the DOM. An asynchronous wrapper of
290+
DOM Testing Library's [`fireEvent`][fire-event].
129291

130-
import Comp from '..'
292+
:::tip
131293

132-
test('count increments when button is clicked', async () => {
133-
render(Comp)
134-
const button = screen.getByText('Count is 0')
294+
Where possible, we recommend [`@testing-library/user-event`][user-event] instead
295+
of `fireEvent`.
135296

136-
// Option 1.
137-
await fireEvent.click(button)
138-
expect(button).toHaveTextContent('Count is 1')
297+
:::
139298

140-
// Option 2.
141-
await fireEvent(
142-
button,
143-
new MouseEvent('click', {
144-
bubbles: true,
145-
cancelable: true,
146-
}),
147-
)
148-
expect(button).toHaveTextContent('Count is 2')
149-
})
299+
```js
300+
import {fireEvent, render, screen} from '@testing-library/svelte'
301+
302+
render(MyComponent)
303+
304+
const button = screen.getByRole('button')
305+
await fireEvent.click(button)
150306
```
151307

152-
[svelte-tick]: https://svelte.dev/docs/svelte#tick
308+
[fire-event]: ../dom-testing-library/api-events.mdx
309+
[user-event]: ../user-event/intro.mdx

0 commit comments

Comments
 (0)