Skip to content

Commit 2bfe0ce

Browse files
committed
02: improve readme
1 parent 8d07db7 commit 2bfe0ce

40 files changed

+616
-24
lines changed

exercises/02.vitest-browser-mode/01.problem.installation-and-setup/README.mdx

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,13 @@ npm uninstall jsdom @testing-library/react
1515
Now I can install the dependencies required for the Browser Mode in Vitest:
1616

1717
```sh
18-
npm i -D @vitest/browser vitest-browser-react playwright
18+
npm i -D @vitest/browser vitest-browser-react
1919
```
2020

2121
Let's break down what these packages do:
2222

2323
- [`@vitest/browser`](https://www.npmjs.com/package/@vitest/browser) enables the browser mode and provides the bindings to interact with the underlying browser;
2424
- [`vitest-browser-react`](https://www.npmjs.com/package/vitest-browser-react) provisions rendering of React components (similar to `@testing-library/react`);
25-
- [`playwright`](https://www.npmjs.com/package/playwright) will serve as the actual browser automation (a browser provider) that Vitest will use to run tests.
2625

2726
The installation step is done, and now it's time to configure Vitest is it can run my component tests in the actual browser.
2827

@@ -68,8 +67,26 @@ export default defineConfig({
6867
})
6968
```
7069

71-
> 🦉 You can configure _multiple browser instances_ to execute your component tests. This is handy for solid cross-browser code coverage.
72-
73-
// TODO: Mention `"types": ["@vitest/browser/providers/playwright"]` in `tsconfig.node.json` to have `.toBeVisible()` and other nice browser assertions!
70+
> 🦉 You can configure _multiple browser instances_ to execute your component tests. This is handy for solid cross-browser code coverage. You will learn how to use browser providers later in this workshop.
71+
72+
## Configure TypeScript
73+
74+
The last thing that remains is to extend the TypeScript configuration to recognize DOM-specific matches, like `expect().toBeVisible()` as they come built-in in Vitest.
75+
76+
```json filename=tsconfig.test.json add=10
77+
{
78+
"extends": "./tsconfig.base.json",
79+
"include": ["vite.config.ts", "**/*.test.ts*"],
80+
"compilerOptions": {
81+
"target": "esnext",
82+
"module": "preserve",
83+
"types": [
84+
"vitest/globals",
85+
// 👇
86+
"@vitest/browser/matchers"
87+
]
88+
}
89+
}
90+
```
7491

75-
This concludes the installation step!
92+
And with that, the installation step is done!
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Migrate the test
2+
3+
Since you are migrating your test from running in Node.js to running in the browser, some changes have to be made to your test suites for that to work. Luckily, those changes aren't dramatic, and mostly involve importing the same things from different packages.
4+
5+
> 🦉 The biggest change from adopting Vitest Browser Mode is that it splits the rendering and the UI selection/interaction between two separate packages: `@vitest/browser` and the framework-specific renderer package, like `vitest-browser-react`.
6+
7+
👨‍💼 In this exercise, your task is to complete the migration of the `file-review.test.tsx` test suite to Vitest Browser Mode. Follow the instructions in that file and have the test passing at the end by calling `npm test`.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<title>Vite App</title>
8+
<link rel="preconnect" href="https://fonts.googleapis.com" />
9+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
10+
</head>
11+
<body>
12+
<div id="root"></div>
13+
<script type="module" src="/src/main.tsx"></script>
14+
</body>
15+
</html>
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"name": "exercises_02.vitest-browser-mode_02.problem.migrate-the-test",
3+
"scripts": {
4+
"dev": "vite",
5+
"test": "vitest"
6+
},
7+
"dependencies": {
8+
"react": "^19.0.0",
9+
"react-dom": "^19.0.0"
10+
},
11+
"devDependencies": {
12+
"@testing-library/dom": "^10.4.0",
13+
"@types/react": "^19.0.6",
14+
"@types/react-dom": "^19.0.3",
15+
"@vitejs/plugin-react": "^4.3.4",
16+
"@vitest/browser": "^3.0.0-beta.4",
17+
"autoprefixer": "^10.4.20",
18+
"postcss": "^8.4.49",
19+
"tailwindcss": "^3.4.17",
20+
"vite": "^6.0.7",
21+
"vitest": "^3.0.0-beta.4",
22+
"vitest-browser-react": "^0.0.4"
23+
}
24+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export default {
2+
plugins: {
3+
tailwindcss: {},
4+
autoprefixer: {},
5+
},
6+
}
Lines changed: 1 addition & 0 deletions
Loading
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { useState } from 'react'
2+
import { FilePreview } from './file-preview.jsx'
3+
4+
export function App() {
5+
const [file, setFile] = useState<File>()
6+
7+
return (
8+
<div>
9+
{file ? (
10+
<div className="flex flex-col items-center">
11+
<FilePreview file={file} />
12+
<button
13+
className="mt-10 rounded-full bg-slate-800 px-6 py-2 text-sm font-bold text-white hover:bg-slate-600"
14+
onClick={() => setFile(undefined)}
15+
>
16+
Preview another file
17+
</button>
18+
</div>
19+
) : (
20+
<div className="rounded-md border border-slate-200 bg-white p-4 shadow-lg shadow-slate-200">
21+
<input
22+
type="file"
23+
name="file"
24+
required
25+
className="text-sm font-medium"
26+
onChange={(event) => {
27+
const [selectedFile] = event.currentTarget.files || []
28+
29+
if (selectedFile) {
30+
setFile(selectedFile)
31+
}
32+
}}
33+
/>
34+
</div>
35+
)}
36+
</div>
37+
)
38+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// 💣 Remove the import from `@testing-library/react`. You won't need it anymore.
2+
import { render, screen } from '@testing-library/react'
3+
// 🐨 Import `page` from '@vitest/browser'
4+
// 💰 import { foo } from 'bar'
5+
//
6+
// 🐨 Import `render` from 'vitest-browser-react'.
7+
// 💰 import { foo } from 'bar'
8+
import { FilePreview } from './file-preview.tsx'
9+
10+
test('displays the preview card', async () => {
11+
render(<FilePreview file={new File(['hello world'], 'file.txt')} />)
12+
13+
// 🐨 Replace `expect()` with `expect.element()`.
14+
expect(
15+
// 🐨 Replace the `screen.getByText` function with
16+
// `page.getByText`.
17+
screen.getByText('file.txt'),
18+
).toBeTruthy()
19+
20+
// 🐨 Using the previous assertion as an example,
21+
// apply the necessary changes to this `expect` as well.
22+
expect(screen.getByText('hello world')).toBeTruthy()
23+
})
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { useEffect, useState } from 'react'
2+
3+
export function FilePreview({ file }: { file: File }) {
4+
const [previewText, setPreviewText] = useState<string>()
5+
6+
useEffect(() => {
7+
file.text().then(setPreviewText)
8+
}, [file])
9+
10+
return (
11+
<div>
12+
<div className="w-full max-w-2xl overflow-hidden rounded-md border border-slate-200 bg-white shadow-lg shadow-slate-200">
13+
<p className="border-b border-slate-200 bg-slate-50 px-4 py-2 font-bold text-slate-600">
14+
{file.name}
15+
</p>
16+
<pre className="max-h-[28ch] overflow-scroll p-4">{previewText}</pre>
17+
</div>
18+
</div>
19+
)
20+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
@import url('https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,100..1000;1,9..40,100..1000&display=swap');
2+
3+
@tailwind base;
4+
@tailwind components;
5+
@tailwind utilities;
6+
7+
html {
8+
@apply flex size-full items-center justify-center bg-slate-100 p-10;
9+
10+
font-family:
11+
'DM Sans',
12+
system-ui,
13+
-apple-system,
14+
BlinkMacSystemFont,
15+
'Segoe UI',
16+
Roboto,
17+
Oxygen,
18+
Ubuntu,
19+
Cantarell,
20+
'Open Sans',
21+
'Helvetica Neue',
22+
sans-serif;
23+
font-style: normal;
24+
font-optical-sizing: auto;
25+
}

0 commit comments

Comments
 (0)