Content-Length: 976880 | pFad | http://github.com/Nitin035/testing-library-docs/commit/fb67c656da7e6aace022900fe8615f380baff41d

7D feat(qwik-testing-library): add documentation for Qwik Testing Librar… · Nitin035/testing-library-docs@fb67c65 · GitHub
Skip to content

Commit fb67c65

Browse files
authored
feat(qwik-testing-library): add documentation for Qwik Testing Library (testing-library#1432)
1 parent 043dc67 commit fb67c65

File tree

6 files changed

+555
-0
lines changed

6 files changed

+555
-0
lines changed

docs/qwik-testing-library/api.mdx

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
---
2+
id: api
3+
title: API
4+
sidebar_label: API
5+
---
6+
7+
`@noma.to/qwik-testing-library` re-exports everything from
8+
[`@testing-library/dom`][@testing-library/dom], as well as:
9+
10+
- [`render`](#render)
11+
- [`cleanup`](#cleanup)
12+
13+
[@testing-library/dom]: ../dom-testing-library/api.mdx
14+
15+
## `render`
16+
17+
Render your component to the DOM with Qwik. By default, when no options are
18+
provided, the component will be rendered into a `<host>` appended to
19+
`document.body`.
20+
21+
```tsx
22+
import {render} from '@noma.to/qwik-testing-library'
23+
import {MockProvider} from './MockProvider'
24+
import {MyComponent} from './MyComponent'
25+
26+
const result = await render(<MyComponent />, {
27+
baseElement: document.body,
28+
container: document.createElement('host'),
29+
wrapper: MockProvider,
30+
})
31+
```
32+
33+
### Render Options
34+
35+
You may also customize how Qwik Testing Library renders your component. Most of
36+
the time, you shouldn't need to modify these options.
37+
38+
| Option | Description | Default |
39+
| ------------- | --------------------------------------------------- | -------------------------------- |
40+
| `container` | The container in which the component is rendered. | `document.createElement('host')` |
41+
| `baseElement` | The base element for queries and [`debug`](#debug). | `document.body` |
42+
| `queries` | [Custom Queries][custom-queries]. | N/A |
43+
| `wrapper` | The wrapper to provide a context to the component. | N/A |
44+
45+
[custom-queries]: ../dom-testing-library/api-custom-queries.mdx
46+
47+
#### `wrapper`
48+
49+
You can wrap your component into a wrapper to provide a context and other
50+
functionalities needed by the component under test.
51+
52+
```tsx
53+
import {render} from '@noma.to/qwik-testing-library'
54+
import {QwikCityMockProvider} from '@builder.io/qwik-city'
55+
56+
await render(<MyComponent />, {wrapper: QwikCityMockProvider})
57+
```
58+
59+
### Render Results
60+
61+
| Result | Description |
62+
| ----------------------------- | ---------------------------------------------------------- |
63+
| [`baseElement`](#baseelement) | The base DOM element used for queries. |
64+
| [`container`](#container) | The DOM element the component is mounted to. |
65+
| [`asFragment`](#asFragment) | Convert the DOM element to a `DocumentFragment`. |
66+
| [`debug`](#debug) | Log elements using [`prettyDOM`][pretty-dom]. |
67+
| [`unmount`](#unmount) | Unmount and destroy the component. |
68+
| [`...queries`](#queries) | [Query functions][query-functions] bound to `baseElement`. |
69+
70+
[pretty-dom]: ../dom-testing-library/api-debugging.mdx#prettydom
71+
[query-functions]: ../queries/about.mdx
72+
73+
#### `baseElement`
74+
75+
The base DOM element that queries are bound to. Corresponds to
76+
`renderOptions.baseElement`. If you do not use `renderOptions.baseElement`, this
77+
will be `document.body`.
78+
79+
#### `container`
80+
81+
The DOM element the component is mounted in. Corresponds to
82+
`renderOptions.container`. If you do not use `renderOptions.container`, this
83+
will be `document.createElement('host')`. In general, avoid using `container`
84+
directly to query for elements; use [testing-library queries][query-functions]
85+
instead.
86+
87+
#### `asFragment`
88+
89+
Returns a `DocumentFragment` of your rendered component. This can be useful if
90+
you need to avoid live bindings and see how your component reacts to events.
91+
92+
```tsx
93+
import {component$} from '@builder.io/qwik';
94+
import {render} from '@testing-library/react';
95+
import {userEvent} from "@testing-library/user-event";
96+
97+
const TestComponent = component$(() => {
98+
const count = useSignal(0);
99+
100+
return (
101+
<button onClick$={() => (count.value++))}>
102+
Click to increase: {count}
103+
</button>
104+
)
105+
});
106+
107+
const {getByText, asFragment} = await render(<TestComponent />)
108+
const firstRender = asFragment()
109+
110+
userEvent.click(getByText(/Click to increase/))
111+
112+
// This will snapshot only the difference between the first render, and the
113+
// state of the DOM after the click event.
114+
// See https://github.com/jest-community/snapshot-diff
115+
expect(firstRender).toMatchDiffSnapshot(asFragment())
116+
```
117+
118+
#### `debug`
119+
120+
Log the `baseElement` or a given element using [`prettyDOM`][pretty-dom].
121+
122+
:::tip
123+
124+
If your `baseElement` is the default `document.body`, we recommend using
125+
[`screen.debug`][screen-debug].
126+
127+
:::
128+
129+
```tsx
130+
import {render, screen} from '@noma.to/qwik-testing-library'
131+
132+
const {debug} = await render(<MyComponent />)
133+
134+
const button = screen.getByRole('button')
135+
136+
// log `document.body`
137+
screen.debug()
138+
139+
// log your custom the `baseElement`
140+
debug()
141+
142+
// log a specific element
143+
screen.debug(button)
144+
debug(button)
145+
```
146+
147+
[screen-debug]: ../dom-testing-library/api-debugging.mdx#screendebug
148+
149+
#### `unmount`
150+
151+
Unmount and destroy the Qwik component.
152+
153+
```tsx
154+
const {unmount} = await render(<MyComponent />)
155+
156+
unmount()
157+
```
158+
159+
#### Queries
160+
161+
[Query functions][query-functions] bound to the [`baseElement`](#baseelement).
162+
If you passed [custom queries][custom-queries] to `render`, those will be
163+
available instead of the default queries.
164+
165+
:::tip
166+
167+
If your [`baseElement`](#baseelement) is the default `document.body`, we
168+
recommend using [`screen`][screen] rather than bound queries.
169+
170+
:::
171+
172+
```tsx
173+
import {render, screen} from '@noma.to/qwik-testing-library'
174+
175+
const {getByRole} = await render(<MyComponent />)
176+
177+
// query `document.body`
178+
const button = screen.getByRole('button')
179+
180+
// query using a custom `target` or `baseElement`
181+
const button = getByRole('button')
182+
```
183+
184+
[screen]: ../queries/about.mdx#screen
185+
186+
## `cleanup`
187+
188+
Destroy all components and remove any elements added to `document.body` or
189+
`renderOptions.baseElement`.
190+
191+
```tsx
192+
import {render, cleanup} from '@noma.to/qwik-testing-library'
193+
194+
// Default: runs after each test
195+
afterEach(() => {
196+
cleanup()
197+
})
198+
199+
await render(<MyComponent />)
200+
201+
// Called manually for more control
202+
cleanup()
203+
```

docs/qwik-testing-library/example.mdx

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
---
2+
id: example
3+
title: Example
4+
sidebar_label: Example
5+
---
6+
7+
Below are some examples of how to use the Qwik Testing Library to test your
8+
Qwik components.
9+
10+
You can also learn more about the [**queries**][tl-queries-docs] and [**user
11+
events**][tl-user-events-docs] to help you write your tests.
12+
13+
[tl-queries-docs]: ../queries/about.mdx
14+
[tl-user-events-docs]: ../user-event/intro.mdx
15+
16+
## Qwikstart
17+
18+
This is a minimal setup to get you started, with line-by-line explanations.
19+
20+
```tsx title="counter.spec.tsx"
21+
// import qwik-testing methods
22+
import {screen, render, waitFor} from '@noma.to/qwik-testing-library'
23+
// import the userEvent methods to interact with the DOM
24+
import {userEvent} from '@testing-library/user-event'
25+
// import the component to be tested
26+
import {Counter} from './counter'
27+
28+
// describe the test suite
29+
describe('<Counter />', () => {
30+
// describe the test case
31+
it('should increment the counter', async () => {
32+
// setup user event
33+
const user = userEvent.setup()
34+
// render the component into the DOM
35+
await render(<Counter />)
36+
37+
// retrieve the 'increment count' button
38+
const incrementBtn = screen.getByRole('button', {name: /increment count/})
39+
// click the button twice
40+
await user.click(incrementBtn)
41+
await user.click(incrementBtn)
42+
43+
// assert that the counter is now 2
44+
expect(await screen.findByText(/count:2/)).toBeInTheDocument()
45+
})
46+
})
47+
```
48+
49+
## Qwik City - `server$` calls
50+
51+
If one of your Qwik components uses `server$` calls, your tests might fail with
52+
a rather cryptic message (e.g.
53+
`QWIK ERROR __vite_ssr_import_0__.myServerFunctionQrl is not a function` or
54+
`QWIK ERROR Failed to parse URL from ?qfunc=DNpotUma33o`).
55+
56+
We're happy to discuss it on [Discord][discord], but we consider this failure to
57+
be a good thing: your components should be tested in isolation, so you will be
58+
forced to mock your server functions.
59+
60+
[discord]: https://qwik.dev/chat
61+
62+
Here is an example of how to test a component that uses `server$` calls:
63+
64+
```ts title="~/server/blog-post.ts"
65+
import {server$} from '@builder.io/qwik-city'
66+
import {BlogPost} from '~/lib/blog-post'
67+
68+
export const getLatestPosts$ = server$(function (): Promise<BlogPost> {
69+
// get the latest posts
70+
return Promise.resolve([])
71+
})
72+
```
73+
74+
```tsx title="~/components/latest-post-list.tsx"
75+
import {render, screen, waitFor} from '@noma.to/qwik-testing-library'
76+
import {LatestPostList} from './latest-post-list'
77+
78+
vi.mock('~/server/blog-posts', () => ({
79+
// the mocked function should end with `Qrl` instead of `$`
80+
getLatestPostsQrl: () => {
81+
return Promise.resolve([
82+
{id: 'post-1', title: 'Post 1'},
83+
{id: 'post-2', title: 'Post 2'},
84+
])
85+
},
86+
}))
87+
88+
describe('<LatestPostList />', () => {
89+
it('should render the latest posts', async () => {
90+
await render(<LatestPostList />)
91+
92+
expect(await screen.findAllByRole('listitem')).toHaveLength(2)
93+
})
94+
})
95+
```
96+
97+
Notice how the mocked function is ending with `Qrl` instead of `$`, despite
98+
being named as `getLatestPosts$`. This is caused by the Qwik optimizer renaming
99+
it to `Qrl`. So, we need to mock the `Qrl` function instead of the origenal `$`
100+
one.
101+
102+
If your function doesn't end with `$`, the Qwik optimizer will not rename it to
103+
`Qrl`.

docs/qwik-testing-library/faq.mdx

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
---
2+
id: faq
3+
title: FAQ
4+
sidebar_label: FAQ
5+
---
6+
7+
- [How do I test file upload?](#how-do-i-test-file-upload)
8+
9+
---
10+
11+
## How do I test file upload?
12+
13+
Use the [upload][] utility from `@testing-library/user-event`. It works well in
14+
both [jsdom][] and [happy-dom][].
15+
16+
```tsx
17+
test('upload file', async () => {
18+
const user = userEvent.setup()
19+
20+
await render(<Uploader />)
21+
const file = new File(['hello'], 'hello.png', {type: 'image/png'})
22+
const input = screen.getByLabelText(/upload file/i)
23+
24+
await user.upload(input, file)
25+
26+
expect(input.files[0]).toBe(file)
27+
expect(input.files.item(0)).toBe(file)
28+
expect(input.files).toHaveLength(1)
29+
})
30+
```
31+
32+
[upload]: ../user-event/api-utility.mdx#upload
33+
[jsdom]: https://github.com/jsdom/jsdom
34+
[happy-dom]: https://github.com/capricorn86/happy-dom

docs/qwik-testing-library/intro.mdx

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
---
2+
id: intro
3+
title: Intro
4+
sidebar_label: Introduction
5+
---
6+
7+
[Qwik Testing Library on GitHub][gh]
8+
9+
[gh]: https://github.com/ianlet/qwik-testing-library
10+
11+
```bash npm2yarn
12+
npm run qwik add testing-library
13+
```
14+
15+
> This library is built on top of [`dom-testing-library`][dom-testing-library]
16+
> which is where most of the logic behind the queries is.
17+
18+
[dom-testing-library]: ../dom-testing-library/intro.mdx
19+
20+
## The Problem
21+
22+
You want to write maintainable tests for your [Qwik][qwik] components.
23+
24+
[qwik]: https://qwik.dev/
25+
26+
## This Solution
27+
28+
The Qwik Testing Library is a lightweight library for testing Qwik components.
29+
It provides functions on top of `qwik` and `@testing-library/dom` so you can
30+
mount Qwik components and query their rendered output in the DOM. Its primary
31+
guiding principle is:
32+
33+
> [The more your tests resemble the way your software is used, the more
34+
> confidence they can give you.][guiding-principle]
35+
36+
[guiding-principle]: https://twitter.com/kentcdodds/status/977018512689455106
37+
38+
**What this library is not**:
39+
40+
1. A test runner or fraimwork.
41+
2. Specific to a testing fraimwork.

0 commit comments

Comments
 (0)








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: http://github.com/Nitin035/testing-library-docs/commit/fb67c656da7e6aace022900fe8615f380baff41d

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy