From 2c23374361a1abf1306911f313ecf767737c5dec Mon Sep 17 00:00:00 2001 From: Aaron McAdam Date: Mon, 17 Feb 2025 18:44:19 +0000 Subject: [PATCH 01/27] typo --- .../02.vitest-browser-mode/04.problem.shared-assets/README.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/02.vitest-browser-mode/04.problem.shared-assets/README.mdx b/exercises/02.vitest-browser-mode/04.problem.shared-assets/README.mdx index 791eb08..0455593 100644 --- a/exercises/02.vitest-browser-mode/04.problem.shared-assets/README.mdx +++ b/exercises/02.vitest-browser-mode/04.problem.shared-assets/README.mdx @@ -32,6 +32,6 @@ Cannot find module './src/index.css' or its corresponding type declarations.ts(2 /// ``` -Lastly, provide the path to the setup file in `vite.config.ts` as the `setupFiles` value of a conrete browser instance (follow the instructions in the configuration file for more details). +Lastly, provide the path to the setup file in `vite.config.ts` as the `setupFiles` value of a concrete browser instance (follow the instructions in the configuration file for more details). Once you have it ready, run the tests again to see the `` component reclaim its striking visuals ✨. From 751767574fed097ddc9ed42419580426e4d5a02b Mon Sep 17 00:00:00 2001 From: Aaron McAdam Date: Mon, 17 Feb 2025 18:47:09 +0000 Subject: [PATCH 02/27] grammar --- .../02.vitest-browser-mode/04.problem.shared-assets/README.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/02.vitest-browser-mode/04.problem.shared-assets/README.mdx b/exercises/02.vitest-browser-mode/04.problem.shared-assets/README.mdx index 0455593..729774f 100644 --- a/exercises/02.vitest-browser-mode/04.problem.shared-assets/README.mdx +++ b/exercises/02.vitest-browser-mode/04.problem.shared-assets/README.mdx @@ -26,7 +26,7 @@ Once you do all this, you will spot that the `*.css` imports fail to resolve in Cannot find module './src/index.css' or its corresponding type declarations.ts(2307) ``` -🐨 To fix this, we need to pull some of the Vite built-in type definitions to help us. At the top of the `vitest.browser.setup.ts` file, add the following type reference comment: +🐨 To fix this, we need to pull in some of the Vite built-in type definitions to help us. At the top of the `vitest.browser.setup.ts` file, add the following type reference comment: ```ts nonumber /// From 054d1d8ab5f975cb3434f733312499ea0a0208f1 Mon Sep 17 00:00:00 2001 From: Aaron McAdam Date: Mon, 17 Feb 2025 18:51:04 +0000 Subject: [PATCH 03/27] grammar/clarity --- .../02.vitest-browser-mode/04.solution.shared-assets/README.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/02.vitest-browser-mode/04.solution.shared-assets/README.mdx b/exercises/02.vitest-browser-mode/04.solution.shared-assets/README.mdx index 0495cca..c15dcc7 100644 --- a/exercises/02.vitest-browser-mode/04.solution.shared-assets/README.mdx +++ b/exercises/02.vitest-browser-mode/04.solution.shared-assets/README.mdx @@ -4,7 +4,7 @@ There are two types of test setup you can have: _global_ and _local_. The global I will start by creating a `vitest.browser.setup.ts` file. The naming here doesn't matter that much, but I like to keep Vitest-related files starting with `vitest.*`. -In that file, I will import the assets I want to apply to all rendered components: +In that file, I will import the assets I want to include when rendering any component: ```ts filename=vitest.browser.setup.ts add=1 import './src/index.css' From e645b8b0b4443f5cc2a1863d6775f1729c9b4aa1 Mon Sep 17 00:00:00 2001 From: Aaron McAdam Date: Mon, 17 Feb 2025 18:54:42 +0000 Subject: [PATCH 04/27] grammar --- .../05.problem.multiple-workspaces/README.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/02.vitest-browser-mode/05.problem.multiple-workspaces/README.mdx b/exercises/02.vitest-browser-mode/05.problem.multiple-workspaces/README.mdx index 2e446da..32a04a9 100644 --- a/exercises/02.vitest-browser-mode/05.problem.multiple-workspaces/README.mdx +++ b/exercises/02.vitest-browser-mode/05.problem.multiple-workspaces/README.mdx @@ -1,6 +1,6 @@ # Multiple workspaces -The way you have Vitest configured right now will run _all tests_ using the Browser Mode. This may be not what you want, especially if you are using Vitest for unit testing or integration testing in Node.js in the same project that needs in-browser component tests as well. +The way you have Vitest configured right now will run _all tests_ using Browser Mode. This may not be what you want, especially if you are using Vitest for unit testing or integration testing in Node.js in the same project that needs in-browser component tests as well. You can fix this by introducing _different workspaces_ for differnt types of tests. In fact, I think this is just the right task for you... From 9c39365f5989fd55c0032980b19b83d99b84b9b0 Mon Sep 17 00:00:00 2001 From: Aaron McAdam Date: Mon, 17 Feb 2025 19:01:32 +0000 Subject: [PATCH 05/27] grammar and flow --- .../05.problem.multiple-workspaces/README.mdx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/exercises/02.vitest-browser-mode/05.problem.multiple-workspaces/README.mdx b/exercises/02.vitest-browser-mode/05.problem.multiple-workspaces/README.mdx index 32a04a9..77f09e7 100644 --- a/exercises/02.vitest-browser-mode/05.problem.multiple-workspaces/README.mdx +++ b/exercises/02.vitest-browser-mode/05.problem.multiple-workspaces/README.mdx @@ -1,14 +1,14 @@ # Multiple workspaces -The way you have Vitest configured right now will run _all tests_ using Browser Mode. This may not be what you want, especially if you are using Vitest for unit testing or integration testing in Node.js in the same project that needs in-browser component tests as well. +Our current Vitest configuration runs _all tests_ in Browser Mode. This isn't ideal when you need to run different types of tests in the same project - like unit tests in Node.js alongside browser-based component tests. -You can fix this by introducing _different workspaces_ for differnt types of tests. In fact, I think this is just the right task for you... +You can fix this by introducing _different workspaces_ for different types of tests. In fact, I think this is just the right task for you... -πŸ‘¨β€πŸ’Ό In this one, you will expand on the Vitest configuration to support running multiple types of tests in the same project. This will be a multi-step process to make sure you have the Vitest and TypeScript configured correctly for your tests. +πŸ‘¨β€πŸ’Ό In this one, you will expand the Vitest configuration to support running multiple types of tests in the same project. This will be a multi-step process to make sure you have Vitest and TypeScript configured correctly for your tests. -🐨 First, update `vite.config.ts` to list multiple [workspaces](https://main.vitest.dev/guide/workspace.html#configuration). Define one for unit tests and the other for component tests. +🐨 First, update `vite.config.ts` to list multiple [workspaces](https://main.vitest.dev/guide/workspace.html#configuration). Define one for unit tests and another for component tests. -🐨 Next, rename `tsconfig.test.json` to `tsconfig.test.browser.json`. This TypeScript configuration will apply only to the component tests now. Update its `include` to target `**/*.browser.test.ts*` files: +🐨 Next, rename `tsconfig.test.json` to `tsconfig.test.browser.json`. This TypeScript configuration will only apply to the component tests now. Update its `include` setting to target `**/*.browser.test.ts*` files: ```json filename=tsconfig.test.browser.json remove=2 add=3 { @@ -17,7 +17,7 @@ You can fix this by introducing _different workspaces_ for differnt types of tes } ``` -🐨 To have proper type-checking in unit tests, create a new `tsconfig.test.unit.json` file and list there the properties necessary for the unit tests. You can use this as an example: +🐨 To have proper type-checking in unit tests, create a new `tsconfig.test.unit.json` file and add the necessary properties for unit tests. You can use this as an example: ```json filename=tsconfig.test.unit.json { @@ -49,6 +49,6 @@ You can fix this by introducing _different workspaces_ for differnt types of tes } ``` -🐨 Finally, rename the existing `file-preview.test.tsx` component test to `file-preview.browser.test.tsx` to be picked up by the proper workspace in Vitest. +🐨 Finally, rename the existing `file-preview.test.tsx` component test to `file-preview.browser.test.tsx` to be included in the correct Vitest workspace. See you on the other side once you're done to go through each step in more detail. From 28aa0ca2db0bb10839b0fa05027747b22619a943 Mon Sep 17 00:00:00 2001 From: Aaron McAdam Date: Mon, 17 Feb 2025 19:33:57 +0000 Subject: [PATCH 06/27] grammar and flow --- .../05.solution.multiple-workspaces/README.mdx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/exercises/02.vitest-browser-mode/05.solution.multiple-workspaces/README.mdx b/exercises/02.vitest-browser-mode/05.solution.multiple-workspaces/README.mdx index 5ad482f..5ebc763 100644 --- a/exercises/02.vitest-browser-mode/05.solution.multiple-workspaces/README.mdx +++ b/exercises/02.vitest-browser-mode/05.solution.multiple-workspaces/README.mdx @@ -74,7 +74,7 @@ The first workspace include the configuration for running unit tests: - `exclude` does the opposite of `include`, listing the file patterns to _ignore_. Since my browser tests also end with `*.test.ts`, I need to exclude them not to be confused with unit tests; - `environment` controls the test environment used for this workspace. I want my unit tests to run in Node.js, so I provide `'node'` as the enivornment here. -> :owl: Notice that each workspace lists Vitest configuration starting from the root (e.g. includes the `test` key again). This is handy because this means each workspace can have a different set of Vite options to handle the test files (e.g. list different `plugins`). +> :owl: Notice that each workspace lists Vitest configuration starting from the root by including the `test` key again. This is handy because each workspace can have a different set of Vite options and `plugins` for different test files. Similarly, here's the workspace for the browser (component) tests: @@ -98,17 +98,17 @@ Similarly, here's the workspace for the browser (component) tests: }, ``` -Here, I'm naming this workspace `'browser'` and configuring it to include only `*.browser.test.ts(x)` test files. Those will be my component tests. For the rest of it, I simply moved the existing `test.browser` configuration under this workspace and left it as-is. +Here, I'm naming this workspace `'browser'` and configuring it to include only `*.browser.test.ts(x)` test files. These will be my component tests. For the rest of the configuration, I simply moved the existing `test.browser` configuration under this workspace and left it as-is. ## TypeScript -The next step is to deal with TypeScript. One of the most overlooked aspects of using TypeScript is that you often need _multiple configurations_ within the same project. Your source code, unit tests, integration tests, or test utilities are all written in TypeScript but have different concerns that may require different types. +The next step is to deal with TypeScript. One of the most overlooked aspects of using TypeScript is that you often need _multiple configurations_ within the same project. Your source code, unit tests, integration tests, and test utilities are all written in TypeScript but have different concerns that may require different types. > :scroll: If you want to dive deeper into the reason behing using multiple TypeScript configurations and how to do that properly, read my post called [One Thing Nobody Explained To You About TypeScript](https://kettanaito.com/blog/one-thing-nobody-explained-to-you-about-typescript). -In our project, unit and component tests have a different set of type requirements because they run in different environments. This means I need to introduce two separate configurations: `tsconfig.test.unit.json` and `tsconfig.test.browser.json` to address those differences. +In our project, unit and component tests have a different set of type requirements because they run in different environments. This means I need to introduce two separate configurations to address these differences: `tsconfig.test.unit.json` and `tsconfig.test.browser.json`. -Let's start with the unit tests. +Let's start with the unit tests: ```json filename=tsconfig.test.unit.json { @@ -129,7 +129,7 @@ Similar to how I've configured Vitest workspaces to apply only to specific file "types": ["node", "vitest/globals"] ``` -This include Node.js type definitions (`@types/node`) and Vitest global types (e.g. `test` and `expect`) for my unit tests. Since I don't have the Node.js types installed, I need to add them as a dependency to the project: +This includes Node.js type definitions (`@types/node`) and Vitest global types (e.g. `test` and `expect`) for my unit tests. Since I don't have the Node.js types installed, I need to add them as a dependency to the project: ```sh nonumber npm i -D @types/node @@ -151,7 +151,7 @@ Next, I rename the existing `tsconfig.test.json` to `tsconfig.test.browser.json` ## Test commands -To make it easier to run specific types of tests, I will modify `package.json` to include the new `test:unit` and `test:integration` commands: +To make it easier to run specific types of tests, I will modify `package.json` to add `test:unit` and `test:integration` commands: ```json { @@ -170,4 +170,4 @@ There are multiple ways to group different types of tests in the same project: - **By file name**. This is the one I'm using this exercise, adopting `*.test.ts` for unit tests and `*.browser.test.tsx` for integration tests; - **By directory name**. For example, you can keep unit tests in `./src` while integration tests in `./tests` -The only wrong choice here is the one not followed consistently. You can choose whichever approach makes more sense in your circumstance, but I don't recommend mixing them in the same app. +The choice is up to you β€” I only recommend you stick to one approach and don't mix them in your app. From f8e5341ab024dbce8fa5801ee4ece916e15980a0 Mon Sep 17 00:00:00 2001 From: Aaron McAdam Date: Mon, 17 Feb 2025 19:46:50 +0000 Subject: [PATCH 07/27] add integration test --- .../05.problem.multiple-workspaces/README.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/02.vitest-browser-mode/05.problem.multiple-workspaces/README.mdx b/exercises/02.vitest-browser-mode/05.problem.multiple-workspaces/README.mdx index 77f09e7..2aaf31a 100644 --- a/exercises/02.vitest-browser-mode/05.problem.multiple-workspaces/README.mdx +++ b/exercises/02.vitest-browser-mode/05.problem.multiple-workspaces/README.mdx @@ -1,6 +1,6 @@ # Multiple workspaces -Our current Vitest configuration runs _all tests_ in Browser Mode. This isn't ideal when you need to run different types of tests in the same project - like unit tests in Node.js alongside browser-based component tests. +Our current Vitest configuration runs _all tests_ in Browser Mode. This isn't ideal when you need to run different types of tests in the same project - like unit and integration tests in Node.js alongside browser-based component tests. You can fix this by introducing _different workspaces_ for different types of tests. In fact, I think this is just the right task for you... From 260cd32a13eeb8c3531f3a38d6ae6291f13b025a Mon Sep 17 00:00:00 2001 From: Aaron McAdam Date: Mon, 17 Feb 2025 19:47:58 +0000 Subject: [PATCH 08/27] add more context --- .../05.problem.multiple-workspaces/README.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/02.vitest-browser-mode/05.problem.multiple-workspaces/README.mdx b/exercises/02.vitest-browser-mode/05.problem.multiple-workspaces/README.mdx index 2aaf31a..4f5ee3c 100644 --- a/exercises/02.vitest-browser-mode/05.problem.multiple-workspaces/README.mdx +++ b/exercises/02.vitest-browser-mode/05.problem.multiple-workspaces/README.mdx @@ -1,6 +1,6 @@ # Multiple workspaces -Our current Vitest configuration runs _all tests_ in Browser Mode. This isn't ideal when you need to run different types of tests in the same project - like unit and integration tests in Node.js alongside browser-based component tests. +Our current Vitest configuration runs _all tests_ in Browser Mode. This isn't ideal when you need to run different types of tests in the same project - like unit and integration tests running in a Node.js environment alongside browser-based component tests. You can fix this by introducing _different workspaces_ for different types of tests. In fact, I think this is just the right task for you... From e3c9d98c6f5151ce92ce5429400ec446993c7837 Mon Sep 17 00:00:00 2001 From: Aaron McAdam Date: Mon, 17 Feb 2025 20:22:39 +0000 Subject: [PATCH 09/27] flow --- exercises/03.best-practices/README.mdx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/exercises/03.best-practices/README.mdx b/exercises/03.best-practices/README.mdx index c073833..4dd13b8 100644 --- a/exercises/03.best-practices/README.mdx +++ b/exercises/03.best-practices/README.mdx @@ -1,17 +1,17 @@ # Best practices -Tools are important. But the most important things often transcend tools. Tools can give you a solid foundation but it's still _your task_ to write great tests. +While tools provide a solid foundation, the most important aspects of testing transcend them. Writing great tests remains _your task_. -In this exercise block, we will go through some of the absolutely essential best practices when it comes to writing integration tests. I've already spoken a lot about the [true purpose of testing](https://www.epicweb.dev/the-true-purpose-of-testing), [what makes a great test](https://www.epicweb.dev/the-golden-rule-of-assertions), and why you want to [write tests that fail](https://www.epicweb.dev/writing-tests-that-fail). All of those still apply. Today, I would like to add another layer onto the onion of your test quality. Today, let's talk about how to achieve fantastic integration tests. +In this exercise block, we will go through some of the absolutely essential best practices when it comes to writing integration tests. I've written extensively about the [true purpose of testing](https://www.epicweb.dev/the-true-purpose-of-testing), [what makes a great test](https://www.epicweb.dev/the-golden-rule-of-assertions), and why you want to [write tests that fail](https://www.epicweb.dev/writing-tests-that-fail). All of those still apply. Today, let's add another layer to your testing expertise by focusing on how to write fantastic integration tests. ## What we will cover -There's countless practices, patterns, and pieces of advices when it comes to testing. Some general, others extremely specific. For this block, I've trimmed all of those down to the following topics: +There are countless practices, patterns, and tips when it comes to testing. Some general, others extremely specific. For this block, I've trimmed all of these down to the following topics: 1. **Accessibility selectors**. Write tests that find HTML elements the same way your users find them. 1. **User events**. Write tests that interact with HTML elements the same way your users do. 1. **Network mocking**. How to mock network requests in your tests with [Mock Service Worker](https://mswjs.io/). 1. **Element presence**. How to test elements presence, especially when something must _not_ appear in the UI. -1. **Page navigation**. Testing page transition (i.e. routing) on the integration level. +1. **Page navigation**. Testing page transitions (i.e. routing) at the integration test level. -If you nail these five, you already establish a strong starting point for the quality of your tests. I think it's time we explored them. +Mastering these five areas will give you a strong foundation for writing quality tests. Let's explore them. From 6b854c278601458d649a5df5b6b8cea314499820 Mon Sep 17 00:00:00 2001 From: Aaron McAdam Date: Mon, 17 Feb 2025 20:27:07 +0000 Subject: [PATCH 10/27] flow --- .../01.problem.accessibility-selectors/README.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/exercises/03.best-practices/01.problem.accessibility-selectors/README.mdx b/exercises/03.best-practices/01.problem.accessibility-selectors/README.mdx index fa7bd84..97cbe49 100644 --- a/exercises/03.best-practices/01.problem.accessibility-selectors/README.mdx +++ b/exercises/03.best-practices/01.problem.accessibility-selectors/README.mdx @@ -1,10 +1,10 @@ # Queries -One of the primary ways to achieve user-driven tests is to access and interact with the UI elements in the same manner user would. Your users don't know HTML or CSS so they don't locate elements on the page by their class names or `test-id` attributes. Instead, they find the things they need by their _roles_ and _names_ (this is true for visually-impared users as well). +One of the primary ways to achieve user-driven tests is to access and interact with the UI elements in the same way the user would. Your users don't know HTML or CSS so they don't locate elements on the page by their class names or `test-id` attributes. Instead, they find the things they need by their _roles_ and _names_ (this is true for visually-impared users as well). The way you access different elements in tests matters a lot. It can vary from giving you a ton of value and implicit accessibility assurance to forcing you to change your tests all the time because they are riddled with implementation details. -When testing, do what users do. +When testing, do what your users would do. πŸ‘¨β€πŸ’Ό In this exercise, your task is to write a simple integration test for a new React component called -``. And what do you know itβ€”this component is a _form_! This means plenty of elements for you to locate. Use locators like `.getByRole()` and `.getByLabelText()`, and write assertions that make sure all the necessary form elements are present on the page. +``. And what do you knowβ€”this component is a _form_! This means plenty of elements for you to locate. Use locators like `.getByRole()` and `.getByLabelText()`, and write assertions that make sure all the necessary form elements are present on the page. From 85cd0e73b5273756d8e6f5941cc9504bb55b2106 Mon Sep 17 00:00:00 2001 From: Aaron McAdam Date: Mon, 17 Feb 2025 20:50:02 +0000 Subject: [PATCH 11/27] flow --- .../01.solution.accessibility-selectors/README.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/exercises/03.best-practices/01.solution.accessibility-selectors/README.mdx b/exercises/03.best-practices/01.solution.accessibility-selectors/README.mdx index e6e7b94..d4d5343 100644 --- a/exercises/03.best-practices/01.solution.accessibility-selectors/README.mdx +++ b/exercises/03.best-practices/01.solution.accessibility-selectors/README.mdx @@ -17,7 +17,7 @@ I'm going to start by locating the discount code input on the page. This one: /> ``` -A user would find this input by its _label text_ because they would see that it says "Discount code" above that input. When creating the `` component, I've made sure to have an accessible layout by associating a `label` element with the input by its `id`: +A user would find this input by its _label text_ because they would see that it says "Discount code" above that input. When creating the `` component, I've made sure to have accessible markup by associating a `label` element with the input by its `id`: ```tsx filename=discount-code-form.tsx highlight=2,8