From 70a77ddf0fc7174ef5c434a841ed3d26d82416df Mon Sep 17 00:00:00 2001 From: Nicolas Date: Wed, 19 Aug 2026 13:18:02 +0200 Subject: [PATCH] feat(web): infra Cypress Component Testing, premier test sur CheckboxOption MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Étape 1 du refactor (voir PR) : met en place le vrai mode Component Testing de Cypress, séparé de l'e2e — monte un composant React isolé (pas de routeur, pas de backend), pour tester les composants génériques (components/ui/) indépendamment de tout parcours utilisateur. - cypress.config.ts : nouveau bloc `component` (devServer Vite, réutilise vite.config.ts de l'appli — même plugin React, même Sass). Le hook GPU-disable est factorisé (`disableGpu`) puisque e2e et component ont chacun leur propre `setupNodeEvents`, pas de config partagée par défaut. - cypress/support/component.ts + component-index.html : fichiers de support standards Cypress CT — importe le vrai global.scss de l'appli (les composants génériques sont stylés via lui, pas de CSS scopé à eux). - cypress/component/CheckboxOption.cy.tsx : 4 scénarios sur components/ui/Checkbox.tsx (rendu du label, reflet du prop `checked` sur l'input natif + la classe `is-selected`, callback `onChange` avec la valeur inversée, comportement contrôlé via un wrapper avec état). Dépendance ajoutée, épinglée : @cypress/vite-dev-server@5.2.1 (dernière version sans peer dependency cypress >=14 — 6.0.3+ l'exige explicitement, on est sur cypress@13.17.0). Testé en local jusqu'au mur GPU/Electron habituel (config + devServer Vite chargent sans erreur) — l'exécution réelle du montage reste à vérifier via la CI. --- apps/web/cypress.config.ts | 46 ++++-- .../cypress/component/CheckboxOption.cy.tsx | 68 +++++++++ apps/web/cypress/support/component-index.html | 9 ++ apps/web/cypress/support/component.ts | 15 ++ apps/web/package.json | 1 + pnpm-lock.yaml | 133 ++++++++++++++++++ 6 files changed, 259 insertions(+), 13 deletions(-) create mode 100644 apps/web/cypress/component/CheckboxOption.cy.tsx create mode 100644 apps/web/cypress/support/component-index.html create mode 100644 apps/web/cypress/support/component.ts diff --git a/apps/web/cypress.config.ts b/apps/web/cypress.config.ts index 20fd5f4..a05626b 100644 --- a/apps/web/cypress.config.ts +++ b/apps/web/cypress.config.ts @@ -1,26 +1,32 @@ import { addCucumberPreprocessorPlugin } from "@badeball/cypress-cucumber-preprocessor"; import { createEsbuildPlugin } from "@badeball/cypress-cucumber-preprocessor/esbuild"; import createBundler from "@bahmutov/cypress-esbuild-preprocessor"; +import { devServer } from "@cypress/vite-dev-server"; import { defineConfig } from "cypress"; +import viteConfig from "./vite.config"; + +// Disable GPU for headless/sandboxed environments (e.g. CI containers) where +// no GPU device is available — needed by both e2e and component testing, +// each of which has its own independent `setupNodeEvents`. +function disableGpu(on: Cypress.PluginEvents) { + on("before:browser:launch", (browser, launchOptions) => { + if (browser.family === "chromium") { + launchOptions.args.push("--disable-gpu", "--no-sandbox"); + } + return launchOptions; + }); +} export default defineConfig({ e2e: { baseUrl: "http://localhost:5173", - // Experimental — testing whether real Gherkin .feature files work with - // this preprocessor version (see experiment/cucumber-cypress). Only one - // throwaway feature exists right now (login.feature); the rest of the - // suite is still plain .cy.ts, matched by the default `**/*.cy.ts` - // pattern alongside `**/*.feature`. + // User journeys, Gherkin-driven (see docs/testing.md once written) live + // alongside plain layout-focused `.cy.ts` specs here — both matched by + // this pattern. Generic component tests are separate, see `component` + // below. specPattern: ["cypress/e2e/**/*.cy.ts", "cypress/e2e/**/*.feature"], async setupNodeEvents(on, config) { - // Disable GPU for headless/sandboxed environments (e.g. CI containers) - // where no GPU device is available. - on("before:browser:launch", (browser, launchOptions) => { - if (browser.family === "chromium") { - launchOptions.args.push("--disable-gpu", "--no-sandbox"); - } - return launchOptions; - }); + disableGpu(on); await addCucumberPreprocessorPlugin(on, config); on( @@ -33,4 +39,18 @@ export default defineConfig({ return config; }, }, + + // Mounts one generic UI component at a time (components/ui/*), no + // router/backend involved — separate from the e2e suite above, which + // always exercises a full routed page. Reuses the app's own vite.config.ts + // (same React plugin, same Sass setup) rather than duplicating it. + component: { + specPattern: "cypress/component/**/*.cy.tsx", + devServer(devServerConfig) { + return devServer({ ...devServerConfig, viteConfig }); + }, + setupNodeEvents(on) { + disableGpu(on); + }, + }, }); diff --git a/apps/web/cypress/component/CheckboxOption.cy.tsx b/apps/web/cypress/component/CheckboxOption.cy.tsx new file mode 100644 index 0000000..02450a0 --- /dev/null +++ b/apps/web/cypress/component/CheckboxOption.cy.tsx @@ -0,0 +1,68 @@ +import { useState } from "react"; +import { CheckboxOption } from "../../src/components/ui/Checkbox"; + +// First real component test — mounts CheckboxOption in isolation (no +// router, no backend), unlike everything under cypress/e2e/ which always +// visits a full routed page. See cypress.config.ts's `component` block. + +describe("CheckboxOption", () => { + it("renders its label content", () => { + cy.mount( + {}}> + Végétarien + , + ); + + cy.contains("label", "Végétarien").should("be.visible"); + }); + + it("reflects the checked prop on the native input, and the is-selected class", () => { + cy.mount( + {}}> + Végétarien + , + ); + cy.get("input[type=checkbox]").should("not.be.checked"); + cy.get("label").should("not.have.class", "is-selected"); + + cy.mount( + {}}> + Végétarien + , + ); + cy.get("input[type=checkbox]").should("be.checked"); + cy.get("label").should("have.class", "is-selected"); + }); + + it("calls onChange with the toggled value when clicked", () => { + const onChange = cy.stub().as("onChange"); + cy.mount( + + Végétarien + , + ); + + cy.get("input[type=checkbox]").click(); + + cy.get("@onChange").should("have.been.calledOnceWith", true); + }); + + it("is a controlled component — stays checked only while the parent says so", () => { + // A tiny stateful wrapper, since CheckboxOption itself takes no + // internal state — this is what actually exercises the checked/onChange + // contract the way a real caller (AllergySelect, the theme picker…) + // would. + function Wrapper() { + const [checked, setChecked] = useState(false); + return ( + + Végétarien + + ); + } + cy.mount(); + + cy.get("input[type=checkbox]").should("not.be.checked").click(); + cy.get("input[type=checkbox]").should("be.checked"); + }); +}); diff --git a/apps/web/cypress/support/component-index.html b/apps/web/cypress/support/component-index.html new file mode 100644 index 0000000..aad39e0 --- /dev/null +++ b/apps/web/cypress/support/component-index.html @@ -0,0 +1,9 @@ + + + + + + +
+ + diff --git a/apps/web/cypress/support/component.ts b/apps/web/cypress/support/component.ts new file mode 100644 index 0000000..38f5f07 --- /dev/null +++ b/apps/web/cypress/support/component.ts @@ -0,0 +1,15 @@ +import { mount } from "cypress/react18"; +// Same global stylesheet the real app loads (see src/main.tsx) — generic +// components (Checkbox, Radio, Dialog…) are styled through it, not their +// own scoped CSS, so mounting one without it would test unstyled markup. +import "../../src/styles/global.scss"; + +declare global { + namespace Cypress { + interface Chainable { + mount: typeof mount; + } + } +} + +Cypress.Commands.add("mount", mount); diff --git a/apps/web/package.json b/apps/web/package.json index 95cb204..8839d4a 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -26,6 +26,7 @@ "devDependencies": { "@badeball/cypress-cucumber-preprocessor": "22.2.0", "@bahmutov/cypress-esbuild-preprocessor": "2.2.8", + "@cypress/vite-dev-server": "5.2.1", "@types/node": "^22.9.0", "@types/react": "^18.3.12", "@types/react-dom": "^18.3.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 523baa5..7560769 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -121,6 +121,9 @@ importers: '@bahmutov/cypress-esbuild-preprocessor': specifier: 2.2.8 version: 2.2.8(esbuild@0.21.5) + '@cypress/vite-dev-server': + specifier: 5.2.1 + version: 5.2.1 '@types/node': specifier: ^22.9.0 version: 22.20.1 @@ -488,6 +491,9 @@ packages: resolution: {integrity: sha512-hauBrOdvu08vOsagkZ/Aju5XuiZx6ldsLfByg1htFeldhex+PeMrYauANzFsMJeAA0+dyPLbDoX2OYuvVoLDkQ==, tarball: https://registry.npmjs.org/@cypress/request/-/request-3.0.10.tgz} engines: {node: '>= 6'} + '@cypress/vite-dev-server@5.2.1': + resolution: {integrity: sha512-5HEUpB2UjpoBByOPAdTBfeJWHlvyDv3Qz5GuGovoiZnzsZyF9eivWfFiYadFdjXXX8i8kVzibo8heWZg+jigGg==, tarball: https://registry.npmjs.org/@cypress/vite-dev-server/-/vite-dev-server-5.2.1.tgz} + '@cypress/xvfb@1.2.4': resolution: {integrity: sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==, tarball: https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.4.tgz} @@ -1439,6 +1445,9 @@ packages: resolution: {integrity: sha512-p5tAzS57i5MV9fZFDj9LeIiTZEufbSe2eDozP+ElheSUq1m74CRq1jI4mYNDdVs9vQztXFLuk/Gd6BWTdwRJ5g==, tarball: https://registry.npmjs.org/body-parser/-/body-parser-1.20.6.tgz} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==, tarball: https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz} + brace-expansion@1.1.18: resolution: {integrity: sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==, tarball: https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz} @@ -1703,6 +1712,13 @@ packages: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==, tarball: https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz} engines: {node: '>= 8'} + css-select@4.3.0: + resolution: {integrity: sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==, tarball: https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz} + + css-what@6.2.2: + resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==, tarball: https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz} + engines: {node: '>= 6'} + csstype@3.2.3: resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==, tarball: https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz} @@ -1857,6 +1873,19 @@ packages: resolution: {integrity: sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==, tarball: https://registry.npmjs.org/diff/-/diff-7.0.0.tgz} engines: {node: '>=0.3.1'} + dom-serializer@1.4.1: + resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==, tarball: https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==, tarball: https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz} + + domhandler@4.3.1: + resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==, tarball: https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz} + engines: {node: '>= 4'} + + domutils@2.8.0: + resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==, tarball: https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz} + dotenv@16.6.1: resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==, tarball: https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz} engines: {node: '>=12'} @@ -1907,6 +1936,9 @@ packages: resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==, tarball: https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz} engines: {node: '>=8.6'} + entities@2.2.0: + resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==, tarball: https://registry.npmjs.org/entities/-/entities-2.2.0.tgz} + entities@7.0.1: resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==, tarball: https://registry.npmjs.org/entities/-/entities-7.0.1.tgz} engines: {node: '>=0.12'} @@ -2084,6 +2116,10 @@ packages: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==, tarball: https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz} engines: {node: '>=10'} + find-up@6.3.0: + resolution: {integrity: sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==, tarball: https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + flat@5.0.2: resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==, tarball: https://registry.npmjs.org/flat/-/flat-5.0.2.tgz} hasBin: true @@ -2546,6 +2582,10 @@ packages: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==, tarball: https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz} engines: {node: '>=10'} + locate-path@7.2.0: + resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==, tarball: https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + lodash.includes@4.3.0: resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==, tarball: https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz} @@ -2779,6 +2819,9 @@ packages: encoding: optional: true + node-html-parser@5.3.3: + resolution: {integrity: sha512-ncg1033CaX9UexbyA7e1N0aAoAYRDiV8jkTvzEnfd1GDvzFdrsXLzR4p4ik8mwLgnaKP/jyUFWDy9q3jvRT2Jw==, tarball: https://registry.npmjs.org/node-html-parser/-/node-html-parser-5.3.3.tgz} + node-releases@2.0.53: resolution: {integrity: sha512-D9UOmYG3UH1V+ENW56t5QXBwJw1YEY18ruVeus89Rw+SyIgjPkCO84bRzO3uNIYosJbNwiabWVn48o3uJLjxFQ==, tarball: https://registry.npmjs.org/node-releases/-/node-releases-2.0.53.tgz} engines: {node: '>=18'} @@ -2808,6 +2851,9 @@ packages: resolution: {integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==, tarball: https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz} deprecated: This package is no longer supported. + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==, tarball: https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz} + object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==, tarball: https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz} engines: {node: '>=0.10.0'} @@ -2846,10 +2892,18 @@ packages: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==, tarball: https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz} engines: {node: '>=10'} + p-limit@4.0.0: + resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==, tarball: https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + p-locate@5.0.0: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==, tarball: https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz} engines: {node: '>=10'} + p-locate@6.0.0: + resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==, tarball: https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + p-map@4.0.0: resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==, tarball: https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz} engines: {node: '>=10'} @@ -2881,6 +2935,10 @@ packages: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==, tarball: https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz} engines: {node: '>=8'} + path-exists@5.0.0: + resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==, tarball: https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + path-is-absolute@1.0.1: resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==, tarball: https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz} engines: {node: '>=0.10.0'} @@ -3720,6 +3778,10 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==, tarball: https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz} engines: {node: '>=10'} + yocto-queue@1.2.2: + resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==, tarball: https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.2.tgz} + engines: {node: '>=12.20'} + yup@1.6.1: resolution: {integrity: sha512-JED8pB50qbA4FOkDol0bYF/p60qSEDQqBD0/qeIrUCG1KbPBIQ776fCUNb9ldbPcSTxA69g/47XTo4TqWiuXOA==, tarball: https://registry.npmjs.org/yup/-/yup-1.6.1.tgz} @@ -4098,6 +4160,15 @@ snapshots: tunnel-agent: 0.6.0 uuid: 8.3.2 + '@cypress/vite-dev-server@5.2.1': + dependencies: + debug: 4.4.3(supports-color@8.1.1) + find-up: 6.3.0 + node-html-parser: 5.3.3 + semver: 7.8.5 + transitivePeerDependencies: + - supports-color + '@cypress/xvfb@1.2.4(supports-color@8.1.1)': dependencies: debug: 3.2.7(supports-color@8.1.1) @@ -4881,6 +4952,8 @@ snapshots: transitivePeerDependencies: - supports-color + boolbase@1.0.0: {} + brace-expansion@1.1.18: dependencies: balanced-match: 1.0.2 @@ -5125,6 +5198,16 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 + css-select@4.3.0: + dependencies: + boolbase: 1.0.0 + css-what: 6.2.2 + domhandler: 4.3.1 + domutils: 2.8.0 + nth-check: 2.1.1 + + css-what@6.2.2: {} + csstype@3.2.3: {} cypress@13.17.0: @@ -5328,6 +5411,24 @@ snapshots: diff@7.0.0: {} + dom-serializer@1.4.1: + dependencies: + domelementtype: 2.3.0 + domhandler: 4.3.1 + entities: 2.2.0 + + domelementtype@2.3.0: {} + + domhandler@4.3.1: + dependencies: + domelementtype: 2.3.0 + + domutils@2.8.0: + dependencies: + dom-serializer: 1.4.1 + domelementtype: 2.3.0 + domhandler: 4.3.1 + dotenv@16.6.1: {} dunder-proto@1.0.1: @@ -5377,6 +5478,8 @@ snapshots: ansi-colors: 4.1.3 strip-ansi: 6.0.1 + entities@2.2.0: {} + entities@7.0.1: {} env-paths@2.2.1: {} @@ -5682,6 +5785,11 @@ snapshots: locate-path: 6.0.0 path-exists: 4.0.0 + find-up@6.3.0: + dependencies: + locate-path: 7.2.0 + path-exists: 5.0.0 + flat@5.0.2: {} follow-redirects@1.16.0(debug@4.4.3): @@ -6141,6 +6249,10 @@ snapshots: dependencies: p-locate: 5.0.0 + locate-path@7.2.0: + dependencies: + p-locate: 6.0.0 + lodash.includes@4.3.0: {} lodash.isboolean@3.0.3: {} @@ -6360,6 +6472,11 @@ snapshots: dependencies: whatwg-url: 5.0.0 + node-html-parser@5.3.3: + dependencies: + css-select: 4.3.0 + he: 1.2.0 + node-releases@2.0.53: {} node-source-walk@7.0.2: @@ -6389,6 +6506,10 @@ snapshots: gauge: 3.0.2 set-blocking: 2.0.0 + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + object-assign@4.1.1: {} object-inspect@1.13.4: {} @@ -6427,10 +6548,18 @@ snapshots: dependencies: yocto-queue: 0.1.0 + p-limit@4.0.0: + dependencies: + yocto-queue: 1.2.2 + p-locate@5.0.0: dependencies: p-limit: 3.1.0 + p-locate@6.0.0: + dependencies: + p-limit: 4.0.0 + p-map@4.0.0: dependencies: aggregate-error: 3.1.0 @@ -6462,6 +6591,8 @@ snapshots: path-exists@4.0.0: {} + path-exists@5.0.0: {} + path-is-absolute@1.0.1: {} path-key@3.1.1: {} @@ -7340,6 +7471,8 @@ snapshots: yocto-queue@0.1.0: {} + yocto-queue@1.2.2: {} + yup@1.6.1: dependencies: property-expr: 2.0.6