diff --git a/docs/guide/browser/index.md b/docs/guide/browser/index.md
index a33310adee8a..d8c8499a539c 100644
--- a/docs/guide/browser/index.md
+++ b/docs/guide/browser/index.md
@@ -399,6 +399,10 @@ However, Vitest also provides packages to render components for several popular
- [`vitest-browser-svelte`](https://github.com/vitest-dev/vitest-browser-svelte) to render [svelte](https://svelte.dev) components
- [`vitest-browser-react`](https://github.com/vitest-dev/vitest-browser-react) to render [react](https://react.dev) components
+Community packages are available for other frameworks:
+
+- [`vitest-browser-lit`](https://github.com/EskiMojo14/vitest-browser-lit) to render [lit](https://lit.dev) components
+
If your framework is not represented, feel free to create your own package - it is a simple wrapper around the framework renderer and `page.elementLocator` API. We will add a link to it on this page. Make sure it has a name starting with `vitest-browser-`.
Besides rendering components and locating elements, you will also need to make assertions. Vitest bundles the [`@testing-library/jest-dom`](https://github.com/testing-library/jest-dom) library to provide a wide range of DOM assertions out of the box. Read more at the [Assertions API](/guide/browser/assertion-api).
@@ -473,6 +477,21 @@ test('loads and displays greeting', async () => {
await expect.element(screen.getByRole('button')).toBeDisabled()
})
```
+```ts [lit]
+import { render } from 'vitest-browser-lit'
+import { html } from 'lit'
+import './greeter-button'
+
+test('greeting appears on click', async () => {
+ const screen = render(html``)
+
+ const button = screen.getByRole('button')
+ await button.click()
+ const greeting = screen.getByText(/hello world/iu)
+
+ await expect.element(greeting).toBeInTheDocument()
+})
+```
:::
Vitest doesn't support all frameworks out of the box, but you can use external tools to run tests with these frameworks. We also encourage the community to create their own `vitest-browser` wrappers - if you have one, feel free to add it to the examples above.
diff --git a/packages/vitest/src/create/browser/creator.ts b/packages/vitest/src/create/browser/creator.ts
index f279de678c0e..21d84d629eac 100644
--- a/packages/vitest/src/create/browser/creator.ts
+++ b/packages/vitest/src/create/browser/creator.ts
@@ -84,6 +84,11 @@ function getFramework(): prompt.Choice[] {
value: 'react',
description: '"The library for web and native user interfaces"',
},
+ {
+ title: 'lit',
+ value: 'lit',
+ description: '"A simple library for building fast, lightweight web components."',
+ },
{
title: 'preact',
value: 'preact',
@@ -112,6 +117,8 @@ function getFrameworkTestPackage(framework: string) {
return 'vitest-browser-svelte'
case 'react':
return 'vitest-browser-react'
+ case 'lit':
+ return 'vitest-browser-lit'
case 'preact':
return '@testing-library/preact'
case 'solid':
@@ -205,6 +212,9 @@ function getPossibleFramework(dependencies: Record) {
if (dependencies.svelte || dependencies['@sveltejs/kit']) {
return 'svelte'
}
+ if (dependencies.lit || dependencies['lit-html']) {
+ return 'lit'
+ }
if (dependencies.preact) {
return 'preact'
}
diff --git a/packages/vitest/src/create/browser/examples.ts b/packages/vitest/src/create/browser/examples.ts
index 7e30e29fced9..49ad549f48aa 100644
--- a/packages/vitest/src/create/browser/examples.ts
+++ b/packages/vitest/src/create/browser/examples.ts
@@ -135,6 +135,62 @@ test('renders name', async () => {
`,
}
+const litExample = {
+ name: 'HelloWorld.js',
+ js: `
+import { html, LitElement } from 'lit'
+
+export class HelloWorld extends LitElement {
+ static properties = {
+ name: { type: String },
+ }
+
+ constructor() {
+ super()
+ this.name = 'World'
+ }
+
+ render() {
+ return html\`Hello \${this.name}!
\`
+ }
+}
+
+customElements.define('hello-world', HelloWorld)
+`,
+ ts: `
+import { html, LitElement } from 'lit'
+import { customElement, property } from 'lit/decorators.js'
+
+@customElement('hello-world')
+export class HelloWorld extends LitElement {
+ @property({ type: String })
+ name = 'World'
+
+ render() {
+ return html\`Hello \${this.name}!
\`
+ }
+}
+
+declare global {
+ interface HTMLElementTagNameMap {
+ 'hello-world': HelloWorld
+ }
+}
+`,
+ test: `
+import { expect, test } from 'vitest'
+import { render } from 'vitest-browser-lit'
+import { html } from 'lit'
+import './HelloWorld.js'
+
+test('renders name', async () => {
+ const screen = render(html\`\`)
+ const element = screen.getByText('Hello Vitest!')
+ await expect.element(element).toBeInTheDocument()
+})
+`,
+}
+
const vanillaExample = {
name: 'HelloWorld.js',
js: `
@@ -191,6 +247,8 @@ function getExampleTest(framework: string) {
return vueExample
case 'svelte':
return svelteExample
+ case 'lit':
+ return litExample
case 'marko':
return markoExample
default: