diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml index 86a4436ee..3f079bf30 100644 --- a/.github/workflows/deploy.yaml +++ b/.github/workflows/deploy.yaml @@ -225,20 +225,20 @@ jobs: fail-fast: false matrix: site: ['fr', 'en'] - browser: [electron] # Firefox is very slow… + browser: [chrome] # Firefox is very slow… viewport: [default] container: [1, 2, 3, 4] include: - site: fr - integrationFolder: mon-entreprise + specPattern: mon-entreprise/**/*.{js,jsx,ts,tsx} baseUrl: ${{ needs.deploy-context.outputs.fr_url }} language: fr - site: fr - integrationFolder: mon-entreprise + specPattern: mon-entreprise/**/*.{js,jsx,ts,tsx} baseUrl: ${{ needs.deploy-context.outputs.fr_url }} language: fr - site: en - integrationFolder: mon-entreprise/english + specPattern: mon-entreprise/english/**/*.{js,jsx,ts,tsx} baseUrl: ${{ needs.deploy-context.outputs.en_url }} language: en exclude: @@ -256,13 +256,13 @@ jobs: uses: actions/checkout@v3 - uses: ./.github/actions/install - name: Test e2e mon-entreprise on preview (site=${{ matrix.site }}, browser=${{ matrix.browser}}, viewport=${{ matrix.viewport }}) - uses: cypress-io/github-action@v2 + uses: cypress-io/github-action@v4 with: install: false working-directory: site record: true tag: ${{ needs.deploy-context.outputs.env-name }}_deploy - config: integrationFolder=cypress/integration/${{ matrix.integrationFolder }},baseUrl=${{ matrix.baseUrl }}${{ matrix.viewport == 'small' && ',viewportHeight=740,viewportWidth=360' || '' }} + config: specPattern=cypress/integration/${{ matrix.specPattern }},baseUrl=${{ matrix.baseUrl }}${{ matrix.viewport == 'small' && ',viewportHeight=740,viewportWidth=360' || '' }} env: language=${{ matrix.language }} browser: ${{ matrix.browser }} headless: true @@ -290,11 +290,11 @@ jobs: container: [1, 2, 3, 4] include: - site: fr - integrationFolder: mon-entreprise + specPattern: mon-entreprise/**/*.{js,jsx,ts,tsx} baseUrl: ${{ needs.deploy-context.outputs.fr_url }} language: fr # - site: en - # integrationFolder: mon-entreprise/english + # specPattern: mon-entreprise/english/**/*.{js,jsx,ts,tsx} # baseUrl: ${{ needs.deploy-context.outputs.en_url }} # language: en # exclude: @@ -312,13 +312,13 @@ jobs: uses: actions/checkout@v3 - uses: ./.github/actions/install - name: Test e2e mon-entreprise on production (site=${{ matrix.site }}, browser=${{ matrix.browser}}, viewport=${{ matrix.viewport }}) - uses: cypress-io/github-action@v2 + uses: cypress-io/github-action@v4 with: install: false working-directory: site record: true tag: ${{ needs.deploy-context.outputs.env-name }}_deploy - config: integrationFolder=cypress/integration/${{ matrix.integrationFolder }},baseUrl=${{ matrix.baseUrl }}${{ matrix.viewport == 'small' && ',viewportHeight=740,viewportWidth=360' || '' }} + config: specPattern=cypress/integration/${{ matrix.specPattern }},baseUrl=${{ matrix.baseUrl }}${{ matrix.viewport == 'small' && ',viewportHeight=740,viewportWidth=360' || '' }} env: language=${{ matrix.language }} browser: ${{ matrix.browser }} headless: true diff --git a/.github/workflows/test-external-integrations.yaml b/.github/workflows/test-external-integrations.yaml index 78bdc5836..f100ef900 100644 --- a/.github/workflows/test-external-integrations.yaml +++ b/.github/workflows/test-external-integrations.yaml @@ -24,16 +24,16 @@ jobs: - run: node site/scripts/get-cypress-packages.js | xargs npm i --legacy-peer-deps - name: Test external integration - uses: cypress-io/github-action@v2 + uses: cypress-io/github-action@v4 with: install: false working-directory: site record: true tag: external-integration - config: integrationFolder=cypress/integration/external,baseUrl=https://mon-entreprise.urssaf.fr + config: specPattern=cypress/integration/external/**/*.{js,jsx,ts,tsx},baseUrl=https://mon-entreprise.urssaf.fr - name: e2e tests with external API calls - uses: cypress-io/github-action@v2 + uses: cypress-io/github-action@v4 with: install: false working-directory: site @@ -43,5 +43,5 @@ jobs: cypress/integration/mon-entreprise/demande-mobilité.js record: true tag: external-mon-entreprise-e2e - config: integrationFolder=cypress/integration/mon-entreprise,baseUrl=https://mon-entreprise.urssaf.fr + config: specPattern=cypress/integration/mon-entreprise/**/*.{js,jsx,ts,tsx},baseUrl=https://mon-entreprise.urssaf.fr env: language=fr,record_http= # prevent stubbing diff --git a/site/cypress.config.ts b/site/cypress.config.ts new file mode 100644 index 000000000..a5935a1a0 --- /dev/null +++ b/site/cypress.config.ts @@ -0,0 +1,15 @@ +import { defineConfig } from 'cypress' + +export default defineConfig({ + projectId: 'jxcngh', + env: { + language: 'fr', + }, + chromeWebSecurity: false, + e2e: { + // eslint-disable-next-line + setupNodeEvents(on, config) {}, + baseUrl: 'http://localhost:8888', + specPattern: 'cypress/integration/mon-entreprise/**/*.{js,jsx,ts,tsx}', + }, +}) diff --git a/site/cypress.json b/site/cypress.json deleted file mode 100644 index fb52e863c..000000000 --- a/site/cypress.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "projectId": "jxcngh", - "baseUrl": "http://localhost:3000/mon-entreprise", - "env": { - "language": "fr" - }, - "integrationFolder": "cypress/integration/mon-entreprise", - "pluginsFile": false, - "chromeWebSecurity": false -} diff --git a/site/cypress/.babelrc b/site/cypress/.babelrc deleted file mode 100644 index 0967ef424..000000000 --- a/site/cypress/.babelrc +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/site/cypress/integration/mon-entreprise/covid19.js b/site/cypress/integration/mon-entreprise/covid19.js deleted file mode 100644 index d247f561b..000000000 --- a/site/cypress/integration/mon-entreprise/covid19.js +++ /dev/null @@ -1,36 +0,0 @@ -const fr = Cypress.env('language') === 'fr' -const testText = (selector, callback) => - cy.get(`[data-test-id=${selector}]`).should(($span) => { - const displayedText = $span.text().trim().replace(/[\s]/g, ' ') - callback(displayedText) - }) - -describe('Page covid-19', function () { - if (!fr) { - return - } - before(function () { - return cy.visit(encodeURI('/simulateurs/chômage-partiel')) - }) - it('should not crash', function () { - cy.contains('Salaire brut mensuel') - }) - it.skip('should display 100% de prise en charge pour un SMIC', function () { - cy.contains('SMIC').click() - testText('comparaison-net', (text) => - expect(text).to.eq('Soit 100 % du revenu net') - ) - testText('comparaison-total', (text) => - expect(text).to.eq('Soit 0 % du coût habituel') - ) - }) - it('should display an amount for the prise en charge pour un salaire médian', function () { - cy.contains('salaire médian').click() - testText('comparaison-net', (text) => - expect(text).to.match(/Soit [\d]{2} % du revenu net/) - ) - testText('comparaison-total', (text) => - expect(text).to.match(/Soit [\d]{1} % du coût habituel/) - ) - }) -}) diff --git a/site/cypress/integration/mon-entreprise/covid19.ts b/site/cypress/integration/mon-entreprise/covid19.ts new file mode 100644 index 000000000..fba52758b --- /dev/null +++ b/site/cypress/integration/mon-entreprise/covid19.ts @@ -0,0 +1,39 @@ +import { fr } from '../../support/utils' + +describe('Page covid-19', function () { + if (!fr) { + return + } + + before(function () { + return cy.visit(encodeURI('/simulateurs/chômage-partiel')) + }) + + it('should not crash', function () { + cy.contains('Salaire brut mensuel') + }) + + it('should display 100% de prise en charge pour un SMIC', function () { + cy.contains('SMIC').click() + + cy.get('[data-test-id=comparaison-net]').contains( + /Soit 100 % du revenu net/ + ) + + cy.get('[data-test-id=comparaison-total]').contains( + /Soit \d % du coût habituel/ + ) + }) + + it('should display an amount for the prise en charge pour un salaire médian', function () { + cy.contains('salaire médian').click() + + cy.get('[data-test-id=comparaison-net]').contains( + /Soit [\d]{2} % du revenu net/ + ) + + cy.get('[data-test-id=comparaison-total]').contains( + /Soit [\d]{1} % du coût habituel/ + ) + }) +}) diff --git a/site/cypress/integration/mon-entreprise/demande-mobilité.js b/site/cypress/integration/mon-entreprise/demande-mobilité.ts similarity index 80% rename from site/cypress/integration/mon-entreprise/demande-mobilité.js rename to site/cypress/integration/mon-entreprise/demande-mobilité.ts index 44f54c360..f4b069138 100644 --- a/site/cypress/integration/mon-entreprise/demande-mobilité.js +++ b/site/cypress/integration/mon-entreprise/demande-mobilité.ts @@ -1,4 +1,4 @@ -const fr = Cypress.env('language') === 'fr' +import { fr } from '../../support/utils' const FIXTURES_FOLDER = 'cypress/fixtures' const DEMANDE_MOBILITE_FIXTURES_FOLDER = `${FIXTURES_FOLDER}/demande-mobilité` @@ -27,6 +27,7 @@ describe(`Formulaire demande mobilité (${ cy.clearLocalStorage() // Try to avoid flaky tests cy.visit(encodeURI('/gérer/demande-mobilité')) }) + after(function () { cy.writeInterceptResponses( pendingRequests, @@ -34,9 +35,18 @@ describe(`Formulaire demande mobilité (${ DEMANDE_MOBILITE_FIXTURES_FOLDER ) }) + it('should allow to select salarié', function () { + cy.intercept({ + method: 'GET', + hostname: 'geo.api.gouv.fr', + url: '/communes*', + }).as('communes') + cy.contains('Employeur adhérent au TESE ou au CEA').click() + cy.contains('Informations concernant le salarié') + cy.contains('Êtes-vous adhérent au TESE ou au CEA') .parent() .next() @@ -44,8 +54,10 @@ describe(`Formulaire demande mobilité (${ .click() // "coordonnées" section - cy.contains('Nom').click({ force: true }) - cy.focused() + cy.contains('Nom') + .parent() + .click() + .focused() .type('Deaux') .tab() .type('Jean Bernard') @@ -55,20 +67,21 @@ describe(`Formulaire demande mobilité (${ .type('Française') .tab() .type('1991-07-25') - cy.contains('Non').click().wait(250) - cy.focused() - .tab() - .type('Pouts', { force: true }) - .wait(500) - .type('{enter}') - .wait(500) - cy.tab().type('{downarrow}').wait(500) - cy.focused() + cy.contains('Non') + .click() + .focused() .tab() - .type('Brest') - .wait(500) + .type('Pouts') + .wait('@communes') + .focused() + cy.contains('65100').type('{enter}').focused().tab().type('{downarrow}') + + cy.focused().tab().type('Brest').wait('@communes') + + cy.contains('29200') .type('{enter}') + .focused() .tab() .type('3 rue de la Rhumerie') .tab() @@ -81,9 +94,9 @@ describe(`Formulaire demande mobilité (${ .type('14 chemin des Docks') .tab() .type('Bre') - .wait(500) - cy.contains('29200').click() - cy.focused() + cy.contains('29200') + .click() + .focused() .tab() .type('Deaux') .tab() @@ -99,9 +112,11 @@ describe(`Formulaire demande mobilité (${ cy.focused().type('2020-11-06').tab().type('2021-04-09').tab() cy.focused().type('Argen{enter}') - cy.contains('Agent contractuel').click().wait(250) - cy.focused() - .tab() + cy.contains('Agent contractuel').click() + cy.contains("Nom de l'entreprise") + .parent() + .click() + .focused() .type('Haldithet Docks') .tab() .type('64E45 12-654') @@ -118,16 +133,10 @@ describe(`Formulaire demande mobilité (${ cy.focused().tab().type('{downarrow}{downarrow}') cy.focused().tab().type('{downarrow}') - cy.focused() - .tab() - - .type('{downarrow}') cy.focused().tab().type('{downarrow}') cy.focused().tab().type('{downarrow}') - cy.focused() - .tab() - - .type('{downarrow}') + cy.focused().tab().type('{downarrow}') + cy.focused().tab().type('{downarrow}') cy.focused().tab().type('{downarrow}') cy.focused().tab() @@ -139,8 +148,7 @@ describe(`Formulaire demande mobilité (${ .next() .contains('Oui') .click() - cy.contains("Combien d'ayants droits partiront") - cy.focused().tab().type(1) + cy.contains("Combien d'ayants droits partiront").parent().next().type('1') cy.contains('Ayant droit n°1') cy.focused() .tab() diff --git a/site/cypress/integration/mon-entreprise/english/prerender.ts b/site/cypress/integration/mon-entreprise/english/prerender.ts new file mode 100644 index 000000000..b57f98b7f --- /dev/null +++ b/site/cypress/integration/mon-entreprise/english/prerender.ts @@ -0,0 +1,19 @@ +import { fr } from '../../../support/utils' +// @ts-ignore +import prerenderPaths from '../../../prerender-paths.json' + +describe('Test prerender', function () { + const paths = ( + prerenderPaths as { 'mon-entreprise': string[]; infrance: string[] } + )[fr ? 'mon-entreprise' : 'infrance'] + + paths.forEach((path) => { + it(`should show the pre-render of ${fr ? 'fr' : 'en'} ${ + path || '/' + }`, function () { + cy.visit(encodeURI(path || '/'), { script: false }) + .get('#loading', { timeout: 200 }) + .should('not.exist') + }) + }) +}) diff --git a/site/cypress/integration/mon-entreprise/english/sitemap.ts b/site/cypress/integration/mon-entreprise/english/sitemap.ts new file mode 100644 index 000000000..c52133183 --- /dev/null +++ b/site/cypress/integration/mon-entreprise/english/sitemap.ts @@ -0,0 +1,7 @@ +import { fr } from '../../../support/utils' + +describe('Test sitemap', function () { + it(`should visit sitemap ${fr ? 'fr' : 'en'}`, function () { + cy.request(`/sitemap.${fr ? 'fr' : 'en'}.txt`).should('be.ok') + }) +}) diff --git a/site/cypress/integration/mon-entreprise/english/status.js b/site/cypress/integration/mon-entreprise/english/status.ts similarity index 92% rename from site/cypress/integration/mon-entreprise/english/status.js rename to site/cypress/integration/mon-entreprise/english/status.ts index d7e18ed70..d0c022a32 100644 --- a/site/cypress/integration/mon-entreprise/english/status.js +++ b/site/cypress/integration/mon-entreprise/english/status.ts @@ -1,5 +1,6 @@ describe('Status guide', function () { const fr = Cypress.env('language') === 'fr' + beforeEach(function () { cy.visit(fr ? encodeURI('/créer') : '/create') cy.contains(fr ? 'Trouver le bon statut' : 'Find the right status').click() @@ -12,6 +13,7 @@ describe('Status guide', function () { cy.contains(fr ? 'Un seul associé' : 'Only one partner').click() cy.contains(fr ? 'Seul ou à plusieurs' : 'Number of partners') }) + it('should guide thought the SASU status', function () { cy.get('button') .contains(fr ? 'Seul' : 'Alone') @@ -19,8 +21,7 @@ describe('Status guide', function () { cy.get('button') .contains(fr ? 'Société' : 'Limited liability company') .click() - // The click fails randomly and unexplicablly on CI - cy.wait(200) + cy.get('button').contains('Assimilé').click() cy.contains(fr ? 'Créer une SASU' : 'Create a SASU').click() cy.url().should('match', /\/SASU$/) diff --git a/site/cypress/integration/mon-entreprise/landing.js b/site/cypress/integration/mon-entreprise/landing.ts similarity index 90% rename from site/cypress/integration/mon-entreprise/landing.js rename to site/cypress/integration/mon-entreprise/landing.ts index 75b0c98b3..e135434b8 100644 --- a/site/cypress/integration/mon-entreprise/landing.js +++ b/site/cypress/integration/mon-entreprise/landing.ts @@ -33,6 +33,12 @@ describe('Landing page', function () { FIXTURES_FOLDER ) + cy.intercept({ + method: 'GET', + hostname: 'api.recherche-entreprises.fabrique.social.gouv.fr', + url: '/api/v1/search*', + }).as('entreprises') + cy.visit('/') cy.get(currentCompanyPath).should('not.exist') @@ -41,7 +47,7 @@ describe('Landing page', function () { cy.get(searchInputPath).invoke('attr', 'type').should('equal', 'search') cy.get(searchInputPath).focus().type('noima') - cy.wait(100) + cy.wait('@entreprises') cy.get(searchResultsPath).children().should('have.length', 6) cy.get(searchResultsPath).children().first().click() diff --git a/site/cypress/integration/mon-entreprise/recherche.js b/site/cypress/integration/mon-entreprise/recherche.ts similarity index 79% rename from site/cypress/integration/mon-entreprise/recherche.js rename to site/cypress/integration/mon-entreprise/recherche.ts index b2d0647e0..baffd9759 100644 --- a/site/cypress/integration/mon-entreprise/recherche.js +++ b/site/cypress/integration/mon-entreprise/recherche.ts @@ -1,7 +1,7 @@ -const fr = Cypress.env('language') === 'fr' +import { fr } from '../../support/utils' describe('Recherche globales', function () { - if (!fr || Cypress.config().baseUrl != 'https://mon-entreprise.urssaf.fr') { + if (!fr) { return } @@ -10,10 +10,8 @@ describe('Recherche globales', function () { cy.contains('Rechercher').click() - cy.wait(30) cy.focused().should('have.attr', 'type', 'search') - cy.wait(100) cy.contains('Simulateurs') .next() .find('[role="button"]') @@ -22,7 +20,6 @@ describe('Recherche globales', function () { cy.focused().type('avocat') - cy.wait(100) cy.contains('Simulateurs') .next() .find('[role="button"]') diff --git a/site/cypress/integration/mon-entreprise/secondary-pages.js b/site/cypress/integration/mon-entreprise/secondary-pages.ts similarity index 60% rename from site/cypress/integration/mon-entreprise/secondary-pages.js rename to site/cypress/integration/mon-entreprise/secondary-pages.ts index a7ff91742..805c60748 100644 --- a/site/cypress/integration/mon-entreprise/secondary-pages.js +++ b/site/cypress/integration/mon-entreprise/secondary-pages.ts @@ -1,4 +1,4 @@ -const fr = Cypress.env('language') === 'fr' +import { fr } from '../../support/utils' describe('Secondary pages', function () { if (!fr) { @@ -10,9 +10,9 @@ describe('Secondary pages', function () { cy.contains('Statistiques détaillées') }) - it.skip('navigate in the news section', function () { + it('navigate in the news section', function () { cy.visit('/nouveautés') cy.contains('←').click() - cy.url().should('match', /\/nouveautés\/[^/]*$/) + cy.url({ decode: true }).should('match', /\/nouveautés\/[^/]*$/) }) }) diff --git a/site/cypress/integration/mon-entreprise/simulateur-ae.js b/site/cypress/integration/mon-entreprise/simulateur-ae.ts similarity index 70% rename from site/cypress/integration/mon-entreprise/simulateur-ae.js rename to site/cypress/integration/mon-entreprise/simulateur-ae.ts index 01b1f4214..b48216d6a 100644 --- a/site/cypress/integration/mon-entreprise/simulateur-ae.js +++ b/site/cypress/integration/mon-entreprise/simulateur-ae.ts @@ -1,11 +1,13 @@ -const fr = Cypress.env('language') === 'fr' -const inputSelector = - 'div[aria-labelledby="simulator-legend"] input[inputmode="numeric"]' +import { fr } from '../../support/utils' describe('Simulateur auto-entrepreneur', function () { if (!fr) { return } + + const inputSelector = + 'div[aria-labelledby="simulator-legend"] input[inputmode="numeric"]' + before(function () { return cy.visit('/simulateurs/auto-entrepreneur') }) @@ -17,14 +19,17 @@ describe('Simulateur auto-entrepreneur', function () { cy.contains('Début 2022').click() cy.contains('ACRE') }) + it('should not have negative value', function () { cy.contains('Mensuel').click() - cy.wait(100) cy.get(inputSelector).first().type('{selectall}5000') cy.get(inputSelector).each(($input) => { cy.wrap($input).should(($i) => { - const val = +$i.val().replace(/[\s,.€]/g, '') - expect(val).not.to.be.below(4000) + const val = $i + .val() + .toString() + .replace(/[\s,.€]/g, '') + expect(parseInt(val)).not.to.be.below(4000) }) }) }) diff --git a/site/cypress/integration/mon-entreprise/simulateur-salarie.js b/site/cypress/integration/mon-entreprise/simulateur-salarie.ts similarity index 78% rename from site/cypress/integration/mon-entreprise/simulateur-salarie.js rename to site/cypress/integration/mon-entreprise/simulateur-salarie.ts index 7c3e45280..632ad9116 100644 --- a/site/cypress/integration/mon-entreprise/simulateur-salarie.js +++ b/site/cypress/integration/mon-entreprise/simulateur-salarie.ts @@ -1,9 +1,10 @@ -const fr = Cypress.env('language') === 'fr' +import { fr } from '../../support/utils' describe('Simulateur salarié', function () { if (!fr) { return } + before(function () { return cy.visit(encodeURI('/simulateurs/salarié')) }) @@ -19,7 +20,6 @@ describe('Simulateur salarié', function () { .click() cy.get('div[role="dialog"]').contains('Oui').click() - cy.wait(300) cy.get('div[role="dialog"]').contains('Continuer').click() cy.get('div[role="dialog"]').contains('Fermer').click() }) @@ -28,9 +28,11 @@ describe('Simulateur salarié', function () { cy.get( '#contrat\\ salarié\\ \\.\\ rémunération\\ \\.\\ brut\\ de\\ base' ).should(($input) => { - expect(+$input.val().replace(/[\s,.€]/g, '')) - .to.be.above(1300) - .and.to.be.below(1600) + const val = $input + .val() + .toString() + .replace(/[\s,.€]/g, '') + expect(parseInt(val)).to.be.above(1300).and.to.be.below(1600) }) }) @@ -42,14 +44,17 @@ describe('Simulateur salarié', function () { .next() .find('button') .click() - cy.focused().type(25) - cy.wait(500) + cy.focused().type('25') cy.contains('Fermer').click() cy.get( '#contrat\\ salarié\\ \\.\\ rémunération\\ \\.\\ net\\ après\\ impôt' ).should(($input) => { - expect(+$input.val().replace(/[\s,.€]/g, '')).to.be.below(1000) + const val = $input + .val() + .toString() + .replace(/[\s,.€]/g, '') + expect(parseInt(val)).to.be.below(1000) }) }) }) diff --git a/site/cypress/jsconfig.json b/site/cypress/jsconfig.json deleted file mode 100644 index 3ce942d63..000000000 --- a/site/cypress/jsconfig.json +++ /dev/null @@ -1,4 +0,0 @@ -// Support IntelliSense for Cypress -{ - "include": ["../../node_modules/cypress", "./integration/**/*.js"] -} diff --git a/site/cypress/prerender-paths.json b/site/cypress/prerender-paths.json new file mode 100644 index 000000000..f49bb95a7 --- /dev/null +++ b/site/cypress/prerender-paths.json @@ -0,0 +1 @@ +{"mon-entreprise":["","/créer","/gérer","/simulateurs","/simulateurs/salaire-brut-net","/simulateurs/chômage-partiel","/simulateurs/auto-entrepreneur","/simulateurs/indépendant","/simulateurs/sasu","/simulateurs/artiste-auteur","/iframes/simulateur-embauche","/iframes/pamc"],"infrance":["","/calculators/salary","/iframes/simulateur-embauche"]} \ No newline at end of file diff --git a/site/cypress/support/commands.js b/site/cypress/support/commands.ts similarity index 52% rename from site/cypress/support/commands.js rename to site/cypress/support/commands.ts index 2b3003fb8..44aa08401 100644 --- a/site/cypress/support/commands.js +++ b/site/cypress/support/commands.ts @@ -23,12 +23,17 @@ // // -- This is will overwrite an existing command -- // Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) -Cypress.Commands.add('iframe', { prevSubject: 'element' }, ($iframe) => { + +import 'cypress-wait-until' + +Cypress.Commands.add('iframe', { prevSubject: ['element'] }, ($iframe) => { + // eslint-disable-next-line return new Cypress.Promise((resolve) => { + // eslint-disable-next-line setTimeout(() => resolve($iframe.contents().find('body')), 6000) }) }) -import 'cypress-wait-until' + Cypress.Commands.add( 'setInterceptResponses', (pendingRequests, responses, hostnames, specFixturesFolder) => { @@ -43,11 +48,13 @@ Cypress.Commands.add( pendingRequests.add(req.url) req.on('after:response', (res) => { pendingRequests.delete(req.url) + // @ts-ignore + // eslint-disable-next-line responses[res.url] = res.body }) }) } else if (stubFixtures) { - const urlOfFilepath = (filename) => { + const urlOfFilepath = (filename: string) => { return atob(filename.slice(0, -'.json'.length)) } cy.exec(`find ${specFixturesFolder} -type f`) @@ -66,6 +73,7 @@ Cypress.Commands.add( } } ) + Cypress.Commands.add( 'writeInterceptResponses', (pendingRequests, responses, specFixturesFolder) => { @@ -75,9 +83,11 @@ Cypress.Commands.add( // We need to wait on all catched requests to be fulfilled and recorded, // otherwise the stubbed cy run might error when a request is not stubbed. // Caveat: we assume request.url to be unique amongst recorded requests. + + // eslint-disable-next-line @typescript-eslint/no-unsafe-call cy.waitUntil(() => pendingRequests.size === 0) - Object.keys(responses).map((url) => { - if (responses[url] === undefined) return + Object.keys(responses).forEach((url) => { + if (responses[url] === undefined) return undefined cy.writeFile( `${specFixturesFolder}/${btoa(url)}.json`, JSON.stringify(responses[url], null, 2) @@ -86,3 +96,85 @@ Cypress.Commands.add( } } ) + +/** + * Add option to disable javascript with { script: false } + */ +Cypress.Commands.overwrite('visit', (orig, url, options = {}) => { + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + const window = cy.state('window') as Cypress.AUTWindow + const parentDocument = window.parent.document + const iframe = parentDocument.querySelector('main iframe') + + if (!iframe) { + // @ts-ignore + return orig(url, options) + } + + if (options.script === false) { + if (Cypress.config('chromeWebSecurity') !== false) { + throw new TypeError( + "When you disable script you also have to set 'chromeWebSecurity' in your config to 'false'" + ) + } + // @ts-ignore + iframe.sandbox = '' + } else { + // In case it was added by a visit before, the attribute has to be removed from the iframe + iframe.removeAttribute('sandbox') + } + + // @ts-ignore + return orig(url, options) +}) + +// Types + +/// +declare global { + /* eslint-disable no-unused-vars */ + // eslint-disable-next-line @typescript-eslint/no-namespace + namespace Cypress { + interface Chainable { + /** + * @param pendingRequests + * @param responses + * @param hostnames + * @param specFixturesFolder + */ + setInterceptResponses( + pendingRequests: Set, + responses: Record, + hostnames: string[], + specFixturesFolder: string + ): Chainable + + /** + * @param pendingRequests + * @param responses + * @param specFixturesFolder + */ + writeInterceptResponses( + pendingRequests: Set, + responses: Record, + specFixturesFolder: string + ): Chainable + + /** + */ + iframe(): Chainable + + visit( + url: string, + options?: Partial & { script?: boolean } + ): Chainable + visit( + options: Partial & { + url: string + script?: boolean + } + ): Chainable + } + } + /* eslint-enable no-unused-vars */ +} diff --git a/site/cypress/support/index.js b/site/cypress/support/e2e.ts similarity index 100% rename from site/cypress/support/index.js rename to site/cypress/support/e2e.ts diff --git a/site/cypress/support/utils.ts b/site/cypress/support/utils.ts new file mode 100644 index 000000000..bc477618e --- /dev/null +++ b/site/cypress/support/utils.ts @@ -0,0 +1 @@ +export const fr = Cypress.env('language') === 'fr' diff --git a/site/cypress/tsconfig.json b/site/cypress/tsconfig.json new file mode 100644 index 000000000..0af783b49 --- /dev/null +++ b/site/cypress/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "target": "es5", + "module": "ESNext", + "lib": ["es5", "dom"], + "types": ["cypress", "cypress-plugin-tab/src", "node"], + "allowSyntheticDefaultImports": true + }, + "include": ["**/*.ts", "../cypress.config.ts"] +} diff --git a/site/package.json b/site/package.json index 1c4e903c0..c3a5a3f2c 100644 --- a/site/package.json +++ b/site/package.json @@ -32,8 +32,8 @@ "preview:infrance": "sed 's|:SITE_EN||g' | sed 's|:API_URL|http://localhost:3004|g' netlify.toml > dist/netlify.toml && cd dist && npx netlify-cli dev -d ./ -p 8889", "typecheck:watch": "tsc --skipLibCheck --noEmit --watch", "test": "vitest", - "test:dev-e2e:mon-entreprise": "cypress open --browser chromium", - "test:dev-e2e:mycompanyinfrance": "cypress open --browser chromium --config baseUrl=http://localhost:8080/infrance,integrationFolder=cypress/integration/mon-entreprise/english --env language=en", + "test:dev-e2e:mon-entreprise": "cypress open --e2e", + "test:dev-e2e:mycompanyinfrance": "cypress open --e2e --config \"baseUrl=http://localhost:8889,specPattern=cypress/integration/mon-entreprise/english/**/*.{js,jsx,ts,tsx}\" --env language=en", "test:record-http-calls:mon-entreprise": "cypress run --env record_http=", "algolia:update": "node --loader ts-node/esm scripts/search/update-data.ts", "algolia:clean": "node scripts/search/clean.js", @@ -133,7 +133,7 @@ "@types/styled-components": "^5.1.24", "@vitejs/plugin-legacy": "^1.8.2", "@vitejs/plugin-react": "^1.3.2", - "cypress": "^9.5.4", + "cypress": "^10.1.0", "cypress-plugin-tab": "^1.0.5", "cypress-wait-until": "^1.7.2", "dotenv": "=8.1.0",