Skip to content

Commit ca8d5ea

Browse files
committed
02/04: add solution and assets
1 parent 0c450fe commit ca8d5ea

File tree

27 files changed

+334
-12
lines changed

27 files changed

+334
-12
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@ It's time to take the first step forward Vitest Browser Mode! In this one, you a
66

77
As the first order of business, I'm going to uninstall the packages I won't be needing anymore:
88

9-
```sh
9+
```sh nonumber
1010
npm uninstall jsdom @testing-library/react
1111
```
1212

1313
> 🦉 I am uninstalling React Testing Library because I won't be using it directly for my in-browser tests. **That doesn't mean its API and practices are gone!** Instead, I will continue using them through the Vitest and Playwright APIs that are inspired by RTL and promote its best practices.
1414
1515
Now I can install the dependencies required for the Browser Mode in Vitest:
1616

17-
```sh
17+
```sh nonumber
1818
npm i -D @vitest/browser vitest-browser-react
1919
```
2020

exercises/02.vitest-browser-mode/02.solution.migrate-the-test/README.mdx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ Finally, it's time to adjust the assertions around the elements rendered by our
6969

7070
This is how they looked like before:
7171

72-
```tsx filename=file-preview.test.tsx
72+
```tsx filename=file-preview.test.tsx nonumber
7373
expect(page.getByText('file.txt')).toBeTruthy()
7474
expect(page.getByText('hello world')).toBeTruthy()
7575
```
@@ -78,7 +78,7 @@ There's a few things to change here.
7878

7979
Now that I know that `page.getBy*` functions return _locators_, they will always be truthy and so the `.toBeTruthhy()` assertion makes little sense here. It wasn't written from the user's perspective, to begin with, and it would be best to use a more fitting matcher like `.toBeVisible()`:
8080

81-
```tsx filename=file-preview.test.tsx
81+
```tsx filename=file-preview.test.tsx nonumber
8282
expect(page.getByText('file.txt')).toBeVisible()
8383
// ^^^^^^^^^^^^^
8484
expect(page.getByText('hello world')).toBeVisible()
@@ -87,7 +87,7 @@ expect(page.getByText('hello world')).toBeVisible()
8787

8888
On its own, this is enough. But there's one more thing that can make these assertions stellar. I can use `expect.element()` instead of `expect()` to have a built-in retry for resolving the given locators:
8989

90-
```tsx filename=file-preview.test.tsx
90+
```tsx filename=file-preview.test.tsx nonumber
9191
await expect.element(page.getByText('file.txt')).toBeVisible()
9292
// ^^^^^^^
9393
await expect.element(page.getByText('hello world')).toBeVisible()
@@ -102,7 +102,7 @@ This reads as "_I eventually expect an element with text 'hello world' to be vis
102102

103103
Now that I've updated the test suite, I can see it passing once I run `npm test`:
104104

105-
```
105+
```txt nonumber nocopy
106106
chromium Browser runner started at http://localhost:63315/
107107
108108
✓ chromium src/file-preview.test.tsx (1 test) 60ms

exercises/02.vitest-browser-mode/03.solution.playwright/README.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ Problem: Using the default `preview` provider in Vitest is great to try things o
1111

1212
Let's start from installing `playwright`:
1313

14-
```sh
14+
```sh nonumber
1515
npm i -D playwright
1616
```
1717

1818
Playwright needs browser executables to be present on your machine to run. In this workshop, I am using Chromium as my browser of choice, so I can install just that particular browser by running the following command:
1919

20-
```sh
20+
```sh nonumber
2121
npx playwright install --with-dewps chromium
2222
```
2323

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Shared assets
2+
3+
Our Vitest is configured and running, but if you take a closer look at the tested component on the page, it seems kind of off:
4+
5+
![A screenshot of the Vitest UI showing the file preview component missing the styles](/assets/02-04-problem.png)
6+
7+
Well, that's because it has no styles! The CSS file that contains the styles for this component is imported all the way in `main.tsx`, which isn't rendered as a part of this test:
8+
9+
```tsx filename=file-preview.test.tsx nonumber
10+
render(<FilePreview file={...} />)
11+
```
12+
13+
That's quite an oversight. Styling is important, not only to see the UI as the user would see it, but also because improper styles can lead to inaccessible elements in the DOM.
14+
15+
I think this is a great problem for you to fix!
16+
17+
👨‍💼 In this exercise, you will create a custom browser setup file that will run as a global setup for all component tests.
18+
19+
First, create a <InlineFile file="vitest.browser.setup.ts">`vitest.browser.setup.ts`</InlineFile> file. In that file, import any assets you wish to apply to _all tests_ (e.g. CSS).
20+
21+
> 🦉 To make Vite process the browser setup file like it does the rest of the app, include the following type reference at the top of the setup file: `/// <reference path="./src/vite-env.d.ts" />`.
22+
23+
Lastly, provide the path to the setup file in <InlineFile file="vite.config.ts">`vite.config.ts`</InlineFile> as the `setupFiles` value of a conrete browser instance (follow the instructions in the configuration file for more details).
24+
25+
Once you have it ready, run the tests again to see the `<FilePreview />` component reclaim its striking visuals ✨.
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: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"type": "module",
3+
"name": "exercises_02.vitest-browser-mode_04.problem.shared-assets",
4+
"scripts": {
5+
"dev": "vite",
6+
"test": "vitest"
7+
},
8+
"dependencies": {
9+
"react": "^19.0.0",
10+
"react-dom": "^19.0.0"
11+
},
12+
"devDependencies": {
13+
"@testing-library/dom": "^10.4.0",
14+
"@testing-library/react": "^16.1.0",
15+
"@types/react": "^19.0.6",
16+
"@types/react-dom": "^19.0.3",
17+
"@vitejs/plugin-react": "^4.3.4",
18+
"@vitest/browser": "^3.0.0-beta.4",
19+
"autoprefixer": "^10.4.20",
20+
"playwright": "^1.49.1",
21+
"postcss": "^8.4.49",
22+
"tailwindcss": "^3.4.17",
23+
"vite": "^6.0.7",
24+
"vitest": "^3.0.0-beta.4"
25+
}
26+
}
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: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { page } from '@vitest/browser/context'
2+
import { render } from 'vitest-browser-react'
3+
import { FilePreview } from './file-preview.tsx'
4+
5+
test('displays the preview card', async () => {
6+
render(<FilePreview file={new File(['hello world'], 'file.txt')} />)
7+
8+
await expect.element(page.getByText('file.txt')).toBeTruthy()
9+
await expect.element(page.getByText('hello world')).toBeTruthy()
10+
})

0 commit comments

Comments
 (0)