diff --git a/app/package.json b/app/package.json index 0bb288c..efd09b9 100644 --- a/app/package.json +++ b/app/package.json @@ -74,8 +74,8 @@ "@typescript-eslint/eslint-plugin": "^8.22.0", "@typescript-eslint/parser": "^8.22.0", "@vitejs/plugin-react": "^4.3.4", - "@vitest/browser": "^3.0.3", - "@vitest/coverage-v8": "^3.0.3", + "@vitest/browser": "^3.0.5", + "@vitest/coverage-v8": "^3.0.5", "babel-plugin-styled-components": "^2.1.4", "eslint": "^8.57.1", "eslint-config-airbnb": "^19.0.4", @@ -103,6 +103,7 @@ "vite": "6.0.11", "vite-plugin-node-polyfills": "^0.23.0", "vitest": "^3.0.5", + "vitest-axe": "^1.0.0-pre.3", "vitest-preview": "^0.0.1" }, "volta": { diff --git a/app/src/core/components/withTextField.tsx b/app/src/core/components/withTextField.tsx index ba19319..26a7dac 100644 --- a/app/src/core/components/withTextField.tsx +++ b/app/src/core/components/withTextField.tsx @@ -19,7 +19,9 @@ const TextField = styled(MuiTextField)` & > .MuiInputBase-root { background: ${({ theme }) => theme.palette.background.paper}; } - + & .MuiFormLabel-root { + color: ${({ theme }) => theme.palette.grey[100]}; + } ${({ theme }) => theme.palette.mode === 'dark' && css` diff --git a/app/src/features/authentication/public/__tests__/LoginView.test.tsx b/app/src/features/authentication/public/__tests__/LoginView.test.tsx index c2da30d..0a058e4 100644 --- a/app/src/features/authentication/public/__tests__/LoginView.test.tsx +++ b/app/src/features/authentication/public/__tests__/LoginView.test.tsx @@ -1,21 +1,30 @@ import userEvent from '@testing-library/user-event'; import { act } from 'react'; -import { Route, createRoutesFromChildren } from 'react-router'; +import { createRoutesFromChildren, Route } from 'react-router'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import useWindowSize from '~/core/hooks/useWindowSize'; import ForgotPasswordView from '~/features/authentication/public/ForgotPasswordView'; import Login from '~/features/authentication/public/LoginView'; +import axe from '~/vitest/axe'; import { renderRoutes, screen, waitFor } from '~/vitest/utils'; +vi.mock('react-router', async () => { + const router = await vi.importActual('react-router'); + return { + ...router, + useLocation: vi.fn().mockReturnValue(vi.fn()), + useNavigate: vi.fn().mockReturnValue(vi.fn()), + }; +}); + // Mock dependencies vi.mock('~/core/hooks/useWindowSize'); - vi.mock('~/core/components/G-splash', () => ({ default: () =>
, })); -describe.skip('LoginView', () => { +describe('LoginView', () => { beforeEach(() => { vi.mocked(useWindowSize).mockReturnValue({ isDesktop: true, @@ -197,4 +206,19 @@ describe.skip('LoginView', () => { return expect(screen.getByText(/Reset Password/i)).toBeInTheDocument(); }); }); + + it('AXE Violations', async () => { + const { container } = renderRoutes( + 'memory', + createRoutesFromChildren( + <> + } path="/login" /> + } path="/forgot-password" /> + + ), + '/login' + ); + + expect(await axe(container)).toHaveNoViolations(); + }); }); diff --git a/app/src/vitest/axe.ts b/app/src/vitest/axe.ts new file mode 100644 index 0000000..3cbff48 --- /dev/null +++ b/app/src/vitest/axe.ts @@ -0,0 +1,12 @@ +import { configureAxe } from 'vitest-axe'; + +const axe = configureAxe({ + // globalOptions: { + // checks: [ + // /* custom checks definitions */ + // ], + // }, + // // ... +}); + +export default axe; diff --git a/app/src/vitest/setup.ts b/app/src/vitest/setup.ts index 4f011bc..6bc0392 100644 --- a/app/src/vitest/setup.ts +++ b/app/src/vitest/setup.ts @@ -1,5 +1,8 @@ import * as matchers from '@testing-library/jest-dom/matchers'; import { expect, vi } from 'vitest'; +import 'vitest-axe/extend-expect'; +import 'vitest'; +import type { AxeMatchers } from 'vitest-axe/matchers'; expect.extend(matchers); @@ -17,4 +20,9 @@ process.on('unhandledRejection', (reason) => { throw reason; }); +declare module 'vitest' { + export interface Assertion extends AxeMatchers {} + export interface AsymmetricMatchersContaining extends AxeMatchers {} +} + export default {}; diff --git a/app/src/vitest/utils.tsx b/app/src/vitest/utils.tsx index 66d9437..2d31bb6 100644 --- a/app/src/vitest/utils.tsx +++ b/app/src/vitest/utils.tsx @@ -142,8 +142,8 @@ const renderRoutes = ( : createMemoryRouter(routesOrRouter, { initialEntries: [initialPath ?? routesOrRouter[0].path ?? '/'], }); - customRender(); - return { router: appRouter }; + const { container } = customRender(); + return { container, router: appRouter }; }; const log = (value: string) => process.stdout.write(`${value} \n`); diff --git a/yarn.lock b/yarn.lock index 827dfd7..eeb1a5c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5544,7 +5544,7 @@ __metadata: languageName: node linkType: hard -"@testing-library/user-event@npm:^14.6.0, @testing-library/user-event@npm:^14.6.1": +"@testing-library/user-event@npm:^14.6.1": version: 14.6.1 resolution: "@testing-library/user-event@npm:14.6.1" peerDependencies: @@ -6587,14 +6587,14 @@ __metadata: languageName: node linkType: hard -"@vitest/browser@npm:^3.0.3": - version: 3.0.3 - resolution: "@vitest/browser@npm:3.0.3" +"@vitest/browser@npm:^3.0.5": + version: 3.0.5 + resolution: "@vitest/browser@npm:3.0.5" dependencies: "@testing-library/dom": "npm:^10.4.0" - "@testing-library/user-event": "npm:^14.6.0" - "@vitest/mocker": "npm:3.0.3" - "@vitest/utils": "npm:3.0.3" + "@testing-library/user-event": "npm:^14.6.1" + "@vitest/mocker": "npm:3.0.5" + "@vitest/utils": "npm:3.0.5" magic-string: "npm:^0.30.17" msw: "npm:^2.7.0" sirv: "npm:^3.0.0" @@ -6602,7 +6602,7 @@ __metadata: ws: "npm:^8.18.0" peerDependencies: playwright: "*" - vitest: 3.0.3 + vitest: 3.0.5 webdriverio: "*" peerDependenciesMeta: playwright: @@ -6611,13 +6611,13 @@ __metadata: optional: true webdriverio: optional: true - checksum: 10/4a5784a34234134f8ca9809fcfca0a9df7802cd66428e61be5be1a390f9ea50038ca4991ffff725e072ac0b47ff90ae978708c90b945940753a0dba27e77e6a6 + checksum: 10/8464f5ac7162e2905711fd2677ce57bab87ded5de7624cb742b2c495874c3d04ed549408dd6e088c831da37d03376dc3837998b07f7d5eea9ec85e3d0c948c6c languageName: node linkType: hard -"@vitest/coverage-v8@npm:^3.0.3": - version: 3.0.3 - resolution: "@vitest/coverage-v8@npm:3.0.3" +"@vitest/coverage-v8@npm:^3.0.5": + version: 3.0.5 + resolution: "@vitest/coverage-v8@npm:3.0.5" dependencies: "@ampproject/remapping": "npm:^2.3.0" "@bcoe/v8-coverage": "npm:^1.0.2" @@ -6632,12 +6632,12 @@ __metadata: test-exclude: "npm:^7.0.1" tinyrainbow: "npm:^2.0.0" peerDependencies: - "@vitest/browser": 3.0.3 - vitest: 3.0.3 + "@vitest/browser": 3.0.5 + vitest: 3.0.5 peerDependenciesMeta: "@vitest/browser": optional: true - checksum: 10/85f80033a3db55c5724164617dedf20f41bbd13a5c075f0872dcf0129874bb4c99f5fffa922b40e509bb470fd05601b40768963b6cf210fe56c3db79d259071e + checksum: 10/aa1aa681b4ee86d5ecf53390c56e24e7b61ea7cb47a178630c224de4bdd7eaf8a30b184299741b6e358d214670759905e2f90fb08d0745abdc3974992dfa137f languageName: node linkType: hard @@ -6653,25 +6653,6 @@ __metadata: languageName: node linkType: hard -"@vitest/mocker@npm:3.0.3": - version: 3.0.3 - resolution: "@vitest/mocker@npm:3.0.3" - dependencies: - "@vitest/spy": "npm:3.0.3" - estree-walker: "npm:^3.0.3" - magic-string: "npm:^0.30.17" - peerDependencies: - msw: ^2.4.9 - vite: ^5.0.0 || ^6.0.0 - peerDependenciesMeta: - msw: - optional: true - vite: - optional: true - checksum: 10/82477f7093fd4ee0a5477a4b99ab5ac748255c74b89f75453ef2f5f14424167fbc7e699ace247f5b3a2763bf9c9692e340feb627bafaa1829ae14d53feedffe6 - languageName: node - linkType: hard - "@vitest/mocker@npm:3.0.5": version: 3.0.5 resolution: "@vitest/mocker@npm:3.0.5" @@ -6691,16 +6672,7 @@ __metadata: languageName: node linkType: hard -"@vitest/pretty-format@npm:3.0.3": - version: 3.0.3 - resolution: "@vitest/pretty-format@npm:3.0.3" - dependencies: - tinyrainbow: "npm:^2.0.0" - checksum: 10/37bfeab77c1daaa0a5208eb991695b8eb3ba183807fa656574072e28e8976dfecc4c77c46f56738911ea49889c6e1394ab384a2940b74afeea57174d3ba9d9ef - languageName: node - linkType: hard - -"@vitest/pretty-format@npm:3.0.5, @vitest/pretty-format@npm:^3.0.5": +"@vitest/pretty-format@npm:3.0.5, @vitest/pretty-format@npm:^3.0.3, @vitest/pretty-format@npm:^3.0.5": version: 3.0.5 resolution: "@vitest/pretty-format@npm:3.0.5" dependencies: @@ -6730,15 +6702,6 @@ __metadata: languageName: node linkType: hard -"@vitest/spy@npm:3.0.3": - version: 3.0.3 - resolution: "@vitest/spy@npm:3.0.3" - dependencies: - tinyspy: "npm:^3.0.2" - checksum: 10/3f408a9d2895d13e16052164084a6dcc21aa57afc8194c3f356f1c32d5cce177e2de4e08bc2e1af53400106a3054496cf39496ddd2a004500597de7f8bef1208 - languageName: node - linkType: hard - "@vitest/spy@npm:3.0.5": version: 3.0.5 resolution: "@vitest/spy@npm:3.0.5" @@ -6748,17 +6711,6 @@ __metadata: languageName: node linkType: hard -"@vitest/utils@npm:3.0.3": - version: 3.0.3 - resolution: "@vitest/utils@npm:3.0.3" - dependencies: - "@vitest/pretty-format": "npm:3.0.3" - loupe: "npm:^3.1.2" - tinyrainbow: "npm:^2.0.0" - checksum: 10/ae2010a796362558434857bfee7b7916ac1c2c8cc555b79e36ab13b8649f6d934174b5a68d6b7fe389a041317d3de95fe782890ead36067468e982d4a9017fcd - languageName: node - linkType: hard - "@vitest/utils@npm:3.0.5": version: 3.0.5 resolution: "@vitest/utils@npm:3.0.5" @@ -7276,8 +7228,8 @@ __metadata: "@typescript-eslint/eslint-plugin": "npm:^8.22.0" "@typescript-eslint/parser": "npm:^8.22.0" "@vitejs/plugin-react": "npm:^4.3.4" - "@vitest/browser": "npm:^3.0.3" - "@vitest/coverage-v8": "npm:^3.0.3" + "@vitest/browser": "npm:^3.0.5" + "@vitest/coverage-v8": "npm:^3.0.5" axios: "npm:^1.7.9" babel-plugin-styled-components: "npm:^2.1.4" dayjs: "npm:^1.11.13" @@ -7328,6 +7280,7 @@ __metadata: vite: "npm:6.0.11" vite-plugin-node-polyfills: "npm:^0.23.0" vitest: "npm:^3.0.5" + vitest-axe: "npm:^1.0.0-pre.3" vitest-preview: "npm:^0.0.1" zod: "npm:^3.24.1" languageName: unknown @@ -7629,7 +7582,7 @@ __metadata: languageName: node linkType: hard -"axe-core@npm:^4.10.0": +"axe-core@npm:^4.10.0, axe-core@npm:^4.10.2": version: 4.10.2 resolution: "axe-core@npm:4.10.2" checksum: 10/a69423b2ff16c15922c4ea7cf9cc5112728a2817bbe0f2cc212248d648885ffd1ba554e3a341dfc289cd9e67fc0d06f333b5c6837c5c38ca6652507381216fc1 @@ -8384,7 +8337,7 @@ __metadata: languageName: node linkType: hard -"chalk@npm:^5.0.0, chalk@npm:^5.0.1, chalk@npm:^5.2.0": +"chalk@npm:^5.0.0, chalk@npm:^5.0.1, chalk@npm:^5.2.0, chalk@npm:^5.4.1": version: 5.4.1 resolution: "chalk@npm:5.4.1" checksum: 10/29df3ffcdf25656fed6e95962e2ef86d14dfe03cd50e7074b06bad9ffbbf6089adbb40f75c00744d843685c8d008adaf3aed31476780312553caf07fa86e5bc7 @@ -14514,6 +14467,13 @@ __metadata: languageName: node linkType: hard +"lodash-es@npm:^4.17.21": + version: 4.17.21 + resolution: "lodash-es@npm:4.17.21" + checksum: 10/03f39878ea1e42b3199bd3f478150ab723f93cc8730ad86fec1f2804f4a07c6e30deaac73cad53a88e9c3db33348bb8ceeb274552390e7a75d7849021c02df43 + languageName: node + linkType: hard + "lodash.clonedeep@npm:^4.5.0": version: 4.5.0 resolution: "lodash.clonedeep@npm:4.5.0" @@ -22149,6 +22109,20 @@ __metadata: languageName: node linkType: hard +"vitest-axe@npm:^1.0.0-pre.3": + version: 1.0.0-pre.5 + resolution: "vitest-axe@npm:1.0.0-pre.5" + dependencies: + "@vitest/pretty-format": "npm:^3.0.3" + axe-core: "npm:^4.10.2" + chalk: "npm:^5.4.1" + lodash-es: "npm:^4.17.21" + peerDependencies: + vitest: ">=1" + checksum: 10/e541f9a0ba037db8ac0a0f4ab42a025488bd614611e497093eb3f1f9b5beeca790c0c1788dd5cd0b13769429982cecb62c13c4a11ec53f47b79080e75e3f5034 + languageName: node + linkType: hard + "vitest-preview@npm:^0.0.1": version: 0.0.1 resolution: "vitest-preview@npm:0.0.1"