🚸(frontend) improve screen reading navigation
- add aria-hidden and empty alt attributes for screen readers to ignore decorative svg and images. - remove icon from input field used to name a group - update translations - update related e2e and components tests
This commit is contained in:
committed by
Sebastien Nobour
parent
72340db74c
commit
14deca13f4
@@ -83,7 +83,7 @@ export const Footer = () => {
|
|||||||
`}
|
`}
|
||||||
>
|
>
|
||||||
<Text $weight="bold">{label}</Text>
|
<Text $weight="bold">{label}</Text>
|
||||||
<IconLink width={18} />
|
<IconLink width={18} aria-hidden="true" />
|
||||||
</StyledLink>
|
</StyledLink>
|
||||||
))}
|
))}
|
||||||
</Box>
|
</Box>
|
||||||
@@ -157,7 +157,7 @@ export const Footer = () => {
|
|||||||
`}
|
`}
|
||||||
>
|
>
|
||||||
<Text $variation="600">licence etalab-2.0</Text>
|
<Text $variation="600">licence etalab-2.0</Text>
|
||||||
<IconLink width={18} />
|
<IconLink width={18} aria-hidden="true" />
|
||||||
</StyledLink>
|
</StyledLink>
|
||||||
</Trans>
|
</Trans>
|
||||||
</Text>
|
</Text>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export const AccountDropdown = () => {
|
|||||||
button={
|
button={
|
||||||
<Box $flex $direction="row" $align="center">
|
<Box $flex $direction="row" $align="center">
|
||||||
<Text $theme="primary">{t('My account')}</Text>
|
<Text $theme="primary">{t('My account')}</Text>
|
||||||
<Text className="material-icons" $theme="primary">
|
<Text className="material-icons" $theme="primary" aria-hidden="true">
|
||||||
arrow_drop_down
|
arrow_drop_down
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
@@ -24,7 +24,11 @@ export const AccountDropdown = () => {
|
|||||||
<Button
|
<Button
|
||||||
onClick={logout}
|
onClick={logout}
|
||||||
color="primary-text"
|
color="primary-text"
|
||||||
icon={<span className="material-icons">logout</span>}
|
icon={
|
||||||
|
<span className="material-icons" aria-hidden="true">
|
||||||
|
logout
|
||||||
|
</span>
|
||||||
|
}
|
||||||
aria-label={t('Logout')}
|
aria-label={t('Logout')}
|
||||||
>
|
>
|
||||||
<Text $weight="normal">{t('Logout')}</Text>
|
<Text $weight="normal">{t('Logout')}</Text>
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ export const Header = () => {
|
|||||||
</LogoGouv>
|
</LogoGouv>
|
||||||
<StyledLink href="/">
|
<StyledLink href="/">
|
||||||
<Box $align="center" $gap="1rem" $direction="row">
|
<Box $align="center" $gap="1rem" $direction="row">
|
||||||
<Image priority src={IconApplication} alt={t('Régie Logo')} />
|
<Image priority src={IconApplication} alt="" />
|
||||||
<Text $margin="none" as="h2" $theme="primary">
|
<Text $margin="none" as="h2" $theme="primary">
|
||||||
{t('Régie')}
|
{t('Régie')}
|
||||||
</Text>
|
</Text>
|
||||||
|
|||||||
@@ -53,12 +53,12 @@ export const LanguagePicker = () => {
|
|||||||
$gap="0.7rem"
|
$gap="0.7rem"
|
||||||
$align="center"
|
$align="center"
|
||||||
>
|
>
|
||||||
<Image priority src={IconLanguage} alt={t('Language Icon')} />
|
<Image priority src={IconLanguage} alt="" />
|
||||||
<Text $theme="primary">{lang.toUpperCase()}</Text>
|
<Text $theme="primary">{lang.toUpperCase()}</Text>
|
||||||
</Box>
|
</Box>
|
||||||
),
|
),
|
||||||
}));
|
}));
|
||||||
}, [languages, t]);
|
}, [languages]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SelectStyled
|
<SelectStyled
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ const TopBanner = ({
|
|||||||
$margin={{ all: 'big', vertical: 'xbig' }}
|
$margin={{ all: 'big', vertical: 'xbig' }}
|
||||||
$gap="2.25rem"
|
$gap="2.25rem"
|
||||||
>
|
>
|
||||||
<MailDomainsLogo aria-label={t('Mail Domains icon')} />
|
<MailDomainsLogo aria-hidden="true" />
|
||||||
<Text $margin="none" as="h3" $size="h3">
|
<Text $margin="none" as="h3" $size="h3">
|
||||||
{name}
|
{name}
|
||||||
</Text>
|
</Text>
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ export const Panel = () => {
|
|||||||
`}
|
`}
|
||||||
onClick={() => setIsOpen(!isOpen)}
|
onClick={() => setIsOpen(!isOpen)}
|
||||||
>
|
>
|
||||||
<IconOpenClose width={24} height={24} />
|
<IconOpenClose width={24} height={24} aria-hidden="true" />
|
||||||
</BoxButton>
|
</BoxButton>
|
||||||
<Box
|
<Box
|
||||||
$css={`
|
$css={`
|
||||||
|
|||||||
@@ -40,11 +40,7 @@ export const PanelActions = () => {
|
|||||||
$background={isSortAsc ? colorsTokens()['primary-200'] : 'transparent'}
|
$background={isSortAsc ? colorsTokens()['primary-200'] : 'transparent'}
|
||||||
$color={colorsTokens()['primary-600']}
|
$color={colorsTokens()['primary-600']}
|
||||||
>
|
>
|
||||||
<IconSort
|
<IconSort width={30} height={30} aria-hidden="true" />
|
||||||
width={30}
|
|
||||||
height={30}
|
|
||||||
aria-label={t('Sort domain names icon')}
|
|
||||||
/>
|
|
||||||
</BoxButton>
|
</BoxButton>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
|
|
||||||
import { Box, StyledLink, Text } from '@/components';
|
import { Box, StyledLink, Text } from '@/components';
|
||||||
import { useCunninghamTheme } from '@/cunningham';
|
import { useCunninghamTheme } from '@/cunningham';
|
||||||
@@ -13,7 +12,6 @@ interface MailDomainProps {
|
|||||||
|
|
||||||
export const PanelMailDomains = ({ mailDomain }: MailDomainProps) => {
|
export const PanelMailDomains = ({ mailDomain }: MailDomainProps) => {
|
||||||
const { colorsTokens } = useCunninghamTheme();
|
const { colorsTokens } = useCunninghamTheme();
|
||||||
const { t } = useTranslation();
|
|
||||||
const {
|
const {
|
||||||
query: { slug },
|
query: { slug },
|
||||||
} = useRouter();
|
} = useRouter();
|
||||||
@@ -55,7 +53,7 @@ export const PanelMailDomains = ({ mailDomain }: MailDomainProps) => {
|
|||||||
>
|
>
|
||||||
<Box $align="center" $direction="row" $gap="0.5rem">
|
<Box $align="center" $direction="row" $gap="0.5rem">
|
||||||
<IconMailDomains
|
<IconMailDomains
|
||||||
aria-label={t(`Mail Domains icon`)}
|
aria-hidden="true"
|
||||||
color={colorsTokens()['primary-500']}
|
color={colorsTokens()['primary-500']}
|
||||||
className="p-t"
|
className="p-t"
|
||||||
width="52"
|
width="52"
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ const MenuItem = ({ Icon, label, href, alias }: MenuItemProps) => {
|
|||||||
>
|
>
|
||||||
<Icon
|
<Icon
|
||||||
width="2.375rem"
|
width="2.375rem"
|
||||||
aria-label={t(`{{label}} icon`, { label })}
|
aria-hidden="true"
|
||||||
style={{
|
style={{
|
||||||
transition: 'color 0.2s ease-in-out',
|
transition: 'color 0.2s ease-in-out',
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -164,7 +164,11 @@ export const ModalAddMembers = ({
|
|||||||
size={ModalSize.MEDIUM}
|
size={ModalSize.MEDIUM}
|
||||||
title={
|
title={
|
||||||
<Box $align="center" $gap="1rem">
|
<Box $align="center" $gap="1rem">
|
||||||
<IconAddMember width={48} color={colorsTokens()['primary-text']} />
|
<IconAddMember
|
||||||
|
width={48}
|
||||||
|
color={colorsTokens()['primary-text']}
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
<Text $size="h3" $margin="none">
|
<Text $size="h3" $margin="none">
|
||||||
{t('Add a member')}
|
{t('Add a member')}
|
||||||
</Text>
|
</Text>
|
||||||
|
|||||||
@@ -53,7 +53,11 @@ export const MemberAction = ({
|
|||||||
setIsDropOpen(false);
|
setIsDropOpen(false);
|
||||||
}}
|
}}
|
||||||
color="primary-text"
|
color="primary-text"
|
||||||
icon={<span className="material-icons">edit</span>}
|
icon={
|
||||||
|
<span className="material-icons" aria-hidden="true">
|
||||||
|
edit
|
||||||
|
</span>
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<Text $theme="primary">{t('Update role')}</Text>
|
<Text $theme="primary">{t('Update role')}</Text>
|
||||||
</Button>
|
</Button>
|
||||||
@@ -64,7 +68,11 @@ export const MemberAction = ({
|
|||||||
setIsDropOpen(false);
|
setIsDropOpen(false);
|
||||||
}}
|
}}
|
||||||
color="primary-text"
|
color="primary-text"
|
||||||
icon={<span className="material-icons">delete</span>}
|
icon={
|
||||||
|
<span className="material-icons" aria-hidden="true">
|
||||||
|
delete
|
||||||
|
</span>
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<Text $theme="primary">{t('Remove from group')}</Text>
|
<Text $theme="primary">{t('Remove from group')}</Text>
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ export const ModalDelete = ({ access, onClose, team }: ModalDeleteProps) => {
|
|||||||
$background={colorsTokens()['primary-150']}
|
$background={colorsTokens()['primary-150']}
|
||||||
$theme="primary"
|
$theme="primary"
|
||||||
>
|
>
|
||||||
<IconUser width={20} height={20} />
|
<IconUser width={20} height={20} aria-hidden="true" />
|
||||||
<Text>{access.user.name}</Text>
|
<Text>{access.user.name}</Text>
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@@ -40,9 +40,9 @@ export const CardCreateTeam = () => {
|
|||||||
<Box $gap="1rem">
|
<Box $gap="1rem">
|
||||||
<Box $align="center">
|
<Box $align="center">
|
||||||
<IconGroup
|
<IconGroup
|
||||||
|
aria-hidden="true"
|
||||||
width={44}
|
width={44}
|
||||||
color={colorsTokens()['primary-text']}
|
color={colorsTokens()['primary-text']}
|
||||||
aria-label={t('icon group')}
|
|
||||||
/>
|
/>
|
||||||
<Text as="h3" $textAlign="center">
|
<Text as="h3" $textAlign="center">
|
||||||
{t('Create a new group')}
|
{t('Create a new group')}
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ export const InputTeamName = ({
|
|||||||
setTeamName(e.target.value);
|
setTeamName(e.target.value);
|
||||||
setIsInputError(false);
|
setIsInputError(false);
|
||||||
}}
|
}}
|
||||||
rightIcon={<span className="material-icons">edit</span>}
|
|
||||||
state={isInputError ? 'error' : 'default'}
|
state={isInputError ? 'error' : 'default'}
|
||||||
/>
|
/>
|
||||||
{isError && error && <TextErrors causes={error.cause} />}
|
{isError && error && <TextErrors causes={error.cause} />}
|
||||||
|
|||||||
@@ -72,7 +72,11 @@ export const ModalRemoveTeam = ({ onClose, team }: ModalRemoveTeamProps) => {
|
|||||||
size={ModalSize.MEDIUM}
|
size={ModalSize.MEDIUM}
|
||||||
title={
|
title={
|
||||||
<Box $align="center" $gap="1rem">
|
<Box $align="center" $gap="1rem">
|
||||||
<IconRemove width={48} color={colorsTokens()['primary-text']} />
|
<IconRemove
|
||||||
|
width={48}
|
||||||
|
color={colorsTokens()['primary-text']}
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
<Text $size="h3" $margin="none">
|
<Text $size="h3" $margin="none">
|
||||||
{t('Deleting the {{teamName}} team', { teamName: team.name })}
|
{t('Deleting the {{teamName}} team', { teamName: team.name })}
|
||||||
</Text>
|
</Text>
|
||||||
@@ -105,7 +109,7 @@ export const ModalRemoveTeam = ({ onClose, team }: ModalRemoveTeamProps) => {
|
|||||||
>
|
>
|
||||||
<IconGroup
|
<IconGroup
|
||||||
className="p-t"
|
className="p-t"
|
||||||
aria-label={t(`Teams icon`)}
|
aria-hidden="true"
|
||||||
color={colorsTokens()['primary-500']}
|
color={colorsTokens()['primary-500']}
|
||||||
width={58}
|
width={58}
|
||||||
style={{
|
style={{
|
||||||
|
|||||||
@@ -75,7 +75,11 @@ export const ModalUpdateTeam = ({ onClose, team }: ModalUpdateTeamProps) => {
|
|||||||
size={ModalSize.MEDIUM}
|
size={ModalSize.MEDIUM}
|
||||||
title={
|
title={
|
||||||
<Box $align="center" $gap="1rem">
|
<Box $align="center" $gap="1rem">
|
||||||
<IconEdit width={48} color={colorsTokens()['primary-text']} />
|
<IconEdit
|
||||||
|
width={48}
|
||||||
|
color={colorsTokens()['primary-text']}
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
<Text $size="h3" $margin="none">
|
<Text $size="h3" $margin="none">
|
||||||
{t('Update team {{teamName}}', { teamName: team.name })}
|
{t('Update team {{teamName}}', { teamName: team.name })}
|
||||||
</Text>
|
</Text>
|
||||||
|
|||||||
@@ -43,7 +43,11 @@ export const TeamActions = ({ currentRole, team }: TeamActionsProps) => {
|
|||||||
setIsDropOpen(false);
|
setIsDropOpen(false);
|
||||||
}}
|
}}
|
||||||
color="primary-text"
|
color="primary-text"
|
||||||
icon={<span className="material-icons">edit</span>}
|
icon={
|
||||||
|
<span className="material-icons" aria-hidden="true">
|
||||||
|
edit
|
||||||
|
</span>
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<Text $theme="primary">{t('Update the team')}</Text>
|
<Text $theme="primary">{t('Update the team')}</Text>
|
||||||
</Button>
|
</Button>
|
||||||
@@ -54,7 +58,11 @@ export const TeamActions = ({ currentRole, team }: TeamActionsProps) => {
|
|||||||
setIsDropOpen(false);
|
setIsDropOpen(false);
|
||||||
}}
|
}}
|
||||||
color="primary-text"
|
color="primary-text"
|
||||||
icon={<span className="material-icons">delete</span>}
|
icon={
|
||||||
|
<span className="material-icons" aria-hidden="true">
|
||||||
|
delete
|
||||||
|
</span>
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<Text $theme="primary">{t('Delete the team')}</Text>
|
<Text $theme="primary">{t('Delete the team')}</Text>
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -44,9 +44,9 @@ export const TeamInfo = ({ team, currentRole }: TeamInfoProps) => {
|
|||||||
</Box>
|
</Box>
|
||||||
<Box $margin="big" $direction="row" $align="center" $gap="1.5rem">
|
<Box $margin="big" $direction="row" $align="center" $gap="1.5rem">
|
||||||
<IconGroup
|
<IconGroup
|
||||||
|
aria-hidden="true"
|
||||||
width={44}
|
width={44}
|
||||||
color={colorsTokens()['primary-text']}
|
color={colorsTokens()['primary-text']}
|
||||||
aria-label={t('icon group')}
|
|
||||||
style={{
|
style={{
|
||||||
flexShrink: 0,
|
flexShrink: 0,
|
||||||
alignSelf: 'start',
|
alignSelf: 'start',
|
||||||
|
|||||||
@@ -55,9 +55,7 @@ describe('PanelTeams', () => {
|
|||||||
|
|
||||||
expect(screen.getByRole('status')).toBeInTheDocument();
|
expect(screen.getByRole('status')).toBeInTheDocument();
|
||||||
|
|
||||||
expect(
|
expect(await screen.findByLabelText('Empty team icon')).toBeInTheDocument();
|
||||||
await screen.findByLabelText('Empty teams icon'),
|
|
||||||
).toBeInTheDocument();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders a team with only 1 member', async () => {
|
it('renders a team with only 1 member', async () => {
|
||||||
@@ -81,12 +79,10 @@ describe('PanelTeams', () => {
|
|||||||
|
|
||||||
expect(screen.getByRole('status')).toBeInTheDocument();
|
expect(screen.getByRole('status')).toBeInTheDocument();
|
||||||
|
|
||||||
expect(
|
expect(await screen.findByLabelText('Empty team icon')).toBeInTheDocument();
|
||||||
await screen.findByLabelText('Empty teams icon'),
|
|
||||||
).toBeInTheDocument();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders a non-empty team', async () => {
|
it('renders a non-empty team', () => {
|
||||||
fetchMock.mock(`end:/teams/?page=1&ordering=-created_at`, {
|
fetchMock.mock(`end:/teams/?page=1&ordering=-created_at`, {
|
||||||
count: 1,
|
count: 1,
|
||||||
results: [
|
results: [
|
||||||
@@ -110,8 +106,6 @@ describe('PanelTeams', () => {
|
|||||||
render(<TeamList />, { wrapper: AppWrapper });
|
render(<TeamList />, { wrapper: AppWrapper });
|
||||||
|
|
||||||
expect(screen.getByRole('status')).toBeInTheDocument();
|
expect(screen.getByRole('status')).toBeInTheDocument();
|
||||||
|
|
||||||
expect(await screen.findByLabelText('Teams icon')).toBeInTheDocument();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders the error', async () => {
|
it('renders the error', async () => {
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ export const PanelActions = () => {
|
|||||||
$background={isSortAsc ? colorsTokens()['primary-200'] : 'transparent'}
|
$background={isSortAsc ? colorsTokens()['primary-200'] : 'transparent'}
|
||||||
$color={colorsTokens()['primary-600']}
|
$color={colorsTokens()['primary-600']}
|
||||||
>
|
>
|
||||||
<IconSort width={30} height={30} aria-label={t('Sort teams icon')} />
|
<IconSort width={30} height={30} aria-hidden="true" />
|
||||||
</BoxButton>
|
</BoxButton>
|
||||||
<StyledLink href="/teams/create">
|
<StyledLink href="/teams/create">
|
||||||
<BoxButton
|
<BoxButton
|
||||||
@@ -49,7 +49,7 @@ export const PanelActions = () => {
|
|||||||
$color={colorsTokens()['primary-600']}
|
$color={colorsTokens()['primary-600']}
|
||||||
tabIndex={-1}
|
tabIndex={-1}
|
||||||
>
|
>
|
||||||
<IconAdd width={30} height={30} aria-label={t('Add team icon')} />
|
<IconAdd width={30} height={30} aria-hidden="true" />
|
||||||
</BoxButton>
|
</BoxButton>
|
||||||
</StyledLink>
|
</StyledLink>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ export const TeamItem = ({ team }: TeamProps) => {
|
|||||||
<Box $align="center" $direction="row" $gap="0.5rem">
|
<Box $align="center" $direction="row" $gap="0.5rem">
|
||||||
{hasMembers ? (
|
{hasMembers ? (
|
||||||
<IconGroup
|
<IconGroup
|
||||||
aria-label={t(`Teams icon`)}
|
aria-label={t(`Team icon`)}
|
||||||
color={colorsTokens()['primary-500']}
|
color={colorsTokens()['primary-500']}
|
||||||
{...commonProps}
|
{...commonProps}
|
||||||
style={{
|
style={{
|
||||||
@@ -77,7 +77,7 @@ export const TeamItem = ({ team }: TeamProps) => {
|
|||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<IconNone
|
<IconNone
|
||||||
aria-label={t(`Empty teams icon`)}
|
aria-label={t(`Empty team icon`)}
|
||||||
color={colorsTokens()['greyscale-500']}
|
color={colorsTokens()['greyscale-500']}
|
||||||
{...commonProps}
|
{...commonProps}
|
||||||
style={{
|
style={{
|
||||||
|
|||||||
@@ -14,8 +14,7 @@
|
|||||||
"Accessibility: non-compliant": "Accessibilité : non conforme",
|
"Accessibility: non-compliant": "Accessibilité : non conforme",
|
||||||
"Add a member": "Ajouter un membre",
|
"Add a member": "Ajouter un membre",
|
||||||
"Add a team": "Ajouter un groupe",
|
"Add a team": "Ajouter un groupe",
|
||||||
"Add members to the team": "Ajoutez des membres à votre groupe",
|
"Add members to the team": "Ajouter des membres à l'équipe",
|
||||||
"Add team icon": "Icône ajout de groupe",
|
|
||||||
"Add to group": "Ajouter au groupe",
|
"Add to group": "Ajouter au groupe",
|
||||||
"Address: National Agency for Territorial Cohesion - 20, avenue de Ségur TSA 10717 75 334 Paris Cedex 07 Paris": "Adresse : Agence Nationale de la Cohésion des Territoires - 20, avenue de Ségur TSA 10717 75 334 Paris Cedex 07",
|
"Address: National Agency for Territorial Cohesion - 20, avenue de Ségur TSA 10717 75 334 Paris Cedex 07 Paris": "Adresse : Agence Nationale de la Cohésion des Territoires - 20, avenue de Ségur TSA 10717 75 334 Paris Cedex 07",
|
||||||
"Administration": "Administration",
|
"Administration": "Administration",
|
||||||
@@ -51,7 +50,7 @@
|
|||||||
"E.g. : jean.dupont@mail.fr": "Ex. : jean.dupont@mail.fr",
|
"E.g. : jean.dupont@mail.fr": "Ex. : jean.dupont@mail.fr",
|
||||||
"Email address prefix": "Préfixe de l'adresse mail",
|
"Email address prefix": "Préfixe de l'adresse mail",
|
||||||
"Emails": "Emails",
|
"Emails": "Emails",
|
||||||
"Empty teams icon": "Icône de groupe vide",
|
"Empty team icon": "Icône équipe vide",
|
||||||
"Enter the new name of the selected team": "Entrez le nouveau nom du groupe sélectionné",
|
"Enter the new name of the selected team": "Entrez le nouveau nom du groupe sélectionné",
|
||||||
"Failed to add {{name}} in the team": "Impossible d'ajouter {{name}} au groupe",
|
"Failed to add {{name}} in the team": "Impossible d'ajouter {{name}} au groupe",
|
||||||
"Failed to create the invitation for {{email}}": "Impossible de créer l'invitation pour {{email}}",
|
"Failed to create the invitation for {{email}}": "Impossible de créer l'invitation pour {{email}}",
|
||||||
@@ -63,6 +62,7 @@
|
|||||||
"Groups": "Groupes",
|
"Groups": "Groupes",
|
||||||
"If you are unable to access content or a service, you can contact the manager of La Régie (Suite Territoriale) \n to be directed to an accessible alternative or obtain the content in another form.": "Si vous n’arrivez pas à accéder à un contenu ou à un service, vous pouvez contacter le responsable de La Régie (Suite Territoriale) pour être orienté vers une alternative accessible ou obtenir le contenu sous une autre forme.",
|
"If you are unable to access content or a service, you can contact the manager of La Régie (Suite Territoriale) \n to be directed to an accessible alternative or obtain the content in another form.": "Si vous n’arrivez pas à accéder à un contenu ou à un service, vous pouvez contacter le responsable de La Régie (Suite Territoriale) pour être orienté vers une alternative accessible ou obtenir le contenu sous une autre forme.",
|
||||||
"Illustration:": "Illustration :",
|
"Illustration:": "Illustration :",
|
||||||
|
"Image 404 page not found": "Image 404 page introuvable",
|
||||||
"Improvement and contact": "Amélioration et contact",
|
"Improvement and contact": "Amélioration et contact",
|
||||||
"Invitation sent to {{email}}": "Invitation envoyée à {{email}}",
|
"Invitation sent to {{email}}": "Invitation envoyée à {{email}}",
|
||||||
"Invite new members to {{teamName}}": "Invitez de nouveaux membres à rejoindre {{teamName}}",
|
"Invite new members to {{teamName}}": "Invitez de nouveaux membres à rejoindre {{teamName}}",
|
||||||
@@ -72,7 +72,6 @@
|
|||||||
"La Régie (Suite Territoriale) is non-compliant with the RGAA. The site has not yet been audited.": "La Régie (Suite Territoriale) est non conforme avec le RGAA. Le site n’a encore pas été audité.",
|
"La Régie (Suite Territoriale) is non-compliant with the RGAA. The site has not yet been audited.": "La Régie (Suite Territoriale) est non conforme avec le RGAA. Le site n’a encore pas été audité.",
|
||||||
"La Suite administration interface: management of users and rights on the various tools (messaging, storage, etc.)": "Interface d’administration de la Suite : gestion des utilisateurs et des droits sur les différents outils (messagerie, stockage, etc.)",
|
"La Suite administration interface: management of users and rights on the various tools (messaging, storage, etc.)": "Interface d’administration de la Suite : gestion des utilisateurs et des droits sur les différents outils (messagerie, stockage, etc.)",
|
||||||
"Language": "Langue",
|
"Language": "Langue",
|
||||||
"Language Icon": "Icône de langue",
|
|
||||||
"Last name": "Nom",
|
"Last name": "Nom",
|
||||||
"Last update at": "Dernière modification le",
|
"Last update at": "Dernière modification le",
|
||||||
"Legal Notice": "Mentions légales",
|
"Legal Notice": "Mentions légales",
|
||||||
@@ -80,7 +79,6 @@
|
|||||||
"List members card": "Carte liste des membres",
|
"List members card": "Carte liste des membres",
|
||||||
"Logout": "Se déconnecter",
|
"Logout": "Se déconnecter",
|
||||||
"Mail Domains": "Domaines de messagerie",
|
"Mail Domains": "Domaines de messagerie",
|
||||||
"Mail Domains icon": "Icône des domaines mail",
|
|
||||||
"Mailbox created!": "Boîte mail créée !",
|
"Mailbox created!": "Boîte mail créée !",
|
||||||
"Mailboxes list": "Liste des boîtes mail",
|
"Mailboxes list": "Liste des boîtes mail",
|
||||||
"Marianne Logo": "Logo Marianne",
|
"Marianne Logo": "Logo Marianne",
|
||||||
@@ -114,23 +112,20 @@
|
|||||||
"Remove this member from the group": "Retirer le membre du groupe",
|
"Remove this member from the group": "Retirer le membre du groupe",
|
||||||
"Roles": "Rôles",
|
"Roles": "Rôles",
|
||||||
"Régie": "Régie",
|
"Régie": "Régie",
|
||||||
"Régie Logo": "Logo Régie",
|
|
||||||
"Search new members (name or email)": "Rechercher de nouveaux membres (nom ou email)",
|
"Search new members (name or email)": "Rechercher de nouveaux membres (nom ou email)",
|
||||||
"Secondary email address": "Adresse e-mail secondaire",
|
"Secondary email address": "Adresse e-mail secondaire",
|
||||||
"Send a letter by post (free of charge, no stamp needed):": "Envoyer un courrier par la poste (gratuit, ne pas mettre de timbre) :",
|
"Send a letter by post (free of charge, no stamp needed):": "Envoyer un courrier par la poste (gratuit, ne pas mettre de timbre) :",
|
||||||
"Something bad happens, please refresh the page.": "Une erreur inattendue s'est produite, rechargez la page.",
|
"Something bad happens, please refresh the page.": "Une erreur inattendue s'est produite, rechargez la page.",
|
||||||
"Something bad happens, please retry.": "Une erreur inattendue s'est produite, rechargez la page.",
|
"Something bad happens, please retry.": "Une erreur inattendue s'est produite, rechargez la page.",
|
||||||
"Something wrong happened, please refresh the page.": "Une erreur inattendue s'est produite, rechargez la page.",
|
"Something wrong happened, please refresh the page.": "Une erreur inattendue s'est produite, rechargez la page.",
|
||||||
"Sort domain names icon": "Trier l'icône des noms de domaine",
|
|
||||||
"Sort teams icon": "Icône trier les groupes",
|
|
||||||
"Sort the domain names by creation date ascendent": "Trier les documents par date de création ascendante",
|
"Sort the domain names by creation date ascendent": "Trier les documents par date de création ascendante",
|
||||||
"Sort the domain names by creation date descendent": "Trier les documents par date de création descendante",
|
"Sort the domain names by creation date descendent": "Trier les documents par date de création descendante",
|
||||||
"Sort the teams by creation date ascendent": "Trier les groupes par date de création ascendante",
|
"Sort the teams by creation date ascendent": "Trier les groupes par date de création ascendante",
|
||||||
"Sort the teams by creation date descendent": "Trier les groupes par date de création descendante",
|
"Sort the teams by creation date descendent": "Trier les groupes par date de création descendante",
|
||||||
"Stéphanie Schaer: Interministerial Digital Director (DINUM).": "Stéphanie Schaer: Directrice numérique interministériel (DINUM).",
|
"Stéphanie Schaer: Interministerial Digital Director (DINUM).": "Stéphanie Schaer: Directrice numérique interministériel (DINUM).",
|
||||||
|
"Team icon": "Icône équipe",
|
||||||
"Team name": "Nom du groupe",
|
"Team name": "Nom du groupe",
|
||||||
"Teams": "Équipes",
|
"Teams": "Équipes",
|
||||||
"Teams icon": "Icône de groupe",
|
|
||||||
"The National Agency for Territorial Cohesion undertakes to make its\n service accessible, in accordance with article 47 of law no. 2005-102\n of February 11, 2005.": "L'Agence Nationale de la Cohésion des Territoires s’engage à rendre son service accessible, conformément à l’article 47 de la loi n° 2005-102 du 11 février 2005.",
|
"The National Agency for Territorial Cohesion undertakes to make its\n service accessible, in accordance with article 47 of law no. 2005-102\n of February 11, 2005.": "L'Agence Nationale de la Cohésion des Territoires s’engage à rendre son service accessible, conformément à l’article 47 de la loi n° 2005-102 du 11 février 2005.",
|
||||||
"The member has been removed from the team": "Le membre a été supprimé de votre groupe",
|
"The member has been removed from the team": "Le membre a été supprimé de votre groupe",
|
||||||
"The role has been updated": "Le rôle a bien été mis à jour",
|
"The role has been updated": "Le rôle a bien été mis à jour",
|
||||||
@@ -161,13 +156,11 @@
|
|||||||
"You must have minimum 1 character": "Vous devez entrer au moins 1 caractère",
|
"You must have minimum 1 character": "Vous devez entrer au moins 1 caractère",
|
||||||
"accessibility-contact-defenseurdesdroits": "Contacter le délégué du<1>Défenseur des droits dans votre région</1>",
|
"accessibility-contact-defenseurdesdroits": "Contacter le délégué du<1>Défenseur des droits dans votre région</1>",
|
||||||
"accessibility-form-defenseurdesdroits": "Écrire un message au<1>Défenseur des droits</1>",
|
"accessibility-form-defenseurdesdroits": "Écrire un message au<1>Défenseur des droits</1>",
|
||||||
"icon group": "icône groupe",
|
|
||||||
"mail domains list loading": "chargement de la liste des domaines de messagerie",
|
"mail domains list loading": "chargement de la liste des domaines de messagerie",
|
||||||
"{{count}} member_many": "{{count}} membres",
|
"{{count}} member_many": "{{count}} membres",
|
||||||
"{{count}} member_one": "{{count}} membre",
|
"{{count}} member_one": "{{count}} membre",
|
||||||
"{{count}} member_other": "{{count}} membres",
|
"{{count}} member_other": "{{count}} membres",
|
||||||
"{{label}} button": "Bouton {{label}}",
|
"{{label}} button": "Bouton {{label}}"
|
||||||
"{{label}} icon": "Icône {{label}}"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ const Page: NextPageWithLayout = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Box $align="center" $margin="auto" $height="70vh" $gap="2rem">
|
<Box $align="center" $margin="auto" $height="70vh" $gap="2rem">
|
||||||
<Icon404 aria-label="Image 404" role="img" />
|
<Icon404 role="img" aria-label={t('Image 404 page not found')} />
|
||||||
|
|
||||||
<Text $size="h2" $weight="700" $theme="greyscale" $variation="900">
|
<Text $size="h2" $weight="700" $theme="greyscale" $variation="900">
|
||||||
{t('Ouch!')}
|
{t('Ouch!')}
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ export const addNewMember = async (
|
|||||||
// Choose a role
|
// Choose a role
|
||||||
await page.getByRole('radio', { name: role }).click();
|
await page.getByRole('radio', { name: role }).click();
|
||||||
|
|
||||||
await page.getByRole('button', { name: 'Validate' }).click();
|
await page.getByRole('button', { name: 'Add to group' }).click();
|
||||||
|
|
||||||
const table = page.getByLabel('List members card').getByRole('table');
|
const table = page.getByLabel('List members card').getByRole('table');
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,8 @@ test.describe('Header', () => {
|
|||||||
header.getByAltText('Freedom Equality Fraternity Logo'),
|
header.getByAltText('Freedom Equality Fraternity Logo'),
|
||||||
).toBeVisible();
|
).toBeVisible();
|
||||||
|
|
||||||
await expect(header.getByAltText('Régie Logo')).toBeVisible();
|
await expect(header.getByRole('link', { name: 'Régie' })).toBeVisible();
|
||||||
|
|
||||||
await expect(header.locator('h2').getByText('Régie')).toHaveCSS(
|
await expect(header.locator('h2').getByText('Régie')).toHaveCSS(
|
||||||
'color',
|
'color',
|
||||||
'rgb(0, 0, 145)',
|
'rgb(0, 0, 145)',
|
||||||
@@ -35,7 +36,7 @@ test.describe('Header', () => {
|
|||||||
}),
|
}),
|
||||||
).toBeVisible();
|
).toBeVisible();
|
||||||
|
|
||||||
await expect(header.getByAltText('Language Icon')).toBeVisible();
|
await expect(header.getByRole('combobox').getByText('EN')).toBeVisible();
|
||||||
await expect(header.getByText('My account')).toBeVisible();
|
await expect(header.getByText('My account')).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,9 @@ test.describe('Members Create', () => {
|
|||||||
page.getByLabel(/Find a member to add to the team/),
|
page.getByLabel(/Find a member to add to the team/),
|
||||||
).toBeVisible();
|
).toBeVisible();
|
||||||
|
|
||||||
await expect(page.getByRole('button', { name: 'Validate' })).toBeVisible();
|
await expect(
|
||||||
|
page.getByRole('button', { name: 'Add to group' }),
|
||||||
|
).toBeVisible();
|
||||||
await expect(page.getByRole('button', { name: 'Cancel' })).toBeVisible();
|
await expect(page.getByRole('button', { name: 'Cancel' })).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -124,7 +126,7 @@ test.describe('Members Create', () => {
|
|||||||
response.url().includes('/accesses/') && response.status() === 201,
|
response.url().includes('/accesses/') && response.status() === 201,
|
||||||
);
|
);
|
||||||
|
|
||||||
await page.getByRole('button', { name: 'Validate' }).click();
|
await page.getByRole('button', { name: 'Add to group' }).click();
|
||||||
|
|
||||||
// Check invitation sent
|
// Check invitation sent
|
||||||
await expect(page.getByText(`Invitation sent to ${email}`)).toBeVisible();
|
await expect(page.getByText(`Invitation sent to ${email}`)).toBeVisible();
|
||||||
@@ -169,7 +171,7 @@ test.describe('Members Create', () => {
|
|||||||
response.url().includes('/accesses/') && response.status() === 201,
|
response.url().includes('/accesses/') && response.status() === 201,
|
||||||
);
|
);
|
||||||
|
|
||||||
await page.getByRole('button', { name: 'Validate' }).click();
|
await page.getByRole('button', { name: 'Add to group' }).click();
|
||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
page.getByText(`Member ${users[0].name} added to the team`),
|
page.getByText(`Member ${users[0].name} added to the team`),
|
||||||
@@ -207,7 +209,7 @@ test.describe('Members Create', () => {
|
|||||||
response.url().includes('/invitations/') && response.status() === 201,
|
response.url().includes('/invitations/') && response.status() === 201,
|
||||||
);
|
);
|
||||||
|
|
||||||
await page.getByRole('button', { name: 'Validate' }).click();
|
await page.getByRole('button', { name: 'Add to group' }).click();
|
||||||
|
|
||||||
// Check invitation sent
|
// Check invitation sent
|
||||||
await expect(page.getByText(`Invitation sent to ${email}`)).toBeVisible();
|
await expect(page.getByText(`Invitation sent to ${email}`)).toBeVisible();
|
||||||
|
|||||||
@@ -28,7 +28,9 @@ test.describe('Members Delete', () => {
|
|||||||
'You are the last owner, you cannot be removed from your team.',
|
'You are the last owner, you cannot be removed from your team.',
|
||||||
),
|
),
|
||||||
).toBeVisible();
|
).toBeVisible();
|
||||||
await expect(page.getByRole('button', { name: 'Validate' })).toBeDisabled();
|
await expect(
|
||||||
|
page.getByRole('button', { name: 'Remove from the group' }),
|
||||||
|
).toBeDisabled();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('it deletes himself when it is not the last owner', async ({
|
test('it deletes himself when it is not the last owner', async ({
|
||||||
@@ -49,7 +51,7 @@ test.describe('Members Delete', () => {
|
|||||||
await cells.nth(4).getByLabel('Member options').click();
|
await cells.nth(4).getByLabel('Member options').click();
|
||||||
await page.getByLabel('Open the modal to delete this member').click();
|
await page.getByLabel('Open the modal to delete this member').click();
|
||||||
|
|
||||||
await page.getByRole('button', { name: 'Validate' }).click();
|
await page.getByRole('button', { name: 'Remove from the group' }).click();
|
||||||
await expect(
|
await expect(
|
||||||
page.getByText(`The member has been removed from the team`),
|
page.getByText(`The member has been removed from the team`),
|
||||||
).toBeVisible();
|
).toBeVisible();
|
||||||
@@ -76,7 +78,9 @@ test.describe('Members Delete', () => {
|
|||||||
await expect(
|
await expect(
|
||||||
page.getByText(`You cannot remove other owner.`),
|
page.getByText(`You cannot remove other owner.`),
|
||||||
).toBeVisible();
|
).toBeVisible();
|
||||||
await expect(page.getByRole('button', { name: 'Validate' })).toBeDisabled();
|
await expect(
|
||||||
|
page.getByRole('button', { name: 'Remove from the group' }),
|
||||||
|
).toBeDisabled();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('it deletes admin member', async ({ page, browserName }) => {
|
test('it deletes admin member', async ({ page, browserName }) => {
|
||||||
@@ -94,7 +98,7 @@ test.describe('Members Delete', () => {
|
|||||||
await cells.nth(4).getByLabel('Member options').click();
|
await cells.nth(4).getByLabel('Member options').click();
|
||||||
await page.getByLabel('Open the modal to delete this member').click();
|
await page.getByLabel('Open the modal to delete this member').click();
|
||||||
|
|
||||||
await page.getByRole('button', { name: 'Validate' }).click();
|
await page.getByRole('button', { name: 'Remove from the group' }).click();
|
||||||
await expect(
|
await expect(
|
||||||
page.getByText(`The member has been removed from the team`),
|
page.getByText(`The member has been removed from the team`),
|
||||||
).toBeVisible();
|
).toBeVisible();
|
||||||
@@ -161,7 +165,7 @@ test.describe('Members Delete', () => {
|
|||||||
await cells.nth(4).getByLabel('Member options').click();
|
await cells.nth(4).getByLabel('Member options').click();
|
||||||
await page.getByLabel('Open the modal to delete this member').click();
|
await page.getByLabel('Open the modal to delete this member').click();
|
||||||
|
|
||||||
await page.getByRole('button', { name: 'Validate' }).click();
|
await page.getByRole('button', { name: 'Remove from the group' }).click();
|
||||||
await expect(
|
await expect(
|
||||||
page.getByText(`The member has been removed from the team`),
|
page.getByText(`The member has been removed from the team`),
|
||||||
).toBeVisible();
|
).toBeVisible();
|
||||||
|
|||||||
@@ -16,8 +16,6 @@ test.describe('Team', () => {
|
|||||||
await createTeam(page, 'team-top-box', browserName, 1)
|
await createTeam(page, 'team-top-box', browserName, 1)
|
||||||
).shift();
|
).shift();
|
||||||
|
|
||||||
await expect(page.getByLabel('icon group')).toBeVisible();
|
|
||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
page.getByRole('heading', {
|
page.getByRole('heading', {
|
||||||
name: teamName,
|
name: teamName,
|
||||||
|
|||||||
@@ -19,8 +19,6 @@ test.describe('Teams Create', () => {
|
|||||||
|
|
||||||
await expect(card.getByLabel('Team name')).toBeVisible();
|
await expect(card.getByLabel('Team name')).toBeVisible();
|
||||||
|
|
||||||
await expect(card.getByLabel('icon group')).toBeVisible();
|
|
||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
card.getByRole('heading', {
|
card.getByRole('heading', {
|
||||||
name: 'Create a new group',
|
name: 'Create a new group',
|
||||||
|
|||||||
Reference in New Issue
Block a user