{"id":21890783,"url":"https://github.com/chantastic/vite-react-jest-testing-library-axe","last_synced_at":"2025-04-15T13:34:41.093Z","repository":{"id":63555255,"uuid":"568649270","full_name":"chantastic/vite-react-jest-testing-library-axe","owner":"chantastic","description":null,"archived":false,"fork":false,"pushed_at":"2022-11-21T06:38:46.000Z","size":11540,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-28T20:36:39.578Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/chantastic.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}},"created_at":"2022-11-21T05:28:14.000Z","updated_at":"2023-08-04T09:23:28.000Z","dependencies_parsed_at":"2022-11-21T07:45:25.675Z","dependency_job_id":null,"html_url":"https://github.com/chantastic/vite-react-jest-testing-library-axe","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/chantastic%2Fvite-react-jest-testing-library-axe","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chantastic%2Fvite-react-jest-testing-library-axe/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chantastic%2Fvite-react-jest-testing-library-axe/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chantastic%2Fvite-react-jest-testing-library-axe/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chantastic","download_url":"https://codeload.github.com/chantastic/vite-react-jest-testing-library-axe/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249080338,"owners_count":21209509,"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":[],"created_at":"2024-11-28T12:16:49.176Z","updated_at":"2025-04-15T13:34:41.074Z","avatar_url":"https://github.com/chantastic.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Storybook demo using vite, react, jest, testing-library, and axe-playwright\n\n## Storybook for component testing\n\nI threw this together to demonstrate some modern Storybook approaches in [a Hacker News thread](https://news.ycombinator.com/item?id=33675261).\n\nThis repo demonstrates how the [`@storybook/test-runner`](https://storybook.js.org/addons/@storybook/test-runner) can be used as a bridge between [Storybook](https://storybook.js.org/) and [Jest](https://jestjs.io/). And provide an improved experiencing, using Storybook as a GUI for Jest + Testing Library.\n\nTo show a handful of things that we can get for free when using Stories as a component testing tool.\n\n![screenshot of Storybook with the interactions pane open. in it are a number of testing-library interactions that have played over the story to create the story's visual state](./README/images/readme_see-testing-library-interactions-in-storybook.png)\n\n## Other modern Storybook notes\n\n### Storybook on esbuild/vite\n\nI used [Storybook's Vite builder](https://storybook.js.org/blog/storybook-for-vite/) in response to other comments.\n\n### Modern Component Story Format 3 syntax\n\nI updated the sample stories to use [CSF 3](https://storybook.js.org/blog/component-story-format-3-0/), the latest Component Story Format syntax for documenting stories. [Ladle](https://ladle.dev/) also uses Component Story Format for component documentation.\n\nI find it a terse, readable (ES Modules), and composable way to write story-driven tests and documentation.\n\n## Reproduction steps\n\n:info: Note: each section heading is a link to the corresponding commit.\n\n### [Add @storybook/test-runner for automatic just smoke-tests](https://github.com/chantastic/vite-react-jest-testing-library-axe/commit/8342601f1c0eae0f64334e893cfa4d6a7f85c111)\n\n- `yarn add -D @storybook/test-runner`\n- add script `\"test-storybook\": \"test-storybook\"`\n\n![screenshot of terminal showing Jest tests generated from component stories. There are three suites (for Header, Button, and Page), 8 tests, and they are all passing](./README/images/readme_add-jest-test-runner.png)\n\n### [Add @storybook/addon-coverage for istanbul cov report](https://github.com/chantastic/vite-react-jest-testing-library-axe/commit/a57ce3d1d8b0bef7ba623de73de5e43d310def79)\n\n- `yarn add -D @storybook/addon-coverage`\n- Register addon in `.storybook/main.js`\n\n```diff\n// main.js\n\nmodule.exports = {\n  // ...\n  \"addons\": [\n    // ...\n+   \"@storybook/addon-coverage\"\n  ],\n  // ...\n}\n```\n\n![screenshot of component test suite passing (3 suites, 9 tests) with Istanbul generated code coverage data. both Button.tsx and Page.tsx are showing less than 100% coverage.](./README/images/readme_add-istanbul-coverage.png)\n\n### [Improve Button test coverage to 100%](https://github.com/chantastic/vite-react-jest-testing-library-axe/commit/e67777341a9ef7dc154cc2fc0406da569fa8d6f6)\n\n- Add new `Button.stories.tsx` story to cover `backgroundColor` prop code path\n\n### [Improve Page test coverage to 100%](https://github.com/chantastic/vite-react-jest-testing-library-axe/commit/5e38ef2d26485e0928930e04db9c06e79bae562a)\n\n- Add new `Page.stories.tsx` stories to cover interactive states.\n  - Use [Storybook play functions](https://storybook.js.org/docs/react/writing-stories/play-function) to interact with stories using [testing-library](https://testing-library.com/).\n- Cover `LoggedInThenLoggedOut` interaction\n- Cover `Sign up` interaction\n\n\n```tsx\n// Page.stories.tsx\n\n// ...\n\nexport const LoggedInThenLoggedOut = Template.bind({});\nLoggedInThenLoggedOut.play = async (context) =\u003e {\n  await LoggedIn.play(context);\n  const canvas = within(context.canvasElement);\n  const logoutButton = await canvas.getByRole(\"button\", {\n    name: /Log out/i,\n  });\n  await userEvent.click(logoutButton);\n};\n\nexport const SignUp = Template.bind({});\nSignUp.play = async ({ canvasElement }) =\u003e {\n  const canvas = within(canvasElement);\n  const signUpButton = await canvas.getByRole(\"button\", {\n    name: /Sign up/i,\n  });\n  await userEvent.click(signUpButton);\n};\n```\n\n![screenshot of terminal showing 100% coverage for all components, using Jest tests generated from stories](./README/images/readme_improve-coverage-to-100.png)\n\n### [Update all stories to tidier CSF 3 syntax](https://github.com/chantastic/vite-react-jest-testing-library-axe/commit/74e5d569355a27bad4b16c9659a6018bce3126b5)\n\n---\n\n- Update all stories to [CSF3 syntax](https://storybook.js.org/blog/component-story-format-3-0/)\n\n```diff\n// example\n- const Template: ComponentStory\u003ctypeof Button\u003e = (args) =\u003e \u003cButton {...args} /\u003e;\n-\n- export const Primary = Template.bind({});\n- Primary.args = {\n-   primary: true,\n-   label: 'Button',\n- }\n+ export const Primary = {\n+   args: {\n+     primary: true,\n+     label: \"Button\",\n+  }\n+ }\n\n```\n\n### [Add @storybook/jest assertions](https://github.com/chantastic/vite-react-jest-testing-library-axe/commit/686df235e8042e8aef839767b2137d71131447a8)\n\n- Add `@storybook/jest`\n- Add assertions directly to interactive `Page.stories.tsx` stories\n\n```diff\n+ expect(await canvas.getByText(\"Jane Doe\"));\n```\n\n![screenshot of terminal output showing Page tests passing, using --verbose flag. In addition to the smoke-test, there are 3 interaction tests for each play function](./README/images/readme_asserts-all-testing-library-interactions-in-jest.png)\n\n![screenshot of Storybook with the interactions pane open. in it are a number of testing-library interactions that have played over the story to create the story's visual state. Jest expectations are also shown.](./README/images/readme_see-testing-library-interactions-in-storybook-with-jest-expectations.png)\n\n\n### [Add toMatchSnapshot() expectation to all stories](https://github.com/chantastic/vite-react-jest-testing-library-axe/commit/26c03a09e3d64af9c2078894e501a363a6d1c8d0)\n\n- Add `.storybook/test-runner.cjs` config to use the test-runner's [test hook API](https://storybook.js.org/addons/@storybook/test-runner#render-lifecycle:~:text=.-,Experimental%20test%20hook%20API,-The%20test%20runner)\n- Add an automatic [Jest snapshot](https://jestjs.io/docs/snapshot-testing) for every story.\n\n```cjs\n// .storybook/test-runner.js\nmodule.exports = {\n  async postRender(page) {\n    const elementHandler = await page.$(\"#root\");\n    const innerHTML = await elementHandler.innerHTML();\n    expect(innerHTML).toMatchSnapshot();\n  },\n};\n```\n\n![screenshot of terminal showing new Jest snapshot tests for all stories. They are all passing.](./README/images/readme_add-automated-toMatchSnapshot-tests-in-test-runner-config.png)\n\n### [Add automated accessibility tests and a11y tree snapshot tests](https://github.com/chantastic/vite-react-jest-testing-library-axe/commit/f29c384479c73d5495e31c405e657be06ff278fc)\n- `yarn add -D axe-playwright`\n- `npx playwright install --with-deps` (to setup the machine's playright environment)\n- Add `.storybook/test-runner` config to automate accessibility tests for every story\n\n```cjs\nconst { injectAxe, checkA11y } = require(\"axe-playwright\");\n\nmodule.exports = {\n  async preRender(page) {\n    await injectAxe(page);\n  },\n  async postRender(page) {\n    await checkA11y(page, \"#root\", {\n      detailedReport: true,\n      detailedReportOptions: {\n        html: true,\n      },\n    });\n\n    const accessibilityTree =\n      await page.accessibility.snapshot();\n    expect(accessibilityTree).toMatchSnapshot();\n\n    // ...\n  },\n};\n```\n\n![screenshot of terminal output showing axe-detected accessibility violations for component stories](./README/images/readme_add-axe-playwright-a11y-tree-snapshots-to-every-story.png)\n\n### [Fix all accessibility violations and update snapshots for green lights](https://github.com/chantastic/vite-react-jest-testing-library-axe/commit/b6baa4c8676a188a14050a636e90f6452174c47b)\n\n![screenshot of terminal output showing that all axe-detected accessibility warnings have be fixed and snapshots updated](./README/images/readme_fix-all-violations-and-update-snapshots.png)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchantastic%2Fvite-react-jest-testing-library-axe","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchantastic%2Fvite-react-jest-testing-library-axe","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchantastic%2Fvite-react-jest-testing-library-axe/lists"}