{"id":16299182,"url":"https://github.com/nejcrogelsek/react-testing","last_synced_at":"2025-04-09T19:48:46.737Z","repository":{"id":114871557,"uuid":"539031362","full_name":"nejcrogelsek/react-testing","owner":"nejcrogelsek","description":"RTL - React Testing Library","archived":false,"fork":false,"pushed_at":"2022-09-28T13:19:41.000Z","size":2287,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-15T11:49:21.069Z","etag":null,"topics":["react-testing-library","react18","typescript"],"latest_commit_sha":null,"homepage":"https://www.youtube.com/watch?v=T2sv8jXoP4s\u0026list=PLC3y8-rFHvwirqe1KHFCHJ0RqNuN61SJd\u0026index=2","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nejcrogelsek.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-09-20T14:26:51.000Z","updated_at":"2024-09-14T07:16:02.000Z","dependencies_parsed_at":"2023-04-10T17:01:33.423Z","dependency_job_id":null,"html_url":"https://github.com/nejcrogelsek/react-testing","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nejcrogelsek%2Freact-testing","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nejcrogelsek%2Freact-testing/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nejcrogelsek%2Freact-testing/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nejcrogelsek%2Freact-testing/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nejcrogelsek","download_url":"https://codeload.github.com/nejcrogelsek/react-testing/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248103290,"owners_count":21048233,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["react-testing-library","react18","typescript"],"created_at":"2024-10-10T20:47:08.678Z","updated_at":"2025-04-09T19:48:46.728Z","avatar_url":"https://github.com/nejcrogelsek.png","language":"TypeScript","readme":"# RTL Tutorial\n\nYou can find tutorial on [Codevolution](https://www.youtube.com/watch?v=T2sv8jXoP4s\u0026list=PLC3y8-rFHvwirqe1KHFCHJ0RqNuN61SJd\u0026index=2).\n\n**IMPORTANT**\n`CRA installs user-event but needs upgrading!`\n\n- Latest version when writing this repo is:\n\n```bash\nnpm i @testing-library/user-event@14.4.3\n```\n\nYou can find different versions [HERE](https://www.npmjs.com/package/@testing-library/user-event)\n\n### Table of contents\n\n- [About tests](#about-tests)\n  - [Group tests](#group-tests)\n  - [Filename conventions](#filename-conventions)\n  - [Assertions](#assertions)\n- [What to test](#what-to-test)\n  - [What not to test](#what-not-to-test)\n- [RTL Queries](#rtl-queries)\n  - [Options](#options)\n    - [getByRole](#getbyrole)\n    - [getByPlaceholderText](#getbyplaceholdertext)\n    - [getByText](#getbytext)\n    - [getByDisplayValue](#getbydisplayvalue)\n    - [getByAltText](#getbyalttext)\n    - [getByTitle](#getbytitle)\n    - [getByTestId](#getbytestid)\n    - [getAllBy](#getallby)\n    - [queryBy \u0026 queryAllBy](#queryby-\u0026-queryallby)\n    - [findBy \u0026 findAllBy](#findby-\u0026-findallby)\n- [Priority Order for Queries](#priority-order-for-queries)\n- [TextMatch](#textmatch)\n- [Testing user interactions](#testing-user-interactions)\n  - [Pointer interactions](#pointer-interactions)\n  - [Keyboard interactions](#keyboard-interactions)\n  - [act](#act)\n- [Mocking HTTP Requests](#mocking-http-requests)\n- [Static analysis testing](#static-analysis-testing)\n  - [ESlint](#eslint)\n  - [Prettier](#prettier)\n  - [Husky](#husky)\n  - [lint-staged](#lint-staged)\n- [Available Scripts](#available-scripts)\n- [Learn more](#learn-more)\n- [References](#references)\n- [Author Info](#author-info)\n\n## About tests\n\nJest is a test runner than can:\n\n- find the tests\n- run it\n- provide user friendly message if test is PASS or FAIL\n\nRun jest: `npm run test`\n\n**test(name, fn, timeout)**\n\n- name: test name used to indentify the test\n- fn: function that contains the expectations to test\n- timeout: is optional for specifying how long to wait before aborting the test. The default timeout value is 5 seconds.\n\n### Group tests\n\n**describe(name, fn)**\n\n- name: group name used to indentify the group of tests\n- fn: function that contains the expectations to test\n\n`test.skip` / `describe.skip` - skips the test or group of tests\n`test.only` / `describe.only` - jest picks only that test / group to run\n\n### Filename conventions\n\n- Files with `.test.js` or `.test.tsx` suffix.\n- Files with `.spec.js` or `.spec.tsx` suffix.\n- Files with `.js` or `.tsx` suffix in ****tests**** folders.\n\nRecommendation is to always put your tests next to the code they are testing so that relative imports are shorter.\n\nWe can use `it` instead of `test`.\nWe can use `fit` instead of `test.only`.\nWe can use `xit` instead of `test.skip`.\n\n### Assertions\n\nWhen writing tests, we often need to check that values meet certain conditions.\nAssertions decide if a test passes or fails.\n\nFind more about using matchers [here](https://jestjs.io/docs/using-matchers) or in [github repo](https://github.com/testing-library/jest-dom).\n\n## What to test\n\nGuidelines:\n\n- Test if component renders\n- Test if component renders with props\n- Test if component renders in different states (auth / no auth)\n- Test if component reacts to events (buttons, font controls)\n\n### What not to test\n\n- Implementation details - test behaviour not how behaviour is implemented\n- Third party code - example: material ui\n- Code that is not important from a user point of view\n\n[Back To The Top](#rtl-tutorial)\n\n## RTL Queries\n\nQueries are methods that Testing Library provides to find elements on the page.\nEvery test we write generally involves the folowing basic steps:\n\n1. Render the component\n2. Find an element rendered by the component\n3. Assert against the element found in step 2 which will pass or fail the test\n\nTo render the component we use `render` method from RTL.\n\nFor assertion, we use expect passing in the value and combine it with a matcher function from jest or jest-dom.\n\nTo find single element on the page, we have:\n\n- getBy..suffix\n- queryBy..suffix\n- findBy..suffix\n\nTo find multiple elements on the page, we have:\n\n- getAllBy..suffix\n- queryAllBy..suffix\n- findAllBy..suffix\n\nThe suffix can be one of `Role`, `LabelText`, `PlaceHolderText`, `Text`, `DisplayValue`, `AltText`, `Title` and finally `TestId`.\n\n### Options\n\n#### getByRole\n\nLink to all roles usage: https://www.w3.org/TR/html-aria/#docconformance\n\n`getByRole Options`:\n\n- name: The accessible name is for simple cases equal to:\n  - the label of a form element\n  - the text content of a button\n  - the value of the aria-label attribute\n- level: Example: for headings\n- hidden\n- selected\n- checked\n- pressed\n\n#### getByPlaceholderText\n\nWill search for all elements with placeholder attribute and find one that maches the given text.\n\n#### getByText\n\nWill search for all elements that have node with textContent matching the given text.\nTypically, you'd use this to find paragraph, div or span elements.\n\n#### getByDisplayValue\n\nReturns the input, textarea or select element that has the matching display value.\n\n#### getByAltText\n\nWill return the element that has the given alt text.\nThis method only supports elements which accept an alt attribute like `img`, `input`, `area` or custom html elements.\n\n#### getByTitle\n\nReturns the element that has the matching title attribute.\n\n#### getByTestId\n\nReturns the element that has the matching data-testid attribute.\n\n#### getAllBy\n\nFind multiple elements in the DOM.\nReturns an array of all matching nodes for a query, and throws an error if no elements match.\n\n#### queryBy \u0026 queryAllBy\n\n`queryBy`:\n\n- Returns the matching node for a query, and return null if no elements match.\n- Useful for asserting an element that is not present.\n- Throws an error if more than one match is found.\n\n`queryAllBy`:\n\n- Returns an array of all matching nodes for a query, and return an empty array if no elements match.\n\n#### findBy \u0026 findAllBy\n\nWhat if elements are not present in the DOM to begin but make their way into the DOM after some time?\nFor example, data tha is fetched from a server will be rendered only after a few miliseconds.\n\n`findBy`:\n\n- Returns a promise which resolves when an element is found which matches the given query.\n- The promise is rejected if no element is found or if more than one element is found after the default timeout of 1000ms.\n\n`findAllBy`:\n\n- Returns a promise which resolves to an array of elements when any elements are found which match the given query.\n- The promise is rejected if no elements are found after the default timeout of 1000ms.\n\n[Back To The Top](#rtl-tutorial)\n\n## Priority Order for Queries\n\n\"Your test should resemble how users interact with your code (component, page, etc.) as much as possible\"\n\n1. getByRole\n2. getByLabelText\n3. getByPlaceholderText\n4. getByText (Example: for non interactive elements)\n5. getByDisplayValue (Example: for pages were inputs are already populated)\n6. look at the component code\n7. getByAltText\n8. getByTitle - is not consistently read by screen readers and is not visible by default for cited users (user cannot hear or see this one)\n\n[Back To The Top](#rtl-tutorial)\n\n## TextMatch\n\nTextMatch represents a type which can be either a:\n\n- string\n- regex\n- function\n\n### TextMatch - string\n\n`Hello World`\nscreen.getByText(**\"Hello World\"**) // full string match\nscreen.getByText(**\"llo World\", { `exact`: false }**) // substring match\nscreen.getByText(**\"hello world\", { `exact`: false }**) // ignore case\n\n### TextMatch - regex\n\n`Hello World`\nscreen.getByText(**/World/**) // substring match\nscreen.getByText(**/world/i**) // substring match, ignore case\nscreen.getByText(**/^hello world$/i**) // full string match, ignore case\n\n### TextMatch - custom function\n\n`Hello World`\n(content?: string, element?: Element | null) =\u003e boolean\n\nscreen.getByText(**(content) =\u003e content.startsWith(\"Hello\")**)\n\nFind multiple elements in the DOM.\nReturns an array of all matching nodes for a query, and throws an error if no elements match.\n\n[Back To The Top](#rtl-tutorial)\n\n## Testing user interactions\n\nDifference between fireEvent and user-event:\n![fireEvent_vs_user-event](./src/assets/readme/fireEvent_vs_user-event.png)\n\n`user-event`:\n\n- A companion library for Testing Library that stimulates user interfaces by dispatching the events that would happen if the interaction took place in the browser.\n- It is recommended way to test user interactions with RTL.\n\n### Pointer interactions\n\n`Convenience APIs` typically used when writting tests.\n\n- click() - is a convenience API that internally calls pointer API\n- dblClick() - double click\n- tripleClick() - triple click\n- hover() - on hover (use example: appearance of tooltips, hover styles,...)\n- unhover() - on unhover (use example: appearance of tooltips, hover styles,...)\n\n`Pointer APIs`\n\n- pointer({keys: '[MouseLeft]'}) - left mouse click `OR` pointer('[MouseLeft]') - if keys is the only argument to functions.\n- pointer({keys: '[MouseLeft][mouseright]'}) - left mouse click followed by right mouse click\n- pointer('[MouseLeft\u003e]') - press a button without releasing it\n- pointer('[/MouseLeft]') - releasing previously pressed button\n\n### Keyboard interactions\n\n`Convenience API`\n\n- tab() - click TAB on keyboard\n\n`Utility API`\n\n- type()\n\n---\n\n- clear()\n  ![utilityapi_clear](./src/assets/readme/utilityapi_clear.png)\n\n---\n\n- selectOptions()\n  ![utilityapi_selectoptions](./src/assets/readme/utilityapi_selectoptions.png)\n\n---\n\n- deselectOptions()\n  ![utilityapi_deselectoptions](./src/assets/readme/utilityapi_deselectoptions.png)\n\n---\n\n- upload()\n  ![utilityapi_upload](./src/assets/readme/utilityapi_upload.png)\n\n---\n\n`Clipboard API`\n\n- copy()\n- cut()\n- paste()\n\n`Keyboard API`\n\n- keyboard('foo') // translates to: f, o, o\n- keyboard('{Shift\u003e}A{/Shift}') // hold a key -\u003e translates to: Shift(down), A, Shift(up)\n\n### act\n\nRead more about act [HERE](https://reactjs.org/docs/testing-recipes.html#act).\n\n[Back To The Top](#rtl-tutorial)\n\n## Mocking HTTP Requests\n\nWe do that with [Mock service worker](https://mswjs.io/docs/).\n\n- [Install instructions](https://mswjs.io/docs/getting-started/install)\n- [Integrate instructions with Node](https://mswjs.io/docs/getting-started/integrate/node)\n\n[Back To The Top](#rtl-tutorial)\n\n## Static analysis testing\n\nProcess of verifying that your code meets certain expectations without actually running it.\n\n- Ensure consistent style and formatting\n- Check for common mistakes and possible bugs\n- Limit the complexity of code\n- Verify type consistency\n\nAll types of tests run the code and then compare the outcome agains known expected outputs to see if everything works OK.\nStatis testing analyses aspects such as readability, consistency, error handling, type checking, and alignment with best practices.\nTesting checks if your code works or not, whereas static analysis checks if it is written well or not.\n\nTools for static analysis testing:\n\n- Typescript\n- ESlint\n- Prettier\n- Husky\n- lint-staged\n\n### ESlint\n\nESlint is a tool for identifying and reporting on patterns found in ECMAScript / JavaScript code, with the goal of making code more consistent and avoiding bugs.\n\n### Prettier\n\nPrettier is an opinionated code formatter that ensures that all outputted code conforms to a consistent style.\n\n```bash\nnpm i -D --exact prettier\n```\n\nWe added `--exact` because we want all users to have the same version of prettier.\n\n### Husky\n\nHusky is a tool that helps improve your commits and more.\n\n```bash\nnpm i -D husky\n```\n\n```bash\nnpm run husky:postinstall\n```\n\n**pre-commit file:**\n```bash\n#!/bin/sh\n. \"$(dirname \"$0\")/_/husky.sh\"\n\nnpm run lint \u0026\u0026 npm run format\n```\n\n### lint-staged\n\nRun linters (and formatters) agains staged git files.\n\n[Back To The Top](#rtl-tutorial)\n\n## Available Scripts\n\nIn the project directory, you can run:\n\n### `npm start`\n\nRuns the app in the development mode.\\\nOpen [http://localhost:3000](http://localhost:3000) to view it in the browser.\n\nThe page will reload if you make edits.\\\nYou will also see any lint errors in the console.\n\n### `npm test`\n\nLaunches the test runner in the interactive watch mode.\\\nSee the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.\n\n### `npm run test:coverage`\n\n`test:coverage in package.json`\n\n```bash\n\"test:coverage\": \"npm run test -- --coverage --watchAll --collectCoverageFrom='src/components/**/*.{ts,tsx}' --collectCoverageFrom='!src/components/**/*.{types,stories,constants,test,spec}.{ts,tsx}'\"\n```\n\n```bash\nnpm run test:coverage\n```\n\n### `npm run build`\n\nBuilds the app for production to the `build` folder.\\\nIt correctly bundles React in production mode and optimizes the build for the best performance.\n\nThe build is minified and the filenames include the hashes.\\\nYour app is ready to be deployed!\n\nSee the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.\n\n### `npm run eject`\n\n**Note: this is a one-way operation. Once you `eject`, you can’t go back!**\n\nIf you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.\n\nInstead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.\n\nYou don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.\n\n[Back To The Top](#rtl-tutorial)\n\n## Learn More\n\nYou can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).\n\nTo learn React, check out the [React documentation](https://reactjs.org/).\n\n[Back To The Top](#rtl-tutorial)\n\n## References\n\n- Youtube channel - [Codevolution](https://www.youtube.com/c/Codevolution)\n\n[Back To The Top](#rtl-tutorial)\n\n## Author Info\n\n- LinkedIn - [@nejcrogelsek](https://www.linkedin.com/in/nejcrogelsek/)\n- Github - [@nejcrogelsek](https://github.com/nejcrogelsek)\n\n[Back To The Top](#rtl-tutorial)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnejcrogelsek%2Freact-testing","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnejcrogelsek%2Freact-testing","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnejcrogelsek%2Freact-testing/lists"}