Skip to content

Commit

Permalink
Feat: Adds jest-axe and Card component test (#2440)
Browse files Browse the repository at this point in the history
## What's the purpose of this pull request?

- Setup `@testing-library/jest-dom` to help to test our components when
checking an element's attributes, its text content, its css classes...
- Adds `Card` component tests
- Introduces accessibility tests: This won't guarantee that what we're
building is accessible, but it's a first step towards it. 🥳
- Updates `CheckboxField` component test 

TODO: Document 

## How it works?

Currently, our components library do not have tests, but we want to
introduce them for upcoming components. For existing components, we will
gradually add tests retroactively.

## How to test it?

1. navigate to `packages/components` -> run `yarn install`
2. run `yarn test`, you will be able to see the tests running
<img width="873" alt="image"
src="https://github.com/user-attachments/assets/1e4c0fcc-4ded-45c5-a078-0fad99c52dba">

_____

3. removing `<Label>` component from `CheckboxField`, when running the
step 2, you will get:
<img width="1005" alt="image"
src="https://github.com/user-attachments/assets/898360ba-2a9a-40d5-afd4-a6c0f74d11a4">


## References

https://testing-library.com/docs/ecosystem-jest-dom
testing-library/jest-dom#546
NickColley/jest-axe#79
  • Loading branch information
hellofanny committed Sep 12, 2024
1 parent ea14927 commit cd93d30
Show file tree
Hide file tree
Showing 8 changed files with 2,735 additions and 3,003 deletions.
20 changes: 10 additions & 10 deletions apps/site/pages/components/molecules/card.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -51,17 +51,17 @@ Card displays some information divided into a body and a header.
iconName="PlusCircle"
title="Card with Icon"
style={{width: '300px'}}>
<h1> First Product </h1>
<p> First Product </p>
<hr/>
<h1> Second Product </h1>
<p> Second Product </p>
</Card>
</OverviewSection>

<OverviewSection>
<Card
title="Card without Icon"
style={{width: '300px'}}>
<h1> Message </h1>
<p> Message </p>
</Card>
</OverviewSection>

Expand All @@ -71,17 +71,17 @@ Card displays some information divided into a body and a header.
iconName="PlusCircle"
title="Card with Icon"
style={{width: '300px'}}>
<h1> First Product </h1>
<p> First Product </p>
<hr/>
<h1> Second Product </h1>
<p> Second Product </p>
</Card>
```

```tsx
<Card
title="Card without Icon"
style={{width: '300px'}}>
<h1> Message </h1>
<p> Message </p>
</Card>
```

Expand Down Expand Up @@ -120,19 +120,19 @@ Follow the instructions in the [Importing FastStore UI component styles](/docs/c
iconName="PlusCircle"
title="Product List"
style={{width: '300px'}}>
<h1> First Product </h1>
<p> First Product </p>
<hr/>
<h1> Second Product </h1>
<p> Second Product </p>
</Card>
</OverviewSection>
```tsx
<Card
iconName="PlusCircle"
title="Product List"
style={{width: '300px'}}>
<h1> First Product </h1>
<p> First Product </p>
<hr/>
<h1> Second Product </h1>
<p> Second Product </p>
</Card>
```

Expand Down
2 changes: 2 additions & 0 deletions packages/components/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,7 @@
module.exports = {
preset: 'ts-jest',
testEnvironment: 'jest-environment-jsdom',
setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
}


3 changes: 3 additions & 0 deletions packages/components/jest.setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import '@testing-library/jest-dom';
import '@testing-library/jest-dom/jest-globals';

3 changes: 3 additions & 0 deletions packages/components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,14 @@
"devDependencies": {
"@faststore/eslint-config": "^3.0.97",
"@faststore/shared": "^3.0.97",
"@testing-library/jest-dom": "^6.5.0",
"@testing-library/react": "^14.3.0",
"@types/jest-axe": "^3.5.9",
"@types/react": "^18.2.42",
"@types/react-dom": "^18.2.17",
"eslint": "7.32.0",
"jest": "^29.7.0",
"jest-axe": "^9.0.0",
"jest-environment-jsdom": "^29.7.0",
"ts-jest": "^29.1.2",
"typescript": "^4.8.4"
Expand Down
55 changes: 55 additions & 0 deletions packages/components/test/molecules/Card/Card.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { describe, expect, it } from '@jest/globals'
import '@testing-library/jest-dom'
import { render, screen } from '@testing-library/react'
import { axe, toHaveNoViolations } from 'jest-axe'

import React from 'react'

import { Card } from '../../../src/index'

expect.extend(toHaveNoViolations)

describe('Card', () => {
const mockIconAction = jest.fn()
it('renders with title', () => {
render(<Card title="Test Card" />)

const cardTitle = screen.getByText('Test Card')
expect(cardTitle).toBeInTheDocument()
})

it('renders with custom max width', () => {
render(<Card title="Test Card" maxWidth="500px" />)

const card = screen.getByTestId('fs-card')
expect(card).toHaveStyle('max-width: 500px')
})

it('renders with icon', () => {
render(<Card title="Test Card" iconName="star" />)

const iconButton = screen.getByLabelText(
'Test Card action'
) as HTMLButtonElement
expect(iconButton).toBeInTheDocument()
})

it('executes the icon action when clicked', () => {
render(
<Card title="Test Card" iconName="star" iconAction={mockIconAction} />
)

const iconButton = screen.getByLabelText(
'Test Card action'
) as HTMLButtonElement
iconButton.click()
expect(mockIconAction).toHaveBeenCalled()
})

it('should not fail any accessibility tests', async () => {
const { container } = render(
<Card title="Test Card" iconName="star" iconAction={mockIconAction} />
)
expect(await axe(container)).toHaveNoViolations()
})
})
Original file line number Diff line number Diff line change
@@ -1,16 +1,39 @@
import { describe, it, expect } from '@jest/globals'
import { describe, expect, it } from '@jest/globals'
import { render, screen } from '@testing-library/react'
import { axe, toHaveNoViolations } from 'jest-axe'

import React from 'react'

import { CheckboxField } from '../../../src/index'

expect.extend(toHaveNoViolations)

describe('CheckboxField', () => {
it('renders all examples from the documentation', () => {
it('renders the default state', () => {
render(<CheckboxField label="Default" id="checkboxfield-default" />)

const input = screen.getByLabelText('Default') as HTMLInputElement

expect(input.checked).toBe(false)
})

it('renders the checked state', () => {
render(<CheckboxField label="Checked" id="checkboxfield-checked" checked />)

const input = screen.getByLabelText('Checked') as HTMLInputElement
expect(input.checked).toBe(true)
})

it('renders the disabled state', () => {
render(
<CheckboxField label="Disabled" id="checkboxfield-disabled" disabled />
)

const input = screen.getByLabelText('Disabled') as HTMLInputElement
expect(input.disabled).toBe(true)
})

it('renders the checked/partial state', () => {
render(
<CheckboxField
label="Checked & Partial"
Expand All @@ -19,21 +42,32 @@ describe('CheckboxField', () => {
partial
/>
)

const input = screen.getByLabelText('Checked & Partial') as HTMLInputElement
expect(input.checked).toBe(true)
})

describe('#checked', () => {
it('should allow the checked property to be passed', () => {
render(<CheckboxField id="identifier" label="Label" checked />)
const input = screen.getByLabelText('Label') as HTMLInputElement

const input = screen.getByLabelText('Label') as HTMLInputElement
expect(input.checked).toBe(true)
})

it('should not be checked if the `checked `prop is not passed', () => {
it('should not be checked if the `checked` prop is not passed', () => {
render(<CheckboxField id="identifier" label="Label" />)
const input = screen.getByLabelText('Label') as HTMLInputElement

const input = screen.getByLabelText('Label') as HTMLInputElement
expect(input.checked).toBe(false)
})
})

it('should not fail any accessibility tests', async () => {
const { container } = render(
<CheckboxField id="identifier" label="Label" />
)

expect(await axe(container)).toHaveNoViolations()
})
})
5 changes: 3 additions & 2 deletions packages/components/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
{
"extends": "@faststore/shared/tsconfig.json",
"compilerOptions": {
"outDir": "dist"
"outDir": "dist",
"types": ["@testing-library/jest-dom/jest-globals"]
},
"include": ["src"],
"exclude": [
"src/**/*.test.ts",
"src/**/*.test.tsx",
"src/**/*.stories.ts",
"src/**/*.stories.tsx",
"src/typings/utils.d.ts",
"src/typings/utils.d.ts"
]
}
Loading

0 comments on commit cd93d30

Please sign in to comment.