diff --git a/site/.env.template b/site/.env.template index 2bc577326..0723bd272 100644 --- a/site/.env.template +++ b/site/.env.template @@ -13,7 +13,7 @@ GITHUB_API_SECRET= ### Variables utilisées par l'app ### VITE_ALGOLIA_APP_ID= VITE_ALGOLIA_SEARCH_KEY= -VITE_ALGOLIA_INDEX_PREFIX=monentreprise-{env}- +VITE_ALGOLIA_INDEX_PREFIX=monentreprise-master- VITE_AT_INTERNET_SITE_ID= VITE_FR_BASE_URL="http://localhost:3000/mon-entreprise" diff --git a/site/cypress/integration/mon-entreprise/covid19.ts b/site/cypress/integration/mon-entreprise/covid19.ts index 313b5be08..96194f0a6 100644 --- a/site/cypress/integration/mon-entreprise/covid19.ts +++ b/site/cypress/integration/mon-entreprise/covid19.ts @@ -1,4 +1,4 @@ -import { fr } from '../../support/utils' +import { checkA11Y, fr } from '../../support/utils' describe('Page covid-19', { testIsolation: 'off' }, function () { if (!fr) { @@ -35,5 +35,7 @@ describe('Page covid-19', { testIsolation: 'off' }, function () { cy.get('[data-test-id=comparaison-total]').contains( /Soit [\d]{1} % du coût habituel/ ) + + checkA11Y() }) }) diff --git a/site/cypress/integration/mon-entreprise/demande-mobilité.ts b/site/cypress/integration/mon-entreprise/demande-mobilité.ts index 75991af4c..8e9e23dd7 100644 --- a/site/cypress/integration/mon-entreprise/demande-mobilité.ts +++ b/site/cypress/integration/mon-entreprise/demande-mobilité.ts @@ -1,4 +1,4 @@ -import { fr } from '../../support/utils' +import { checkA11Y, fr } from '../../support/utils' const writeFixtures = Cypress.env('record_http') !== undefined @@ -176,5 +176,7 @@ describe(`Formulaire demande mobilité (${ cy.focused().type('Plougastel') cy.contains('Générer la demande').click() cy.contains('Télécharger le fichier').click() + + checkA11Y() }) }) diff --git a/site/cypress/integration/mon-entreprise/landing.ts b/site/cypress/integration/mon-entreprise/landing.ts index b9be4c37a..b03481b73 100644 --- a/site/cypress/integration/mon-entreprise/landing.ts +++ b/site/cypress/integration/mon-entreprise/landing.ts @@ -1,3 +1,5 @@ +import { checkA11Y } from '../../support/utils' + const searchInputPath = '[data-test-id=company-search-input]' const searchResultsPath = '[data-test-id=company-search-results]' const currentCompanyPath = '[data-test-id=currently-selected-company]' @@ -7,6 +9,8 @@ const FIXTURES_FOLDER = 'cypress/fixtures/landing' describe('Landing page', function () { it('should not crash', function () { cy.visit('/') + + checkA11Y() }) it('should display logo', function () { diff --git a/site/cypress/integration/mon-entreprise/recherche.ts b/site/cypress/integration/mon-entreprise/recherche.ts index 6a41b0b52..87f4b940d 100644 --- a/site/cypress/integration/mon-entreprise/recherche.ts +++ b/site/cypress/integration/mon-entreprise/recherche.ts @@ -1,4 +1,4 @@ -import { fr } from '../../support/utils' +import { checkA11Y, fr } from '../../support/utils' describe('Recherche globales', function () { if (!fr) { @@ -28,5 +28,7 @@ describe('Recherche globales', function () { .next() .find('li') .should('have.length.of.at.least', 1) + + checkA11Y() }) }) diff --git a/site/cypress/integration/mon-entreprise/secondary-pages.ts b/site/cypress/integration/mon-entreprise/secondary-pages.ts index 805c60748..92adfbb9c 100644 --- a/site/cypress/integration/mon-entreprise/secondary-pages.ts +++ b/site/cypress/integration/mon-entreprise/secondary-pages.ts @@ -1,4 +1,4 @@ -import { fr } from '../../support/utils' +import { checkA11Y, fr } from '../../support/utils' describe('Secondary pages', function () { if (!fr) { @@ -8,11 +8,15 @@ describe('Secondary pages', function () { it("page stats doesn't crash", function () { cy.visit('/stats') cy.contains('Statistiques détaillées') + + checkA11Y() }) it('navigate in the news section', function () { cy.visit('/nouveautés') cy.contains('←').click() cy.url({ decode: true }).should('match', /\/nouveautés\/[^/]*$/) + + checkA11Y() }) }) diff --git a/site/cypress/integration/mon-entreprise/simulateur-ae.ts b/site/cypress/integration/mon-entreprise/simulateur-ae.ts index 99a4f9be7..949ce0eca 100644 --- a/site/cypress/integration/mon-entreprise/simulateur-ae.ts +++ b/site/cypress/integration/mon-entreprise/simulateur-ae.ts @@ -1,4 +1,4 @@ -import { fr } from '../../support/utils' +import { checkA11Y, fr } from '../../support/utils' describe('Simulateur auto-entrepreneur', { testIsolation: 'off' }, function () { if (!fr) { @@ -73,5 +73,7 @@ describe('Simulateur auto-entrepreneur', { testIsolation: 'off' }, function () { expect(activitéMixtes[0]).to.be.equal(activitéMixtes[2]) expect(activitéMixtes[1]).to.be.equal(activitéMixtes[0] * 2) }) + + checkA11Y() }) }) diff --git a/site/cypress/integration/mon-entreprise/simulateur-dividendes.js b/site/cypress/integration/mon-entreprise/simulateur-dividendes.js index 093f402a5..fabb05ccf 100644 --- a/site/cypress/integration/mon-entreprise/simulateur-dividendes.js +++ b/site/cypress/integration/mon-entreprise/simulateur-dividendes.js @@ -1,3 +1,5 @@ +import { checkA11Y } from '../../support/utils' + const inputSelector = 'div[id="simulator-legend"] input' const fr = Cypress.env('language') === 'fr' @@ -11,5 +13,7 @@ describe('Simulateur dividendes', function () { cy.get(inputSelector).first().type('{selectall}5000') cy.contains(/[cC]otisations\s+17,2\s*%/) cy.contains(/[Ii]mpôt\s+12,8\s*%/) + + checkA11Y() }) }) diff --git a/site/cypress/integration/mon-entreprise/simulateur-salarie.ts b/site/cypress/integration/mon-entreprise/simulateur-salarie.ts index 3121cab35..30c527c90 100644 --- a/site/cypress/integration/mon-entreprise/simulateur-salarie.ts +++ b/site/cypress/integration/mon-entreprise/simulateur-salarie.ts @@ -1,4 +1,4 @@ -import { fr } from '../../support/utils' +import { checkA11Y, fr } from '../../support/utils' describe('Simulateur salarié : part time contract', function () { if (!fr) { @@ -50,5 +50,7 @@ describe('Simulateur salarié : part time contract', function () { .replace(/[\s,.€]/g, '') expect(parseInt(val)).to.be.below(1000) }) + + checkA11Y() }) }) diff --git a/site/cypress/support/e2e.ts b/site/cypress/support/e2e.ts index 41f339393..ae108d762 100644 --- a/site/cypress/support/e2e.ts +++ b/site/cypress/support/e2e.ts @@ -16,6 +16,7 @@ // Import commands.js using ES2015 syntax: import 'cypress-plugin-tab' import './commands' +import 'cypress-axe' // Alternatively you can use CommonJS syntax: // require('./commands') diff --git a/site/cypress/support/simulateur.js b/site/cypress/support/simulateur.js index 9c7f5c4d6..317ca0400 100644 --- a/site/cypress/support/simulateur.js +++ b/site/cypress/support/simulateur.js @@ -1,3 +1,5 @@ +import { checkA11Y } from './utils' + const inputSelector = 'div[id="simulator-legend"] input[inputmode="numeric"]:not([id="entreprisecharges"])' const chargeInputSelector = 'input[id="entreprisecharges"]' @@ -69,6 +71,7 @@ export const runSimulateurTest = (simulateur) => { .first() .invoke('val') .should('match', /2[\s,]000/) + checkA11Y() }) }) } diff --git a/site/cypress/support/utils.ts b/site/cypress/support/utils.ts index 6be5f52e6..0f1107479 100644 --- a/site/cypress/support/utils.ts +++ b/site/cypress/support/utils.ts @@ -1,2 +1,38 @@ export const fr = Cypress.env('language') === 'fr' export const baseUrl = Cypress.config('baseUrl') + +type ViolationType = { + description: string +} + +export const checkA11Y = () => { + cy.injectAxe() + cy.configureAxe({ + rules: [ + { + id: 'color-contrast', + enabled: false, + }, + ], + }) + cy.checkA11y( + null, + null, + (violations: ViolationType[]) => { + if (violations.length > 0) { + cy.log( + `${violations.length} erreur${ + violations.length > 1 ? 's' : '' + } d'accessibilité sur cette page :` + ) + violations.forEach((violation, index) => { + cy.log(`Violation ${index + 1} : ${violation.description}`) + }) + cy.log( + 'Pour y remédier, lancer la commande yarn start:axe-debugging en local.' + ) + } + }, + null + ) +} diff --git a/site/cypress/tsconfig.json b/site/cypress/tsconfig.json index 69ecdef6c..32651f817 100644 --- a/site/cypress/tsconfig.json +++ b/site/cypress/tsconfig.json @@ -3,7 +3,7 @@ "target": "es5", "module": "ESNext", "lib": ["es5", "dom"], - "types": ["cypress", "cypress-plugin-tab/src", "node"] + "types": ["cypress", "cypress-plugin-tab/src", "node", "cypress-axe"] }, "include": ["**/*.ts", "../cypress.config.ts"] } diff --git a/site/package.json b/site/package.json index 4039d3fdc..c91111bb9 100644 --- a/site/package.json +++ b/site/package.json @@ -51,6 +51,7 @@ "@atomik-color/component": "^1.0.16", "@axe-core/react": "^4.5.2", "@internationalized/number": "^3.1.1", + "@publicodes/api": "^1.0.0-beta.63", "@react-aria/accordion": "^3.0.0-alpha.13", "@react-aria/button": "^3.6.3", "@react-aria/checkbox": "^3.7.0", @@ -80,8 +81,8 @@ "isbot": "^3.6.5", "markdown-to-jsx": "^7.1.7", "modele-social": "workspace:^", - "publicodes": "^1.0.0-beta.62", - "publicodes-react": "^1.0.0-beta.62", + "publicodes": "^1.0.0-beta.63", + "publicodes-react": "^1.0.0-beta.63", "react": "^18.2.0", "react-colorful": "^5.6.1", "react-dom": "^18.2.0", @@ -129,6 +130,7 @@ "@vitejs/plugin-legacy": "^2.3.1", "@vitejs/plugin-react": "^2.2.0", "cypress": "https://cdn.cypress.io/beta/npm/12.0.0/linux-arm64/release/12.0.0-e8898d2f6b65a11f36ceb2dd32ce7f1d87b103bc/cypress.tgz", + "cypress-axe": "^1.1.0", "cypress-plugin-tab": "^1.0.5", "cypress-wait-until": "^1.7.2", "dotenv": "^16.0.3", diff --git a/site/source/App.tsx b/site/source/App.tsx index d9f7eaaca..91eebdab6 100644 --- a/site/source/App.tsx +++ b/site/source/App.tsx @@ -114,10 +114,10 @@ const App = () => { return ( {!isEmbedded &&
} - - {t('Passer le contenu')} -
+ + {t('Passer le contenu')} + diff --git a/site/source/components/SimulateurWarning.tsx b/site/source/components/SimulateurWarning.tsx index e034e8fc8..7f53c32e8 100644 --- a/site/source/components/SimulateurWarning.tsx +++ b/site/source/components/SimulateurWarning.tsx @@ -1,6 +1,7 @@ import { Evaluation } from 'publicodes' import { useContext } from 'react' import { Trans } from 'react-i18next' +import styled from 'styled-components' import Warning from '@/components/ui/WarningBlock' import { Link } from '@/design-system/typography/link' @@ -28,7 +29,7 @@ export default function SimulateurWarning({
    {simulateur === 'auto-entrepreneur' && ( <> -
  • + Les auto-entrepreneurs bénéficient d’un régime très simplifié avec un taux forfaitaire pour le calcul des cotisations et @@ -39,8 +40,8 @@ export default function SimulateurWarning({ revenu net est donc le chiffre d’affaires moins toutes les charges engagées pour l’entreprise. -
  • -
  • + + Le simulateur n'intègre pas la cotisation foncière des entreprise (CFE) qui est dûe dès la deuxième année d'exercice. @@ -53,30 +54,30 @@ export default function SimulateurWarning({ Plus d'infos. -
  • + )} {simulateur !== 'artiste-auteur' && ( -
  • + Les calculs sont indicatifs. Ils ne se substituent pas aux décomptes réels de l’Urssaf, de l’administration fiscale ou de toute autre organisme. -
  • + )} {simulateur === 'profession-libérale' && ( -
  • + Ce simulateur est à destination des professions libérales en BNC. Il ne prend pas en compte les sociétés d'exercice libéral. -
  • +
    )} {simulateur === 'artiste-auteur' && ( <> -
  • + Cette estimation est proposée à titre indicatif. Elle est faite à partir des éléments réglementaires applicables et des éléments @@ -84,33 +85,39 @@ export default function SimulateurWarning({ l'ensemble de votre situation. Le montant réel de vos cotisations peut donc être différent. -
  • -
  • + + Ce simulateur permet d'estimer le montant de vos cotisations à partir de votre revenu projeté -
  • + )} {['indépendant', 'profession-libérale'].includes(simulateur) && ( -
  • + Le montant calculé correspond aux cotisations de l’année{' '} {{ year }} (pour un revenu {{ year }}). -
  • + )} {['profession-libérale'].includes(simulateur) && ( -
  • + Pour les professions réglementées, le simulateur ne calcule pas le montant des cotisations à l'ordre. Elles doivent être ajoutées manuellement dans la case « charges de fonctionnement ». -
  • + )}
) } + +const StyledLi = styled(Li)` + &::before { + color: ${({ theme }) => theme.colors.bases.tertiary[800]} !important; + } +` diff --git a/site/source/components/search/SimulatorHits.tsx b/site/source/components/search/SimulatorHits.tsx index 466af11f6..ab8145538 100644 --- a/site/source/components/search/SimulatorHits.tsx +++ b/site/source/components/search/SimulatorHits.tsx @@ -38,10 +38,10 @@ const SimulateurCardHit = ({ to={{ pathname: path }} state={{ fromSimulateurs: true }} title={ -

+

{' '} {tooltip && {tooltip}} -

+ } /> ) diff --git a/site/source/components/simulationExplanation/IndépendantExplanation.tsx b/site/source/components/simulationExplanation/IndépendantExplanation.tsx index 6e6ba6c6e..1d8d3649d 100644 --- a/site/source/components/simulationExplanation/IndépendantExplanation.tsx +++ b/site/source/components/simulationExplanation/IndépendantExplanation.tsx @@ -176,12 +176,10 @@ function DroitsRetraite() {
  • Retraite de base :{' '} - - - +
  • @@ -206,13 +204,11 @@ function DroitsRetraite() {
  • Points de retraite complémentaire acquis :{' '} - - {' '} - points acquis - + {' '} + points acquis non connue diff --git a/site/source/pages/Landing/Landing.tsx b/site/source/pages/Landing/Landing.tsx index f005d91c4..ee4ef33e8 100644 --- a/site/source/pages/Landing/Landing.tsx +++ b/site/source/pages/Landing/Landing.tsx @@ -37,10 +37,11 @@ export default function Landing() { ogImage="/logo-share.png" />
    - - {t('Passer le contenu')} - +
    + + {t('Passer le contenu')} + Tableau indiquant le salaire net et le coût pour l'employeur avec ou sans @@ -204,7 +206,7 @@ function ComparaisonTable({ rows: [head, ...body] }: ComparaisonTableProps) { {head.map((label, i) => ( - {label} + {label || t('Type')} ))} diff --git a/site/source/pages/gerer/demande-mobilité/demande-mobilité.yaml b/site/source/pages/gerer/demande-mobilité/demande-mobilité.yaml index 7ec1603ab..7461ffc9e 100644 --- a/site/source/pages/gerer/demande-mobilité/demande-mobilité.yaml +++ b/site/source/pages/gerer/demande-mobilité/demande-mobilité.yaml @@ -158,7 +158,7 @@ notification signature: valeur: oui type: groupe description: | - #### Ce document doit être signé ✍️ + ### Ce document doit être signé ✍️ Nous vous invitons à utiliser un écran tactile pour le compléter (téléphone, tablette, etc.). Sinon, vous devrez l’imprimer, le signer et le scanner avant envoi par mail. diff --git a/site/source/pages/gerer/demande-mobilité/index.tsx b/site/source/pages/gerer/demande-mobilité/index.tsx index fe0a535ef..262273bf0 100644 --- a/site/source/pages/gerer/demande-mobilité/index.tsx +++ b/site/source/pages/gerer/demande-mobilité/index.tsx @@ -147,7 +147,7 @@ function FormulairePublicodes() { }) => { const meta = getMeta<{ affichage?: string }>(rawNode, {}) - const headerLevel = Math.min(dottedName.split(' . ').length + 1, 6) + const headerLevel = Math.min(dottedName.split(' . ').length + 1, 4) const HeaderComponent = headings.fromLevel(headerLevel) return ( diff --git a/yarn.lock b/yarn.lock index 6aed6bf97..7c6b2e813 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4754,6 +4754,21 @@ __metadata: languageName: node linkType: hard +"@publicodes/api@npm:^1.0.0-beta.63": + version: 1.0.0-beta.63 + resolution: "@publicodes/api@npm:1.0.0-beta.63" + dependencies: + "@koa/cors": ^3.3.0 + "@koa/router": ^10.1.1 + koa: ^2.13.4 + koa-body: ^5.0.0 + openapi-validator-middleware: ^3.2.6 + peerDependencies: + publicodes: ^1.0.0-beta.47 + checksum: 53d0cf908e787e6299224547dd5b345fb24dbf092625410b245c9bb2e66cd7084bfb2fd5f215eb98796c4200f65395f88003c5c13eaccd4cb0bcf37eb8061183 + languageName: node + linkType: hard + "@react-aria/accordion@npm:^3.0.0-alpha.13": version: 3.0.0-nightly.3598 resolution: "@react-aria/accordion@npm:3.0.0-nightly.3598" @@ -12881,6 +12896,16 @@ __metadata: languageName: node linkType: hard +"cypress-axe@npm:^1.1.0": + version: 1.1.0 + resolution: "cypress-axe@npm:1.1.0" + peerDependencies: + axe-core: ^3 || ^4 + cypress: ^10 || ^11 + checksum: a86b4ff0d35eab82ac5cfd40bbe4077aaf5e7f075b40a49efa949e2c40c60d0f78c1b43d65f98e255c1675d8492b674933da12e11ff71b1f670bd6cfa03b363c + languageName: node + linkType: hard + "cypress-plugin-tab@npm:^1.0.5": version: 1.0.5 resolution: "cypress-plugin-tab@npm:1.0.5" @@ -23768,16 +23793,16 @@ __metadata: languageName: node linkType: hard -"publicodes-react@npm:^1.0.0-beta.62": - version: 1.0.0-beta.62 - resolution: "publicodes-react@npm:1.0.0-beta.62" +"publicodes-react@npm:^1.0.0-beta.63": + version: 1.0.0-beta.63 + resolution: "publicodes-react@npm:1.0.0-beta.63" dependencies: styled-components: ^5.1.0 peerDependencies: publicodes: ^1.0.0-beta.40 react: ^17 || ^18 react-dom: ^17 || ^18 - checksum: 71e73059a9509b7741b6c308bbd8a740cc9daf0c2afba45d6c2db9f3bde735840d94c31cd38a730fce3aee3c5d5d590d9a9d8b84907ee6cb44123deca9ece2e6 + checksum: c3078deed199de42eb5a65cecc5db12696e93a4ae5c082e38c3edea959be734e0d574acc240ebb7da9ba35d7126b3991d1d6daf41b1647aac7736a06bafe8701 languageName: node linkType: hard @@ -23793,6 +23818,18 @@ __metadata: languageName: node linkType: hard +"publicodes@npm:^1.0.0-beta.63": + version: 1.0.0-beta.63 + resolution: "publicodes@npm:1.0.0-beta.63" + dependencies: + moo: ^0.5.1 + nearley: ^2.19.2 + peerDependencies: + "@types/mocha": ^9.0.0 + checksum: 7aff3e841735582737b0d89bb763c49c4bc8ddd5806ff5c7c32fa79d7b49d2b2ba29ad86a3eaa28c25bc28007ba49f068856cefe6e5430d405e0f51f0637e163 + languageName: node + linkType: hard + "pump@npm:^1.0.0": version: 1.0.3 resolution: "pump@npm:1.0.3" @@ -25943,6 +25980,7 @@ __metadata: "@atomik-color/component": ^1.0.16 "@axe-core/react": ^4.5.2 "@internationalized/number": ^3.1.1 + "@publicodes/api": ^1.0.0-beta.63 "@react-aria/accordion": ^3.0.0-alpha.13 "@react-aria/button": ^3.6.3 "@react-aria/checkbox": ^3.7.0 @@ -25992,6 +26030,7 @@ __metadata: "@vitejs/plugin-react": ^2.2.0 algoliasearch: ^4.14.2 cypress: "https://cdn.cypress.io/beta/npm/12.0.0/linux-arm64/release/12.0.0-e8898d2f6b65a11f36ceb2dd32ce7f1d87b103bc/cypress.tgz" + cypress-axe: ^1.1.0 cypress-plugin-tab: ^1.0.5 cypress-wait-until: ^1.7.2 dotenv: ^16.0.3 @@ -26003,8 +26042,8 @@ __metadata: markdown-to-jsx: ^7.1.7 modele-social: "workspace:^" netlify-cli: ^12.2.8 - publicodes: ^1.0.0-beta.62 - publicodes-react: ^1.0.0-beta.62 + publicodes: ^1.0.0-beta.63 + publicodes-react: ^1.0.0-beta.63 react: ^18.2.0 react-colorful: ^5.6.1 react-dom: ^18.2.0