+ {@render message?.(greeting)} +
+``` +::: + +## See also + +- [Svelte Testing Library documentation](https://testing-library.com/docs/svelte-testing-library/intro) +- [Svelte Testing Library examples](https://github.com/testing-library/svelte-testing-library/tree/main/examples) diff --git a/docs/api/browser/vue.md b/docs/api/browser/vue.md new file mode 100644 index 000000000000..965f9efcba2b --- /dev/null +++ b/docs/api/browser/vue.md @@ -0,0 +1,205 @@ +--- +outline: deep +--- + +# vitest-browser-vue + +The community [`vitest-browser-vue`](https://www.npmjs.com/package/vitest-browser-vue) package renders [Vue](https://vuejs.org/) components in [Browser Mode](/guide/browser/). + +```ts +import { render } from 'vitest-browser-vue' +import { expect, test } from 'vitest' +import Component from './Component.vue' + +test('counter button increments the count', async () => { + const screen = render(Component, { + props: { + initialCount: 1, + } + }) + + await screen.getByRole('button', { name: 'Increment' }).click() + + await expect.element(screen.getByText('Count is 2')).toBeVisible() +}) +``` + +::: warning +This library takes inspiration from [`@testing-library/vue`](https://github.com/testing-library/vue-testing-library). + +If you have used `@testing-library/vue` in your tests before, you can keep using it, however the `vitest-browser-vue` package provides certain benefits unique to the Browser Mode that `@testing-library/vue` lacks: + +`vitest-browser-vue` returns APIs that interact well with built-in [locators](/api/browser/locators), [user events](/api/browser/interactivity) and [assertions](/api/browser/assertions): for example, Vitest will automatically retry the element until the assertion is successful, even if it was rerendered between the assertions. +::: + +The package exposes two entry points: `vitest-browser-vue` and `vitest-browser-vue/pure`. They expose identical API, but the `pure` entry point doesn't add a handler to remove the component before the next test has started. + +## render + +```ts +export function render( + component: Component, + options?: ComponentRenderOptions, +): RenderResult +``` + +### Options + +The `render` function supports all [`mount` options](https://test-utils.vuejs.org/api/#mount) from `@vue/test-utils` (except `attachTo` - use `container` instead). In addition to them, there are also `container` and `baseElement`. + +#### container + +By default, Vitest will create a `div`, append it to `document.body`, and render your component there. If you provide your own `HTMLElement` container, it will not be appended automatically — you'll need to call `document.body.appendChild(container)` before `render`. + +For example, if you are unit testing a `tbody` element, it cannot be a child of a `div`. In this case, you can specify a `table` as the render container. + +```js +const table = document.createElement('table') + +const { container } = render(TableBody, { + props, + // ⚠️ appending the element to `body` manually before rendering + container: document.body.appendChild(table), +}) +``` + +#### baseElement + +If the `container` is specified, then this defaults to that, otherwise this defaults to `document.body`. This is used as the base element for the queries as well as what is printed when you use `debug()`. + +### Render Result + +In addition to documented return value, the `render` function also returns all available [locators](/api/browser/locators) relative to the [`baseElement`](#baseelement), including [custom ones](/api/browser/locators#custom-locators). + +```ts +const screen = render(TableBody, { props }) + +await screen.getByRole('link', { name: 'Expand' }).click() +``` + +#### container + +The containing DOM node where your Vue component is rendered. This is a regular DOM node, so you technically could call `container.querySelector` etc. to inspect the children. + +:::danger +If you find yourself using `container` to query for rendered elements then you should reconsider! The [locators](/api/browser/locators) are designed to be more resilient to changes that will be made to the component you're testing. Avoid using `container` to query for elements! +::: + +#### baseElement + +The containing DOM node where your Vue component is rendered in the `container`. If you don't specify the `baseElement` in the options of render, it will default to `document.body`. + +This is useful when the component you want to test renders something outside the container `div`, e.g. when you want to snapshot test your portal component which renders its HTML directly in the body. + +:::tip +The queries returned by the `render` looks into `baseElement`, so you can use queries to test your portal component without the `baseElement`. +::: + +#### locator + +The [locator](/api/browser/locators) of your `container`. It is useful to use queries scoped only to your component, or pass it down to other assertions: + +```js +import { render } from 'vitest-browser-vue' + +const { locator } = render(NumberDisplay, { + props: { number: 2 } +}) + +await locator.getByRole('button').click() +await expect.element(locator).toHaveTextContent('Hello World') +``` + +#### debug + +```ts +function debug( + el?: HTMLElement | HTMLElement[] | Locator | Locator[], + maxLength?: number, + options?: PrettyDOMOptions, +): void +``` + +This method is a shortcut for `console.log(prettyDOM(baseElement))`. It will print the DOM content of the container or specified elements to the console. + +#### rerender + +```ts +function rerender(props: Partial