agroptima-design-system 0.24.5 → 0.25.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -1
- package/src/atoms/Input.tsx +4 -2
- package/src/atoms/PopoverMenu/PopoverMenu.scss +46 -0
- package/src/atoms/PopoverMenu/PopoverMenu.tsx +13 -0
- package/src/atoms/PopoverMenu/PopoverMenuOption.tsx +42 -0
- package/src/atoms/PopoverMenu/index.ts +4 -0
- package/src/icons/index.tsx +2 -0
- package/src/icons/user-menu.svg +1 -0
- package/src/stories/Changelog.mdx +9 -0
- package/src/stories/PopoverMenu.stories.js +43 -0
- package/tests/Button.spec.tsx +113 -0
- package/tests/Checkbox.spec.tsx +21 -0
- package/tests/Collapsible.spec.tsx +2 -2
- package/tests/EmptyState.spec.tsx +44 -0
- package/tests/FloatingButton.spec.tsx +86 -0
- package/tests/Icon.spec.tsx +19 -0
- package/tests/IconButton.spec.tsx +80 -0
- package/tests/Input.spec.tsx +90 -0
- package/tests/Multiselect.spec.tsx +126 -0
- package/tests/PopoverMenu.spec.tsx +28 -0
- package/tests/Select.spec.tsx +121 -0
- package/tests/TextArea.spec.tsx +43 -0
- package/tests/utils/{classNames.spec.tx → classNames.spec.tsx} +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agroptima-design-system",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.25.0-beta.2",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"dev": "npm run storybook",
|
|
6
6
|
"storybook": "storybook dev -p 6006 --ci",
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"types": "tsc --noEmit",
|
|
12
12
|
"chromatic": "npx chromatic --exit-zero-on-changes",
|
|
13
13
|
"test": "jest",
|
|
14
|
+
"test-coverage": "jest --coverage",
|
|
14
15
|
"publish:beta": "npm publish --tag beta"
|
|
15
16
|
},
|
|
16
17
|
"dependencies": {
|
|
@@ -35,6 +36,7 @@
|
|
|
35
36
|
"@svgr/webpack": "^8.1.0",
|
|
36
37
|
"@testing-library/jest-dom": "^6.4.2",
|
|
37
38
|
"@testing-library/react": "^16.0.0",
|
|
39
|
+
"@testing-library/user-event": "^14.5.2",
|
|
38
40
|
"@types/jest": "^29.5.12",
|
|
39
41
|
"@types/jest-axe": "^3.5.9",
|
|
40
42
|
"@types/node": "^22.1.0",
|
package/src/atoms/Input.tsx
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { IconType } from './Icon'
|
|
2
2
|
import React, { useState } from 'react'
|
|
3
3
|
import { Icon } from './Icon'
|
|
4
|
+
import { IconButton } from './Button/IconButton'
|
|
4
5
|
import { classNames } from '../utils/classNames'
|
|
5
6
|
import { buildHelpText } from '../utils/buildHelpText'
|
|
6
7
|
import './Input.scss'
|
|
@@ -76,9 +77,10 @@ export function Input({
|
|
|
76
77
|
/>
|
|
77
78
|
{suffix && <span className="input-suffix">{suffix}</span>}
|
|
78
79
|
{type === 'password' && (
|
|
79
|
-
<
|
|
80
|
+
<IconButton
|
|
81
|
+
accessibilityLabel={handlePasswordIcon()}
|
|
80
82
|
className="password-icon"
|
|
81
|
-
|
|
83
|
+
icon={handlePasswordIcon()}
|
|
82
84
|
onClick={handlePasswordVisibility}
|
|
83
85
|
/>
|
|
84
86
|
)}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
@use '../../settings/color_alias';
|
|
2
|
+
@use '../../settings/typography/content' as typography;
|
|
3
|
+
@use '../../settings/config';
|
|
4
|
+
@use '../../settings/depth';
|
|
5
|
+
|
|
6
|
+
.popover-menu {
|
|
7
|
+
box-shadow:
|
|
8
|
+
0px 3px 6px -4px rgba(0, 0, 0, 0.12),
|
|
9
|
+
0px 6px 16px 0px rgba(0, 0, 0, 0.08),
|
|
10
|
+
0px 9px 28px 8px rgba(0, 0, 0, 0.05);
|
|
11
|
+
|
|
12
|
+
.popover-menu-option {
|
|
13
|
+
@include typography.body-regular-primary;
|
|
14
|
+
display: flex;
|
|
15
|
+
flex-direction: row;
|
|
16
|
+
align-items: flex-start;
|
|
17
|
+
justify-content: space-between;
|
|
18
|
+
width: 100%;
|
|
19
|
+
padding: config.$space-2x config.$space-3x config.$space-2x config.$space-3x;
|
|
20
|
+
gap: config.$space-3x;
|
|
21
|
+
border-radius: config.$corner-radius-xxs;
|
|
22
|
+
text-decoration: none;
|
|
23
|
+
cursor: default;
|
|
24
|
+
|
|
25
|
+
&:hover {
|
|
26
|
+
text-decoration: none;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
&.primary {
|
|
30
|
+
background: color_alias.$neutral-white;
|
|
31
|
+
|
|
32
|
+
&.active {
|
|
33
|
+
background-color: transparent;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
&:not(.disabled):hover {
|
|
37
|
+
background: color_alias.$primary-color-50;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
&.disabled {
|
|
41
|
+
background: color_alias.$neutral-color-50;
|
|
42
|
+
@include typography.body-regular-disabled;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface PopoverMenuProps
|
|
2
|
+
extends React.ComponentPropsWithoutRef<'div'> {}
|
|
3
|
+
|
|
4
|
+
export function PopoverMenu({
|
|
5
|
+
children,
|
|
6
|
+
...props
|
|
7
|
+
}: PopoverMenuProps): React.JSX.Element {
|
|
8
|
+
return (
|
|
9
|
+
<div role="menu" className="popover-menu" {...props}>
|
|
10
|
+
{children}
|
|
11
|
+
</div>
|
|
12
|
+
)
|
|
13
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { LinkProps as NextLinkProps } from 'next/link'
|
|
2
|
+
import { classNames } from '../../utils/classNames'
|
|
3
|
+
import Link from 'next/link'
|
|
4
|
+
import './PopoverMenu.scss'
|
|
5
|
+
|
|
6
|
+
export type Variant = 'primary'
|
|
7
|
+
|
|
8
|
+
type LinkProps = NextLinkProps & React.AnchorHTMLAttributes<HTMLAnchorElement>
|
|
9
|
+
export interface PopoverMenuOptionProps extends LinkProps {
|
|
10
|
+
variant?: Variant
|
|
11
|
+
title: string
|
|
12
|
+
disabled?: boolean
|
|
13
|
+
href: string
|
|
14
|
+
active?: boolean
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function PopoverMenuOption({
|
|
18
|
+
variant = 'primary',
|
|
19
|
+
className,
|
|
20
|
+
title,
|
|
21
|
+
disabled,
|
|
22
|
+
href,
|
|
23
|
+
active,
|
|
24
|
+
...props
|
|
25
|
+
}: PopoverMenuOptionProps): React.JSX.Element {
|
|
26
|
+
const cssClasses = classNames('popover-menu-option', variant, className, {
|
|
27
|
+
disabled,
|
|
28
|
+
active,
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<Link
|
|
33
|
+
role="menuitem"
|
|
34
|
+
className={cssClasses}
|
|
35
|
+
href={disabled ? '#' : href}
|
|
36
|
+
aria-disabled={disabled}
|
|
37
|
+
{...props}
|
|
38
|
+
>
|
|
39
|
+
<span className="title">{title}</span>
|
|
40
|
+
</Link>
|
|
41
|
+
)
|
|
42
|
+
}
|
package/src/icons/index.tsx
CHANGED
|
@@ -36,6 +36,7 @@ import Settings from './settings.svg'
|
|
|
36
36
|
import Show from './show.svg'
|
|
37
37
|
import ShowOff from './show-off.svg'
|
|
38
38
|
import Sorter from './sorter.svg'
|
|
39
|
+
import UserMenu from './user-menu.svg'
|
|
39
40
|
import Warning from './warning.svg'
|
|
40
41
|
import DeliveryNote from './delivery-note.svg'
|
|
41
42
|
import PDF from './pdf.svg'
|
|
@@ -81,5 +82,6 @@ export {
|
|
|
81
82
|
Show,
|
|
82
83
|
ShowOff,
|
|
83
84
|
Sorter,
|
|
85
|
+
UserMenu,
|
|
84
86
|
Warning,
|
|
85
87
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#user-menu__a)"><path d="M10 0C4.48 0 0 4.48 0 10s4.48 10 10 10 10-4.48 10-10S15.52 0 10 0Zm0 4c1.93 0 3.5 1.57 3.5 3.5S11.93 11 10 11 6.5 9.43 6.5 7.5 8.07 4 10 4Zm0 14c-2.03 0-4.43-.82-6.14-2.88a9.947 9.947 0 0 1 12.28 0C14.43 17.18 12.03 18 10 18Z" fill="#161C26"/></g><defs><clipPath id="user-menu__a"><path fill="#fff" d="M0 0h20v20H0z"/></clipPath></defs></svg>
|
|
@@ -4,6 +4,15 @@ import { Meta } from "@storybook/blocks";
|
|
|
4
4
|
|
|
5
5
|
# Changelog
|
|
6
6
|
|
|
7
|
+
# 0.25.0
|
|
8
|
+
|
|
9
|
+
* Add PopoverMenu and PopoverMenuOption components.
|
|
10
|
+
* Add UserMenu icon.
|
|
11
|
+
|
|
12
|
+
# 0.24.5
|
|
13
|
+
|
|
14
|
+
* Add tests to all components.
|
|
15
|
+
|
|
7
16
|
# 0.24.4
|
|
8
17
|
|
|
9
18
|
* Remove margin from Alert component.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
|
|
3
|
+
import { PopoverMenu, PopoverMenuOption } from '../atoms/PopoverMenu'
|
|
4
|
+
|
|
5
|
+
const figmaPrimaryDesign = {
|
|
6
|
+
design: {
|
|
7
|
+
type: 'figma',
|
|
8
|
+
url: 'https://www.figma.com/design/DN2ova21vWqCRvPspBXgI1/Design-System?node-id=3200-3749&m=dev',
|
|
9
|
+
},
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const meta = {
|
|
13
|
+
title: 'Design System/Atoms/PopoverMenu',
|
|
14
|
+
component: PopoverMenuOption,
|
|
15
|
+
tags: ['autodocs'],
|
|
16
|
+
argTypes: {
|
|
17
|
+
variant: {
|
|
18
|
+
description: 'Component variant used',
|
|
19
|
+
},
|
|
20
|
+
title: {
|
|
21
|
+
description: 'Component title text',
|
|
22
|
+
},
|
|
23
|
+
disabled: {
|
|
24
|
+
description: 'Is the component disabled?',
|
|
25
|
+
},
|
|
26
|
+
active: {
|
|
27
|
+
description: 'Is the component active?',
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
parameters: figmaPrimaryDesign,
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export default meta
|
|
34
|
+
|
|
35
|
+
export const Menu = {
|
|
36
|
+
render: () => (
|
|
37
|
+
<PopoverMenu>
|
|
38
|
+
<PopoverMenuOption active href="#" variant="primary" title="Profile" />
|
|
39
|
+
<PopoverMenuOption href="#" variant="primary" title="Change password" />
|
|
40
|
+
<PopoverMenuOption disabled href="#" variant="primary" title="Logout" />
|
|
41
|
+
</PopoverMenu>
|
|
42
|
+
),
|
|
43
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import type { ButtonVariant } from '@/atoms/Button/Button'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
import { screen, render } from '@testing-library/react'
|
|
4
|
+
import userEvent from '@testing-library/user-event'
|
|
5
|
+
import { Button } from '@/atoms/Button/Button'
|
|
6
|
+
|
|
7
|
+
describe('Button', () => {
|
|
8
|
+
const variants = [
|
|
9
|
+
'primary',
|
|
10
|
+
'primary-ghost',
|
|
11
|
+
'primary-outlined',
|
|
12
|
+
'neutral',
|
|
13
|
+
'neutral-ghost',
|
|
14
|
+
'neutral-outlined',
|
|
15
|
+
'error',
|
|
16
|
+
'error-ghost',
|
|
17
|
+
'error-outlined',
|
|
18
|
+
'success',
|
|
19
|
+
'success-ghost',
|
|
20
|
+
'success-outlined',
|
|
21
|
+
'info',
|
|
22
|
+
'info-ghost',
|
|
23
|
+
'info-outlined',
|
|
24
|
+
'warning',
|
|
25
|
+
'warning-ghost',
|
|
26
|
+
'warning-outlined',
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
it.each(variants)(
|
|
30
|
+
'renders the Link version %s variant with text and expected styles',
|
|
31
|
+
(variant) => {
|
|
32
|
+
const label = `${variant} Button`
|
|
33
|
+
const { getByRole, getByText } = render(
|
|
34
|
+
<Button
|
|
35
|
+
id={`${variant}-button`}
|
|
36
|
+
label={label}
|
|
37
|
+
variant={variant as ButtonVariant}
|
|
38
|
+
href="link.com"
|
|
39
|
+
/>,
|
|
40
|
+
)
|
|
41
|
+
expect(getByRole('link')).toHaveClass(`button ${variant}`)
|
|
42
|
+
expect(getByText(label)).toBeInTheDocument()
|
|
43
|
+
expect(getByRole('link')).toBeInTheDocument()
|
|
44
|
+
},
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
it.each(variants)(
|
|
48
|
+
'renders the Button version %s variant with text and expected styles',
|
|
49
|
+
(variant) => {
|
|
50
|
+
const label = `${variant} Button`
|
|
51
|
+
const { getByRole, getByText } = render(
|
|
52
|
+
<Button
|
|
53
|
+
id={`${variant}-button`}
|
|
54
|
+
label={label}
|
|
55
|
+
variant={variant as ButtonVariant}
|
|
56
|
+
onClick={() => alert('click')}
|
|
57
|
+
/>,
|
|
58
|
+
)
|
|
59
|
+
expect(getByRole('button')).toHaveClass(`button ${variant}`)
|
|
60
|
+
expect(getByText(label)).toBeInTheDocument()
|
|
61
|
+
expect(getByRole('button')).toBeInTheDocument()
|
|
62
|
+
},
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
it('renders the icon when leftIcon prop is passed', async () => {
|
|
66
|
+
const { getByRole } = render(
|
|
67
|
+
<Button
|
|
68
|
+
id="button-with-icon"
|
|
69
|
+
label="Button with icon"
|
|
70
|
+
variant="info"
|
|
71
|
+
leftIcon="AngleLeft"
|
|
72
|
+
href="link.com"
|
|
73
|
+
/>,
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
expect(getByRole('img').title).toBe('AngleLeft')
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
it('triggers event on onClick', async () => {
|
|
80
|
+
const user = userEvent.setup()
|
|
81
|
+
const onClickEvent = jest.fn()
|
|
82
|
+
render(
|
|
83
|
+
<Button
|
|
84
|
+
id="enabled-button"
|
|
85
|
+
label="Enabled button"
|
|
86
|
+
variant="info"
|
|
87
|
+
onClick={onClickEvent}
|
|
88
|
+
/>,
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
await user.click(screen.getByRole('button'))
|
|
92
|
+
|
|
93
|
+
expect(onClickEvent).toHaveBeenCalled()
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
it('does not trigger event on onClick if Button is disabled', async () => {
|
|
97
|
+
const user = userEvent.setup()
|
|
98
|
+
const onClickEvent = jest.fn()
|
|
99
|
+
render(
|
|
100
|
+
<Button
|
|
101
|
+
id="disabled-button"
|
|
102
|
+
label="Disabled button"
|
|
103
|
+
variant="info"
|
|
104
|
+
disabled
|
|
105
|
+
onClick={onClickEvent}
|
|
106
|
+
/>,
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
await user.click(screen.getByRole('button'))
|
|
110
|
+
|
|
111
|
+
expect(onClickEvent).not.toHaveBeenCalled()
|
|
112
|
+
})
|
|
113
|
+
})
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { render } from '@testing-library/react'
|
|
3
|
+
import { Checkbox } from '@/atoms/Checkbox'
|
|
4
|
+
|
|
5
|
+
describe('Checkbox', () => {
|
|
6
|
+
const variants = ['primary']
|
|
7
|
+
|
|
8
|
+
it.each(variants)('renders with label and expected styles', (variant) => {
|
|
9
|
+
const { getByRole, getAllByRole, getByText } = render(
|
|
10
|
+
<Checkbox
|
|
11
|
+
accessibilityLabel="Marks if the user likes videogames"
|
|
12
|
+
id="checkbox-videogames-preference"
|
|
13
|
+
label="Do you like videogames?"
|
|
14
|
+
variant="primary"
|
|
15
|
+
/>,
|
|
16
|
+
)
|
|
17
|
+
expect(getAllByRole('generic')[1]).toHaveClass(`checkbox-group ${variant}`)
|
|
18
|
+
expect(getByRole('checkbox')).toHaveClass(`checkbox ${variant}`)
|
|
19
|
+
expect(getByText(/Do you like videogames/i)).toBeInTheDocument()
|
|
20
|
+
})
|
|
21
|
+
})
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
-
import {
|
|
2
|
+
import { render } from '@testing-library/react'
|
|
3
3
|
import { Collapsible } from '@/atoms/Collapsible'
|
|
4
4
|
import { Input } from '@/atoms/Input'
|
|
5
5
|
|
|
6
6
|
describe('Collapsible', () => {
|
|
7
7
|
it('renders', () => {
|
|
8
|
-
const { getByRole, getByText
|
|
8
|
+
const { getByRole, getByText } = render(
|
|
9
9
|
<Collapsible title="My personal data" name="personal-data" open>
|
|
10
10
|
<Input
|
|
11
11
|
accessibilityLabel="Fill the form name"
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { render } from '@testing-library/react'
|
|
3
|
+
import type { Variant } from '@/atoms/EmptyState'
|
|
4
|
+
import { EmptyState } from '@/atoms/EmptyState'
|
|
5
|
+
import { Button } from '@/atoms/Button/Button'
|
|
6
|
+
|
|
7
|
+
describe('EmptyState', () => {
|
|
8
|
+
const variants = ['primary']
|
|
9
|
+
it.each(variants)(
|
|
10
|
+
'renders the Basic %s variant with the expected image and text',
|
|
11
|
+
(variant) => {
|
|
12
|
+
const content = `${variant} empty state content`
|
|
13
|
+
const { getAllByRole, getByRole, getByText } = render(
|
|
14
|
+
<EmptyState variant={variant as Variant}>
|
|
15
|
+
<p>{content}</p>
|
|
16
|
+
</EmptyState>,
|
|
17
|
+
)
|
|
18
|
+
expect(getAllByRole('generic')[1]).toHaveClass(`empty-state ${variant}`)
|
|
19
|
+
expect(getByRole('img').title).toBe('EmptyState')
|
|
20
|
+
expect(getByText(content)).toBeInTheDocument()
|
|
21
|
+
},
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
it('renders the Custom version with the expected image and content', () => {
|
|
25
|
+
const { getAllByRole, getByRole, getByText } = render(
|
|
26
|
+
<EmptyState>
|
|
27
|
+
<p>
|
|
28
|
+
There are no videogames yet. You can import videogames to your{' '}
|
|
29
|
+
<a href="#">list</a>.
|
|
30
|
+
</p>
|
|
31
|
+
<Button
|
|
32
|
+
label="Import videogames"
|
|
33
|
+
onClick={() => alert('click')}
|
|
34
|
+
></Button>
|
|
35
|
+
</EmptyState>,
|
|
36
|
+
)
|
|
37
|
+
expect(getAllByRole('generic')[1]).toHaveClass(`empty-state primary`)
|
|
38
|
+
expect(getByRole('img').title).toBe('EmptyState')
|
|
39
|
+
expect(getByText(/There are no videogames yet/i)).toBeInTheDocument()
|
|
40
|
+
expect(getByText('Import videogames')).toBeInTheDocument()
|
|
41
|
+
expect(getByRole('link')).toBeInTheDocument()
|
|
42
|
+
expect(getByRole('button')).toBeInTheDocument()
|
|
43
|
+
})
|
|
44
|
+
})
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import type { Variant } from '@/atoms/Button/FloatingButton'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
import { screen, render } from '@testing-library/react'
|
|
4
|
+
import userEvent from '@testing-library/user-event'
|
|
5
|
+
import { FloatingButton } from '@/atoms/Button/FloatingButton'
|
|
6
|
+
|
|
7
|
+
describe('Floating Button', () => {
|
|
8
|
+
const variants = ['primary']
|
|
9
|
+
|
|
10
|
+
it.each(variants)(
|
|
11
|
+
'renders the Link version %s variant with text and expected styles',
|
|
12
|
+
(variant) => {
|
|
13
|
+
const { getByRole } = render(
|
|
14
|
+
<FloatingButton
|
|
15
|
+
id={`${variant}-floating-button`}
|
|
16
|
+
icon="Add"
|
|
17
|
+
shape="circle"
|
|
18
|
+
accessibilityLabel="Add game"
|
|
19
|
+
variant={variant as Variant}
|
|
20
|
+
href="link.com"
|
|
21
|
+
/>,
|
|
22
|
+
)
|
|
23
|
+
expect(getByRole('link')).toHaveClass(`floating-button ${variant} circle`)
|
|
24
|
+
expect(getByRole('img').title).toBe('Add')
|
|
25
|
+
expect(getByRole('link')).toBeInTheDocument()
|
|
26
|
+
},
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
it.each(variants)(
|
|
30
|
+
'renders the Button version %s variant with text and expected styles',
|
|
31
|
+
(variant) => {
|
|
32
|
+
const { getByRole } = render(
|
|
33
|
+
<FloatingButton
|
|
34
|
+
id={`${variant}-floating-button`}
|
|
35
|
+
icon="Add"
|
|
36
|
+
shape="rounded-square"
|
|
37
|
+
accessibilityLabel="Add game"
|
|
38
|
+
variant={variant as Variant}
|
|
39
|
+
onClick={() => alert('click')}
|
|
40
|
+
/>,
|
|
41
|
+
)
|
|
42
|
+
expect(getByRole('button')).toHaveClass(
|
|
43
|
+
`floating-button ${variant} rounded-square`,
|
|
44
|
+
)
|
|
45
|
+
expect(getByRole('img').title).toBe('Add')
|
|
46
|
+
expect(getByRole('button')).toBeInTheDocument()
|
|
47
|
+
},
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
it('triggers event on onClick', async () => {
|
|
51
|
+
const user = userEvent.setup()
|
|
52
|
+
const onClickEvent = jest.fn()
|
|
53
|
+
render(
|
|
54
|
+
<FloatingButton
|
|
55
|
+
id="enabled-floating-button"
|
|
56
|
+
icon="Add"
|
|
57
|
+
shape="rounded-square"
|
|
58
|
+
accessibilityLabel="Add game"
|
|
59
|
+
onClick={onClickEvent}
|
|
60
|
+
/>,
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
await user.click(screen.getByRole('button'))
|
|
64
|
+
|
|
65
|
+
expect(onClickEvent).toHaveBeenCalled()
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
it('does not trigger event on onClick if Button is disabled', async () => {
|
|
69
|
+
const user = userEvent.setup()
|
|
70
|
+
const onClickEvent = jest.fn()
|
|
71
|
+
render(
|
|
72
|
+
<FloatingButton
|
|
73
|
+
id="disabled-floating-button"
|
|
74
|
+
icon="Add"
|
|
75
|
+
shape="rounded-square"
|
|
76
|
+
accessibilityLabel="Add game"
|
|
77
|
+
disabled
|
|
78
|
+
onClick={onClickEvent}
|
|
79
|
+
/>,
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
await user.click(screen.getByRole('button'))
|
|
83
|
+
|
|
84
|
+
expect(onClickEvent).not.toHaveBeenCalled()
|
|
85
|
+
})
|
|
86
|
+
})
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { render } from '@testing-library/react'
|
|
3
|
+
import { Icon } from '@/atoms/Icon'
|
|
4
|
+
|
|
5
|
+
describe('Icon', () => {
|
|
6
|
+
it('renders with the expected graphic and styles', () => {
|
|
7
|
+
const { getByRole } = render(<Icon name="AngleLeft" className="info" />)
|
|
8
|
+
|
|
9
|
+
expect(getByRole('img')).toHaveClass('icon info')
|
|
10
|
+
expect(getByRole('img').title).toBe('AngleLeft')
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
it('has a rotating animation', () => {
|
|
14
|
+
const { getByRole } = render(<Icon name="Loading" className="info" />)
|
|
15
|
+
|
|
16
|
+
expect(getByRole('img')).toHaveClass('icon info rotate')
|
|
17
|
+
expect(getByRole('img').title).toBe('Loading')
|
|
18
|
+
})
|
|
19
|
+
})
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { Variant } from '@/atoms/Button/IconButton'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
import { screen, render } from '@testing-library/react'
|
|
4
|
+
import userEvent from '@testing-library/user-event'
|
|
5
|
+
import { IconButton } from '@/atoms/Button/IconButton'
|
|
6
|
+
|
|
7
|
+
describe('Icon Button', () => {
|
|
8
|
+
const variants = ['primary', 'secondary']
|
|
9
|
+
|
|
10
|
+
it.each(variants)(
|
|
11
|
+
'renders the Link version %s variant with text and expected styles',
|
|
12
|
+
(variant) => {
|
|
13
|
+
const { getByRole } = render(
|
|
14
|
+
<IconButton
|
|
15
|
+
id={`${variant}-icon-button`}
|
|
16
|
+
icon="Edit"
|
|
17
|
+
accessibilityLabel="Edit game"
|
|
18
|
+
variant={variant as Variant}
|
|
19
|
+
href="link.com"
|
|
20
|
+
/>,
|
|
21
|
+
)
|
|
22
|
+
expect(getByRole('link')).toHaveClass(`icon-button ${variant}`)
|
|
23
|
+
expect(getByRole('img').title).toBe('Edit game')
|
|
24
|
+
expect(getByRole('link')).toBeInTheDocument()
|
|
25
|
+
},
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
it.each(variants)(
|
|
29
|
+
'renders the Button version %s variant with text and expected styles',
|
|
30
|
+
(variant) => {
|
|
31
|
+
const { getByRole } = render(
|
|
32
|
+
<IconButton
|
|
33
|
+
id={`${variant}-icon-button`}
|
|
34
|
+
icon="Edit"
|
|
35
|
+
accessibilityLabel="Edit game"
|
|
36
|
+
variant={variant as Variant}
|
|
37
|
+
onClick={() => alert('click')}
|
|
38
|
+
/>,
|
|
39
|
+
)
|
|
40
|
+
expect(getByRole('button')).toHaveClass(`icon-button ${variant}`)
|
|
41
|
+
expect(getByRole('img').title).toBe('Edit game')
|
|
42
|
+
expect(getByRole('button')).toBeInTheDocument()
|
|
43
|
+
},
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
it('triggers event on onClick', async () => {
|
|
47
|
+
const user = userEvent.setup()
|
|
48
|
+
const onClickEvent = jest.fn()
|
|
49
|
+
render(
|
|
50
|
+
<IconButton
|
|
51
|
+
id="enabled-icon-button"
|
|
52
|
+
icon="Edit"
|
|
53
|
+
accessibilityLabel="Edit game"
|
|
54
|
+
onClick={onClickEvent}
|
|
55
|
+
/>,
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
await user.click(screen.getByRole('button'))
|
|
59
|
+
|
|
60
|
+
expect(onClickEvent).toHaveBeenCalled()
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
it('does not trigger event on onClick if Button is disabled', async () => {
|
|
64
|
+
const user = userEvent.setup()
|
|
65
|
+
const onClickEvent = jest.fn()
|
|
66
|
+
render(
|
|
67
|
+
<IconButton
|
|
68
|
+
id="disabled-icon-button"
|
|
69
|
+
icon="Edit"
|
|
70
|
+
accessibilityLabel="Edit game"
|
|
71
|
+
disabled
|
|
72
|
+
onClick={onClickEvent}
|
|
73
|
+
/>,
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
await user.click(screen.getByRole('button'))
|
|
77
|
+
|
|
78
|
+
expect(onClickEvent).not.toHaveBeenCalled()
|
|
79
|
+
})
|
|
80
|
+
})
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { render, screen } from '@testing-library/react'
|
|
3
|
+
import userEvent from '@testing-library/user-event'
|
|
4
|
+
import { Input } from '@/atoms/Input'
|
|
5
|
+
|
|
6
|
+
describe('Input', () => {
|
|
7
|
+
it('renders the Text type', () => {
|
|
8
|
+
const { getByPlaceholderText, getAllByRole, getByRole, getByText } = render(
|
|
9
|
+
<Input
|
|
10
|
+
accessibilityLabel="Fill the form email"
|
|
11
|
+
helpText="This text can help you"
|
|
12
|
+
id="email_input"
|
|
13
|
+
label="Email"
|
|
14
|
+
name="email"
|
|
15
|
+
placeholder="Write your email..."
|
|
16
|
+
type="email"
|
|
17
|
+
variant="primary"
|
|
18
|
+
/>,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
expect(getByRole('textbox')).toHaveAttribute('type', 'email')
|
|
22
|
+
expect(getAllByRole('generic')[1]).toHaveClass('input-group primary')
|
|
23
|
+
expect(getByText('Email')).toBeInTheDocument()
|
|
24
|
+
expect(getByPlaceholderText(/Write your email.../)).toBeInTheDocument()
|
|
25
|
+
expect(getByText(/This text can help you/i)).toBeInTheDocument()
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
it('renders the Password type', async () => {
|
|
29
|
+
const user = userEvent.setup()
|
|
30
|
+
const { getByPlaceholderText, getAllByRole, getByRole, getByText } = render(
|
|
31
|
+
<Input
|
|
32
|
+
helpText="This text can help you"
|
|
33
|
+
id="password_input"
|
|
34
|
+
label="Password"
|
|
35
|
+
name="login_password"
|
|
36
|
+
placeholder="Write your password..."
|
|
37
|
+
type="password"
|
|
38
|
+
variant="primary"
|
|
39
|
+
/>,
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
expect(getByPlaceholderText(/Write your password.../)).toHaveAttribute(
|
|
43
|
+
'type',
|
|
44
|
+
'password',
|
|
45
|
+
)
|
|
46
|
+
expect(getAllByRole('generic')[1]).toHaveClass('input-group primary')
|
|
47
|
+
expect(getByText('Password')).toBeInTheDocument()
|
|
48
|
+
expect(getByRole('img').title).toBe('Show')
|
|
49
|
+
expect(getByText(/This text can help you/i)).toBeInTheDocument()
|
|
50
|
+
|
|
51
|
+
await user.click(screen.getByRole('button'))
|
|
52
|
+
|
|
53
|
+
expect(getByRole('img').title).toBe('ShowOff')
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
it('renders input with errors', () => {
|
|
57
|
+
const { getAllByRole, getByText } = render(
|
|
58
|
+
<Input
|
|
59
|
+
accessibilityLabel="Fill the form email"
|
|
60
|
+
errors={['error1', 'error2']}
|
|
61
|
+
helpText="This text can help you"
|
|
62
|
+
id="email_input"
|
|
63
|
+
label="Email"
|
|
64
|
+
name="email"
|
|
65
|
+
placeholder="Email..."
|
|
66
|
+
type="email"
|
|
67
|
+
variant="primary"
|
|
68
|
+
/>,
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
expect(getAllByRole('generic')[1]).toHaveClass('input-group invalid')
|
|
72
|
+
expect(getByText(/error1/i)).toBeInTheDocument()
|
|
73
|
+
expect(getByText(/error2/i)).toBeInTheDocument()
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
it('renders input with suffix', () => {
|
|
77
|
+
const { getByRole, getByText } = render(
|
|
78
|
+
<Input
|
|
79
|
+
helpText="This text can help you"
|
|
80
|
+
label="Input with suffix"
|
|
81
|
+
name="price"
|
|
82
|
+
suffix="€/Bottle"
|
|
83
|
+
type="number"
|
|
84
|
+
/>,
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
expect(getByRole('spinbutton')).toBeInTheDocument()
|
|
88
|
+
expect(getByText('€/Bottle')).toBeInTheDocument()
|
|
89
|
+
})
|
|
90
|
+
})
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { render, screen } from '@testing-library/react'
|
|
3
|
+
import userEvent from '@testing-library/user-event'
|
|
4
|
+
import { Multiselect } from '@/atoms/Multiselect'
|
|
5
|
+
|
|
6
|
+
describe('Multiselect', () => {
|
|
7
|
+
it('renders', async () => {
|
|
8
|
+
const user = userEvent.setup()
|
|
9
|
+
const { getAllByRole, getByText } = render(
|
|
10
|
+
<Multiselect
|
|
11
|
+
accessibilityLabel="Select your favourite videogames options"
|
|
12
|
+
helpText="This text can help you"
|
|
13
|
+
id="multiselect-videogames"
|
|
14
|
+
label="Videogames"
|
|
15
|
+
name="example"
|
|
16
|
+
options={[
|
|
17
|
+
{
|
|
18
|
+
id: '1',
|
|
19
|
+
label: 'The Legend of Zelda: Ocarina of Time',
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
id: '2',
|
|
23
|
+
label: 'Spyro the Dragon',
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
id: '3',
|
|
27
|
+
label: 'Halo',
|
|
28
|
+
},
|
|
29
|
+
]}
|
|
30
|
+
placeholder="Select your favourite videogames..."
|
|
31
|
+
selectedLabel="videogames selected"
|
|
32
|
+
variant="primary"
|
|
33
|
+
/>,
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
expect(getAllByRole('generic')[1]).toHaveClass('multiselect-group primary')
|
|
37
|
+
expect(getByText('Videogames')).toBeInTheDocument()
|
|
38
|
+
expect(getByText(/Select your favourite videogames.../)).toBeInTheDocument()
|
|
39
|
+
expect(getByText(/This text can help you/i)).toBeInTheDocument()
|
|
40
|
+
|
|
41
|
+
await user.click(screen.getByRole('alert'))
|
|
42
|
+
|
|
43
|
+
expect(getByText(/Zelda/i)).toBeInTheDocument()
|
|
44
|
+
expect(getByText(/Spyro/i)).toBeInTheDocument()
|
|
45
|
+
expect(getByText(/Halo/i)).toBeInTheDocument()
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
it('renders the number of options selected', async () => {
|
|
49
|
+
const user = userEvent.setup()
|
|
50
|
+
const { getByText } = render(
|
|
51
|
+
<Multiselect
|
|
52
|
+
helpText="This text can help you"
|
|
53
|
+
id="multiselect-videogames"
|
|
54
|
+
label="Videogames"
|
|
55
|
+
name="example"
|
|
56
|
+
options={[
|
|
57
|
+
{
|
|
58
|
+
id: '1',
|
|
59
|
+
label: 'The Legend of Zelda: Ocarina of Time',
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
id: '2',
|
|
63
|
+
label: 'Spyro the Dragon',
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
id: '3',
|
|
67
|
+
label: 'Halo',
|
|
68
|
+
},
|
|
69
|
+
]}
|
|
70
|
+
placeholder="Select your favourite videogames..."
|
|
71
|
+
selected={[
|
|
72
|
+
{
|
|
73
|
+
id: '2',
|
|
74
|
+
label: 'Spyro the Dragon',
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
id: '1',
|
|
78
|
+
label: 'The Legend of Zelda: Ocarina of Time',
|
|
79
|
+
},
|
|
80
|
+
]}
|
|
81
|
+
selectedLabel="videogames selected"
|
|
82
|
+
variant="primary"
|
|
83
|
+
/>,
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
expect(getByText(/2 videogames selected/i)).toBeInTheDocument()
|
|
87
|
+
|
|
88
|
+
await user.click(screen.getByRole('alert'))
|
|
89
|
+
await user.click(screen.getAllByRole('option')[0])
|
|
90
|
+
|
|
91
|
+
expect(getByText(/1 videogames selected/i)).toBeInTheDocument()
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
it('renders with errors', () => {
|
|
95
|
+
const { getByText } = render(
|
|
96
|
+
<Multiselect
|
|
97
|
+
accessibilityLabel="Select your favourite videogames options"
|
|
98
|
+
errors={['error1', 'error2']}
|
|
99
|
+
helpText="This text can help you"
|
|
100
|
+
id="multiselect-videogames"
|
|
101
|
+
label="Videogames"
|
|
102
|
+
name="example"
|
|
103
|
+
options={[
|
|
104
|
+
{
|
|
105
|
+
id: '1',
|
|
106
|
+
label: 'The Legend of Zelda: Ocarina of Time',
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
id: '2',
|
|
110
|
+
label: 'Spyro the Dragon',
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
id: '3',
|
|
114
|
+
label: 'Halo',
|
|
115
|
+
},
|
|
116
|
+
]}
|
|
117
|
+
placeholder="Select your favourite videogames..."
|
|
118
|
+
selectedLabel="videogames selected"
|
|
119
|
+
variant="primary"
|
|
120
|
+
/>,
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
expect(getByText(/error1/i)).toBeInTheDocument()
|
|
124
|
+
expect(getByText(/error2/i)).toBeInTheDocument()
|
|
125
|
+
})
|
|
126
|
+
})
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { render } from '@testing-library/react'
|
|
3
|
+
import { PopoverMenu, PopoverMenuOption } from '@/atoms/PopoverMenu'
|
|
4
|
+
|
|
5
|
+
describe('PopoverMenu', () => {
|
|
6
|
+
it('renders', () => {
|
|
7
|
+
const { getByText, getAllByRole } = render(
|
|
8
|
+
<PopoverMenu>
|
|
9
|
+
<PopoverMenuOption active href="#" variant="primary" title="Profile" />
|
|
10
|
+
<PopoverMenuOption href="#" variant="primary" title="Change password" />
|
|
11
|
+
<PopoverMenuOption disabled href="#" variant="primary" title="Logout" />
|
|
12
|
+
</PopoverMenu>,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
expect(getAllByRole('menuitem')[0]).toHaveClass(
|
|
16
|
+
`popover-menu-option primary active`,
|
|
17
|
+
)
|
|
18
|
+
expect(getAllByRole('menuitem')[1]).toHaveClass(
|
|
19
|
+
`popover-menu-option primary`,
|
|
20
|
+
)
|
|
21
|
+
expect(getAllByRole('menuitem')[2]).toHaveClass(
|
|
22
|
+
`popover-menu-option primary disabled`,
|
|
23
|
+
)
|
|
24
|
+
expect(getByText(/Profile/i)).toBeInTheDocument()
|
|
25
|
+
expect(getByText(/Change password/i)).toBeInTheDocument()
|
|
26
|
+
expect(getByText(/Logout/i)).toBeInTheDocument()
|
|
27
|
+
})
|
|
28
|
+
})
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { render, screen } from '@testing-library/react'
|
|
3
|
+
import userEvent from '@testing-library/user-event'
|
|
4
|
+
import { Select } from '@/atoms/Select'
|
|
5
|
+
|
|
6
|
+
describe('Select', () => {
|
|
7
|
+
it('renders', async () => {
|
|
8
|
+
const user = userEvent.setup()
|
|
9
|
+
const { getAllByRole, getByText } = render(
|
|
10
|
+
<Select
|
|
11
|
+
accessibilityLabel="Select your favourite gaming system options"
|
|
12
|
+
helpText="This text can help you"
|
|
13
|
+
id="select-videogames"
|
|
14
|
+
label="Videogames"
|
|
15
|
+
name="example"
|
|
16
|
+
options={[
|
|
17
|
+
{
|
|
18
|
+
id: '1',
|
|
19
|
+
label: 'Nintendo Switch',
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
id: '2',
|
|
23
|
+
label: 'PlayStation 5',
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
id: '3',
|
|
27
|
+
label: 'Xbox Series S/X',
|
|
28
|
+
},
|
|
29
|
+
]}
|
|
30
|
+
placeholder="Select your favourite gaming system..."
|
|
31
|
+
variant="primary"
|
|
32
|
+
/>,
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
expect(getAllByRole('generic')[1]).toHaveClass('select-group primary')
|
|
36
|
+
expect(getByText('Videogames')).toBeInTheDocument()
|
|
37
|
+
expect(
|
|
38
|
+
getByText(/Select your favourite gaming system.../),
|
|
39
|
+
).toBeInTheDocument()
|
|
40
|
+
expect(getByText(/This text can help you/i)).toBeInTheDocument()
|
|
41
|
+
|
|
42
|
+
await user.click(screen.getByRole('alert'))
|
|
43
|
+
|
|
44
|
+
expect(getByText(/Switch/i)).toBeInTheDocument()
|
|
45
|
+
expect(getByText(/PlayStation/i)).toBeInTheDocument()
|
|
46
|
+
expect(getByText(/Xbox/i)).toBeInTheDocument()
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
it('renders the selected option', async () => {
|
|
50
|
+
const user = userEvent.setup()
|
|
51
|
+
const { getByText, queryByText } = render(
|
|
52
|
+
<Select
|
|
53
|
+
defaultValue="2"
|
|
54
|
+
helpText="This text can help you"
|
|
55
|
+
id="select-videogames"
|
|
56
|
+
label="Videogames"
|
|
57
|
+
name="example"
|
|
58
|
+
options={[
|
|
59
|
+
{
|
|
60
|
+
id: '1',
|
|
61
|
+
label: 'Nintendo Switch',
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
id: '2',
|
|
65
|
+
label: 'PlayStation 5',
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
id: '3',
|
|
69
|
+
label: 'Xbox Series S/X',
|
|
70
|
+
},
|
|
71
|
+
]}
|
|
72
|
+
placeholder="Select your favourite gaming system..."
|
|
73
|
+
variant="primary"
|
|
74
|
+
/>,
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
expect(getByText(/PlayStation/i)).toBeInTheDocument()
|
|
78
|
+
expect(queryByText(/Switch/i)).not.toBeInTheDocument()
|
|
79
|
+
expect(queryByText(/Xbox/i)).not.toBeInTheDocument()
|
|
80
|
+
|
|
81
|
+
await user.click(screen.getByRole('alert'))
|
|
82
|
+
await user.click(screen.getAllByRole('option')[0])
|
|
83
|
+
|
|
84
|
+
expect(getByText(/Switch/i)).toBeInTheDocument()
|
|
85
|
+
expect(queryByText(/PlayStation/i)).not.toBeInTheDocument()
|
|
86
|
+
expect(queryByText(/Xbox/i)).not.toBeInTheDocument()
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
it('renders with errors', () => {
|
|
90
|
+
const { getByText } = render(
|
|
91
|
+
<Select
|
|
92
|
+
accessibilityLabel="Select your favourite gaming system options"
|
|
93
|
+
errors={['error1', 'error2']}
|
|
94
|
+
helpText="This text can help you"
|
|
95
|
+
id="select-videogames"
|
|
96
|
+
label="Videogames"
|
|
97
|
+
name="example"
|
|
98
|
+
onChange={() => {}}
|
|
99
|
+
options={[
|
|
100
|
+
{
|
|
101
|
+
id: '1',
|
|
102
|
+
label: 'Nintendo Switch',
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
id: '2',
|
|
106
|
+
label: 'PlayStation 5',
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
id: '3',
|
|
110
|
+
label: 'Xbox Series S/X',
|
|
111
|
+
},
|
|
112
|
+
]}
|
|
113
|
+
placeholder="Select your favourite gaming system..."
|
|
114
|
+
variant="primary"
|
|
115
|
+
/>,
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
expect(getByText(/error1/i)).toBeInTheDocument()
|
|
119
|
+
expect(getByText(/error2/i)).toBeInTheDocument()
|
|
120
|
+
})
|
|
121
|
+
})
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { render } from '@testing-library/react'
|
|
3
|
+
import { TextArea } from '@/atoms/TextArea'
|
|
4
|
+
|
|
5
|
+
describe('TextArea', () => {
|
|
6
|
+
it('renders', () => {
|
|
7
|
+
const { getByPlaceholderText, getAllByRole, getByRole, getByText } = render(
|
|
8
|
+
<TextArea
|
|
9
|
+
accessibilityLabel="Fill the textarea"
|
|
10
|
+
helpText="This text can help you"
|
|
11
|
+
id="textarea"
|
|
12
|
+
label="Description"
|
|
13
|
+
name="textarea"
|
|
14
|
+
placeholder="Write here..."
|
|
15
|
+
variant="primary"
|
|
16
|
+
/>,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
expect(getByRole('textbox')).toBeInTheDocument()
|
|
20
|
+
expect(getAllByRole('generic')[1]).toHaveClass('input-group primary')
|
|
21
|
+
expect(getByText('Description')).toBeInTheDocument()
|
|
22
|
+
expect(getByPlaceholderText(/Write here.../)).toBeInTheDocument()
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
it('renders with errors', () => {
|
|
26
|
+
const { getAllByRole, getByText } = render(
|
|
27
|
+
<TextArea
|
|
28
|
+
accessibilityLabel="Fill the form textarea"
|
|
29
|
+
errors={['Che che che', 'Another error']}
|
|
30
|
+
helpText="This text can help you"
|
|
31
|
+
id="textarea"
|
|
32
|
+
label="Description"
|
|
33
|
+
name="textarea"
|
|
34
|
+
placeholder="Write here..."
|
|
35
|
+
variant="primary"
|
|
36
|
+
/>,
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
expect(getAllByRole('generic')[1]).toHaveClass('input-group invalid')
|
|
40
|
+
expect(getByText(/Che che che/i)).toBeInTheDocument()
|
|
41
|
+
expect(getByText(/Another error/i)).toBeInTheDocument()
|
|
42
|
+
})
|
|
43
|
+
})
|