diff --git a/.github/workflows/workflow-continuous-integration.yml b/.github/workflows/workflow-continuous-integration.yml
index dbf580958..905206535 100644
--- a/.github/workflows/workflow-continuous-integration.yml
+++ b/.github/workflows/workflow-continuous-integration.yml
@@ -124,6 +124,30 @@ jobs:
NAMESPACE: ${{ needs.expose-vars.outputs.NAMESPACE }}
TAG: pr-${{ github.event.pull_request.number || github.event.number }}
+ playwright-tests:
+ uses: ./.github/workflows/job-playwright.yml
+ if: ${{ needs.path-filter.outputs.apps == 'true' || needs.path-filter.outputs.packages == 'true' || needs.path-filter.outputs.ci == 'true' || needs.path-filter.outputs.e2e == 'true' }}
+ needs:
+ - path-filter
+ - expose-vars
+ - build
+ with:
+ NODE_VERSION: ${{ needs.expose-vars.outputs.NODE_VERSION }}
+ TAG: pr-${{ github.event.pull_request.number || github.event.number }}
+
+ cypress-tests:
+ uses: ./.github/workflows/job-tests-e2e.yml
+ if: ${{ needs.path-filter.outputs.apps == 'true' || needs.path-filter.outputs.packages == 'true' || needs.path-filter.outputs.ci == 'true' || needs.path-filter.outputs.e2e == 'true' }}
+ needs:
+ - playwright-tests
+ - path-filter
+ - expose-vars
+ - build
+ with:
+ NODE_VERSION: ${{ needs.expose-vars.outputs.NODE_VERSION }}
+ TAG: pr-${{ github.event.pull_request.number || github.event.number }}
+ BROWSERS: "${{ github.base_ref == 'main' && 'chrome,firefox' || 'firefox' }}"
+
# Workaround for required status check in protection branches (see. https://github.com/orgs/community/discussions/13690)
all-jobs-passed:
name: Check jobs status
@@ -135,6 +159,8 @@ jobs:
- lint
- unit-tests
- build
+ - playwright-tests
+ - cypress-tests
- scan-vuln
steps:
- name: Check status of all required jobs
diff --git a/apps/client/cypress.config.ts b/apps/client/cypress.config.ts
deleted file mode 100644
index 882cc0c35..000000000
--- a/apps/client/cypress.config.ts
+++ /dev/null
@@ -1,80 +0,0 @@
-import path from 'node:path'
-import { defineConfig } from 'cypress'
-import vitePreprocessor from 'cypress-vite'
-import viteConfig from './vite.config.js'
-
-const argocdUrl = process.env.ARGOCD_URL ?? 'https://argo-cd.readthedocs.io'
-const gitlabUrl = process.env.GITLAB_URL ?? 'https://gitlab.com'
-const harborUrl = process.env.HARBOR_URL ?? 'https://goharbor.io'
-const nexusUrl = process.env.NEXUS_URL ?? 'https://sonatype.com/products/nexus-repository'
-const sonarqubeUrl = process.env.SONARQUBE_URL ?? 'https://www.sonarqube.org'
-const vaultUrl = process.env.VAULT_URL ?? 'https://www.vaultproject.io'
-const clientHost = process.env.CLIENT_HOST ?? 'localhost'
-const clientPort = process.env.CLIENT_PORT ?? '8080'
-
-if (viteConfig.server) {
- viteConfig.server.host = '127.0.0.1'
- viteConfig.server.port = 9000
-}
-
-export default defineConfig({
- e2e: {
- setupNodeEvents(on, config) {
- on('file:preprocessor', vitePreprocessor({
- configFile: path.resolve('./vite.config.ts'),
- mode: 'development',
- }))
- on('before:browser:launch', (browser, launchOptions) => {
- if (browser.family === 'chromium') {
- launchOptions.args.push('--disable-background-networking')
- launchOptions.args.push('--disable-service-worker')
- launchOptions.args.push('--disable-extensions')
- launchOptions.args.push('--disable-sync')
- }
- if (browser.family === 'firefox') {
- launchOptions.preferences['network.proxy.testing_localhost_is_secure_when_hijacked'] = true
- launchOptions.preferences['dom.serviceWorkers.enabled'] = false
- }
- return launchOptions
- })
- return config
- },
- viewportHeight: 1024,
- viewportWidth: 1280,
- baseUrl: `http://${clientHost}:${clientPort}`,
- fixturesFolder: 'cypress/e2e/fixtures',
- specPattern: 'cypress/e2e/specs/**/*.{cy,e2e}.{j,t}s',
- supportFile: 'cypress/e2e/support/index.ts',
- video: false,
- screenshotsFolder: 'cypress/e2e/screenshots',
- numTestsKeptInMemory: 2,
- chromeWebSecurity: false,
- experimentalModifyObstructiveThirdPartyCode: true,
- experimentalCspAllowList: true,
- experimentalWebKitSupport: false,
- env: {
- argocdUrl,
- gitlabUrl,
- nexusUrl,
- harborUrl,
- sonarqubeUrl,
- vaultUrl,
- clientHost,
- clientPort,
- },
- },
-
- component: {
- specPattern: 'cypress/components/specs/**/*.{cy,ct}.{j,t}s',
- supportFile: 'cypress/components/support/index.ts',
- indexHtmlFile: 'cypress/components/support/component-index.html',
- video: false,
- screenshotsFolder: 'cypress/components/screenshots',
- numTestsKeptInMemory: 1,
- devServer: {
- framework: 'vue',
- bundler: 'vite',
- viteConfig,
- },
- },
-})
diff --git a/apps/client/cypress/components/specs/choice-selector.ct.ts b/apps/client/cypress/components/specs/choice-selector.ct.ts
deleted file mode 100644
index 5fbebf7cd..000000000
--- a/apps/client/cypress/components/specs/choice-selector.ct.ts
+++ /dev/null
@@ -1,150 +0,0 @@
-import ChoiceSelector from '@/components/ChoiceSelector.vue'
-import '@gouvfr/dsfr/dist/dsfr.min.css'
-import '@gouvfr/dsfr/dist/utility/icons/icons.min.css'
-import '@gouvfr/dsfr/dist/utility/utility.main.min.css'
-import '@gouvminint/vue-dsfr/styles'
-import '@/main.css'
-
-describe('ChoiceSelector.vue', () => {
- const options = [
- { id: '1', name: 'Option 1' },
- { id: '2', name: 'Option 2' },
- { id: '3', name: 'Option 3' },
- { id: '4', name: 'Option 4' },
- { id: '5', name: 'Option 5' },
- { id: '6', name: 'Option 6' },
- { id: '7', name: 'Option 7' },
- ]
-
- const selectedOptions = [
- { id: '1', name: 'Option 1' },
- ]
-
- beforeEach(() => {
- cy.mount(ChoiceSelector, {
- props: {
- options,
- optionsSelected: selectedOptions,
- label: 'Test Title',
- description: 'Test Description',
- disabled: false,
- id: 'test-multi-select',
- valueKey: 'id',
- labelKey: 'name',
- wrapped: false,
- },
- })
- })
-
- it('Should mount and display correctly', () => {
- cy.get('[data-testid="choice-selector-title-test-multi-select"]').should('exist').and('contain', 'Test Title')
- cy.get('[data-testid="choice-selector-description-test-multi-select"]').should('exist').and('contain', 'Test Description')
- })
-
- it('Should display options correctly', () => {
- cy.get('[data-testid="1-test-multi-select-tag"]').should('exist').and('contain', 'Option 1')
- cy.get('[data-testid="2-test-multi-select-tag"]').should('exist').and('contain', 'Option 2')
- cy.get('[data-testid="3-test-multi-select-tag"]').should('exist').and('contain', 'Option 3')
- })
-
- it('Should search and filter options', () => {
- cy.get('[data-testid="choice-selector-search-test-multi-select"]').type('Option 2')
- cy.get('[data-testid="2-test-multi-select-tag"]').should('be.visible')
- cy.get('[data-testid="1-test-multi-select-tag"]').should('not.exist')
- cy.get('[data-testid="3-test-multi-select-tag"]').should('not.exist')
- })
-
- it('Should add and remove options', () => {
- cy.get('[data-testid="2-test-multi-select-tag"]').click()
- cy.get('[data-testid="2-test-multi-select-tag"]').should('have.class', 'fr-tag--dismiss')
- cy.get('[data-testid="1-test-multi-select-tag"]').click()
- cy.get('[data-testid="1-test-multi-select-tag"]').should('not.have.class', 'fr-tag--dismiss')
- })
-
- it('Should handle add all and remove all', () => {
- cy.get('[data-testid="choice-selector-add-all-test-multi-select"]').click()
- cy.get('[data-testid="1-test-multi-select-tag"]').should('have.class', 'fr-tag--dismiss')
- cy.get('[data-testid="2-test-multi-select-tag"]').should('have.class', 'fr-tag--dismiss')
- cy.get('[data-testid="3-test-multi-select-tag"]').should('have.class', 'fr-tag--dismiss')
-
- cy.get('[data-testid="choice-selector-remove-all-test-multi-select"]').click()
- cy.get('[data-testid="1-test-multi-select-tag"]').should('not.have.class', 'fr-tag--dismiss')
- cy.get('[data-testid="2-test-multi-select-tag"]').should('not.have.class', 'fr-tag--dismiss')
- cy.get('[data-testid="3-test-multi-select-tag"]').should('not.have.class', 'fr-tag--dismiss')
- })
-
- it('Should handle add visible and remove visible', () => {
- cy.get('[data-testid="choice-selector-search-test-multi-select"]').type('Option 2')
- cy.get('[data-testid="choice-selector-add-visible-test-multi-select"]').click()
- cy.get('[data-testid="2-test-multi-select-tag"]').should('have.class', 'fr-tag--dismiss')
-
- cy.get('[data-testid="choice-selector-search-test-multi-select"]').clear()
- cy.get('[data-testid="choice-selector-remove-visible-test-multi-select"]').click()
- cy.get('[data-testid="1-test-multi-select-tag"]').should('not.have.class', 'fr-tag--dismiss')
- cy.get('[data-testid="2-test-multi-select-tag"]').should('not.have.class', 'fr-tag--dismiss')
- cy.get('[data-testid="3-test-multi-select-tag"]').should('not.have.class', 'fr-tag--dismiss')
- })
-
- it('Should display correct message when no options available', () => {
- // Remount the component with no options
- cy.mount(ChoiceSelector, {
- props: {
- options: [],
- optionsSelected: [],
- label: 'Test Title',
- description: 'Test Description',
- disabled: false,
- id: 'test-multi-select',
- valueKey: 'id',
- labelKey: 'name',
- wrapped: false,
- },
- })
-
- cy.contains('Aucun choix disponible').should('be.visible')
- })
-
- it('Should display correct wrapped message when no selected options', () => {
- // Remount the component with no selected options
- cy.mount(ChoiceSelector, {
- props: {
- options,
- optionsSelected: [],
- label: 'Test Title',
- description: 'Test Description',
- disabled: false,
- id: 'test-multi-select',
- valueKey: 'id',
- labelKey: 'name',
- wrapped: true,
- },
- })
-
- cy.contains('Aucune sélection, 7 choix disponibles').should('be.visible')
- })
- it('Should display correct wrapped message when more than 3 selected options', () => {
- // Remount the component with no selected options
- const options = [
- { id: '1', name: 'Option 1' },
- { id: '2', name: 'Option 2' },
- { id: '3', name: 'Option 3' },
- { id: '4', name: 'Option 4' },
- { id: '5', name: 'Option 5' },
- ]
- cy.mount(ChoiceSelector, {
- props: {
- options,
- optionsSelected: options,
- label: 'Test Title',
- description: 'Test Description',
- disabled: false,
- id: 'test-multi-select',
- valueKey: 'id',
- labelKey: 'name',
- wrapped: true,
- },
- })
-
- cy.contains('et 2 de +').should('be.visible')
- })
-})
diff --git a/apps/client/cypress/components/specs/cluster-form.ct.ts b/apps/client/cypress/components/specs/cluster-form.ct.ts
deleted file mode 100644
index c85034f54..000000000
--- a/apps/client/cypress/components/specs/cluster-form.ct.ts
+++ /dev/null
@@ -1,192 +0,0 @@
-import type { Pinia } from 'pinia'
-import type { ComponentCustomProps } from 'vue'
-import { ClusterPrivacy, deleteValidationInput } from '@cpn-console/shared'
-import { getRandomCluster, getRandomEnv, getRandomStage, getRandomZone, repeatFn } from '@cpn-console/test-utils'
-
-import { faker } from '@faker-js/faker'
-import { createPinia, setActivePinia } from 'pinia'
-import ClusterForm from '@/components/ClusterForm.vue'
-import { useSnackbarStore } from '@/stores/snackbar.js'
-import '@gouvfr/dsfr/dist/dsfr.min.css'
-
-import '@gouvfr/dsfr/dist/utility/icons/icons.min.css'
-import '@gouvfr/dsfr/dist/utility/utility.main.min.css'
-import '@gouvminint/vue-dsfr/styles'
-import '@/main.css'
-
-describe('ClusterForm.vue', () => {
- let pinia: Pinia
-
- beforeEach(() => {
- pinia = createPinia()
-
- setActivePinia(pinia)
- })
-
- it('Should mount a new cluster ClusterForm', () => {
- useSnackbarStore()
-
- const allProjects = repeatFn(5)(() => { return { id: faker.string.uuid(), label: faker.lorem.word() } })
- const allStages = repeatFn(4)(getRandomStage)
- const allZones = repeatFn(3)(getRandomZone)
-
- const props = {
- allProjects,
- allStages,
- allZones,
- associatedEnvironments: [],
- }
-
- cy.mount(ClusterForm, { props } as ComponentCustomProps)
- cy.getByDataTestid('tlsServerNameInput')
- .type('tlsServerName')
- cy.getByDataTestid('labelInput')
- .type('label')
- cy.get('#privacy-select')
- .select(ClusterPrivacy.DEDICATED)
- cy.get('#zone-select')
- .select(1)
- cy.get('#projects-select')
- .click()
- cy.getByDataTestid(`${allProjects[0].id}-projects-select-tag`)
- .click()
- cy.get('#stages-select')
- .click()
- cy.getByDataTestid(`${allStages[1].id}-stages-select-tag`)
- .click()
- cy.getByDataTestid('addClusterBtn').should('be.enabled')
- cy.getByDataTestid('associatedEnvironmentsZone').should('not.exist')
- cy.getByDataTestid('deleteClusterZone').should('not.exist')
- })
-
- it('Should mount an update cluster ClusterForm', () => {
- useSnackbarStore()
- const allProjects = repeatFn(5)(() => { return { id: faker.string.uuid(), label: faker.lorem.word() } })
- const allStages = repeatFn(2)(getRandomStage)
- const allZones = repeatFn(1)(getRandomZone)
-
- const props = {
- cluster: getRandomCluster({ projectIds: [allProjects[0].id], stageIds: [allStages[1].id], privacy: ClusterPrivacy.DEDICATED, zoneId: allZones[0].id }),
- allProjects,
- allStages,
- allZones,
- isNewCluster: false,
- associatedEnvironments: [],
- }
-
- cy.mount(ClusterForm, { props } as ComponentCustomProps)
-
- cy.getByDataTestid('user-json').should('be.visible')
- cy.getByDataTestid('cluster-json').should('be.visible')
- cy.getByDataTestid('tlsServerNameInput')
- .should('have.value', props.cluster.kubeconfig.cluster.tlsServerName)
- .and('be.enabled')
- cy.getByDataTestid('labelInput')
- .should('have.value', props.cluster.label)
- .and('be.enabled')
- cy.getByDataTestid('infosInput')
- .should('have.value', props.cluster.infos)
- .and('be.enabled')
- cy.get('#privacy-select')
- .should('have.value', props.cluster.privacy)
- cy.get('#zone-select')
- .should('have.value', props.cluster.zoneId)
- .and('be.enabled')
- cy.get('#projects-select')
- .click()
- cy.get('#projects-select .fr-tag--dismiss')
- .should('have.length', props.cluster.projectIds?.length)
- cy.get('#stages-select')
- .click()
- cy.get('#stages-select .fr-tag--dismiss')
- .should('have.length', props.cluster.stageIds?.length)
- cy.getByDataTestid('memoryInput')
- .should('have.value', props.cluster.memory)
- cy.getByDataTestid('cpuInput')
- .should('have.value', props.cluster.cpu)
- cy.getByDataTestid('gpuInput')
- .should('have.value', props.cluster.gpu)
- cy.getByDataTestid('updateClusterBtn').should('be.enabled')
- cy.getByDataTestid('associatedEnvironmentsZone').should('not.exist')
- cy.getByDataTestid('deleteClusterZone').should('exist')
- cy.getByDataTestid('showDeleteClusterBtn').click()
- cy.getByDataTestid('deleteClusterBtn').should('be.disabled')
- cy.getByDataTestid('deleteClusterInput').clear().type(deleteValidationInput)
- cy.getByDataTestid('deleteClusterBtn').should('be.enabled')
- })
-
- it('Should mount an update cluster ClusterForm with associated environments', () => {
- useSnackbarStore()
- const allProjects = repeatFn(5)(() => { return { id: faker.string.uuid(), label: faker.lorem.word() } })
- const allStages = repeatFn(2)(getRandomStage)
- const allZones = repeatFn(2)(getRandomZone)
-
- const cluster = getRandomCluster({ projectIds: [allProjects[0].id], stageIds: [allStages[1].id], privacy: ClusterPrivacy.DEDICATED, zoneId: allZones[0].id })
- const env = getRandomEnv('integ-1', allProjects[0].id, 'qsId', cluster.id)
- const associatedEnvironments = [{ project: allProjects[0].name, name: env.name, owner: 'owner@dso.fr' }]
-
- const props = {
- cluster,
- allProjects,
- allStages,
- allZones,
- isNewCluster: false,
- associatedEnvironments,
- }
-
- cy.mount(ClusterForm, { props } as ComponentCustomProps)
-
- cy.getByDataTestid('user-json').should('be.visible')
- cy.getByDataTestid('cluster-json').should('be.visible')
- cy.getByDataTestid('tlsServerNameInput')
- .should('have.value', props.cluster.kubeconfig.cluster.tlsServerName)
- .and('be.enabled')
- cy.getByDataTestid('labelInput')
- .should('have.value', props.cluster.label)
- .and('be.disabled')
- cy.getByDataTestid('infosInput')
- .should('have.value', props.cluster.infos)
- .and('be.enabled')
- cy.get('#privacy-select')
- .should('have.value', props.cluster.privacy)
- cy.get('#zone-select')
- .should('have.value', props.cluster.zoneId)
- .and('be.enabled')
- cy.get('#projects-select')
- .click()
- cy.get('#projects-select .fr-tag--dismiss')
- .should('have.length', props.cluster.projectIds?.length)
- cy.get('#stages-select')
- .click()
- cy.get('#stages-select .fr-tag--dismiss')
- .should('have.length', props.cluster.stageIds?.length)
- cy.getByDataTestid('memoryInput')
- .should('have.value', props.cluster.memory)
- cy.getByDataTestid('cpuInput')
- .should('have.value', props.cluster.cpu)
- cy.getByDataTestid('gpuInput')
- .should('have.value', props.cluster.gpu)
- cy.getByDataTestid('updateClusterBtn').should('be.enabled')
- cy.getByDataTestid('deleteClusterZone').should('not.exist')
- cy.getByDataTestid('associatedEnvironmentsZone').should('exist')
- })
-
- it('Should disable project selector when privacy is public', () => {
- useSnackbarStore()
-
- const allProjects = repeatFn(5)(() => { return { id: faker.string.uuid(), label: faker.lorem.word() } })
-
- const props = {
- allProjects,
- associatedEnvironments: [],
- }
-
- cy.mount(ClusterForm, { props } as ComponentCustomProps)
- cy.get('#privacy-select')
- .select('dedicated')
- cy.get('#projects-select').should('be.visible')
- cy.get('#privacy-select')
- .select('public')
- cy.get('#projects-select').should('not.to.exist')
- })
-})
diff --git a/apps/client/cypress/components/specs/config-param.ct.ts b/apps/client/cypress/components/specs/config-param.ct.ts
deleted file mode 100644
index 4d96d639a..000000000
--- a/apps/client/cypress/components/specs/config-param.ct.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-import { ref } from 'vue'
-import ConfigParamComponent from '@/components/ConfigParam.vue'
-import '@gouvfr/dsfr/dist/dsfr.min.css'
-import '@gouvfr/dsfr/dist/utility/icons/icons.min.css'
-import '@gouvfr/dsfr/dist/utility/utility.main.min.css'
-import '@gouvminint/vue-dsfr/styles'
-import '@/main.css'
-
-describe('ConfigParamComponent.vue', () => {
- it('Affiche correctement le composant avec un champ de texte', () => {
- const props = {
- options: {
- value: ref('test'),
- description: 'Description test',
- name: 'Test Input',
- disabled: false,
- kind: 'text',
- placeholder: 'Placeholder test',
- },
- }
-
- cy.mount(ConfigParamComponent, { props })
-
- cy.contains('Test Input')
- cy.contains('Description test')
- cy.get('[data-testid="input"]').should('have.attr', 'placeholder', 'Placeholder test')
- })
-
- it('Affiche correctement le composant avec un bouton de commutation', () => {
- const props = {
- options: {
- value: ref('enabled'),
- description: 'Description test',
- name: 'Test Switch',
- disabled: false,
- kind: 'switch',
- },
- }
-
- cy.mount(ConfigParamComponent, { props })
-
- cy.contains('Test Switch')
- cy.contains('Description test')
- cy.get('[data-testid="switch"]').within(() => {
- cy.get('input')
- .should('have.length', 3) // Vérifie qu'il y a trois boutons de commutation
- })
- })
-
- it('Modifie correctement la valeur du composant', () => {
- const props = {
- options: {
- value: ref('enabled'),
- name: 'Test Switch',
- disabled: false,
- kind: 'switch',
- },
- }
-
- cy.mount(ConfigParamComponent, { props })
-
- // Vérifie que la valeur a été modifiée
- cy.get('[data-testid="switch"]').within(() => {
- cy.get('.fr-segmented__element').eq(1).click() // Sélectionne le bouton de commutation "Défaut"
- cy.get('input').eq(1).should('be.checked')
- })
- })
-})
diff --git a/apps/client/cypress/components/specs/pagination-ct.ct.ts b/apps/client/cypress/components/specs/pagination-ct.ct.ts
deleted file mode 100644
index ecea3e5b2..000000000
--- a/apps/client/cypress/components/specs/pagination-ct.ct.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-import PaginationCt from '@/components/PaginationCt.vue'
-import '@gouvfr/dsfr/dist/dsfr.min.css'
-import '@gouvfr/dsfr/dist/utility/icons/icons.min.css'
-import '@gouvfr/dsfr/dist/utility/utility.main.min.css'
-import '@gouvminint/vue-dsfr/styles'
-import '@/main.css'
-
-describe('PaginationCt.vue', () => {
- it('Should mount a PaginationCt, first page', () => {
- const props = {
- length: 15,
- step: 2,
- page: 0,
- }
-
- cy.mount(PaginationCt, { props })
- cy.getByDataTestid('positionInfo').should('contain', `1 - 2 sur ${props.length}`)
- cy.getByDataTestid('seeFirstPageBtn').should('be.disabled')
- cy.getByDataTestid('seePreviousPageBtn').should('be.disabled')
- cy.getByDataTestid('seeNextPageBtn').should('be.enabled')
- cy.getByDataTestid('seeLastPageBtn').should('be.enabled')
- })
-
- it('Should mount a PaginationCt, page 1', () => {
- const props = {
- length: 20,
- step: 5,
- page: 1,
- }
-
- cy.mount(PaginationCt, { props })
- cy.getByDataTestid('positionInfo').should('contain', `6 - 10 sur ${props.length}`)
- cy.getByDataTestid('seeFirstPageBtn').should('be.enabled')
- cy.getByDataTestid('seePreviousPageBtn').should('be.enabled')
- cy.getByDataTestid('seeNextPageBtn').should('be.enabled')
- cy.getByDataTestid('seeLastPageBtn').should('be.enabled')
- })
-
- it('Should mount a PaginationCt, last page', () => {
- const props = {
- length: 43,
- step: 10,
- page: 4,
- }
-
- cy.mount(PaginationCt, { props })
- cy.getByDataTestid('positionInfo').should('contain', `41 - 43 sur ${props.length}`)
- cy.getByDataTestid('seeFirstPageBtn').should('be.enabled')
- cy.getByDataTestid('seePreviousPageBtn').should('be.enabled')
- cy.getByDataTestid('seeNextPageBtn').should('be.disabled')
- cy.getByDataTestid('seeLastPageBtn').should('be.disabled')
- })
-})
diff --git a/apps/client/cypress/components/specs/project-settings.ct.ts b/apps/client/cypress/components/specs/project-settings.ct.ts
deleted file mode 100644
index ec8ddb5dd..000000000
--- a/apps/client/cypress/components/specs/project-settings.ct.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import type { ComponentCustomProps } from 'vue'
-import { createRandomDbSetup } from '@cpn-console/test-utils'
-import ProjectSettings from '@/components/ProjectSettings.vue'
-import '@gouvminint/vue-dsfr/styles'
-import '@gouvfr/dsfr/dist/dsfr.min.css'
-import '@gouvfr/dsfr/dist/utility/icons/icons.min.css'
-import '@gouvfr/dsfr/dist/utility/utility.main.min.css'
-import '@/main.css'
-
-describe('ProjectSettings.vue', () => {
- it('Should mount a ProjectSettings', () => {
- const randomDbSetup = createRandomDbSetup({})
-
- const props = {
- project: randomDbSetup.project,
- }
-
- cy.mount(ProjectSettings, { props } as ComponentCustomProps)
-
- cy.getByDataTestid('limitlessProjectSwitch')
- .should('be.visible')
- .and('not.be.checked')
- })
-})
diff --git a/apps/client/cypress/components/specs/repo-form.ct.ts b/apps/client/cypress/components/specs/repo-form.ct.ts
deleted file mode 100644
index 0ef004ee4..000000000
--- a/apps/client/cypress/components/specs/repo-form.ct.ts
+++ /dev/null
@@ -1,327 +0,0 @@
-import type { Pinia } from 'pinia'
-import type { ComponentCustomProps } from 'vue'
-import { fakeToken, missingCredentials } from '@cpn-console/shared'
-import { createRandomDbSetup } from '@cpn-console/test-utils'
-
-import { createPinia, setActivePinia } from 'pinia'
-import RepoForm from '@/components/RepoForm.vue'
-import { useProjectStore } from '@/stores/project.js'
-import '@gouvminint/vue-dsfr/styles'
-import '@gouvfr/dsfr/dist/dsfr.min.css'
-
-import '@gouvfr/dsfr/dist/utility/icons/icons.min.css'
-import '@gouvfr/dsfr/dist/utility/utility.main.min.css'
-import '@/main.css'
-
-describe('RepoForm.vue', () => {
- let pinia: Pinia
-
- beforeEach(() => {
- pinia = createPinia()
-
- setActivePinia(pinia)
- })
-
- it('Should mount a new repo RepoForm', () => {
- const props = {
- canManage: true,
- }
-
- const randomDbSetup = createRandomDbSetup({})
- const projectStore = useProjectStore()
- projectStore.myProjectsBySlug = {
- [randomDbSetup.project.slug]: randomDbSetup.project,
- }
-
- cy.mount(RepoForm, { props } as ComponentCustomProps)
-
- cy.get('h2').should('contain', 'Ajouter un dépôt au projet')
- cy.getByDataTestid('repoFieldset').should('have.length', 1)
- // Case 1 : no Git source
- cy.getByDataTestid('internalRepoNameInput')
- .should('have.value', '')
- .type('candilib')
- cy.getByDataTestid('standaloneRepoSwitch')
- .find('input')
- .check({ force: true })
- cy.getByDataTestid('externalRepoUrlInput').should('not.exist')
- cy.getByDataTestid('input-checkbox-privateRepoCbx').should('not.exist')
- cy.getByDataTestid('externalUserNameInput').should('not.exist')
- cy.getByDataTestid('externalTokenInput').should('not.exist')
- cy.getByDataTestid('input-checkbox-infraRepoCbx')
- .should('not.be.checked')
- .and('be.enabled')
- cy.getByDataTestid('addRepoBtn').should('be.enabled')
- cy.getByDataTestid('cancelRepoBtn').should('be.enabled')
- // Case 2 : no Git source, infra
- cy.getByDataTestid('input-checkbox-infraRepoCbx').check({ force: true })
- cy.getByDataTestid('addRepoBtn').should('be.enabled')
- cy.getByDataTestid('cancelRepoBtn').should('be.enabled')
- // Case 3 : Git source
- cy.getByDataTestid('standaloneRepoSwitch')
- .find('input')
- .uncheck({ force: true })
- cy.getByDataTestid('externalRepoUrlInput')
- .type('https://github.com/LAB-MI/candilibV2.git')
- .blur()
- cy.getByDataTestid('addRepoBtn').should('be.enabled')
- cy.getByDataTestid('cancelRepoBtn').should('be.enabled')
- // Case 4 : Git source, private
- cy.getByDataTestid('input-checkbox-privateRepoCbx')
- .should('exist')
- .and('be.enabled')
- cy.getByDataTestid('input-checkbox-privateRepoCbx').check({ force: true })
- cy.getByDataTestid('externalUserNameInput').should('exist')
- cy.getByDataTestid('externalTokenInput').should('exist')
- cy.getByDataTestid('addRepoBtn').should('be.disabled')
- cy.getByDataTestid('cancelRepoBtn').should('be.enabled')
- cy.getByDataTestid('externalUserNameInput').type('claire+nlet')
- cy.getByDataTestid('externalTokenInput')
- .type('aaaaaa')
- .blur()
- cy.getByDataTestid('addRepoBtn').should('be.enabled')
- cy.getByDataTestid('cancelRepoBtn').should('be.enabled')
- })
-
- it('Should mount an update repo RepoForm', () => {
- const props = {
- repo: {
- id: '83833faf-f654-40dd-bcd5-cf2e944fc504',
- projectId: '83833faf-f654-40dd-bcd5-cf2e944fc500',
- internalRepoName: 'candilib',
- externalRepoUrl: 'https://github.com/LAB-MI/candilibV2.git',
- isPrivate: true,
- isInfra: false,
- externalUserName: 'claire+nlet',
- deployRevision: 'fix/deploy',
- deployPath: 'helm4/',
- helmValuesFiles: 'values/prod.yaml,values/extra.yaml',
- },
- canManage: true,
- }
-
- const randomDbSetup = createRandomDbSetup({})
- const projectStore = useProjectStore()
- projectStore.myProjectsBySlug = {
- [randomDbSetup.project.slug]: randomDbSetup.project,
- }
-
- cy.mount(RepoForm, { props } as ComponentCustomProps)
-
- cy.get('h2').should('contain', 'Modifier le dépôt')
- cy.getByDataTestid('repoFieldset').should('have.length', 1)
- cy.getByDataTestid('internalRepoNameInput').should('have.value', props.repo.internalRepoName)
- .and('be.disabled')
- cy.getByDataTestid('externalRepoUrlInput').should('have.value', props.repo.externalRepoUrl)
- .and('be.enabled')
- cy.getByDataTestid('input-checkbox-privateRepoCbx').should('be.checked')
- .and('be.enabled')
- cy.getByDataTestid('externalUserNameInput').should('have.value', props.repo.externalUserName)
- .and('be.enabled')
- cy.getByDataTestid('externalTokenInput').should('have.value', fakeToken)
- .and('be.enabled')
- cy.getByDataTestid('input-checkbox-infraRepoCbx').should('not.be.checked')
- .and('be.enabled')
- cy.getByDataTestid('standaloneRepoSwitch')
- .find('input')
- .should('not.be.checked')
- .and('be.enabled')
- cy.getByDataTestid('cancelRepoBtn').should('be.enabled')
- cy.getByDataTestid('updateRepoBtn').should('be.enabled')
- cy.getByDataTestid('externalTokenInput')
- .clear()
- .type('aaaaaaa')
- .blur()
- cy.getByDataTestid('updateRepoBtn').should('be.enabled')
-
- // Case 1 privacy handling
- cy.getByDataTestid('input-checkbox-privateRepoCbx')
- .uncheck({ force: true })
- cy.getByDataTestid('input-checkbox-privateRepoCbx').check({ force: true })
- cy.getByDataTestid('externalUserNameInput')
- .should('exist')
- .and('have.value', '')
- cy.getByDataTestid('externalTokenInput')
- .should('exist')
- .and('have.value', '')
- cy.getByDataTestid('updateRepoBtn').should('be.disabled')
- cy.getByDataTestid('cancelRepoBtn').should('be.enabled')
- cy.getByDataTestid('externalUserNameInput').type(props.repo.externalUserName)
- cy.getByDataTestid('externalTokenInput')
- .type('aaaaaa')
- .blur()
- cy.getByDataTestid('updateRepoBtn').should('be.enabled')
- cy.getByDataTestid('cancelRepoBtn').should('be.enabled')
-
- // Case 2 : no Git source
- cy.getByDataTestid('externalRepoUrlInput')
- .clear()
- .should('have.value', '')
- .blur()
- cy.getByDataTestid('standaloneRepoSwitch')
- .find('input')
- .check({ force: true })
- cy.getByDataTestid('input-checkbox-privateRepoCbx')
- .should('not.exist')
- cy.getByDataTestid('externalUserNameInput').should('not.exist')
- cy.getByDataTestid('externalTokenInput').should('not.exist')
- cy.getByDataTestid('input-checkbox-infraRepoCbx')
- .should('not.be.checked')
- .and('be.enabled')
- cy.getByDataTestid('updateRepoBtn').should('be.enabled')
- cy.getByDataTestid('cancelRepoBtn').should('be.enabled')
-
- // Case 3 : no Git source, infra
- cy.getByDataTestid('input-checkbox-infraRepoCbx').check({ force: true })
- cy.getByDataTestid('deployRevisionInput').should('have.value', props.repo.deployRevision)
- .and('be.enabled')
- cy.getByDataTestid('deployPathInput').should('have.value', props.repo.deployPath)
- .and('be.enabled')
- cy.getByDataTestid('helmValuesFilesTextarea').should('have.value', props.repo.helmValuesFiles.split(',').join('\n'))
- .and('be.enabled')
- cy.getByDataTestid('updateRepoBtn').should('be.enabled')
- cy.getByDataTestid('cancelRepoBtn').should('be.enabled')
-
- // Case 4 : Git source
- cy.getByDataTestid('standaloneRepoSwitch')
- .find('input')
- .uncheck({ force: true })
- cy.getByDataTestid('externalRepoUrlInput')
- .type(props.repo.externalRepoUrl)
- .blur()
- cy.getByDataTestid('updateRepoBtn').should('be.enabled')
- cy.getByDataTestid('cancelRepoBtn').should('be.enabled')
- })
-
- it('Should handle token behaviors, create', () => {
- const props = {
- canManage: true,
- }
-
- const randomDbSetup = createRandomDbSetup({})
- const projectStore = useProjectStore()
- projectStore.myProjectsBySlug = {
- [randomDbSetup.project.slug]: randomDbSetup.project,
- }
-
- cy.mount(RepoForm, { props } as ComponentCustomProps)
-
- cy.getByDataTestid('repoFieldset').should('have.length', 1)
- cy.getByDataTestid('internalRepoNameInput')
- .should('have.value', '')
- .type('candilib')
-
- cy.getByDataTestid('externalRepoUrlInput')
- .type('https://github.com/LAB-MI/candilibV2.git')
- .blur()
- cy.getByDataTestid('addRepoBtn').should('be.enabled')
-
- cy.getByDataTestid('input-checkbox-privateRepoCbx').check({ force: true })
- cy.getByDataTestid('addRepoBtn').should('be.disabled')
- cy.getByDataTestid('externalUserNameInput').should('exist')
- cy.getByDataTestid('externalTokenInput')
- .type('aaaaaa')
- .blur()
- cy.getByDataTestid('repo-form').should('not.contain', missingCredentials)
- cy.getByDataTestid('addRepoBtn').should('be.enabled')
- cy.getByDataTestid('externalTokenInput')
- .clear()
- .blur()
- cy.getByDataTestid('repo-form').should('contain', missingCredentials)
- cy.getByDataTestid('addRepoBtn').should('be.disabled')
- })
-
- it('Should handle token behaviors, update public', () => {
- const props = {
- repo: {
- id: '83833faf-f654-40dd-bcd5-cf2e944fc504',
- projectId: '83833faf-f654-40dd-bcd5-cf2e944fc500',
- internalRepoName: 'candilib',
- externalRepoUrl: 'https://github.com/LAB-MI/candilibV2.git',
- isPrivate: false,
- isInfra: false,
- externalUserName: 'claire+nlet',
- },
- canManage: true,
- }
-
- const randomDbSetup = createRandomDbSetup({})
- const projectStore = useProjectStore()
- projectStore.myProjectsBySlug = {
- [randomDbSetup.project.slug]: randomDbSetup.project,
- }
-
- cy.mount(RepoForm, { props } as ComponentCustomProps)
-
- cy.getByDataTestid('repoFieldset').should('have.length', 1)
-
- cy.getByDataTestid('updateRepoBtn').should('be.enabled')
-
- cy.getByDataTestid('input-checkbox-privateRepoCbx').check({ force: true })
- cy.getByDataTestid('updateRepoBtn').should('be.disabled')
- cy.getByDataTestid('externalUserNameInput').should('exist')
- cy.getByDataTestid('externalTokenInput')
- .type('aaaaaa')
- .blur()
- cy.getByDataTestid('repo-form').should('not.contain', missingCredentials)
- cy.getByDataTestid('updateRepoBtn').should('be.enabled')
- cy.getByDataTestid('externalTokenInput')
- .clear()
- .blur()
- cy.getByDataTestid('repo-form').should('contain', missingCredentials)
- cy.getByDataTestid('updateRepoBtn').should('be.disabled')
- })
-
- it('Should handle token behaviors, update private', () => {
- const props = {
- repo: {
- id: '83833faf-f654-40dd-bcd5-cf2e944fc504',
- projectId: '83833faf-f654-40dd-bcd5-cf2e944fc500',
- internalRepoName: 'candilib',
- externalRepoUrl: 'https://github.com/LAB-MI/candilibV2.git',
- isPrivate: true,
- isInfra: false,
- externalUserName: 'claire+nlet',
- },
- canManage: true,
- }
-
- const randomDbSetup = createRandomDbSetup({})
- const projectStore = useProjectStore()
- projectStore.myProjectsBySlug = {
- [randomDbSetup.project.slug]: randomDbSetup.project,
- }
-
- cy.mount(RepoForm, { props } as ComponentCustomProps)
-
- cy.getByDataTestid('repoFieldset').should('have.length', 1)
-
- cy.getByDataTestid('updateRepoBtn').should('be.enabled')
-
- cy.getByDataTestid('input-checkbox-privateRepoCbx').check({ force: true })
- cy.getByDataTestid('updateRepoBtn').should('be.enabled')
- cy.getByDataTestid('externalUserNameInput').should('exist')
- cy.getByDataTestid('externalTokenInput')
- .type('a')
- .blur()
- cy.getByDataTestid('warningSecretChanged')
- .should('be.visible')
- cy.getByDataTestid('repo-form').should('not.contain', missingCredentials)
- cy.getByDataTestid('updateRepoBtn').should('be.enabled')
- cy.getByDataTestid('resetTokenButton')
- .click()
- cy.getByDataTestid('warningSecretChanged')
- .should('not.exist')
- cy.getByDataTestid('repo-form').should('not.contain', missingCredentials)
- cy.getByDataTestid('updateRepoBtn').should('be.enabled')
- // missing creds
- cy.getByDataTestid('externalTokenInput')
- .clear()
- .blur()
- cy.getByDataTestid('externalUserNameInput')
- .clear()
- .blur()
- cy.getByDataTestid('repo-form').should('contain', missingCredentials)
- cy.getByDataTestid('updateRepoBtn').should('be.disabled')
- })
-})
diff --git a/apps/client/cypress/components/specs/services-config.ct.ts b/apps/client/cypress/components/specs/services-config.ct.ts
deleted file mode 100644
index 2e9c8edde..000000000
--- a/apps/client/cypress/components/specs/services-config.ct.ts
+++ /dev/null
@@ -1,114 +0,0 @@
-import type { Pinia } from 'pinia'
-import { faker } from '@faker-js/faker'
-import { createPinia, setActivePinia } from 'pinia'
-import ServicesConfig from '@/components/ServicesConfig.vue'
-import { useProjectStore } from '@/stores/project.js'
-import { useUserStore } from '@/stores/user.js'
-import { Project } from '@/utils/project-utils.js'
-import '@gouvfr/dsfr/dist/dsfr.min.css'
-import '@gouvfr/dsfr/dist/utility/icons/icons.min.css'
-import '@gouvfr/dsfr/dist/utility/utility.main.min.css'
-import '@gouvminint/vue-dsfr/styles'
-import '@/main.css'
-
-process.env.NODE_ENV = 'test'
-process.env.CT = 'true'
-
-const argoto = { to: 'https://argocd.domain.com/applications?showFavorites=false&proj=&sync=&health=&namespace=&cluster=&labels=&search=org-project', name: '' }
-const gitlabto = { to: 'https://gitlab.domain.com/forge-mi/projects/org/project', name: '' }
-const services = [
- { imgSrc: '/img/argocd.svg', title: 'ArgoCD', name: 'argocd', urls: [argoto, argoto, argoto], manifest: {} },
- { imgSrc: '/img/gitlab.svg', title: 'Gitlab', name: 'gitlab', urls: [gitlabto, gitlabto], manifest: {} },
- { imgSrc: '/img/harbor.svg', title: 'Harbor', name: 'registry', urls: [{ to: 'https://harbor.domain.com/harbor/projects/254', name: '' }], manifest: { global: [{ permissions: { admin: { read: true, write: true }, user: { read: true, write: false } }, key: 'publish-ro-robot-by-default', kind: 'switch', title: 'Publier le robot RO par défaut', value: 'default', initialValue: 'disabled' }], project: [{ permissions: { admin: { read: true, write: true }, user: { read: true, write: false } }, key: 'view-robot', kind: 'switch', title: 'Publier le robot', initialValue: 'disabled', value: 'default', description: 'Autoriser un robot de lecture sur le projet' }] } },
- { imgSrc: '/img/sonarqube.svg', title: 'SonarQube', name: 'sonarqube', urls: [], manifest: {} },
-]
-
-const urlsLength = services.reduce((length, service) => length + service.urls.length, 0)
-
-const project = {
- clusterIds: [],
- createdAt: Date.now().toString(),
- updatedAt: Date.now().toString(),
- everyonePerms: '0',
- id: faker.string.uuid(),
- lastSuccessProvisionningVersion: null,
- locked: false,
- members: [],
- name: 'projet-test',
- owner: {
- createdAt: Date.now().toString(),
- updatedAt: Date.now().toString(),
- email: faker.internet.email(),
- firstName: faker.person.firstName(),
- lastName: faker.person.lastName(),
- id: faker.string.uuid(),
- type: 'human' as const,
- lastLogin: null,
- },
- ownerId: faker.string.uuid(),
- roles: [],
- slug: faker.string.alphanumeric(10),
- status: 'created' as const,
-}
-
-describe('Service Configuration Component', () => {
- let pinia: Pinia
-
- beforeEach(() => {
- pinia = createPinia()
-
- setActivePinia(pinia)
- })
- it('Affiche correctement les services et leurs configurations', () => {
- const projectStore = useProjectStore()
- projectStore.projectsBySlug[project.slug] = project
-
- useUserStore()
- const instanceProject = new Project(project)
- cy.intercept('GET', 'api/v1/projects/*/services*', {
- body: services,
- }).as('listServices')
- cy.mount(ServicesConfig, {
- propsData: {
- project: instanceProject,
- permissionTarget: 'user',
- displayGlobal: true,
- },
- })
-
- // Vérifie que les services sont correctement affichés
- cy.getByDataTestid('services-urls').find('a').should('have.length', urlsLength)
-
- cy.getByDataTestid('service-config-registry').should('exist')
-
- // Vérifie que les boutons de lien sont présents et fonctionnent
- cy.getByDataTestid('service-config-registry').click() // Simule un clic sur le premier lien
-
- // Vérifie que les boutons de rechargement sont présents
- cy.getByDataTestid('reloadBtn').should('exist')
- })
-
- it('Interagit correctement avec le bouton de dropdown', () => {
- useProjectStore()
- useUserStore()
- const instanceProject = new Project(project)
- cy.intercept('GET', 'api/v1/projects/*/services*', {
- body: services,
- }).as('listServices')
-
- cy.mount(ServicesConfig, {
- propsData: {
- project: instanceProject,
- permissionTarget: 'user',
- displayGlobal: true,
- },
- })
- // Simule un clic sur le bouton d'extension
- cy.getByDataTestid('service-config-registry')
- .click()
- cy.getByDataTestid('service-project-config-registry')
- .should('exist')
- cy.getByDataTestid('service-project-config-registry')
- .should('exist')
- })
-})
diff --git a/apps/client/cypress/components/specs/stage-form.ct.ts b/apps/client/cypress/components/specs/stage-form.ct.ts
deleted file mode 100644
index a61ffcad9..000000000
--- a/apps/client/cypress/components/specs/stage-form.ct.ts
+++ /dev/null
@@ -1,102 +0,0 @@
-import type { Pinia } from 'pinia'
-import type { ComponentCustomProps } from 'vue'
-import { getRandomCluster, getRandomEnv, getRandomStage } from '@cpn-console/test-utils'
-import { createPinia, setActivePinia } from 'pinia'
-import StageForm from '@/components/StageForm.vue'
-import { useSnackbarStore } from '@/stores/snackbar.js'
-import '@gouvfr/dsfr/dist/dsfr.min.css'
-import '@gouvfr/dsfr/dist/utility/icons/icons.min.css'
-import '@gouvfr/dsfr/dist/utility/utility.main.min.css'
-import '@gouvminint/vue-dsfr/styles'
-import '@/main.css'
-
-describe('StageForm.vue', () => {
- let pinia: Pinia
-
- beforeEach(() => {
- pinia = createPinia()
-
- setActivePinia(pinia)
- })
- it('Should mount a new StageForm', () => {
- useSnackbarStore()
- const allClusters = [getRandomCluster({}), getRandomCluster({})]
-
- const props = {
- isNewStage: true,
- allClusters,
- }
-
- cy.mount(StageForm, { props } as ComponentCustomProps)
- cy.get('h1').invoke('text').should('match', /^Informations du type d'environnement $/)
- cy.getByDataTestid('updateStageBtn').should('not.exist')
- cy.getByDataTestid('addStageBtn').should('be.visible').and('be.disabled')
- cy.getByDataTestid('nameInput')
- .type('integ')
- cy.get('h1').invoke('text').should('match', /^Informations du type d'environnement integ$/)
- cy.getByDataTestid('addStageBtn').should('be.enabled')
- cy.getByDataTestid(`${allClusters[0].id}-clusters-select-tag`)
- .click()
- cy.getByDataTestid(`${allClusters[1].id}-clusters-select-tag`)
- .click()
- cy.getByDataTestid('addStageBtn').should('be.enabled')
- })
-
- it('Should mount an update stage StageForm', () => {
- useSnackbarStore()
- const allClusters = [getRandomCluster({}), getRandomCluster({})]
- // @ts-ignore
- const stageToUpdate = getRandomStage(undefined, { clusters: allClusters })
- const associatedEnvironments = [
- getRandomEnv('env1', 'projectId', 'stageId', allClusters[0].id),
- getRandomEnv('env2', 'projectId', 'stageId', allClusters[1].id),
- ]
-
- const props = {
- stage: stageToUpdate,
- allClusters,
- associatedEnvironments,
- isNewStage: false,
- }
-
- cy.mount(StageForm, { props } as ComponentCustomProps)
- cy.get('h1').invoke('text').should('contain', `Informations du type d'environnement ${stageToUpdate.name}`)
- cy.getByDataTestid('addStageBtn').should('not.exist')
- cy.getByDataTestid('updateStageBtn').should('be.visible').and('be.enabled')
- cy.getByDataTestid('nameInput')
- .should('have.value', stageToUpdate.name)
- .and('be.disabled')
- cy.getByDataTestid(`${allClusters[0].id}-clusters-select-tag`)
- .should('have.class', 'fr-tag--dismiss')
- cy.getByDataTestid('updateStageBtn').should('be.enabled')
- cy.getByDataTestid('associatedEnvironmentsTable').should('exist')
- .find('tbody > tr')
- .should('have.length', associatedEnvironments.length)
- })
-
- it('Should mount an update StageForm without associatedEnvironments', () => {
- useSnackbarStore()
- const allClusters = [getRandomCluster({}), getRandomCluster({})]
- // @ts-ignore
- const stageToUpdate = getRandomStage(undefined, { clusters: [allClusters[0]] })
-
- const props = {
- stage: stageToUpdate,
- allClusters,
- isNewStage: false,
- }
-
- cy.mount(StageForm, { props } as ComponentCustomProps)
- cy.get('h1').invoke('text').should('contain', `Informations du type d'environnement ${stageToUpdate.name}`)
- cy.getByDataTestid('addStageBtn').should('not.exist')
- cy.getByDataTestid('updateStageBtn').should('be.visible').and('be.enabled')
- cy.getByDataTestid('nameInput')
- .should('have.value', stageToUpdate.name)
- .and('be.disabled')
- cy.getByDataTestid(`${allClusters[0].id}-clusters-select-tag`)
- .should('have.class', 'fr-tag--dismiss')
- cy.getByDataTestid('updateStageBtn').should('be.enabled')
- cy.getByDataTestid('associatedEnvironmentsZone').should('not.exist')
- cy.getByDataTestid('deleteStageZone').should('exist')
- })
-})
diff --git a/apps/client/cypress/components/specs/suggestion-input.ct.ts b/apps/client/cypress/components/specs/suggestion-input.ct.ts
deleted file mode 100644
index 9e829c933..000000000
--- a/apps/client/cypress/components/specs/suggestion-input.ct.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import { createRandomDbSetup } from '@cpn-console/test-utils'
-import SuggestionInput from '@/components/SuggestionInput.vue'
-import '@gouvminint/vue-dsfr/styles'
-import '@gouvfr/dsfr/dist/dsfr.min.css'
-import '@gouvfr/dsfr/dist/utility/icons/icons.min.css'
-import '@gouvfr/dsfr/dist/utility/utility.main.min.css'
-import '@/main.css'
-
-describe('SuggestionInput.vue', () => {
- it('Should mount a SuggestionInput', () => {
- const randomDbSetup = createRandomDbSetup({ nbUsers: 5 })
-
- const props = {
- suggestions: randomDbSetup.users.map(user => user.email),
- }
-
- cy.mount(SuggestionInput, { props })
-
- cy.get('input[list="suggestionList"]')
- .should('have.length', 1)
- .and('have.value', '')
- .clear()
- .type(props.suggestions[0].slice(0, 2))
- cy.get('datalist#suggestionList')
- .should('have.length', 1)
- .find('option')
- .should('have.length', props.suggestions.length)
- })
-})
diff --git a/apps/client/cypress/components/specs/team-ct.ct.ts b/apps/client/cypress/components/specs/team-ct.ct.ts
deleted file mode 100644
index 0b092b118..000000000
--- a/apps/client/cypress/components/specs/team-ct.ct.ts
+++ /dev/null
@@ -1,110 +0,0 @@
-import type { ProjectV2 } from '@cpn-console/shared'
-import type { Pinia } from 'pinia'
-import { faker } from '@faker-js/faker'
-import { createPinia, setActivePinia } from 'pinia'
-import TeamCt from '@/components/TeamCt.vue'
-import { useProjectStore } from '@/stores/project.js'
-import { useUserStore } from '@/stores/user.js'
-import { useUsersStore } from '@/stores/users.js'
-import '@gouvminint/vue-dsfr/styles'
-import '@gouvfr/dsfr/dist/dsfr.min.css'
-import '@gouvfr/dsfr/dist/utility/icons/icons.min.css'
-import '@gouvfr/dsfr/dist/utility/utility.main.min.css'
-import '@/main.css'
-
-const ownerId = faker.string.uuid()
-const props: {
- project: ProjectV2
- canManage: boolean
- canTransfer: boolean
-} = {
- project: {
- members: [{
- userId: faker.string.uuid(),
- roleIds: [],
- email: faker.internet.email(),
- }],
- owner: {
- email: faker.internet.email(),
- id: ownerId,
- },
- ownerId,
- roles: [],
- },
- canManage: true,
- canTransfer: true,
-}
-
-describe('TeamCt.vue', () => {
- let pinia: Pinia
-
- beforeEach(() => {
- pinia = createPinia()
-
- setActivePinia(pinia)
- })
-
- it('Should mount a TeamCt for owner', () => {
- useProjectStore()
- useUsersStore()
-
- cy.mount(TeamCt, { props })
-
- cy.getByDataTestid('teamTable').should('be.visible')
- .within(() => {
- cy.get('caption')
- .should('contain', 'Membres du projet')
- cy.get('tbody > tr')
- .should('have.length', props.project.members.length + 1) // +1 cause owner is not a member
- cy.get('thead > tr > th')
- .should('have.length', 4)
- })
- cy.getByDataTestid('showTransferProjectBtn')
- .should('be.enabled')
- .should('be.visible')
- cy.getByDataTestid('addUserSuggestionInput')
- .should('be.enabled')
- .should('be.visible')
- })
- it('Should mount a TeamCt for manage', () => {
- useProjectStore()
- cy.mount(TeamCt, { props: { ...props, canTransfer: false } })
-
- cy.getByDataTestid('teamTable').should('be.visible')
- .within(() => {
- cy.get('caption')
- .should('contain', 'Membres du projet')
- cy.get('tbody > tr')
- .should('have.length', props.project.members.length + 1) // +1 cause owner is not a member
- cy.get('thead > tr > th')
- .should('have.length', 4)
- })
- cy.getByDataTestid('showTransferProjectBtn')
- .should('not.exist')
- cy.getByDataTestid('addUserSuggestionInput')
- .should('be.enabled')
- .should('be.visible')
- })
- it('Should mount a TeamCt for user', () => {
- useProjectStore()
- const userStore = useUserStore()
- // devrait tester que l'on peut toujours quitter un projet
- userStore.userProfile = { id: props.project.members[0].id }
-
- cy.mount(TeamCt, { props: { ...props, canTransfer: false, canManage: false } })
-
- cy.getByDataTestid('teamTable').should('be.visible')
- .within(() => {
- cy.get('caption')
- .should('contain', 'Membres du projet')
- cy.get('tbody > tr')
- .should('have.length', props.project.members.length + 1) // +1 cause owner is not a member
- cy.get('thead > tr > th')
- .should('have.length', 4)
- })
- cy.getByDataTestid('showTransferProjectBtn')
- .should('not.exist')
- cy.getByDataTestid('addUserSuggestionInput')
- .should('not.exist')
- })
-})
diff --git a/apps/client/cypress/components/specs/token-form.ct.ts b/apps/client/cypress/components/specs/token-form.ct.ts
deleted file mode 100644
index 7c7737766..000000000
--- a/apps/client/cypress/components/specs/token-form.ct.ts
+++ /dev/null
@@ -1,72 +0,0 @@
-import type { Pinia } from 'pinia'
-import { createPinia, setActivePinia } from 'pinia'
-
-import TokenForm from '@/components/TokenForm.vue'
-import { useSnackbarStore } from '@/stores/snackbar.js'
-import '@gouvfr/dsfr/dist/dsfr.min.css'
-import '@gouvfr/dsfr/dist/utility/icons/icons.min.css'
-import '@gouvfr/dsfr/dist/utility/utility.main.min.css'
-
-import '@gouvminint/vue-dsfr/styles'
-import '@/main.css'
-
-describe('TokenForm.vue', () => {
- let pinia: Pinia
-
- beforeEach(() => {
- pinia = createPinia()
-
- setActivePinia(pinia)
- })
-
- it('Should mount a TokenForm', () => {
- useSnackbarStore()
- // @ts-ignore
- cy.mount(TokenForm, { props: {
- exposedToken: undefined,
- } })
-
- cy.getByDataTestid('saveBtn')
- .should('be.disabled')
-
- cy.getByDataTestid('newTokenName')
- .type('test')
-
- cy.getByDataTestid('saveBtn')
- .should('be.enabled')
- .click()
- })
-
- it('Should mount a TokenForm', () => {
- const password = 'dfvbjfdbvjkdbvdfb'
-
- useSnackbarStore()
- // @ts-ignore
- cy.mount(TokenForm, { props: {
- exposedToken: password,
- } })
-
- cy.getByDataTestid('newTokenPassword')
- .get('input')
- .should('be.visible')
- .should('contain.value', password)
- .should('have.attr', 'type', 'password')
-
- cy.getByDataTestid('showNewTokenPassword')
- .click()
-
- cy.getByDataTestid('newTokenPassword')
- .get('input')
- .should('have.attr', 'type', 'text')
-
- cy.getByDataTestid('showNewTokenPassword')
- .click()
-
- cy.getByDataTestid('newTokenPassword')
- .get('input')
- .should('have.attr', 'type', 'password')
-
- cy.getByDataTestid('showNewTokenFormBtn')
- .click()
- })
-})
diff --git a/apps/client/cypress/components/specs/zone-form.ct.ts b/apps/client/cypress/components/specs/zone-form.ct.ts
deleted file mode 100644
index 2b44e51c0..000000000
--- a/apps/client/cypress/components/specs/zone-form.ct.ts
+++ /dev/null
@@ -1,125 +0,0 @@
-import type { Pinia } from 'pinia'
-import { getRandomCluster, getRandomZone } from '@cpn-console/test-utils'
-
-import { createPinia, setActivePinia } from 'pinia'
-import ZoneForm from '@/components/ZoneForm.vue'
-import { useSnackbarStore } from '@/stores/snackbar.js'
-import '@gouvfr/dsfr/dist/dsfr.min.css'
-import '@gouvfr/dsfr/dist/utility/icons/icons.min.css'
-
-import '@gouvfr/dsfr/dist/utility/utility.main.min.css'
-import '@gouvminint/vue-dsfr/styles'
-import '@/main.css'
-
-describe('ZoneForm.vue', () => {
- let pinia: Pinia
-
- beforeEach(() => {
- pinia = createPinia()
-
- setActivePinia(pinia)
- })
-
- it('Should mount a new zone ZoneForm', () => {
- useSnackbarStore()
-
- const props = {
- associatedClusters: [],
- isNewZone: true,
- allClusters: [getRandomCluster({})],
- }
-
- cy.mount(ZoneForm, { props })
-
- cy.getByDataTestid('addZoneBtn').should('be.disabled')
- cy.getByDataTestid('deleteZoneZone').should('not.exist')
- cy.getByDataTestid('slugInput')
- .clear()
- .type('zad')
- cy.getByDataTestid('labelInput')
- .clear()
- .type('Zone à Défendre')
- cy.getByDataTestid('argocdUrlInput')
- .clear()
- .type('https://vousetesici.fr')
- cy.getByDataTestid('addZoneBtn').should('be.enabled')
- cy.getByDataTestid('descriptionInput')
- .clear()
- .type('Cette zone de déploiement est publique.')
- cy.getByDataTestid('addZoneBtn').should('be.enabled')
- })
-
- it('Should mount a new zone ZoneForm without clusters', () => {
- useSnackbarStore()
-
- const props = {
- associatedClusters: [],
- isNewZone: true,
- allClusters: [],
- }
-
- cy.mount(ZoneForm, { props })
-
- cy.getByDataTestid('addZoneBtn').should('be.disabled')
- cy.getByDataTestid('deleteZoneZone').should('not.exist')
- cy.getByDataTestid('slugInput')
- .clear()
- .type('zad')
- cy.getByDataTestid('labelInput')
- .clear()
- .type('Zone à Défendre')
- cy.getByDataTestid('argocdUrlInput')
- .clear()
- .type('https://vousetesici.fr')
- cy.getByDataTestid('addZoneBtn').should('be.enabled')
- cy.getByDataTestid('descriptionInput')
- .clear()
- .type('Cette zone de déploiement est publique.')
- cy.getByDataTestid('addZoneBtn').should('be.enabled')
- })
-
- it('Should mount an update ZoneForm', () => {
- const zone = getRandomZone()
- const cluster = getRandomCluster({ zoneId: zone.id })
- useSnackbarStore()
-
- const props = {
- associatedClusters: [cluster],
- zone: { ...zone, clusterIds: [cluster.id] },
- allClusters: [cluster],
- }
-
- cy.mount(ZoneForm, { props })
-
- cy.getByDataTestid('updateZoneBtn').should('be.enabled')
- cy.getByDataTestid('deleteZoneZone').should('not.exist')
- cy.getByDataTestid('slugInput')
- .should('have.value', props.zone.slug)
- .and('be.disabled')
- cy.getByDataTestid('labelInput')
- .should('have.value', props.zone.label)
- .and('be.enabled')
- .clear()
- .type('Zone à Détruire')
- cy.getByDataTestid('argocdUrlInput')
- .should('have.value', props.zone.argocdUrl)
- .and('be.enabled')
- .clear()
- .type('https://vousetesici.fr')
- cy.getByDataTestid('updateZoneBtn').should('be.enabled')
- cy.getByDataTestid('descriptionInput')
- .should('have.value', props.zone.description)
- .and('be.enabled')
- .clear()
- .type('Cette zone de déploiement est privée.')
- cy.getByDataTestid('updateZoneBtn').should('be.enabled')
- cy.get('#clusters-select h6')
- .click()
- cy.getByDataTestid(`${props.allClusters[0].id}-clusters-select-tag`)
- .should('be.visible')
- .click()
- cy.getByDataTestid(`${props.allClusters[0].id}-clusters-select-tag`)
- .should('be.disabled')
- cy.getByDataTestid('updateZoneBtn').should('be.enabled')
- })
-})
diff --git a/apps/client/cypress/components/support/commands.ts b/apps/client/cypress/components/support/commands.ts
deleted file mode 100644
index bb718ef14..000000000
--- a/apps/client/cypress/components/support/commands.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import { mount } from '@cypress/vue'
-import VueDsfr from '@gouvminint/vue-dsfr'
-
-import 'virtual:uno.css'
-import 'uno.css'
-import 'virtual:unocss-devtools'
-import '@/main.css'
-// import { ComponentOptions, ComponentOptionsWithObjectProps } from 'vue'
-
-Cypress.Commands.add('mount', (component, options = {}) => {
- // Setup options object
- options.global = options.global || {}
- options.global.components = options.global.components || {}
- options.global.plugins = options.global.plugins || []
-
- options.global.plugins.push({
- install(app) {
- app.use(VueDsfr)
- },
- })
-
- return mount(component, options)
-})
-
-Cypress.Commands.add('getByDataTestid', (dataTestid) => {
- cy.get(`[data-testid="${dataTestid}"]`)
-})
diff --git a/apps/client/cypress/components/support/component-index.html b/apps/client/cypress/components/support/component-index.html
deleted file mode 100644
index 9757aea74..000000000
--- a/apps/client/cypress/components/support/component-index.html
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
- Components App
-
-
-
-
-
diff --git a/apps/client/cypress/components/support/index.ts b/apps/client/cypress/components/support/index.ts
deleted file mode 100644
index 92074a8c6..000000000
--- a/apps/client/cypress/components/support/index.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-/* eslint-disable ts/method-signature-style */
-import type { mount } from '@cypress/vue'
-import './commands.js'
-
-type MountParams = Parameters
-type OptionsParam = MountParams[1]
-
-declare global {
- // eslint-disable-next-line ts/no-namespace
- namespace Cypress {
- interface Chainable {
- /**
- * Helper mount function for Vue Components
- * @param component Vue Component or JSX Element to mount
- * @param options Options passed to mount the component
- */
- mount(
- component: any,
- options?: OptionsParam
- ): Chainable
- }
- }
-}
diff --git a/apps/client/cypress/e2e/specs/03-modal.e2e.ts b/apps/client/cypress/e2e/specs/03-modal.e2e.ts
deleted file mode 100644
index 1ed0741e1..000000000
--- a/apps/client/cypress/e2e/specs/03-modal.e2e.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-import { getModelById } from '../support/func.js'
-
-describe('Manage project environments', () => {
- const project = getModelById('project', '011e7860-04d7-461f-912d-334c622d38c5')
-
- it('Test modal behaviour', () => {
- cy.kcLogin('test')
-
- cy.intercept('GET', 'api/v1/clusters').as('getClusters')
- cy.intercept('GET', 'api/v1/stages').as('listStages')
- cy.intercept('GET', 'api/v1/quotas').as('listQuotas')
- cy.intercept('GET', '/api/v1/projects?filter=member&statusNotIn=archived').as('listProjects')
-
- cy.goToProjects()
- .getByDataTestid(`projectTile-${project?.slug}`)
- .click()
-
- cy.getByDataTestid('environmentTr-integration')
- .as('envTr')
-
- // Open the modal
- cy.get('@envTr').click()
- cy.get('#fr-modal-1').should('be.visible')
-
- // close by clickOutside
- cy.get('#fr-modal-1')
- .click('right')
- cy.getByDataTestid('resource-modal')
- .should('not.exist')
-
- // Open the modal
- cy.get('@envTr').click()
- cy.get('#fr-modal-1').should('be.visible')
-
- // close by native button
- cy.get('div.fr-modal__header > button.fr-btn--close')
- .click()
- cy.getByDataTestid('resource-modal')
- .should('not.exist')
-
- // Open the modal
- cy.get('@envTr').click()
- cy.get('#fr-modal-1').should('be.visible')
-
- // cancel by form button
- cy.getByDataTestid('cancelEnvironmentBtn')
- .click()
- cy.getByDataTestid('resource-modal')
- .should('not.exist')
-
- // Open the modal
- cy.get('@envTr').click()
- cy.get('#fr-modal-1').should('be.visible')
-
- // cancel by pressing escape
- cy.get('body').type('{esc}')
- cy.getByDataTestid('resource-modal')
- .should('not.exist')
- })
-})
diff --git a/apps/client/cypress/e2e/specs/admin/logs.e2e.ts b/apps/client/cypress/e2e/specs/admin/logs.e2e.ts
deleted file mode 100644
index b94d408cd..000000000
--- a/apps/client/cypress/e2e/specs/admin/logs.e2e.ts
+++ /dev/null
@@ -1,82 +0,0 @@
-import type { Log } from '@cpn-console/shared'
-
-describe('Administration logs', () => {
- let logCount: number
- let logs: Log[]
-
- beforeEach(() => {
- cy.intercept('GET', 'api/v1/logs*').as('getAllLogs')
-
- cy.kcLogin('tcolin')
- cy.visit('/admin/logs')
- cy.url().should('contain', '/admin/logs')
- cy.wait('@getAllLogs', { timeout: 10_000 }).its('response').then((response) => {
- logs = response?.body?.logs
- logCount = response?.body?.total
- })
- })
-
- it('Should display logs list, loggedIn as admin', () => {
- cy.getByDataTestid('logCountInfo').should('contain', `Total : ${logCount} événements`)
- cy.getByDataTestid('positionInfo').should('contain', `1 - 10 sur ${logCount}`)
-
- cy.getByDataTestid('seePreviousPageBtn').should('be.disabled')
- cy.getByDataTestid('seeFirstPageBtn').should('be.disabled')
- cy.getByDataTestid('seeNextPageBtn').should('be.enabled')
- cy.getByDataTestid('seeLastPageBtn').should('be.enabled')
- cy.get('[data-testid$="-json"]').should('have.length', 10)
- logs.slice(0, 10).forEach((log) => {
- cy.getByDataTestid(`${log.id}-json`)
- .should('be.visible')
- })
-
- cy.getByDataTestid('seeNextPageBtn').first().click()
- cy.getByDataTestid('seePreviousPageBtn').should('be.enabled')
- cy.getByDataTestid('seeFirstPageBtn').should('be.enabled')
- cy.getByDataTestid('seeNextPageBtn').should('be.enabled')
- cy.getByDataTestid('seeLastPageBtn').should('be.enabled')
- cy.get('[data-testid$="-json"]').should('have.length', 10)
- logs.slice(10, 10).forEach((log) => {
- cy.getByDataTestid(`${log.id}-json`)
- .should('be.visible')
- })
-
- cy.getByDataTestid('seeLastPageBtn').first().click()
- cy.getByDataTestid('seePreviousPageBtn').should('be.enabled')
- cy.getByDataTestid('seeFirstPageBtn').should('be.enabled')
- cy.getByDataTestid('seeNextPageBtn').should('be.disabled')
- cy.getByDataTestid('seeLastPageBtn').should('be.disabled')
- cy.get('[data-testid$="-json"]')
- .should('have.length.of.at.least', 1)
- .and('have.length.at.most', 10)
- logs.slice(20, logCount - 20).forEach((log) => {
- cy.getByDataTestid(`${log.id}-json`)
- .should('be.visible')
- })
-
- cy.getByDataTestid('seeFirstPageBtn').first().click()
- cy.getByDataTestid('seePreviousPageBtn').should('be.disabled')
- cy.getByDataTestid('seeFirstPageBtn').should('be.disabled')
- cy.getByDataTestid('seeNextPageBtn').should('be.enabled')
- cy.getByDataTestid('seeLastPageBtn').should('be.enabled')
- cy.get('[data-testid$="-json"]').should('have.length', 10)
- logs.slice(0, 10).forEach((log) => {
- cy.getByDataTestid(`${log.id}-json`)
- .should('be.visible')
- })
- })
-
- it('Should display compact logs list, loggedIn as admin', () => {
- cy.get('h1')
- .should('contain', ' Journaux des services associés à la chaîne DSO ')
- cy.getByDataTestid('showLogsBtn')
- .click()
- logs.forEach((log) => {
- cy.getByDataTestid(`${log.id}-json`).should('not.exist')
- })
- cy.getByDataTestid('showLogsBtn').click()
- logs.forEach((log) => {
- cy.getByDataTestid(`${log.id}-json`).should('exist')
- })
- })
-})
diff --git a/apps/client/cypress/e2e/specs/admin/projects.e2e.ts b/apps/client/cypress/e2e/specs/admin/projects.e2e.ts
deleted file mode 100644
index 486319dcb..000000000
--- a/apps/client/cypress/e2e/specs/admin/projects.e2e.ts
+++ /dev/null
@@ -1,372 +0,0 @@
-import type { ProjectV2 } from '@cpn-console/shared'
-import type { Project } from '@/utils/project-utils.js'
-import { sortArrByObjKeyAsc, statusDict } from '@cpn-console/shared'
-import { getModelById } from '../../support/func.js'
-
-describe('Administration projects', () => {
- const admin = getModelById('user', 'cb8e5b4b-7b7b-40f5-935f-594f48ae6566')
- let projects: ProjectV2[]
-
- const mapProjects = (body: Project[]) => {
- return sortArrByObjKeyAsc(body, 'name')
- }
-
- beforeEach(() => {
- cy.intercept('GET', 'api/v1/projects*').as('getProjects')
-
- cy.kcLogin((admin.firstName.slice(0, 1) + admin.lastName).toLowerCase())
- cy.visit('/admin/projects')
- cy.url().should('contain', '/admin/projects')
- cy.wait('@getProjects', { timeout: 10_000 }).its('response').then((response) => {
- projects = mapProjects(response?.body)
- })
- })
-
- it('Should display projects table, loggedIn as admin', () => {
- cy.intercept('GET', 'api/v1/projects*').as('getAllProjects')
- cy.wait('@getAllProjects')
- cy.get('select#projectSearchFilter').select('Tous')
- cy.getByDataTestid('projectsSearchBtn')
- .click()
- cy.wait('@getAllProjects').its('response').then((response) => {
- const projects = response.body
- cy.getByDataTestid('tableAdministrationProjects')
- .get('tbody tr')
- .should('have.length.at.least', 2)
- projects.forEach((project: Project) => {
- cy.getByDataTestid(`tr-${project.id}`)
- .within(() => {
- cy.get('td:nth-of-type(2)').should('contain', project.slug)
- cy.get('td:nth-of-type(3)').should('contain', project.name)
- cy.get('td:nth-of-type(4)').should('contain', project.owner.email)
- cy.get('td:nth-of-type(5)').invoke('attr', 'title').should('contain', statusDict.status[project.status].wording)
- cy.get('td:nth-of-type(5)').invoke('attr', 'title').should('contain', statusDict.locked[String(!!project.locked)].wording)
- cy.get('td:nth-of-type(6)').should('contain.text', project.lastSuccessProvisionningVersion)
- cy.get('td:nth-of-type(7)').should('contain.text', 'il y a')
- })
- })
- })
- })
-
- it('Should display handle multi-select and bulk actions, loggedIn as admin', () => {
- cy.intercept('GET', 'api/v1/projects*').as('getAllProjects')
- cy.wait('@getAllProjects')
-
- // attente que les lignes soient bien rendus
- cy.getByDataTestid('tableAdministrationProjects')
- .get('tbody > tr')
- .should('not.have.text', 'Chargement...')
-
- cy.getByDataTestid('tableAdministrationProjects')
- .get('tbody > tr')
- .should('not.have.attr', 'selected')
- cy.getByDataTestid('select-all-cbx')
- .check()
- cy.getByDataTestid('tableAdministrationProjects')
- .get('tbody > tr')
- .should('have.attr', 'selected')
- cy.getByDataTestid('select-all-cbx')
- .check()
- cy.getByDataTestid(`tr-${projects[1].id}`)
- .click()
- .should('not.have.attr', 'selected')
- cy.getByDataTestid('select-all-cbx')
- .should('not.be.checked')
- cy.getByDataTestid(`tr-${projects[1].id}`)
- .click()
- .should('have.attr', 'selected')
- cy.getByDataTestid('select-all-cbx')
- .should('be.checked')
-
- // count must appear
- cy.getByDataTestid('projectSelectedCount')
- .should('contain.text', 'projets')
- // filter by partial name
- cy.getByDataTestid('projectsSearchInput')
- .clear()
- .type('li')
- cy.getByDataTestid('projectsSearchBtn')
- .click()
- // count must equal only displayed element
- cy.getByDataTestid('projectSelectedCount')
- .should('contain.text', '3 projets')
- // verrouillage des projets
- cy.getByDataTestid('selectBulkAction')
- .select('lock')
- cy.getByDataTestid('validateBulkAction')
- .click()
- cy.getByDataTestid('snackbar').should('contain', `Traitement en cours`)
- cy.getByDataTestid('projectsSearchBtn')
- .click()
- cy.getByDataTestid('tableAdministrationProjects')
- .get('tbody > tr')
- .should('not.have.attr', 'selected')
- cy.getByDataTestid('tableAdministrationProjects')
- .get('tbody > tr > td:nth-of-type(5)')
- .invoke('attr', 'title')
- .should('contain', statusDict.locked.true.wording)
- // annulation de la modification
- cy.getByDataTestid('select-all-cbx')
- .check()
- cy.getByDataTestid('projectSelectedCount')
- .should('contain.text', '3 projets')
- cy.getByDataTestid('selectBulkAction')
- .select('unlock')
- cy.getByDataTestid('validateBulkAction')
- .click()
- cy.getByDataTestid('snackbar').should('contain', `Traitement en cours`)
- cy.getByDataTestid('projectsSearchBtn')
- .click()
- cy.getByDataTestid('tableAdministrationProjects')
- .get('tbody > tr')
- .should('not.have.attr', 'selected')
- cy.getByDataTestid('tableAdministrationProjects')
- .get('tbody > tr > td:nth-of-type(5)')
- .invoke('attr', 'title')
- .should('contain', statusDict.locked.false.wording)
- })
-
- it('Should display filtered projects, loggedIn as admin', () => {
- cy.intercept('GET', /api\/v1\/projects\?filter=all$/).as('getAllProjects')
- cy.intercept('GET', /api\/v1\/projects\?filter=all&search=pr$/).as('searchInputProjects')
- cy.intercept('GET', 'api/v1/projects?filter=all&statusNotIn=archived').as('getActiveProjects')
- cy.intercept('GET', 'api/v1/projects?filter=all&statusIn=archived').as('getArchivedProjects')
- cy.intercept('GET', 'api/v1/projects?filter=all&statusIn=failed').as('getFailedProjects')
- cy.intercept('GET', 'api/v1/projects?filter=all&locked=true&statusNotIn=archived').as('getLockedProjects')
-
- cy.get('select#projectSearchFilter').select('Tous')
- cy.getByDataTestid('projectsSearchBtn')
- .click()
- cy.wait('@getAllProjects').its('response').then((response) => {
- cy.checkTableBody('tableAdministrationProjects', response.body.length, 'Aucun projet trouvé')
- })
-
- cy.get('select#projectSearchFilter').select('Archivés')
- cy.getByDataTestid('projectsSearchBtn')
- .click()
- cy.wait('@getArchivedProjects').its('response').then((response) => {
- cy.checkTableBody('tableAdministrationProjects', response.body.length, 'Aucun projet trouvé')
- })
-
- cy.get('select#projectSearchFilter').select('Non archivés')
- cy.getByDataTestid('projectsSearchBtn')
- .click()
- cy.wait('@getActiveProjects').its('response').then((response) => {
- cy.checkTableBody('tableAdministrationProjects', response.body.length, 'Aucun projet trouvé')
- })
-
- cy.get('select#projectSearchFilter').select('Échoués')
- cy.getByDataTestid('projectsSearchBtn')
- .click()
- cy.wait('@getFailedProjects').its('response').then((response) => {
- cy.checkTableBody('tableAdministrationProjects', response.body.length, 'Aucun projet trouvé')
- })
-
- cy.get('select#projectSearchFilter').select('Verrouillés')
- cy.getByDataTestid('projectsSearchBtn')
- .click()
- cy.wait('@getLockedProjects').its('response').then((response) => {
- cy.checkTableBody('tableAdministrationProjects', response.body.length, 'Aucun projet trouvé')
- })
-
- cy.get('select#projectSearchFilter').select('Tous')
- cy.getByDataTestid('projectsSearchInput')
- .clear()
- .type('pr')
- cy.getByDataTestid('projectsSearchBtn')
- .click()
- cy.wait('@searchInputProjects').its('response').then((response) => {
- cy.checkTableBody('tableAdministrationProjects', response.body.length, 'Aucun projet trouvé')
- })
- })
-
- it('Should replay hooks for a project, loggedIn as admin', () => {
- const project = projects.find(p => p.name === 'candilib')
-
- cy.intercept('PUT', `/api/v1/projects/${project.id}/hooks`).as('replayHooks')
-
- cy.getByDataTestid('tableAdministrationProjects').within(() => {
- cy.get('tr').contains(project.name)
- .click()
- })
- cy.get('.fr-callout__title')
- .should('contain', project.name)
- cy.getByDataTestid('replayHooksBtn')
- .should('contain', 'Reprovisionner le projet')
- .click()
-
- cy.wait('@replayHooks').its('response.statusCode').should('match', /^20\d$/)
- })
-
- it('Should lock and unlock a project, loggedIn as admin', () => {
- const project = projects[0]
-
- cy.intercept('PUT', `/api/v1/projects/${project.id}`).as('handleProjectLocking')
-
- cy.getByDataTestid('tableAdministrationProjects').within(() => {
- cy.get('tr').contains(project.name)
- .click()
- })
- cy.get('.fr-callout__title')
- .should('contain', project.name)
- cy.getByDataTestid('handleProjectLockingBtn')
- .should('contain', project.locked ? 'Déverrouiller le projet' : 'Verrouiller le projet')
- .click()
- cy.wait('@handleProjectLocking')
- .its('response.statusCode')
- .should('match', /^20\d$/)
- cy.getByDataTestid('handleProjectLockingBtn')
- .should('contain', 'Déverrouiller le projet')
- .click()
- cy.wait('@handleProjectLocking')
- .its('response.statusCode')
- .should('match', /^20\d$/)
- })
-
- it('Should remove and add a user from a project, loggedIn as admin', () => {
- const project = projects.find(project => project.name === 'betaapp') as ProjectV2
- const member = project.members[0]
-
- cy.intercept('GET', 'api/v1/projects*').as('getAllProjects')
- cy.intercept('DELETE', `api/v1/projects/${project.id}/members/${member.userId}`).as('removeUser')
- cy.intercept('POST', `api/v1/projects/${project.id}/members`).as('addUser')
-
- cy.getByDataTestid('tableAdministrationProjects').within(() => {
- cy.get('tr').contains(project.name)
- .click()
- })
- cy.getByDataTestid('test-tab-team').click()
- cy.get('.fr-callout__title')
- .should('contain', project.name)
- cy.get(`div[title="Quitter le projet"]`)
- .click()
- cy.wait('@removeUser')
- .its('response.statusCode')
- .should('match', /^20\d$/)
- cy.get(`div[title="Quitter le projet"]`)
- .should('not.exist')
- cy.getByDataTestid('addUserSuggestionInput')
- .find('input')
- .as('inputAddUser')
- cy.get('@inputAddUser')
- .clear()
- cy.get('@inputAddUser')
- .type(member.email)
- cy.getByDataTestid('addUserBtn')
- .click()
- cy.wait('@addUser')
- .its('response.statusCode')
- .should('match', /^20\d$/)
- cy.get(`div[title="Quitter le projet"]`)
- .should('exist')
- })
-
- it('Should transfert owner role to a team member, loggedIn as admin', () => {
- const project = projects.find(project => project.name === 'betaapp') as ProjectV2
- const owner = project.owner
- const userToTransfer = project.members[0]
-
- cy.intercept('GET', 'api/v1/projects*').as('getAllProjects')
- cy.intercept('GET', `api/v1/projects/${project.id}/services?permissionTarget=admin`).as('getServices')
- cy.intercept('GET', 'api/v1/repositories?projectId=*').as('listRepositories')
- cy.intercept('GET', 'api/v1/environments?projectId=*').as('listEnvironments')
- cy.intercept('PUT', `/api/v1/projects/${project.id}`).as('transferOwnership')
-
- cy.getByDataTestid('tableAdministrationProjects').within(() => {
- cy.get('tr').contains(project.name)
- .click()
- })
- cy.getByDataTestid('test-tab-team').click()
-
- cy.wait('@getServices')
- cy.wait('@listRepositories')
- cy.wait('@listEnvironments')
-
- cy.get('.fr-callout__title')
- .should('contain', project.name)
-
- cy.wait(500)
- cy.getByDataTestid('showTransferProjectBtn')
- .click()
- cy.getByDataTestid('transferProjectBtn')
- .should('exist')
- .should('be.disabled')
- cy.get('#nextOwnerSelect').select(userToTransfer.userId)
- cy.getByDataTestid('transferProjectBtn')
- .should('be.enabled')
- .click()
- cy.wait('@transferOwnership')
- .its('response.statusCode')
- .should('match', /^20\d$/)
-
- cy.getByDataTestid('tableAdministrationProjects').within(() => {
- cy.get('tr').contains(project.name)
- .click()
- })
- cy.getByDataTestid('test-tab-team').click()
-
- cy.getByDataTestid('teamTable').get('tr').contains('Propriétaire')
- .should('have.length', 1)
- .parent()
- .parent()
- .should('contain', userToTransfer.email)
-
- cy.getByDataTestid('showTransferProjectBtn').click()
- cy.getByDataTestid('transferProjectBtn')
- .should('exist')
- .should('be.disabled')
- cy.get('#nextOwnerSelect').select(owner.id)
- cy.getByDataTestid('transferProjectBtn')
- .should('be.enabled')
- .click()
- cy.wait('@transferOwnership')
- .its('response.statusCode')
- .should('match', /^20\d$/)
-
- cy.getByDataTestid('tableAdministrationProjects').within(() => {
- cy.get('tr').contains(project.name)
- .click()
- })
- cy.getByDataTestid('test-tab-team').click()
-
- cy.getByDataTestid('teamTable').get('tr').contains('Propriétaire')
- .should('have.length', 1)
- .parent()
- .parent()
- .should('contain', owner.email)
- })
-
- it('Should access project services, loggedIn as admin', () => {
- const project = projects.find(project => project.name === 'betaapp')
-
- cy.intercept('GET', 'api/v1/projects*').as('getAllProjects')
-
- cy.getByDataTestid('tableAdministrationProjects', 15_000).within(() => {
- cy.get('tr').contains(project.name)
- .click()
- })
- cy.getByDataTestid('test-tab-services').click()
- cy.get('.fr-callout__title')
- .should('contain', project.name)
- cy.get('#servicesTable').should('exist')
- cy.getByDataTestid('service-config-argocd')
- .click()
- .within(() => {
- cy.get('input')
- .should('have.length', 1)
- })
- })
-
- it('Should download projects informations, loggedIn as admin', () => {
- cy.intercept('GET', 'api/v1/projects*').as('getAllProjects')
- cy.get('.fr-link--download').should('not.exist')
- cy.getByDataTestid('download-btn')
- .click()
- cy.get('.fr-link--download').should('exist')
- .click()
- .find('span').should(($span) => {
- const text = $span.text()
- expect(text).to.match(/CSV – \d* bytes/)
- })
- })
-})
diff --git a/apps/client/cypress/e2e/specs/admin/system-settings.e2e.ts b/apps/client/cypress/e2e/specs/admin/system-settings.e2e.ts
deleted file mode 100644
index 8a7b641f9..000000000
--- a/apps/client/cypress/e2e/specs/admin/system-settings.e2e.ts
+++ /dev/null
@@ -1,93 +0,0 @@
-import type { SystemSettings } from '@cpn-console/shared'
-import { getModel } from '../../support/func.js'
-
-describe('Administration system settings', () => {
- const systemSettings = getModel('systemSetting') as SystemSettings
- const contactEmail = Cypress.env('CONTACT_EMAIL') || 'cloudpinative-relations@interieur.gouv.fr'
-
- beforeEach(() => {
- cy.intercept('GET', 'api/v1/system/settings').as('listSystemSettings')
- cy.intercept('POST', 'api/v1/system/settings').as('upsertSystemSetting')
-
- cy.kcLogin('tcolin')
- cy.visit('/admin/system-settings')
- cy.url().should('contain', '/admin/system-settings')
- cy.wait('@listSystemSettings', { timeout: 5_000 }).its('response').then(($response) => {
- expect($response?.statusCode).to.match(/^20\d$/)
- })
- })
-
- it('Should turn on maintenance mode', () => {
- cy.intercept('GET', 'api/v1/admin/roles').as('listRoles')
-
- systemSettings.forEach((setting) => {
- cy.getByDataTestid(`toggle-${setting.key}`)
- .find('input')
- .should('be.enabled')
- })
-
- cy.getByDataTestid(`toggle-maintenance`)
- .find('input')
- .check({ force: true })
- cy.wait('@upsertSystemSetting').its('response').then(($response) => {
- expect($response?.statusCode).to.match(/^20\d$/)
- expect(JSON.stringify($response?.body)).to.equal(JSON.stringify({
- key: 'maintenance',
- value: 'on',
- }))
- })
-
- cy.visit('/projects')
- cy.url().should('contain', '/projects')
- cy.getByDataTestid('maintenance-notice')
- .should('be.visible')
- cy.kcLogout()
-
- cy.visit('/')
- cy.getByDataTestid('maintenance-notice')
- .should('not.exist')
-
- cy.kcLogin('test')
- cy.getByDataTestid('maintenance-notice')
- .should('not.exist')
- cy.visit('/projects')
- cy.wait('@listRoles')
- cy.getByDataTestid('maintenance-notice')
- .should('be.visible')
- cy.visit('/projects')
- cy.url().should('contain', '/maintenance')
- cy.getByDataTestid('contact-us')
- .should('have.attr', 'title', contactEmail)
- })
-
- it('Should turn off maintenance mode', () => {
- systemSettings.forEach((setting) => {
- cy.getByDataTestid(`toggle-${setting.key}`)
- .find('input')
- .should('be.enabled')
- })
-
- cy.getByDataTestid(`toggle-maintenance`)
- .find('input')
- .uncheck({ force: true })
- cy.wait('@upsertSystemSetting').its('response').then(($response) => {
- expect($response?.statusCode).to.match(/^20\d$/)
- expect(JSON.stringify($response?.body)).to.equal(JSON.stringify({
- key: 'maintenance',
- value: 'off',
- }))
- })
-
- cy.visit('/projects')
- cy.getByDataTestid('maintenance-notice')
- .should('not.exist')
- cy.url().should('contain', '/projects')
- cy.kcLogout()
-
- cy.kcLogin('test')
- cy.getByDataTestid('maintenance-notice')
- .should('not.exist')
- cy.visit('/projects')
- cy.url().should('contain', '/projects')
- })
-})
diff --git a/apps/client/cypress/e2e/specs/admin/users.e2e.ts b/apps/client/cypress/e2e/specs/admin/users.e2e.ts
deleted file mode 100644
index 015453199..000000000
--- a/apps/client/cypress/e2e/specs/admin/users.e2e.ts
+++ /dev/null
@@ -1,55 +0,0 @@
-import type { User } from '@cpn-console/shared'
-import { getModel } from '../../support/func.js'
-
-const users = getModel('user') as User[]
-const anonUser = users.find(user => user.email === 'anon@user') as User
-
-describe('Administration users', () => {
- beforeEach(() => {
- cy.intercept('GET', 'api/v1/users').as('getAllUsers')
-
- cy.kcLogin('tcolin')
- cy.visit('/admin/users')
-
- cy.wait('@getAllUsers', { timeout: 10_000 }).its('response.statusCode').should('match', /^20\d$/)
- })
-
- it('Should display admin users, loggedIn as admin', () => {
- users.forEach((user) => {
- cy.getByDataTestid(`user-${user.id}`)
- .should('contain.text', user.email)
- .should('contain.text', user.lastName)
- .should('contain.text', user.firstName)
- .parent()
- .should('contain.text', '202') // test que la date s'affiche
- })
- cy.getByDataTestid('input-checkbox-tableAdministrationUsersDisplayId')
- .should('exist')
- .click({ force: true })
- users.forEach((user) => {
- cy.getByDataTestid(`user-${user.id}`)
- .should('contain.text', user.id)
- })
-
- cy.getByDataTestid(`user-${anonUser.id}`).should('exist')
- cy.getByDataTestid('input-checkbox-tableAdministrationUsersHideBots')
- .should('exist')
- .click({ force: true })
- cy.getByDataTestid(`user-${anonUser.id}`).should('not.exist')
- cy.getByDataTestid('input-checkbox-tableAdministrationUsersHideBots')
- .should('exist')
- .click({ force: true })
-
- cy.getByDataTestid('tableAdministrationUsers')
- .find('tbody')
- .find('tr')
- .should('have.length.at.least', users.length)
- cy.getByDataTestid('tableAdministrationUsersSearch')
- .clear()
- .type(anonUser.email)
- cy.getByDataTestid('tableAdministrationUsers')
- .find('tbody')
- .find('tr')
- .should('have.length', 1)
- })
-})
diff --git a/apps/client/cypress/e2e/specs/create-project.e2e.ts b/apps/client/cypress/e2e/specs/create-project.e2e.ts
deleted file mode 100644
index 46354c856..000000000
--- a/apps/client/cypress/e2e/specs/create-project.e2e.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-describe('Create Project', () => {
- const project = {
- name: 'project01',
- slug: 'project01',
- description: 'Application de prise de rendez-vous en préfécture.',
- }
-
- beforeEach(() => {
- cy.kcLogin('test')
- })
-
- it('Should create a project with minimal form informations', () => {
- cy.intercept('POST', '/api/v1/projects').as('postProject')
- cy.intercept('GET', '/api/v1/projects?filter=member&statusNotIn=archived').as('listProjects')
-
- cy.goToProjects()
- .getByDataTestid('createProjectLink').click()
- .get('h1').should('contain', 'Commander un espace projet')
- .get('[data-testid^="repoFieldset-"]').should('not.exist')
-
- cy.getByDataTestid('nameInput').type(`${project.name} ErrorSpace`)
- .getByDataTestid('nameInput').should('have.class', 'fr-input--error')
- .getByDataTestid('createProjectBtn').should('be.disabled')
- .getByDataTestid('nameInput').clear().type(project.name)
- .getByDataTestid('nameInput').should('not.have.class', 'fr-input--error')
- .getByDataTestid('createProjectBtn').should('be.enabled')
- .getByDataTestid('descriptionInput').clear().type(project.description)
- cy.getByDataTestid('createProjectBtn').should('be.enabled').click()
-
- cy.wait('@postProject').its('response.statusCode').should('match', /^20\d$/)
- cy.url().should('contain', `/projects/${project.slug}`)
-
- cy.wait('@listProjects').its('response.statusCode').should('match', /^20\d$/)
-
- cy.assertCreateProjects([project.slug])
- })
-
- it('Should not create a project if name is already taken', () => {
- cy.intercept('POST', '/api/v1/projects').as('postProject')
- cy.intercept('GET', '/api/v1/projects?filter=member&statusNotIn=archived').as('listProjects')
-
- cy.goToProjects()
- .getByDataTestid('createProjectLink').click()
- .getByDataTestid('nameInput').type(project.name)
- cy.getByDataTestid('createProjectBtn').should('be.enabled').click()
- cy.wait('@postProject').its('response.statusCode').should('match', /^20\d$/)
- cy.url().should('contain', `/projects/${project.slug}-1`)
- })
-})
diff --git a/apps/client/cypress/e2e/specs/home.e2e.ts b/apps/client/cypress/e2e/specs/home.e2e.ts
deleted file mode 100644
index c61975105..000000000
--- a/apps/client/cypress/e2e/specs/home.e2e.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import { swaggerUiPath } from '@cpn-console/shared'
-import { getModelById } from '../support/func.js'
-
-const user = getModelById('user', 'cb8e5b4b-7b7b-40f5-935f-594f48ae6567')
-
-describe('Header', () => {
- it('Should display application Header', () => {
- cy.visit('/')
- .get('.fr-header__service')
- .should('contain', 'Console Cloud π Native')
- .get('.fr-header__service-tagline')
- .should('not.exist')
- })
-
- it('Should display name once logged', () => {
- cy.kcLogin((user.firstName.slice(0, 1) + user.lastName).toLowerCase())
- .visit('/')
- .getByDataTestid('menuUserList')
- .should('contain', `${user.firstName} ${user.lastName}`)
- })
-
- it('Should display app version and swagger', () => {
- cy.visit('/')
- cy.getByDataTestid('swaggerUrl')
- .should('have.attr', 'href', swaggerUiPath)
- cy.getByDataTestid('appVersionUrl')
- .contains('vpr-')
- .invoke('attr', 'href')
- .should('match', /https:\/\/github.com\/cloud-pi-native\/console\/releases\/tag\/vpr-/)
- })
-})
diff --git a/apps/client/cypress/e2e/specs/not-found.e2e.ts b/apps/client/cypress/e2e/specs/not-found.e2e.ts
deleted file mode 100644
index c19bdb27f..000000000
--- a/apps/client/cypress/e2e/specs/not-found.e2e.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-describe('Redirect to 404 if page not found', () => {
- it('should redirect loggedin user to 404 if page not found', () => {
- cy.kcLogin('test')
- cy.visit('/nowhere')
- cy.get('.fr-h1')
- .should('contain.text', 'Page non trouvée')
- })
-})
diff --git a/apps/client/cypress/e2e/specs/redirection.e2e.ts b/apps/client/cypress/e2e/specs/redirection.e2e.ts
deleted file mode 100644
index 51548170b..000000000
--- a/apps/client/cypress/e2e/specs/redirection.e2e.ts
+++ /dev/null
@@ -1,87 +0,0 @@
-import { swaggerUiPath } from '@cpn-console/shared'
-import { keycloakDomain } from '@/utils/env.js'
-import { getModelById } from '../support/func.js'
-
-const project = getModelById('project', '011e7860-04d7-461f-912d-334c622d38b3')
-
-describe('Redirection', () => {
- it('Should redirect to original page on reload', () => {
- cy.intercept('GET', '/api/v1/projects?filter=member&statusNotIn=archived').as('listProjects')
- cy.intercept('POST', '/realms/cloud-pi-native/protocol/openid-connect/token').as('postToken')
-
- cy.kcLogin('test')
- cy.visit('/')
- cy.reload()
- cy.url().should('match', /\/#state=/)
- cy.goToProjects()
- cy.reload()
- cy.wait('@postToken')
- cy.url().should('match', /projects#state=/)
- cy.wait('@listProjects').its('response').then((response) => {
- cy.get('[data-testid^="projectTile-"]')
- cy.should('have.length', `${response?.body.length}`)
- cy.getByDataTestid(`projectTile-${project.slug}`).click()
- cy.url().should('contain', `/projects/${project.slug}`)
- })
- cy.reload()
- cy.wait('@postToken')
- cy.url().should('contain', `/projects/${project.slug}`)
- cy.wait('@listProjects').its('response').then((_response) => {
- cy.getByDataTestid('descriptionP')
- cy.should('contain', project.description)
- })
- })
-
- it('Should redirect to login page if not logged in', () => {
- cy.intercept('GET', '/api/v1/projects?filter=member&statusNotIn=archived').as('listProjects')
- cy.intercept('POST', '/realms/cloud-pi-native/protocol/openid-connect/token').as('postToken')
- cy.intercept('GET', '/realms/cloud-pi-native/account').as('getAccount')
-
- cy.visit(`/projects/${project.slug}`)
- cy.url().should('not.contain', `/projects/${project.slug}`)
- cy.origin(`http://${keycloakDomain}`, () => {
- cy.get('input#username').type('test')
- .get('input#password').type('test')
- .get('#kc-login').click()
- })
- cy.wait('@postToken')
- cy.url().should('contain', `/projects/${project.slug}`)
- cy.wait('@listProjects', { timeout: 5_000 }).its('response').then((_response) => {
- cy.getByDataTestid('descriptionP')
- cy.should('contain', project.description)
- })
- })
-
- it('Should redirect to home if trying to access login page while logged', () => {
- cy.intercept('POST', '/realms/cloud-pi-native/protocol/openid-connect/token').as('postToken')
- cy.intercept('GET', '/realms/cloud-pi-native/account').as('getAccount')
-
- cy.visit('/login')
- cy.url().should('not.contain', '/login')
- cy.origin(`http://${keycloakDomain}`, () => {
- cy.get('input#username').type('test')
- .get('input#password').type('test')
- .get('#kc-login').click()
- })
- cy.wait('@postToken')
- cy.url().should('contain', '/')
- cy.get('h1').contains(' Cloud π Native ')
- .should('exist')
- })
-
- it('Should redirect to swagger ui', () => {
- cy.intercept('POST', '/realms/cloud-pi-native/protocol/openid-connect/token').as('postToken')
-
- cy.visit('/')
- cy.get('h1').contains(' Cloud π Native ')
- .should('exist')
-
- cy.getByDataTestid('swaggerUrl')
- .should('have.attr', 'target', '_blank')
- .invoke('attr', 'target', '_self')
- .click()
- cy.url().should('contain', swaggerUiPath)
- cy.get('div.description')
- .should('contain', 'API de gestion des ressources Cloud Pi Native.')
- })
-})
diff --git a/apps/client/cypress/e2e/specs/roles.e2e.ts b/apps/client/cypress/e2e/specs/roles.e2e.ts
deleted file mode 100644
index db110a20e..000000000
--- a/apps/client/cypress/e2e/specs/roles.e2e.ts
+++ /dev/null
@@ -1,172 +0,0 @@
-import type { Environment, ProjectPermsKeys, ProjectRole, ProjectV2, Repo, User } from '@cpn-console/shared'
-import { getModel, getModelById } from '../support/func.js'
-
-const roles: ProjectRole[] = getModel('projectRole')
-const user: User = getModelById('user', 'cb8e5b4b-7b7b-40f5-935f-594f48ae6569')
-const repositories: Repo[] = getModel('repository')
-const environments: Environment[] = getModel('environment')
-
-const newRole = {
- name: 'elo hell',
-} satisfies Partial
-
-const project = getModelById('project', '94c860ab-023f-4e6e-8a4e-ff41456e249b') as ProjectV2
-const projectRoles = roles.filter(role => role.projectId === project.id)
-const projectRepos = repositories.filter(repo => repo.projectId === project.id)
-const projectEnvs = environments.filter(env => env.projectId === project.id)
-const testRole = projectRoles.find(projectRole => projectRole.id === 'c77a1b96-377d-4aa3-bc94-65d4415f9599') as ProjectRole
-
-function assignPerms() {
- // @ts-expect-error
- const perms: ProjectPermsKeys[] = this as ProjectPermsKeys[]
- cy.kcLogin('test')
- cy.goToProjects()
- cy.getByDataTestid(`projectTile-${project.slug}`).click()
- cy.getByDataTestid('test-tab-roles').click()
- cy.get('[data-testid$="-tab"]').contains(testRole.name)
- .should('be.visible')
- .click()
- perms.forEach((key) => {
- cy.getByDataTestid(`input-checkbox-${key}-cbx`).check({ force: true })
- })
- cy.getByDataTestid('saveBtn')
- .should('be.enabled')
- .click()
-}
-
-describe('Project roles', () => {
- beforeEach(() => {
- cy.intercept('GET', '/api/v1/projects').as('listProjects')
- cy.intercept('POST', '/api/v1/projects/*/roles').as('createRole')
- })
-
- describe('Project roles, without perms', () => {
- it('Should create role without perms', () => {
- cy.kcLogin('test')
- cy.goToProjects()
- cy.getByDataTestid(`projectTile-${project.slug}`).click()
- cy.getByDataTestid('test-tab-roles').click()
- projectRoles.forEach((role) => {
- cy.getByDataTestid(`${role.id}-tab`)
- .should('be.visible')
- })
-
- cy.getByDataTestid('addRoleBtn')
- .should('be.enabled')
- .click()
- cy.wait('@createRole')
- .its('response.statusCode').should('match', /^20\d$/)
- cy.getByDataTestid('snackbar').should('contain', 'Rôle ajouté')
- cy.getByDataTestid('saveBtn').should('be.disabled')
- cy.getByDataTestid('roleNameInput')
- .should('have.value', 'Nouveau rôle')
- .clear()
- .type(newRole.name)
- cy.getByDataTestid('saveBtn')
- .should('be.enabled')
- .click()
- cy.getByDataTestid('test-members').click()
- cy.getByDataTestid(`input-checkbox-${user.id}-cbx`).check({ force: true })
- })
-
- it('Should not grant perms', () => {
- cy.kcLogin((user.firstName.slice(0, 1) + user.lastName).toLowerCase())
- cy.goToProjects()
- cy.getByDataTestid(`projectTile-${project.slug}`).click()
-
- cy.getByDataTestid('test-tab-team').click()
- cy.getByDataTestid('teamTable').get('th').contains('Retirer du projet').should('be.visible')
- cy.getByDataTestid('addUserSuggestionInput').should('not.exist')
- cy.getByDataTestid('showTransferProjectBtn').should('not.exist')
-
- cy.getByDataTestid('replayHooksBtn').should('not.exist')
- cy.getByDataTestid('showSecretsBtn').should('not.exist')
-
- cy.getByDataTestid('test-tab-roles').should('exist')
- })
- })
-
- describe('Project roles, with view perms', () => {
- const intermediatePermsOptions: ProjectPermsKeys[] = ['LIST_ENVIRONMENTS', 'LIST_REPOSITORIES']
-
- it('Should assign view perms', assignPerms.bind(intermediatePermsOptions))
-
- it('Should grant view perms', () => {
- cy.kcLogin((user.firstName.slice(0, 1) + user.lastName).toLowerCase())
- cy.goToProjects()
- cy.getByDataTestid(`projectTile-${project.slug}`).click()
-
- cy.getByDataTestid('noReposTr').should('not.exist')
-
- cy.getByDataTestid('addRepoLink').should('not.exist')
- cy.getByDataTestid(`repoTr-${projectRepos[0].internalRepoName}`).click()
- cy.getByDataTestid('syncRepoBtn').should('not.exist')
- cy.getByDataTestid('updateRepoBtn').should('not.exist')
- cy.getByDataTestid('showDeleteRepoBtn').should('not.exist')
- cy.get('.fr-modal__header > button.fr-btn--close').click()
-
- cy.getByDataTestid('noEnvsTr').should('not.exist')
- cy.getByDataTestid('addEnvironmentLink').should('not.exist')
- cy.getByDataTestid(`environmentTr-${projectEnvs[0].name}`).click()
- cy.getByDataTestid('putEnvironmentBtn').should('not.exist')
- cy.getByDataTestid('showDeleteEnvironmentBtn').should('not.exist')
- cy.get('.fr-modal__header > button.fr-btn--close').click()
-
- cy.getByDataTestid('test-tab-team').click()
- cy.getByDataTestid('teamTable').get('th').contains('Retirer du projet').should('be.visible')
- cy.getByDataTestid('addUserSuggestionInput').should('not.exist')
- cy.getByDataTestid('showTransferProjectBtn').should('not.exist')
-
- cy.getByDataTestid('replayHooksBtn').should('not.exist')
- cy.getByDataTestid('showSecretsBtn').should('not.exist')
-
- cy.getByDataTestid('test-tab-roles').should('exist').click()
- cy.getByDataTestid('insuficientPermsRoles').should('be.visible')
- })
- })
-
- describe('Project roles, with full access perms', () => {
- const fullPermsOptions: ProjectPermsKeys[][] = [
- ['MANAGE_ENVIRONMENTS', 'MANAGE_MEMBERS', 'MANAGE_REPOSITORIES', 'MANAGE_ROLES', 'REPLAY_HOOKS', 'SEE_SECRETS'],
- ['MANAGE'],
- ]
-
- fullPermsOptions.forEach((perms, idx) => {
- it(`Should assign full access perms (${idx + 1})`, assignPerms.bind(perms))
-
- it(`Should grant full access perms (${idx + 1})`, () => {
- cy.kcLogin((user.firstName.slice(0, 1) + user.lastName).toLowerCase())
- cy.goToProjects()
- cy.getByDataTestid(`projectTile-${project.slug}`).click()
-
- cy.getByDataTestid('noEnvsTr').should('not.exist')
- cy.getByDataTestid('noReposTr').should('not.exist')
- cy.getByDataTestid('addRepoLink').should('be.enabled')
- cy.getByDataTestid(`repoTr-${projectRepos[0].internalRepoName}`).click()
- cy.getByDataTestid('syncRepoBtn').should('be.enabled')
- cy.getByDataTestid('updateRepoBtn').should('be.enabled')
- cy.getByDataTestid('showDeleteRepoBtn').should('be.enabled')
- cy.get('.fr-modal__header > button.fr-btn--close').click()
-
- cy.getByDataTestid('addEnvironmentLink').should('be.enabled')
- cy.getByDataTestid(`environmentTr-${projectEnvs[0].name}`).click()
- cy.getByDataTestid('putEnvironmentBtn').should('be.enabled')
- cy.getByDataTestid('showDeleteEnvironmentBtn').should('be.enabled')
- cy.get('.fr-modal__header > button.fr-btn--close').click()
-
- cy.getByDataTestid('test-tab-team').click()
- cy.getByDataTestid('teamTable').get('th').contains('Retirer du projet').should('be.visible')
- cy.getByDataTestid('addUserSuggestionInput').should('be.visible')
- cy.getByDataTestid('showTransferProjectBtn').should('not.exist')
-
- cy.getByDataTestid('replayHooksBtn').should('be.enabled')
- cy.getByDataTestid('showSecretsBtn').should('be.enabled')
-
- cy.getByDataTestid('test-tab-roles').should('be.visible').click()
- projectRoles.forEach((role) => {
- cy.getByDataTestid(`${role.id}-tab`).should('be.visible')
- })
- })
- })
- })
-})
diff --git a/apps/client/cypress/e2e/specs/services-health.e2e.ts b/apps/client/cypress/e2e/specs/services-health.e2e.ts
deleted file mode 100644
index 3da8f4085..000000000
--- a/apps/client/cypress/e2e/specs/services-health.e2e.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-describe('Services health', () => {
- it('Should display services health, loggedIn', () => {
- cy.intercept('GET', '/api/v1/services').as('getServices')
-
- cy.kcLogin('test')
-
- cy.visit('/')
- .getByDataTestid('menuServicesHealth').click()
- .url().should('contain', '/services-health')
- .get('h1').should('contain', 'Status des services de la plateforme DSO')
- cy.getByDataTestid('box-info').children().should('have.length', 7)
- })
-
- it('Should display services health, not loggedIn', () => {
- cy.intercept('GET', '/api/v1/services').as('getServices')
-
- cy.visit('/')
- cy.get('a.fr-btn').should('contain', 'Se connecter')
- cy.getByDataTestid('menuServicesHealth')
- .should('be.visible')
- .click()
- cy.url().should('contain', '/services-health')
- cy.get('h1').should('contain', 'Status des services de la plateforme DSO')
- cy.getByDataTestid('box-info').children().should('have.length', 7)
- })
-})
diff --git a/apps/client/cypress/e2e/specs/services.e2e.ts b/apps/client/cypress/e2e/specs/services.e2e.ts
deleted file mode 100644
index af2ef2fc2..000000000
--- a/apps/client/cypress/e2e/specs/services.e2e.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import { getModelById } from '../support/func.js'
-
-const project = getModelById('project', '011e7860-04d7-461f-912d-334c622d38b3')
-
-describe('Services view', () => {
- beforeEach(() => {
- cy.kcLogin('test')
- })
-
- it('Should display tiles and url services according to selected project', () => {
- cy.goToProjects()
- cy.getByDataTestid(`projectTile-${project.slug}`).click()
- cy.getByDataTestid('test-tab-services').click()
- cy.getByDataTestid('service-config-argocd')
- .click()
- .within(() => {
- cy.get('input')
- .should('have.length', 1)
- })
- })
-})
diff --git a/apps/client/cypress/e2e/specs/sidemenu.e2e.ts b/apps/client/cypress/e2e/specs/sidemenu.e2e.ts
deleted file mode 100644
index 5898d4e58..000000000
--- a/apps/client/cypress/e2e/specs/sidemenu.e2e.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-import { getModelById } from '../support/func.js'
-
-const project = getModelById('project', '011e7860-04d7-461f-912d-334c622d38b3')
-
-describe('Sidemenu', () => {
- it('Should display Sidemenu, not loggedIn', () => {
- cy.visit('/')
- .getByDataTestid('mainMenu').should('be.visible')
- .getByDataTestid('menuProjectBtn').should('not.exist')
- .getByDataTestid('menuDoc').should('be.visible')
- .getByDataTestid('menuAdministrationList').should('not.exist')
- .getByDataTestid('menuAdministrationBtn').should('not.exist')
- })
- it('Should display Sidemenu, loggedIn, isNotAdmin', () => {
- cy.kcLogin('test')
-
- cy.visit('/')
- .getByDataTestid('mainMenu').should('be.visible')
- .getByDataTestid('menuMyProjects').click()
- .url().should('contain', '/projects')
- .getByDataTestid(`projectTile-${project.slug}`).click()
- .url().should('contain', `/projects/${project.slug}`)
- })
-
- it('Should display Sidemenu, loggedIn, isAdmin', () => {
- cy.kcLogin('tcolin')
-
- cy.visit('/')
- .getByDataTestid('mainMenu').should('be.visible')
- .getByDataTestid('menuAdministrationList').should('not.be.visible')
-
- // Projects
- .getByDataTestid('menuMyProjects').click()
- .getByDataTestid('menuAdministrationList').should('not.be.visible')
- .url().should('contain', '/projects')
- .getByDataTestid(`projectTile-${project.slug}`).click()
- .getByDataTestid('menuAdministrationList').should('not.be.visible')
- .url().should('contain', `/projects/${project.slug}`)
-
- // Doc
- .getByDataTestid('menuDoc').should('be.visible')
- .getByDataTestid('menuAdministrationList').should('not.be.visible')
-
- // Admin
- .getByDataTestid('menuAdministrationBtn').click()
- .getByDataTestid('menuAdministrationList').should('be.visible')
- .getByDataTestid('menuAdministrationUsers').click()
- .getByDataTestid('menuAdministrationUsers').should('have.class', 'router-link-active')
- .getByDataTestid('menuAdministrationList').should('be.visible')
- .url().should('contain', '/admin/users')
- })
-})
diff --git a/apps/client/cypress/e2e/specs/team.e2e.ts b/apps/client/cypress/e2e/specs/team.e2e.ts
deleted file mode 100644
index 018f2ac79..000000000
--- a/apps/client/cypress/e2e/specs/team.e2e.ts
+++ /dev/null
@@ -1,166 +0,0 @@
-import { getModelById } from '../support/func.js'
-
-const project = getModelById('project', '22e7044f-8414-435d-9c4a-2df42a65034b')
-const newMember = getModelById('user', 'cb8e5b4b-7b7b-40f5-935f-594f48ae6567')
-
-describe('Team view', () => {
- beforeEach(() => {
- cy.kcLogin('test')
- })
-
- it('Should display team members', () => {
- cy.goToProjects()
- .getByDataTestid(`projectTile-${project.slug}`).click()
- .getByDataTestid('test-tab-team').click()
- .getByDataTestid('teamTable')
- .find('tbody > tr')
- .should('have.length', project.members.length + 1)
- })
-
- it('Should not add a non-existing team member', () => {
- cy.goToProjects()
- .getByDataTestid(`projectTile-${project.slug}`).click()
- .getByDataTestid('test-tab-team').click()
- .getByDataTestid('teamTable')
- .find('tbody > tr')
- .should('have.length', project.members.length + 1)
-
- cy.getByDataTestid('addUserSuggestionInput')
- .find('input')
- .clear()
- .type('jenexistepas@criseexistentielle.com')
- cy.getByDataTestid('addUserBtn')
- .should('be.enabled').click()
-
- cy.getByDataTestid('snackbar').should('contain', 'Utilisateur introuvable')
-
- cy.getByDataTestid('teamTable')
- .find('tbody > tr')
- .should('have.length', project.members.length + 1)
- })
-
- it('Should add a team member', () => {
- cy.intercept('POST', `api/v1/projects/${project.id}/members`).as('addUser')
-
- cy.goToProjects()
- cy.getByDataTestid(`projectTile-${project.slug}`).click()
- cy.getByDataTestid('test-tab-team').click()
- cy.getByDataTestid('teamTable')
- .find('tbody > tr')
- .should('have.length', project.members.length + 1)
-
- cy.getByDataTestid('addUserSuggestionInput')
- .find('input')
- .clear()
- .type('test@test.com')
- cy.getByDataTestid('userErrorInfo')
- .should('contain', 'L\'utilisateur associé à cette adresse e-mail fait déjà partie du projet.')
- cy.getByDataTestid('addUserBtn')
- .should('be.disabled')
- cy.getByDataTestid('addUserSuggestionInput')
- .find('input')
- .clear()
-
- cy.getByDataTestid('addUserSuggestionInput')
- .find('input')
- .clear()
- .type(newMember.email)
- cy.getByDataTestid('userErrorInfo')
- .should('not.exist')
- cy.getByDataTestid('addUserBtn')
- .should('be.enabled').click()
- cy.wait('@addUser')
- .its('response.statusCode')
- .should('match', /^20\d$/)
-
- cy.getByDataTestid('teamTable')
- .find('tbody > tr')
- .should('have.length', project.members.length + 1 + 1)
- })
-
- it('Should transfert owner role to a team member', () => {
- const owner = getModelById('user', 'cb8e5b4b-7b7b-40f5-935f-594f48ae6565')
- const userToTransfer = getModelById('user', 'cb8e5b4b-7b7b-40f5-935f-594f48ae6566')
-
- cy.intercept('PUT', `/api/v1/projects/${project.id}`).as('transferOwnership')
- cy.intercept('GET', `/api/v1/projects?filter=member&statusNotIn=archived`).as('getProjectMembers')
-
- cy.goToProjects()
- cy.getByDataTestid(`projectTile-${project.slug}`).click()
- cy.getByDataTestid('test-tab-team').click()
-
- cy.getByDataTestid('showTransferProjectBtn')
- .should('be.enabled')
- cy.getByDataTestid('transferProjectBtn')
- .should('not.exist')
-
- cy.getByDataTestid('teamTable').get('tr').contains('Propriétaire').should('have.length', 1)
- cy.getByDataTestid('showTransferProjectBtn').click()
- cy.getByDataTestid('transferProjectBtn')
- .should('exist')
- .should('be.disabled')
- cy.get('#nextOwnerSelect').select(userToTransfer.id)
- cy.getByDataTestid('transferProjectBtn')
- .should('be.enabled')
- .click()
- cy.wait('@transferOwnership')
- .its('response.statusCode')
- .should('match', /^20\d$/)
- cy.wait('@getProjectMembers')
- .its('response.statusCode')
- .should('match', /^20\d$/)
-
- cy.getByDataTestid('teamTable').get('tr').contains('Propriétaire').should('have.length', 1)
- cy.getByDataTestid('showTransferProjectBtn')
- .should('not.exist')
- cy.getByDataTestid('transferProjectBtn')
- .should('not.exist')
-
- cy.kcLogin((userToTransfer.firstName.slice(0, 1) + userToTransfer.lastName).toLowerCase())
-
- cy.goToProjects()
- cy.getByDataTestid(`projectTile-${project.slug}`).click()
- cy.getByDataTestid('test-tab-team').click()
-
- cy.getByDataTestid('showTransferProjectBtn').click()
- cy.getByDataTestid('transferProjectBtn')
- .should('exist')
- .should('be.disabled')
- cy.get('#nextOwnerSelect').select(owner.id)
- cy.getByDataTestid('transferProjectBtn')
- .should('be.enabled')
- .click()
- cy.wait('@transferOwnership')
- .its('response.statusCode')
- .should('match', /^20\d$/)
- cy.wait('@getProjectMembers')
- .its('response.statusCode')
- .should('match', /^20\d$/)
-
- cy.getByDataTestid('teamTable').get('tr').contains('Propriétaire').should('have.length', 1)
- cy.getByDataTestid('showTransferProjectBtn')
- .should('not.exist')
- cy.getByDataTestid('transferProjectBtn')
- .should('not.exist')
- })
-
- it('Should remove a team member', () => {
- cy.intercept('DELETE', `api/v1/projects/${project.id}/members/*`).as('removeUser')
-
- cy.goToProjects()
- cy.getByDataTestid(`projectTile-${project.slug}`).click()
- cy.getByDataTestid('test-tab-team').click()
- cy.getByDataTestid('teamTable')
- .find('tbody > tr')
- .should('have.length', project.members.length + 1 + 1)
- .get(`div[title="Retirer ${newMember.email} du projet"]`)
- .click()
- cy.wait('@removeUser')
- .its('response.statusCode')
- .should('match', /^20\d$/)
-
- cy.getByDataTestid('teamTable')
- .find('tbody > tr')
- .should('have.length', project.members.length + 1)
- })
-})
diff --git a/apps/client/cypress/e2e/support/commands.ts b/apps/client/cypress/e2e/support/commands.ts
deleted file mode 100644
index 57d9ecdb0..000000000
--- a/apps/client/cypress/e2e/support/commands.ts
+++ /dev/null
@@ -1,466 +0,0 @@
-import { deleteValidationInput } from '@cpn-console/shared'
-import { keycloakDomain } from '@/utils/env.js'
-import { getModelById } from './func.js'
-
-const defaultOwner = getModelById('user', 'cb8e5b4b-7b7b-40f5-935f-594f48ae6565')
-
-Cypress.Commands.add('kcLogout', () => {
- cy.get('a.fr-btn').should('contain', 'Se déconnecter').click()
-})
-
-Cypress.Commands.add('kcLogin', (name, password = 'test') => {
- cy.session(name, () => {
- cy.visit('/')
- .get('a.fr-btn').should('contain', 'Se connecter').click()
- cy.origin(`http://${keycloakDomain}`, { args: { name, password } }, ({ name, password }) => {
- cy.get('input#username').type(name)
- .get('input#password').type(password)
- .get('#kc-login').click()
- })
- cy.url().should('contain', `${Cypress.env('clientHost')}`)
- }, {
- validate() {
- cy.visit('/')
- .get('a.fr-btn').should('contain', 'Se déconnecter')
- },
- })
-})
-
-Cypress.Commands.add('goToProjects', () => {
- cy.intercept('GET', 'api/v1/projects?filter=member&statusNotIn=archived').as('listProjects')
-
- cy.get('body').then(($body) => {
- // Vérifie si un élément est présent
- if ($body.find('a').length === 0) {
- // Si l'élément n'est pas trouvé, on considère qu'on est dans les limbes
- cy.visit('/')
- }
- })
- cy.getByDataTestid('menuMyProjects').click()
- cy.url({ timeout: 10_000 }).should('contain', '/projects')
-})
-
-Cypress.Commands.add('createProject', (project, ownerEmail = defaultOwner.email) => {
- cy.intercept('POST', '/api/v1/projects').as('postProject')
- cy.intercept('GET', '/api/v1/projects?filter=member&statusNotIn=archived').as('listProjects')
-
- const newProject = {
- name: 'cloud-pi-native',
- ...project,
- }
-
- cy.goToProjects()
- .getByDataTestid('createProjectLink').click()
- .get('h1').should('contain', 'Commander un espace projet')
- .get('[data-testid^="repoFieldset-"]').should('not.exist')
- cy.getByDataTestid('ownerInfo').should('contain', ownerEmail)
- .getByDataTestid('nameInput').clear().type(newProject.name)
- .getByDataTestid('nameInput').should('not.have.class', 'fr-input--error')
- cy.getByDataTestid('createProjectBtn').should('be.enabled').click()
-
- cy.wait('@postProject').its('response.statusCode').should('eq', 201)
- cy.wait('@listProjects').its('response.statusCode').should('eq', 200)
-})
-
-Cypress.Commands.add('assertCreateProjects', (slugs) => {
- cy.intercept('GET', '/api/v1/projects?filter=member&statusNotIn=archived').as('listProjects')
- cy.goToProjects()
- .url().should('match', /\/projects$/)
- .wait('@listProjects').its('response.statusCode').should('eq', 200)
- slugs.forEach(slug => cy.getByDataTestid(`projectTile-${slug}`).should('exist'))
-})
-
-Cypress.Commands.add('archiveProject', (project) => {
- cy.intercept('GET', '/api/v1/projects?filter=member&statusNotIn=archived').as('listProjects')
- cy.intercept('GET', '/api/v1/stages').as('getAllStages')
-
- cy.goToProjects()
- .getByDataTestid(`projectTile-${project.slug}`).click()
-
- cy.url().should('contain', project.slug)
- cy.wait('@getAllStages')
- .getByDataTestid('archiveProjectInput').should('not.exist')
- .getByDataTestid('showArchiveProjectBtn')
- .should('be.visible')
- .click()
- cy.getByDataTestid('confirmDeletionBtn')
- .should('be.disabled')
- cy.getByDataTestid('archiveProjectInput').should('be.visible')
- .type(deleteValidationInput)
- cy.getByDataTestid('confirmDeletionBtn')
- .should('be.enabled')
- .click()
-
- cy.url().should('match', /\/projects$/)
- cy.wait('@listProjects').its('response.statusCode').should('eq', 200)
- cy.getByDataTestid(`projectTile-${project.slug}`)
- .should('not.exist')
-})
-
-Cypress.Commands.add('addRepos', (project, repos) => {
- cy.intercept('POST', '/api/v1/repositories').as('postRepo')
- cy.intercept('GET', `/api/v1/repositories?projectId=${project.id}`).as('listRepos')
-
- const newRepo = repo => ({
- internalRepoName: 'console',
- externalUserName: 'this-is+tobi',
- externalRepoUrl: 'https://github.com/cloud-pi-native/console.git',
- isInfra: false,
- isPrivate: false,
- externalToken: 'private-token',
- ...repo,
- })
-
- const newRepos = repos.map(newRepo)
-
- cy.goToProjects()
- .getByDataTestid(`projectTile-${project.slug}`).click()
-
- newRepos.forEach((repo) => {
- cy.getByDataTestid('addRepoLink').click()
- .get('h2').should('contain', 'Ajouter un dépôt au projet')
- .getByDataTestid('internalRepoNameInput').type(repo.internalRepoName)
- .getByDataTestid('externalRepoUrlInput').clear().type(repo.externalRepoUrl)
-
- if (repo.isPrivate) {
- cy.getByDataTestid('input-checkbox-privateRepoCbx').check({ force: true })
- if (repo.externalUserName) {
- cy.getByDataTestid('externalUserNameInput').type(repo.externalUserName)
- }
- if (repo.externalToken) {
- cy.getByDataTestid('externalTokenInput').clear().type(repo.externalToken)
- }
- }
-
- if (repo.isInfra) {
- cy.getByDataTestid('input-checkbox-infraRepoCbx').check({ force: true })
- }
-
- cy.getByDataTestid('addRepoBtn').click()
- cy.wait('@postRepo').its('response.statusCode').should('eq', 201)
- cy.wait('@listRepos').its('response.statusCode').should('eq', 200)
- cy.getByDataTestid(`repoTr-${repo.internalRepoName}`).should('exist')
- })
-})
-
-Cypress.Commands.add('assertAddRepo', (project, repos) => {
- cy.goToProjects()
- .getByDataTestid(`projectTile-${project.slug}`).click()
- .getByDataTestid('test-tab-resources').click()
-
- repos.forEach((repo) => {
- cy.getByDataTestid(`repoTr-${repo.internalRepoName}`).should('exist')
- })
-})
-
-Cypress.Commands.add('deleteRepo', (project, repo) => {
- cy.goToProjects()
- .getByDataTestid(`projectTile-${project.slug}`).click()
-
- cy.getByDataTestid(`repoTr-${repo.internalRepoName}`).click()
- .getByDataTestid('repo-form').should('exist')
- .getByDataTestid('deleteRepoInput').should('not.exist')
- .getByDataTestid('deleteRepoZone')
- .scrollIntoView()
- .should('be.visible')
- .getByDataTestid('showDeleteRepoBtn').click()
- .getByDataTestid('deleteRepoBtn')
- .should('be.disabled')
- .getByDataTestid('deleteRepoInput').should('be.visible')
- .type(deleteValidationInput)
- .getByDataTestid('deleteRepoBtn')
- .should('be.enabled')
- .click()
- .getByDataTestid('repo-form').should('not.exist')
- .reload()
- .getByDataTestid(`repoTr-${repo.internalRepoName}`)
- .should('not.exist')
-})
-
-Cypress.Commands.add('addEnvironment', (project, environments) => {
- cy.intercept('GET', 'api/v1/stages').as('listStages')
- cy.intercept('GET', `api/v1/environments?projectId=${project.id}`).as('listEnvironments')
- cy.intercept('GET', 'api/v1/quotas').as('listQuotas')
- cy.intercept('GET', 'api/v1/clusters').as('getClusters')
- cy.intercept('POST', '/api/v1/environments').as('postEnvironment')
- cy.intercept('GET', '/api/v1/projects?filter=member&statusNotIn=archived').as('listProjects')
-
- cy.goToProjects()
- .getByDataTestid(`projectTile-${project?.slug}`)
- .click()
- cy.getByDataTestid('test-tab-resources')
- .click()
- cy.wait('@getClusters')
-
- environments.forEach((environment) => {
- cy.getByDataTestid('addEnvironmentLink').click()
- cy.wait('@listStages')
- cy.wait('@listQuotas')
- cy.get('h1').should('contain', 'Ajouter un environnement au projet')
- cy.getByDataTestid('environmentNameInput')
- .type(environment?.name)
- cy.get('#zone-select')
- .select('a66c4230-eba6-41f1-aae5-bb1e4f90cce2')
- cy.get('#stage-select')
- .select(environment?.stage?.id)
- cy.get('#quota-select')
- .select(environment?.quota?.id)
- cy.get('#cluster-select')
- .select(environment?.cluster?.id)
-
- cy.getByDataTestid('addEnvironmentBtn').click()
- cy.wait('@postEnvironment').its('response.statusCode').should('eq', 201)
- cy.wait('@listEnvironments').its('response.statusCode').should('eq', 200)
- cy.getByDataTestid(`environmentTr-${environment?.name}`).should('exist')
- })
-})
-
-Cypress.Commands.add('assertAddEnvironment', (project, environments, isDeepCheck = true) => {
- cy.intercept('GET', '/api/v1/environments?projectId=*').as('listEnvironments')
- cy.intercept('GET', 'api/v1/clusters').as('getClusters')
- cy.intercept('GET', 'api/v1/stages').as('listStages')
- cy.intercept('GET', 'api/v1/quotas').as('listQuotas')
- cy.goToProjects()
- .getByDataTestid(`projectTile-${project.slug}`)
- .click()
- cy.getByDataTestid('test-tab-resources')
- .click()
- cy.wait('@listEnvironments')
- cy.wait('@getClusters')
-
- environments.forEach((environment) => {
- cy.getByDataTestid(`environmentTr-${environment.name}`)
- .should('exist')
- if (isDeepCheck) {
- cy.getByDataTestid(`environmentTr-${environment.name}`)
- .click()
- cy.wait('@listStages')
- cy.wait('@listQuotas')
- cy.getByDataTestid('environmentNameInput')
- .should('have.value', environment?.name)
- cy.get('#zone-select')
- .should('have.value', 'a66c4230-eba6-41f1-aae5-bb1e4f90cce2')
- cy.get('#stage-select')
- .should('have.value', environment?.stage?.id)
- cy.get('#quota-select')
- .should('have.value', environment?.quota?.id)
- cy.get('#cluster-select')
- .should('have.value', environment?.cluster?.id)
- cy.getByDataTestid('cancelEnvironmentBtn')
- .click()
- cy.getByDataTestid('resource-modal')
- .should('not.exist')
- }
- })
-})
-
-Cypress.Commands.add('deleteEnvironment', (project, environmentName) => {
- cy.intercept('GET', '/api/v1/environments?projectId=*').as('listEnvironments')
- cy.intercept('GET', 'api/v1/clusters').as('getClusters')
- cy.intercept('DELETE', '/api/v1/environments/*').as('deleteEnvironment')
- cy.intercept('GET', '/api/v1/projects?filter=member&statusNotIn=archived').as('listProjects')
-
- cy.goToProjects()
- cy.getByDataTestid(`projectTile-${project.slug}`).click()
- cy.wait('@listEnvironments')
- cy.wait('@getClusters')
- cy.getByDataTestid(`environmentTr-${environmentName}`)
- .click()
- cy.getByDataTestid('showDeleteEnvironmentBtn').click()
- cy.getByDataTestid('deleteEnvironmentInput').should('be.visible')
- cy.getByDataTestid('deleteEnvironmentInput')
- .type(environmentName.slice(0, 2))
- cy.getByDataTestid('deleteEnvironmentBtn').should('be.disabled')
- cy.getByDataTestid('deleteEnvironmentInput').clear()
- .type(deleteValidationInput)
- cy.getByDataTestid('deleteEnvironmentBtn').should('be.enabled')
- .click()
- cy.wait('@deleteEnvironment').its('response.statusCode').should('eq', 204)
- cy.wait('@listProjects').its('response.statusCode').should('eq', 200)
- cy.getByDataTestid(`environmentTr-${environmentName}`).should('not.exist')
-})
-
-Cypress.Commands.add('addProjectMember', (project, userEmail) => {
- cy.intercept('POST', /\/api\/v1\/projects\/[\w-]{36}\/users$/).as('postUser')
-
- cy.goToProjects()
- .getByDataTestid(`projectTile-${project.slug}`).click()
- .getByDataTestid('menuTeam').click()
- .url().should('match', /\/team$/)
- .getByDataTestid('teamTable')
- .find('tbody > tr')
- .should('have.length', project.users.length)
- .getByDataTestid('addUserSuggestionInput')
- .find('input')
- .clear()
- .type(userEmail)
- .getByDataTestid('userErrorInfo')
- .should('not.exist')
- .getByDataTestid('addUserBtn')
- .should('be.enabled').click()
- .wait('@postUser')
- .its('response.statusCode').should('eq', 201)
- .getByDataTestid('teamTable')
- .find('tbody > tr')
- .should('have.length', project.users.length + 1)
-})
-
-Cypress.Commands.add('assertUsers', (project, emails) => {
- cy.goToProjects()
- .getByDataTestid(`projectTile-${project.slug}`).click()
- .getByDataTestid('test-tab-team').click()
-
- emails.forEach((email) => {
- cy.getByDataTestid('teamTable').within(() => {
- cy.get('td')
- .contains(email)
- .should('exist')
- })
- })
-})
-
-Cypress.Commands.add('generateGitLabCI', (ciForms) => {
- let version
- ciForms.forEach((ciForm) => {
- if (ciForm.language === 'java') version = `BUILD_IMAGE_NAME: maven:3.8-openjdk-${ciForm.version}`
- if (ciForm.language === 'node') version = `BUILD_IMAGE_NAME: node:${ciForm.version}`
- if (ciForm.language === 'python') version = `BUILD_IMAGE_NAME: maven:3.8-openjdk-${ciForm.version}`
-
- cy.get('select#type-language-select')
- .select(`${ciForm.language}`)
-
- if (ciForm.language === 'node') {
- cy.getByDataTestid('nodeVersionInput').clear().type(`${ciForm.version}`)
- .getByDataTestid('nodeInstallInput').clear().type(`${ciForm.install}`)
- .getByDataTestid('nodeBuildInput').clear().type(`${ciForm.build}`)
- }
- if (ciForm.language === 'java') {
- cy.getByDataTestid('javaVersionInput').clear().type(`${ciForm.version}`)
- .getByDataTestid('artefactDirInput').clear().type(`${ciForm.artefactDir}`)
- }
- cy.getByDataTestid('workingDirInput').clear().type(`${ciForm.workingDir}`)
- .getByDataTestid('generateCIBtn').click()
- .getByDataTestid('generatedCI').should('be.visible')
- .getByDataTestid('zip-download-link').should('contain', 'Télécharger tous les fichiers')
- .getByDataTestid(`copy-${ciForm.language}-ContentBtn`).should('exist')
- .getByDataTestid('copy-vault-ContentBtn').should('exist')
- .getByDataTestid('copy-docker-ContentBtn').should('exist')
- .getByDataTestid('copy-rules-ContentBtn').should('exist')
- .getByDataTestid('copy-gitlab-ci-dso-ContentBtn').click()
- cy.assertClipboard(version)
- cy.get('.fr-link--download').first().click()
- .find('span').should(($span) => {
- const text = $span.text()
- expect(text).to.match(/zip – \d* bytes/)
- })
- cy.get('.fr-link--download').last().click()
- .find('span').should(($span) => {
- const text = $span.text()
- expect(text).to.match(/YAML – \d* bytes/)
- })
- })
-})
-
-Cypress.Commands.add('assertClipboard', (value) => {
- cy.window().then((win) => {
- win.navigator.clipboard.readText().then((text) => {
- expect(text).to.contain(value)
- })
- })
-})
-
-Cypress.Commands.add('getServicesResponse', () => {
- cy.wait('@getServices').its('response').then((response) => {
- const services = response.body
- services.map(service =>
- cy.getByDataTestid(`${service.name}-info`).should('contain', `${service.code} - ${service.message}`),
- )
- if (services.some(service => service.code >= 400)) {
- cy.getByDataTestid('services-health-badge').should('contain', 'Un ou plusieurs services dysfonctionnent')
- } else {
- cy.getByDataTestid('services-health-badge').should('contain', 'Tous les services fonctionnent')
- }
- })
-})
-
-Cypress.Commands.add('getByDataTestid', (dataTestid, timeout = 4_000) => {
- cy.get(`[data-testid="${dataTestid}"]`, { timeout })
-})
-
-Cypress.Commands.add('selectProject', (element) => {
- cy.getByDataTestid('projectSelector')
- ?.find('select')
- ?.select(element)
-})
-
-Cypress.Commands.add('deleteIndexedDB', () => {
- Cypress.on('window:before:load', (win) => {
- win.indexedDB.deleteDatabase('localforage')
- })
-})
-
-Cypress.on('uncaught:exception', (_err, _runnable) => false)
-
-// Commande pour accéder / interagir avec le store dans les tests
-Cypress.Commands.add('getStore', () => cy.window().its('app.$store'))
-
-// A utiliser sur les éléments détâchés du DOM (lors de rerendu assez lourds dans le DOM)
-// https://github.com/cypress-io/cypress/issues/7306#issuecomment-850621378
-// Recursively gets an element, returning only after it's determined to be attached to the DOM for good
-Cypress.Commands.add('getSettled', (selector, opts = {}) => {
- const retries = opts.retries || 3
- const delay = opts.delay || 100
-
- const isAttached = (resolve, count = 0) => {
- const el = Cypress.$(selector)
-
- // Is element attached to the DOM?
- count = Cypress.dom.isAttached(el) ? count + 1 : 0
-
- // Hit our base case, return the element
- if (count >= retries) {
- return resolve(el)
- }
-
- // Retry after a bit of a delay
- setTimeout(isAttached, delay, resolve, count)
- }
-
- // Wrap, so we can chain cypress commands off the result
- return cy.wrap(null).then(() => {
- return new Cypress.Promise((resolve) => {
- return isAttached(resolve, 0)
- }).then((el) => {
- return cy.wrap(el)
- })
- })
-})
-
-Cypress.Commands.add('goToAdminListUsers', () => {
- cy.get('body').then(($body) => {
- if ($body.find('a').length === 0) {
- // Si l'élément n'est pas trouvé, on considère qu'on est dans les limbes
- cy.visit('/admin/users')
- }
- })
- try {
- cy.getByDataTestid('menuAdministrationUsers', 100).click()
- cy.url().should('contain', '/admin/users')
- } catch {
- cy.getByDataTestid('menuAdministrationBtn').click()
- .getByDataTestid('menuAdministrationUsers').click()
- cy.url().should('contain', '/admin/users')
- }
-})
-
-Cypress.Commands.add('checkTableBody', (tableDataTestId: string, rowLength: number, noResultText?: string) => {
- if (rowLength) {
- cy.getByDataTestid(tableDataTestId)
- .get('tbody > tr')
- .should('not.have.text', noResultText)
- .should('have.length', rowLength)
- } else {
- cy.get('tr:last-child>td:first-child')
- .should('have.text', noResultText)
- }
-})
diff --git a/apps/client/cypress/e2e/support/func.ts b/apps/client/cypress/e2e/support/func.ts
deleted file mode 100644
index 1269d9cf2..000000000
--- a/apps/client/cypress/e2e/support/func.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import type { ProjectV2 } from '@cpn-console/shared'
-import { data } from '@cpn-console/test-utils'
-
-export const getModel = (model: keyof typeof data) => data[model]
-export const getProjectById = (id: string) => getProjects().find((project: ProjectV2) => project.id === id)
-
-export function getModelById(model: string, id: string) {
- return model === 'project'
- ? getProjectById(id)
- : data[model]?.find(key => key.id === id)
-}
-
-export function getProjects(): ProjectV2[] {
- return getModel('project')
- .map(project => ({
- ...project,
- repositories: getModel('repository')
- ?.filter(repository => repository.projectId === project.id),
- environments: getModel('environment')
- ?.filter(environment => environment.projectId === project.id)
- ?.map(environment => ({
- ...environment,
- permissions: getModel('permission')?.filter(permission => permission.environmentId === environment.id),
- })),
- members: getModel('projectMembers')
- ?.filter(member => member.projectId === project.id)
- ?.map(member => ({
- roleIds: member.roleIds,
- ...getModelById('user', member.userId),
- })),
- })) satisfies ProjectV2[]
-}
-
-export function getProjectMembers(userId: string) {
- return getProjects()
- ?.filter(project => project.status !== 'archived' && project.members?.find(member => member.id === userId))
-}
diff --git a/apps/client/cypress/e2e/support/index.ts b/apps/client/cypress/e2e/support/index.ts
deleted file mode 100644
index ad27b743a..000000000
--- a/apps/client/cypress/e2e/support/index.ts
+++ /dev/null
@@ -1,273 +0,0 @@
-// ***********************************************************
-// This example support/index.js is processed and
-// loaded automatically before your test files.
-//
-// This is a great place to put global configuration and
-// behavior that modifies Cypress.
-//
-// You can change the location of this file or turn off
-// automatically serving support files with the
-// 'supportFile' configuration option.
-//
-// You can read more here:
-// https://on.cypress.io/configuration
-// ***********************************************************
-
-/* eslint-disable ts/method-signature-style */
-
-import type { CiForm, Project, Repository } from '../../types.js'
-import './commands.js'
-
-Cypress.on('window:before:load', (win) => {
- let copyText: string
- if (!win.navigator.clipboard) {
- // @ts-ignore
- win.navigator.clipboard = {}
- }
- Object.setPrototypeOf(win.navigator.clipboard, {
- writeText: async (text: string) => (copyText = text),
- readText: async () => copyText,
- })
-})
-
-declare global {
- // eslint-disable-next-line ts/no-namespace
- namespace Cypress {
- interface Chainable {
- /**
- * Custom command to logout from application
- * @example cy.kcLogout()
- */
- kcLogout(): Chainable>
-
- /**
- * Custom command to login to application with a given user
- * @param name
- * @param password
- * @example cy.kcLogin('test', 'test')
- */
- kcLogin(
- name: string,
- password?: string,
- ): Chainable>
-
- /**
- * Custom command to visit the projects page
- * @example cy.goToProjects()
- */
- goToProjects(): Chainable>
-
- /**
- * Custom command to create a new project
- * @param project
- * @example cy.createProject({ name: 'projectName' })
- */
- createProject(
- project: Project
- ): Chainable>
-
- /**
- * Custom command to assert projects creation
- * @param names
- * @example cy.assertCreateProjects(['project1', 'project2'])
- */
- assertCreateProjects(
- names: string[]
- ): Chainable>
-
- /**
- * Custom command to archive a project
- * @param project
- * @example cy.archiveProject({ name: 'projectName' })
- */
- archiveProject(
- project: Project
- ): Chainable>
-
- /**
- * Custom command to add repositories into a project
- * @param project
- * @param repos
- * @example cy.addRepos({ name: 'projectName' }, [{ internalRepoName: 'repo1' }, { internalRepoName: 'repo2' }])
- */
- addRepos(
- project: Project,
- repos: Repository[]
- ): Chainable>
-
- /**
- * Custom command to assert repos creation
- * @param project
- * @param repos
- * @example cy.assertAddRepo({ name: 'projectName' }, [{ internalRepoName: 'repo1' }, { internalRepoName: 'repo2' }])
- */
- assertAddRepo(
- project: Project,
- repos: Repository[]
- ): Chainable>
-
- /**
- * Custom command to delete a repo
- * @param project
- * @param repo
- * @example cy.deleteRepo({ name: 'projectName' }, { internalRepoName: 'repo1' })
- */
- deleteRepo(
- project: Project,
- repo: Repository
- ): Chainable>
-
- /**
- * Custom command to create environments
- * @param project
- * @param environments
- * @example cy.addEnvironment({ name: 'projectName' }, ['preprod', 'prod'])
- */
- addEnvironment(
- project: Project,
- environments: any[]
- ): Chainable>
-
- /**
- * Custom command to assert environments creation
- * @param project
- * @param environments
- * @example cy.assertAddEnvironment({ name: 'projectName' }, ['preprod', 'prod'])
- */
- assertAddEnvironment(
- project: Project,
- environments: any[],
- isDeepCheck?: boolean,
- ): Chainable>
-
- /**
- * Custom command to delete an environment
- * @param project
- * @param environment
- * @example cy.deleteEnvironment({ name: 'projectName' }, 'prod')
- */
- deleteEnvironment(
- project: Project,
- environment: string
- ): Chainable>
-
- /**
- * Custom command to assert permission creations
- * @param project
- * @param environment
- * @param permissions
- * @example cy.assertPermission({ name: 'projectName' }, 'prod', [{ email: 'test1@test.com', isOwner: true }, { email: 'test2@test.com', isOwner: false }])
- */
- assertPermission(
- project: Project,
- environment: string,
- permissions: {
- email: string
- isOwner: boolean
- }[]
- ): Chainable>
-
- /**
- * Custom command to add a member to a project
- * @param project
- * @param userEmail
- * @example cy.addProjectMember({ name: 'projectName' }, 'test@test.com')
- */
- addProjectMember(
- project: Project & {
- users: Record[]
- },
- userEmail: string,
- ): Chainable>
-
- /**
- * Custom command to assert members creation into a project
- * @param project
- * @param emails
- * @example cy.assertUsers({ name: 'projectName' }, ['test1@test.com', 'test2@test.com'])
- */
- assertUsers(
- project: Project,
- emails: string[]
- ): Chainable>
-
- /**
- * Custom command to assert members creation into a project
- * @param ciForms
- * @example cy.generateGitLabCI([{ language: 'node', version: '20.0.0', install: 'npm install', build: 'npm run build',workingDir: './' }])
- */
- generateGitLabCI(
- ciForms: CiForm[]
- ): Chainable>
-
- /**
- * Custom command to assert clipboard value
- * @param value
- * @example cy.assertClipboard('test')
- */
- assertClipboard(
- value: string
- ): Chainable>
-
- /**
- * Custom command to assert services health
- * @example cy.getServicesResponse()
- */
- getServicesResponse(): Chainable>
-
- /**
- * Custom command to get an html element by its 'data-testid'
- * @param dataTestid
- * @param timeout
- * @example cy.getByDataTestid('testBtn')
- */
- getByDataTestid(
- dataTestid: string,
- timeout?: number
- ): Chainable>
-
- /**
- * Custom command to select a project from the selector
- * @param element
- * @example cy.selectProject('project1')
- */
- selectProject(
- element: string
- ): Chainable>
-
- /**
- * Custom command to delete window indexedDB 'localForage'
- * @example cy.deleteIndexedDB()
- */
- deleteIndexedDB(): Chainable>
-
- /**
- * Custom command to access pinia store
- * @example cy.getStore()
- */
- getStore(): Chainable>
-
- /**
- * Custom command to get an html element by its 'data-testid' with a retry system for flaky tests
- * @param selector
- * @param opt
- * @param opt.delay
- * @param opt.retries
- * @example cy.getSettled('testBtn')
- */
- getSettled(
- selector: string,
- opt?: {
- delay?: number
- retries?: number
- }
- ): void
-
- /**
- * Custom command to visit admin user list page
- * @example cy.goToAdminListUsers()
- */
- goToAdminListUsers(): Chainable>
- }
- }
-}
diff --git a/apps/client/cypress/tsconfig.json b/apps/client/cypress/tsconfig.json
deleted file mode 100644
index a2dc2006a..000000000
--- a/apps/client/cypress/tsconfig.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "extends": "../tsconfig.json",
- "compilerOptions": {
- "baseUrl": "./",
- "paths": {
- "@/*": ["../src/*"]
- },
- "types": ["cypress", "node"],
- "noEmit": true
- },
- "include": [
- "./**/*.ts"
- ],
- "exclude": []
-}
diff --git a/apps/client/cypress/types.ts b/apps/client/cypress/types.ts
deleted file mode 100644
index 83274933e..000000000
--- a/apps/client/cypress/types.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import type { Project as ProjectType, Repo } from '@cpn-console/shared'
-
-export type Project = Partial>
-
-export type Repository = Partial
-
-export interface CiForm {
- language: string
- version: string
- install?: string
- build?: string
- artefactDir?: string
- workingDir: string
-}
diff --git a/apps/client/package.json b/apps/client/package.json
index 3ef79cf5e..85e6dd694 100644
--- a/apps/client/package.json
+++ b/apps/client/package.json
@@ -12,7 +12,6 @@
"build": "run-s icons type-check build-only",
"build-only": "vite --mode=production build",
"build:clean": "rimraf ./dist ./tsconfig.tsbuildinfo",
- "cypress:install": "cypress install",
"dev": "vite --mode=development",
"format": "NODE_OPTIONS='--no-warnings=ExperimentalWarning' eslint ./ --fix",
"format:style": "stylelint ./src/**/*.{css,vue} --fix",
@@ -24,10 +23,6 @@
"preview": "vite preview --port 8080",
"test": "vitest run",
"test:cov": "vitest run --coverage",
- "test:ct": "NODE_ENV=test cypress open --component --browser=firefox",
- "test:ct-ci": "NODE_ENV=test cypress run --component --browser=firefox",
- "test:e2e": "cypress open --browser=firefox",
- "test:e2e-ci": "cypress run --browser=firefox",
"type-check": "vue-tsc --noEmit -p tsconfig.json"
},
"dependencies": {
@@ -53,11 +48,6 @@
"vue3-json-viewer": "^2.4.1",
"xbytes": "^1.9.1"
},
- "optionalDependencies": {
- "@cypress/vue": "6.0.2",
- "cypress": "15.6.0",
- "cypress-vite": "1.8.0"
- },
"devDependencies": {
"@cpn-console/eslint-config": "workspace:^",
"@cpn-console/test-utils": "workspace:^",
@@ -70,7 +60,6 @@
"@vitejs/plugin-vue": "^6.0.4",
"@vitest/coverage-v8": "^2.1.9",
"@vue/eslint-config-typescript": "^14.7.0",
- "eslint-plugin-cypress": "^4.3.0",
"eslint-plugin-vue": "^10.8.0",
"jsdom": "^25.0.1",
"npm-run-all": "^4.1.5",
diff --git a/apps/client/vite.config.ts b/apps/client/vite.config.ts
index 07bc1c148..7875604c5 100644
--- a/apps/client/vite.config.ts
+++ b/apps/client/vite.config.ts
@@ -138,9 +138,6 @@ export default defineConfig({
target: 'ESNext',
},
optimizeDeps: {
- entries: [
- './cypress/components/specs/environment-form.ct.ts',
- ],
include: [
'jszip',
],
diff --git a/ci/scripts/run-tests.sh b/ci/scripts/run-tests.sh
index a2de05ee8..cf18c018f 100755
--- a/ci/scripts/run-tests.sh
+++ b/ci/scripts/run-tests.sh
@@ -20,7 +20,6 @@ DOCKER_BUILDX_VERSION="$(docker buildx version)"
# Default
RUN_LINT="false"
RUN_UNIT_TESTS="false"
-RUN_COMPONENT_TESTS="false"
RUN_E2E_TESTS="false"
RUN_STATUS_CHECK="false"
@@ -28,10 +27,6 @@ RUN_STATUS_CHECK="false"
TEXT_HELPER="\nThis script aims to run application tests.
Following flags are available:
- -b (Optional) Browser used for e2e components and tests
-
- -c Run component tests
-
-e Run e2e tests
-l Run lint
@@ -49,13 +44,9 @@ print_help() {
}
# Parse options
-while getopts hb:ceklst:u flag
+while getopts heklst:u flag
do
case "${flag}" in
- b)
- BROWSER=${OPTARG};;
- c)
- RUN_COMPONENT_TESTS=true;;
e)
RUN_E2E_TESTS=true;;
l)
@@ -74,7 +65,7 @@ done
# Script condition
-if [ "$RUN_LINT" == "false" ] && [ "$RUN_UNIT_TESTS" == "false" ] && [ "$RUN_E2E_TESTS" == "false" ] && [ "$RUN_COMPONENT_TESTS" == "false" ] && [ "$RUN_STATUS_CHECK" == "false" ]; then
+if [ "$RUN_LINT" == "false" ] && [ "$RUN_UNIT_TESTS" == "false" ] && [ "$RUN_E2E_TESTS" == "false" ] && [ "$RUN_STATUS_CHECK" == "false" ]; then
printf "\nArgument(s) missing, you don't specify any kind of test to run.\n"
print_help
exit 1
@@ -108,7 +99,6 @@ printf "\nScript settings:
-> docker version: ${DOCKER_VERSION}
-> docker buildx version: ${DOCKER_BUILDX_VERSION}
-> run unit tests: ${RUN_UNIT_TESTS}
- -> run component tests: ${RUN_COMPONENT_TESTS}
-> run e2e tests: ${RUN_E2E_TESTS}
-> run deploy status check: ${RUN_STATUS_CHECK}\n"
@@ -126,18 +116,6 @@ if [ "$RUN_UNIT_TESTS" == "true" ]; then
npm run test:cov
fi
-# Run component tests
-if [ "$RUN_COMPONENT_TESTS" == "true" ]; then
- checkDockerRunning
-
- printf "\n${red}${i}.${no_color} Launch component tests\n"
- i=$(($i + 1))
-
- [[ -n "$BROWSER" ]] && BROWSER_ARGS="-- --browser $BROWSER"
-
- npm run test:ct-ci $BROWSER_ARGS
-fi
-
# Run e2e tests
if [ "$RUN_E2E_TESTS" == "true" ]; then
checkDockerRunning
@@ -145,8 +123,6 @@ if [ "$RUN_E2E_TESTS" == "true" ]; then
printf "\n${red}${i}.${no_color} Launch e2e tests\n"
i=$(($i + 1))
- [[ -n "$BROWSER" ]] && BROWSER_ARGS="-- --browser $BROWSER"
-
npm --prefix $PROJECT_DIR/packages/shared run build
npm --prefix $PROJECT_DIR/packages/test-utils run build
@@ -157,7 +133,7 @@ if [ "$RUN_E2E_TESTS" == "true" ]; then
docker pull ghcr.io/cloud-pi-native/console/nginx-strangler:$TAG && docker tag ghcr.io/cloud-pi-native/console/client:$TAG dso-console/nginx-strangler:ci
fi
- npm run docker:e2e-ci $BROWSER_ARGS
+ npm run docker:e2e-ci
printf "\n${red}${i}.${no_color} Remove resources\n"
i=$(($i + 1))
diff --git a/package.json b/package.json
index 8f1f30219..15f95cea1 100644
--- a/package.json
+++ b/package.json
@@ -23,8 +23,8 @@
"docker:dev:build": "export COMPOSE_FILE=./docker/docker-compose.dev.yml && ./scripts/run-build.sh $COMPOSE_FILE",
"docker:dev:clean": "docker compose -f ./docker/docker-compose.dev.yml down --remove-orphans",
"docker:dev:delete": "docker compose -f ./docker/docker-compose.dev.yml down -v --remove-orphans",
- "docker:e2e": "docker compose -f ./docker/docker-compose.dev.yml up ${TAG:+--no-build} -d --remove-orphans; pnpm --filter=@cpn-console/client run test:e2e; docker compose -f ./docker/docker-compose.dev.yml down --remove-orphans",
- "docker:e2e-ci": "docker compose -f ./docker/docker-compose.ci.yml up ${TAG:+--no-build} -d --remove-orphans; pnpm --filter=@cpn-console/client run test:e2e-ci",
+ "docker:e2e": "docker compose -f ./docker/docker-compose.dev.yml up ${TAG:+--no-build} -d --remove-orphans; pnpm playwright:test; docker compose -f ./docker/docker-compose.dev.yml down --remove-orphans",
+ "docker:e2e-ci": "docker compose -f ./docker/docker-compose.ci.yml up ${TAG:+--no-build} -d --remove-orphans; pnpm playwright:test",
"docker:e2e-ci:delete": "docker compose -f ./docker/docker-compose.ci.yml down -v --remove-orphans",
"docker:integ": "docker compose --env-file apps/server/.env.integ -f ./docker/docker-compose.integ.yml up -d; docker compose --env-file apps/server/.env.integ -f ./docker/docker-compose.integ.yml watch --no-up & docker compose --env-file apps/server/.env.integ -f ./docker/docker-compose.integ.yml logs server client -f",
"docker:integ:build": "export $(cat apps/server/.env.integ | grep -v '#' | xargs) && export COMPOSE_FILE=./docker/docker-compose.integ.yml && cd $(dirname $COMPOSE_FILE) && docker buildx bake --allow=fs.read=.. --file $(basename $COMPOSE_FILE) --load && cd - > /dev/null",
@@ -51,8 +51,6 @@
"prepare": "husky",
"test": "pnpm -r run test",
"test:cov": "pnpm -r run test:cov",
- "test:ct": "pnpm --filter @cpn-console/shared run build && pnpm --filter @cpn-console/test-utils run build && pnpm --filter @cpn-console/client run test:ct",
- "test:ct-ci": "pnpm -r run test:ct-ci",
"test:e2e": "pnpm kube:e2e",
"test:e2e-ci": "pnpm kube:prod; pnpm kube:e2e-ci"
},
@@ -73,7 +71,6 @@
"onlyBuiltDependencies": [
"@prisma/client",
"@prisma/engines",
- "cypress",
"esbuild",
"prisma",
"vue-demi"
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index d9d215a96..cc15cc5df 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -135,9 +135,6 @@ importers:
'@vue/eslint-config-typescript':
specifier: ^14.7.0
version: 14.7.0(eslint-plugin-vue@10.8.0(@stylistic/eslint-plugin@5.10.0(eslint@10.0.3(jiti@2.6.1)))(@typescript-eslint/parser@8.57.0(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.3(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@10.0.3(jiti@2.6.1))))(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)
- eslint-plugin-cypress:
- specifier: ^4.3.0
- version: 4.3.0(eslint@10.0.3(jiti@2.6.1))
eslint-plugin-vue:
specifier: ^10.8.0
version: 10.8.0(@stylistic/eslint-plugin@5.10.0(eslint@10.0.3(jiti@2.6.1)))(@typescript-eslint/parser@8.57.0(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.3(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@10.0.3(jiti@2.6.1)))
@@ -195,16 +192,6 @@ importers:
workbox-window:
specifier: ^7.4.0
version: 7.4.0
- optionalDependencies:
- '@cypress/vue':
- specifier: 6.0.2
- version: 6.0.2(cypress@15.6.0)(vue@3.5.30(typescript@5.9.3))
- cypress:
- specifier: 15.6.0
- version: 15.6.0
- cypress-vite:
- specifier: 1.8.0
- version: 1.8.0(vite@7.3.1(@types/node@24.12.0)(jiti@2.6.1)(terser@5.46.0)(yaml@2.8.2))
apps/server:
dependencies:
@@ -1944,24 +1931,6 @@ packages:
peerDependencies:
postcss-selector-parser: ^7.1.1
- '@cypress/request@3.0.10':
- resolution: {integrity: sha512-hauBrOdvu08vOsagkZ/Aju5XuiZx6ldsLfByg1htFeldhex+PeMrYauANzFsMJeAA0+dyPLbDoX2OYuvVoLDkQ==}
- engines: {node: '>= 6'}
-
- '@cypress/vue@6.0.2':
- resolution: {integrity: sha512-To+Ik4CnhTPMmDh7VGpl5k0Z1LuE0xrI0j6LF7QyjROY2bkQwUE50WTmVPCz/Dvez9WrVpkJjRmflR5KlVmGiQ==}
- engines: {node: '>=18'}
- peerDependencies:
- '@cypress/webpack-dev-server': '*'
- cypress: '>=7.0.0'
- vue: '>=3.0.0'
- peerDependenciesMeta:
- '@cypress/webpack-dev-server':
- optional: true
-
- '@cypress/xvfb@1.2.4':
- resolution: {integrity: sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==}
-
'@e18e/eslint-plugin@0.2.0':
resolution: {integrity: sha512-mXgODVwhuDjTJ+UT+XSvmMmCidtGKfrV5nMIv1UtpWex2pYLsIM3RSpT8HWIMAebS9qANbXPKlSX4BE7ZvuCgA==}
peerDependencies:
@@ -3925,12 +3894,6 @@ packages:
'@types/serve-static@2.2.0':
resolution: {integrity: sha512-8mam4H1NHLtu7nmtalF7eyBH14QyOASmcxHhSfEoRyr0nP/YdoesEtU+uSRvMe96TW/HPTtkoKqQLl53N7UXMQ==}
- '@types/sinonjs__fake-timers@8.1.1':
- resolution: {integrity: sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==}
-
- '@types/sizzle@2.3.10':
- resolution: {integrity: sha512-TC0dmN0K8YcWEAEfiPi5gJP14eJe30TTGjkvek3iM/1NdHHsdCA/Td6GvNndMOo/iSnIsZ4HuuhrYPDAmbxzww==}
-
'@types/statuses@2.0.6':
resolution: {integrity: sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA==}
@@ -3946,9 +3909,6 @@ packages:
'@types/tedious@4.0.14':
resolution: {integrity: sha512-KHPsfX/FoVbUGbyYvk1q9MMQHLPeRZhRJZdO45Q4YjvFkv4hMNghCWTvy7rdKessBsmtz4euWCWAB6/tVpI1Iw==}
- '@types/tmp@0.2.6':
- resolution: {integrity: sha512-chhaNf2oKHlRkDGt+tiKE2Z5aJ6qalm7Z9rlLdBwmOiAAf09YQvvoLXjWK4HWPF1xU/fqvMgfNfpVoBscA/tKA==}
-
'@types/tough-cookie@4.0.5':
resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==}
@@ -3958,9 +3918,6 @@ packages:
'@types/unist@3.0.3':
resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==}
- '@types/yauzl@2.10.3':
- resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==}
-
'@typescript-eslint/eslint-plugin@8.57.0':
resolution: {integrity: sha512-qeu4rTHR3/IaFORbD16gmjq9+rEs9fGKdX0kF6BKSfi+gCuG3RCKLlSBYzn/bGsY9Tj7KE/DAQStbp8AHJGHEQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
@@ -4324,10 +4281,6 @@ packages:
resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==}
engines: {node: '>= 14'}
- aggregate-error@3.1.0:
- resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==}
- engines: {node: '>=8'}
-
ajv-draft-04@1.0.0:
resolution: {integrity: sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==}
peerDependencies:
@@ -4388,10 +4341,6 @@ packages:
resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==}
engines: {node: '>=6'}
- ansi-escapes@4.3.2:
- resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==}
- engines: {node: '>=8'}
-
ansi-escapes@7.3.0:
resolution: {integrity: sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==}
engines: {node: '>=18'}
@@ -4430,9 +4379,6 @@ packages:
append-field@1.0.0:
resolution: {integrity: sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==}
- arch@2.2.0:
- resolution: {integrity: sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==}
-
are-docs-informative@0.0.2:
resolution: {integrity: sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==}
engines: {node: '>=14'}
@@ -4463,13 +4409,6 @@ packages:
asn1.js@5.4.1:
resolution: {integrity: sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==}
- asn1@0.2.6:
- resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==}
-
- assert-plus@1.0.0:
- resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==}
- engines: {node: '>=0.8'}
-
assertion-error@2.0.1:
resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==}
engines: {node: '>=12'}
@@ -4503,12 +4442,6 @@ packages:
avvio@8.4.0:
resolution: {integrity: sha512-CDSwaxINFy59iNwhYnkvALBwZiTydGkOecZyPkqBpABYR1KqGEsET0VOOYDwtleZSUIdeY36DC2bSZ24CO1igA==}
- aws-sign2@0.7.0:
- resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==}
-
- aws4@1.13.2:
- resolution: {integrity: sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==}
-
axios-retry@4.5.0:
resolution: {integrity: sha512-aR99oXhpEDGo0UuAlYcn2iGRds30k366Zfa05XWScR9QaQD4JYiP3/1Qt1u7YlefUOK+cn0CcwoL1oefavQUlQ==}
peerDependencies:
@@ -4547,9 +4480,6 @@ packages:
engines: {node: '>=6.0.0'}
hasBin: true
- bcrypt-pbkdf@1.0.2:
- resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==}
-
bignumber.js@9.3.1:
resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==}
@@ -4560,12 +4490,6 @@ packages:
bl@4.1.0:
resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==}
- blob-util@2.0.2:
- resolution: {integrity: sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==}
-
- bluebird@3.7.2:
- resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==}
-
bn.js@4.12.3:
resolution: {integrity: sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g==}
@@ -4598,9 +4522,6 @@ packages:
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
hasBin: true
- buffer-crc32@0.2.13:
- resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==}
-
buffer-equal-constant-time@1.0.1:
resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==}
@@ -4649,10 +4570,6 @@ packages:
cacheable@2.3.3:
resolution: {integrity: sha512-iffYMX4zxKp54evOH27fm92hs+DeC1DhXmNVN8Tr94M/iZIV42dqTHSR2Ik4TOSPyOAwKr7Yu3rN9ALoLkbWyQ==}
- cachedir@2.4.0:
- resolution: {integrity: sha512-9EtFOZR8g22CL7BWjJ9BUx1+A/djkofnyW3aOXZORNW2kxoUpx2h+uN2cOqwPmFhnpVmxg+KW2OjOSgChTEvsQ==}
- engines: {node: '>=6'}
-
call-bind-apply-helpers@1.0.2:
resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
engines: {node: '>= 0.4'}
@@ -4679,9 +4596,6 @@ packages:
caniuse-lite@1.0.30001777:
resolution: {integrity: sha512-tmN+fJxroPndC74efCdp12j+0rk0RHwV5Jwa1zWaFVyw2ZxAuPeG8ZgWC3Wz7uSjT3qMRQ5XHZ4COgQmsCMJAQ==}
- caseless@0.12.0:
- resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==}
-
ccount@2.0.1:
resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==}
@@ -4750,10 +4664,6 @@ packages:
resolution: {integrity: sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==}
engines: {node: '>=4'}
- clean-stack@2.2.0:
- resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==}
- engines: {node: '>=6'}
-
cli-cursor@3.1.0:
resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==}
engines: {node: '>=8'}
@@ -4766,18 +4676,10 @@ packages:
resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==}
engines: {node: '>=6'}
- cli-table3@0.6.1:
- resolution: {integrity: sha512-w0q/enDHhPLq44ovMGdQeeDLvwxwavsJX7oQGYt/LrBlYsyaxyDnp6z3QzFut/6kLLKnlcUVJLrpB7KBfgG/RA==}
- engines: {node: 10.* || >= 12.*}
-
cli-table3@0.6.5:
resolution: {integrity: sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==}
engines: {node: 10.* || >= 12.*}
- cli-truncate@2.1.0:
- resolution: {integrity: sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==}
- engines: {node: '>=8'}
-
cli-truncate@5.2.0:
resolution: {integrity: sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw==}
engines: {node: '>=20'}
@@ -4820,10 +4722,6 @@ packages:
colorette@2.0.20:
resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==}
- colors@1.4.0:
- resolution: {integrity: sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==}
- engines: {node: '>=0.1.90'}
-
combined-stream@1.0.8:
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
engines: {node: '>= 0.8'}
@@ -4839,10 +4737,6 @@ packages:
resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
engines: {node: '>= 6'}
- commander@6.2.1:
- resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==}
- engines: {node: '>= 6'}
-
comment-json@4.4.1:
resolution: {integrity: sha512-r1To31BQD5060QdkC+Iheai7gHwoSZobzunqkf2/kQ6xIAfJyrKNAFUwdKvkK7Qgu7pVTKQEa7ok7Ed3ycAJgg==}
engines: {node: '>= 6'}
@@ -4924,9 +4818,6 @@ packages:
core-js-compat@3.48.0:
resolution: {integrity: sha512-OM4cAF3D6VtH/WkLtWvyNC56EZVXsZdU3iqaMG2B4WvYrlqU831pc4UtG5yp0sE9z8Y02wVN7PjW5Zf9Gt0f1Q==}
- core-util-is@1.0.2:
- resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==}
-
core-util-is@1.0.3:
resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==}
@@ -4998,24 +4889,10 @@ packages:
csstype@3.2.3:
resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
- cypress-vite@1.8.0:
- resolution: {integrity: sha512-rPkIpDzCIo+upsDkFa/NlrnzVumuQ45UcwL7a2k/n8WFIwsW8QYuQaWU2JiIKExP/LNQew3H3Hbs/bp26xC0Fw==}
- peerDependencies:
- vite: ^2.9.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0
-
- cypress@15.6.0:
- resolution: {integrity: sha512-Vqo66GG1vpxZ7H1oDX9umfmzA3nF7Wy80QAc3VjwPREO5zTY4d1xfQFNPpOWleQl9vpdmR2z1liliOcYlRX6rQ==}
- engines: {node: ^20.1.0 || ^22.0.0 || >=24.0.0}
- hasBin: true
-
dargs@8.1.0:
resolution: {integrity: sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==}
engines: {node: '>=12'}
- dashdash@1.14.1:
- resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==}
- engines: {node: '>=0.10'}
-
data-uri-to-buffer@4.0.1:
resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==}
engines: {node: '>= 12'}
@@ -5048,14 +4925,6 @@ packages:
de-indent@1.0.2:
resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==}
- debug@3.2.7:
- resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
- peerDependencies:
- supports-color: '*'
- peerDependenciesMeta:
- supports-color:
- optional: true
-
debug@4.4.3:
resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
engines: {node: '>=6.0'}
@@ -5190,9 +5059,6 @@ packages:
eastasianwidth@0.2.0:
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
- ecc-jsbn@0.1.2:
- resolution: {integrity: sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==}
-
ecdsa-sig-formatter@1.0.11:
resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==}
@@ -5237,10 +5103,6 @@ packages:
resolution: {integrity: sha512-/ce7+jQ1PQ6rVXwe+jKEg5hW5ciicHwIQUagZkp6IufBoY3YDgdTTY1azVs0qoRgVmvsNB+rbjLJxDAeHHtwsQ==}
engines: {node: '>=10.13.0'}
- enquirer@2.4.1:
- resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==}
- engines: {node: '>=8.6'}
-
entities@4.5.0:
resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
engines: {node: '>=0.12'}
@@ -5372,11 +5234,6 @@ packages:
'@typescript-eslint/utils': '*'
eslint: '*'
- eslint-plugin-cypress@4.3.0:
- resolution: {integrity: sha512-CgS/S940MJlT8jtnWGKI0LvZQBGb/BB0QCpgBOxFMM/Z6znD+PZUwBhCTwHKN2GEr5AOny3xB92an0QfzBGooQ==}
- peerDependencies:
- eslint: '>=9'
-
eslint-plugin-depend@1.5.0:
resolution: {integrity: sha512-i3UeLYmclf1Icp35+6W7CR4Bp2PIpDgBuf/mpmXK5UeLkZlvYJ21VuQKKHHAIBKRTPivPGX/gZl5JGno1o9Y0A==}
peerDependencies:
@@ -5574,9 +5431,6 @@ packages:
resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==}
engines: {node: '>= 0.6'}
- eventemitter2@6.4.7:
- resolution: {integrity: sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg==}
-
eventemitter3@5.0.4:
resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==}
@@ -5584,14 +5438,6 @@ packages:
resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==}
engines: {node: '>=0.8.x'}
- execa@4.1.0:
- resolution: {integrity: sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==}
- engines: {node: '>=10'}
-
- executable@4.1.1:
- resolution: {integrity: sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==}
- engines: {node: '>=4'}
-
expect-type@1.3.0:
resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==}
engines: {node: '>=12.0.0'}
@@ -5606,15 +5452,6 @@ packages:
extend@3.0.2:
resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==}
- extract-zip@2.0.1:
- resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==}
- engines: {node: '>= 10.17.0'}
- hasBin: true
-
- extsprintf@1.3.0:
- resolution: {integrity: sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==}
- engines: {'0': node >=0.6.0}
-
fast-check@3.23.2:
resolution: {integrity: sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A==}
engines: {node: '>=8.0.0'}
@@ -5692,9 +5529,6 @@ packages:
fault@2.0.1:
resolution: {integrity: sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==}
- fd-slicer@1.1.0:
- resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==}
-
fdir@6.5.0:
resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
engines: {node: '>=12.0.0'}
@@ -5708,10 +5542,6 @@ packages:
resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==}
engines: {node: ^12.20 || >= 14.13}
- figures@3.2.0:
- resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==}
- engines: {node: '>=8'}
-
file-entry-cache@11.1.2:
resolution: {integrity: sha512-N2WFfK12gmrK1c1GXOqiAJ1tc5YE+R53zvQ+t5P8S5XhnmKYVB5eZEiLNZKDSmoG8wqqbF9EXYBBW/nef19log==}
@@ -5782,9 +5612,6 @@ packages:
resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==}
engines: {node: '>=14'}
- forever-agent@0.6.1:
- resolution: {integrity: sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==}
-
fork-ts-checker-webpack-plugin@9.1.0:
resolution: {integrity: sha512-mpafl89VFPJmhnJ1ssH+8wmM2b50n+Rew5x42NeI2U78aRWgtkEtGmctp7iT16UjquJTjorEmIfESj3DxdW84Q==}
engines: {node: '>=14.21.3'}
@@ -5888,10 +5715,6 @@ packages:
resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==}
engines: {node: '>= 0.4'}
- get-stream@5.2.0:
- resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==}
- engines: {node: '>=8'}
-
get-symbol-description@1.1.0:
resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==}
engines: {node: '>= 0.4'}
@@ -5899,9 +5722,6 @@ packages:
get-tsconfig@4.13.6:
resolution: {integrity: sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==}
- getpass@0.1.7:
- resolution: {integrity: sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==}
-
giget@2.0.0:
resolution: {integrity: sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==}
hasBin: true
@@ -5949,10 +5769,6 @@ packages:
resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==}
engines: {node: '>=18'}
- global-dirs@3.0.1:
- resolution: {integrity: sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==}
- engines: {node: '>=10'}
-
global-modules@2.0.0:
resolution: {integrity: sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==}
engines: {node: '>=6'}
@@ -6055,10 +5871,6 @@ packages:
hash.js@1.1.7:
resolution: {integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==}
- hasha@5.2.2:
- resolution: {integrity: sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==}
- engines: {node: '>=8'}
-
hashery@1.5.0:
resolution: {integrity: sha512-nhQ6ExaOIqti2FDWoEMWARUqIKyjr2VcZzXShrI+A3zpeiuPWzx6iPftt44LhP74E5sW36B75N6VHbvRtpvO6Q==}
engines: {node: '>=20'}
@@ -6119,10 +5931,6 @@ packages:
resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==}
engines: {node: '>= 14'}
- http-signature@1.4.0:
- resolution: {integrity: sha512-G5akfn7eKbpDN+8nPS/cb57YeA1jLTVxjpCj7tmm3QKPdyDy7T+qSC40e9ptydSWvkwjSXw1VbkpyEm39ukeAg==}
- engines: {node: '>=0.10'}
-
http2-client@1.3.5:
resolution: {integrity: sha512-EC2utToWl4RKfs5zd36Mxq7nzHHBuomZboI0yYL6Y0RmBgT7Sgkq4rQ0ezFTYoIsSs7Tm9SJe+o2FcAg6GBhGA==}
@@ -6130,10 +5938,6 @@ packages:
resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==}
engines: {node: '>= 14'}
- human-signals@1.1.1:
- resolution: {integrity: sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==}
- engines: {node: '>=8.12.0'}
-
husky@9.1.7:
resolution: {integrity: sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==}
engines: {node: '>=18'}
@@ -6185,10 +5989,6 @@ packages:
resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
engines: {node: '>=0.8.19'}
- indent-string@4.0.0:
- resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==}
- engines: {node: '>=8'}
-
indent-string@5.0.0:
resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==}
engines: {node: '>=12'}
@@ -6199,10 +5999,6 @@ packages:
ini@1.3.8:
resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==}
- ini@2.0.0:
- resolution: {integrity: sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==}
- engines: {node: '>=10'}
-
ini@4.1.1:
resolution: {integrity: sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==}
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
@@ -6299,10 +6095,6 @@ packages:
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
engines: {node: '>=0.10.0'}
- is-installed-globally@0.4.0:
- resolution: {integrity: sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==}
- engines: {node: '>=10'}
-
is-interactive@1.0.0:
resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==}
engines: {node: '>=8'}
@@ -6337,10 +6129,6 @@ packages:
resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==}
engines: {node: '>=8'}
- is-path-inside@3.0.3:
- resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==}
- engines: {node: '>=8'}
-
is-path-inside@4.0.0:
resolution: {integrity: sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==}
engines: {node: '>=12'}
@@ -6395,9 +6183,6 @@ packages:
resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==}
engines: {node: '>= 0.4'}
- is-typedarray@1.0.0:
- resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==}
-
is-unicode-supported@0.1.0:
resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==}
engines: {node: '>=10'}
@@ -6427,9 +6212,6 @@ packages:
resolution: {integrity: sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w==}
engines: {node: '>=18'}
- isstream@0.1.2:
- resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==}
-
istanbul-lib-coverage@3.2.2:
resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==}
engines: {node: '>=8'}
@@ -6491,9 +6273,6 @@ packages:
resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==}
hasBin: true
- jsbn@0.1.1:
- resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==}
-
jsdoc-type-pratt-parser@7.1.1:
resolution: {integrity: sha512-/2uqY7x6bsrpi3i9LVU6J89352C0rpMk0as8trXxCtvd4kPk1ke/Eyif6wqfSLvoNJqcDG9Vk4UsXgygzCt2xA==}
engines: {node: '>=20.0.0'}
@@ -6547,9 +6326,6 @@ packages:
json-stable-stringify-without-jsonify@1.0.1:
resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
- json-stringify-safe@5.0.1:
- resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==}
-
json5@2.2.3:
resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==}
engines: {node: '>=6'}
@@ -6569,10 +6345,6 @@ packages:
resolution: {integrity: sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==}
engines: {node: '>=0.10.0'}
- jsprim@2.0.2:
- resolution: {integrity: sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==}
- engines: {'0': node >=0.6.0}
-
jszip@3.10.1:
resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==}
@@ -6620,15 +6392,6 @@ packages:
engines: {node: '>=20.17'}
hasBin: true
- listr2@3.14.0:
- resolution: {integrity: sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==}
- engines: {node: '>=10.0.0'}
- peerDependencies:
- enquirer: '>= 2.3.0 < 3'
- peerDependenciesMeta:
- enquirer:
- optional: true
-
listr2@9.0.5:
resolution: {integrity: sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g==}
engines: {node: '>=20.0.0'}
@@ -6672,9 +6435,6 @@ packages:
lodash.mergewith@4.6.2:
resolution: {integrity: sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==}
- lodash.once@4.1.1:
- resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==}
-
lodash.snakecase@4.1.1:
resolution: {integrity: sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==}
@@ -6697,10 +6457,6 @@ packages:
resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==}
engines: {node: '>=10'}
- log-update@4.0.0:
- resolution: {integrity: sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==}
- engines: {node: '>=10'}
-
log-update@6.1.0:
resolution: {integrity: sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==}
engines: {node: '>=18'}
@@ -7137,10 +6893,6 @@ packages:
engines: {node: '>= 4'}
hasBin: true
- npm-run-path@4.0.1:
- resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==}
- engines: {node: '>=8'}
-
nth-check@2.1.1:
resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==}
@@ -7232,9 +6984,6 @@ packages:
resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==}
engines: {node: '>=10'}
- ospath@1.2.2:
- resolution: {integrity: sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==}
-
outvariant@1.4.3:
resolution: {integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==}
@@ -7263,10 +7012,6 @@ packages:
resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
engines: {node: '>=10'}
- p-map@4.0.0:
- resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==}
- engines: {node: '>=10'}
-
package-json-from-dist@1.0.1:
resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==}
@@ -7355,18 +7100,12 @@ packages:
resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==}
engines: {node: '>= 14.16'}
- pend@1.2.0:
- resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==}
-
perfect-debounce@1.0.0:
resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==}
perfect-debounce@2.1.0:
resolution: {integrity: sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==}
- performance-now@2.1.0:
- resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==}
-
pg-int8@1.0.1:
resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==}
engines: {node: '>=4.0.0'}
@@ -7402,10 +7141,6 @@ packages:
engines: {node: '>=0.10'}
hasBin: true
- pify@2.3.0:
- resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==}
- engines: {node: '>=0.10.0'}
-
pify@3.0.0:
resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==}
engines: {node: '>=4'}
@@ -7544,10 +7279,6 @@ packages:
process-warning@5.0.0:
resolution: {integrity: sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==}
- process@0.11.10:
- resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==}
- engines: {node: '>= 0.6.0'}
-
protobufjs@7.5.4:
resolution: {integrity: sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==}
engines: {node: '>=12.0.0'}
@@ -7560,9 +7291,6 @@ packages:
resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==}
engines: {node: '>= 0.10'}
- proxy-from-env@1.0.0:
- resolution: {integrity: sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==}
-
proxy-from-env@1.1.0:
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
@@ -7583,10 +7311,6 @@ packages:
resolution: {integrity: sha512-tsSGN1x3h569ZSU1u6diwhltLyfUWDp3YbFHedapTmpBl0B3P6U3+Qptg7xu+v+1io1EwhdPyyRHYbEw0KN2FA==}
engines: {node: '>=20'}
- qs@6.14.2:
- resolution: {integrity: sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==}
- engines: {node: '>=0.6'}
-
qs@6.15.0:
resolution: {integrity: sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==}
engines: {node: '>=0.6'}
@@ -7713,9 +7437,6 @@ packages:
resolution: {integrity: sha512-85THTg1RgOYtqQw42JON6AqvHLptlj1biw265Tsq4fD4cPdUvhDB2Qh9NTv17yCD322ROuO9aOmpc4GyayGVBA==}
engines: {node: '>=8.0.0'}
- request-progress@3.0.0:
- resolution: {integrity: sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg==}
-
require-directory@2.1.1:
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
engines: {node: '>=0.10.0'}
@@ -7995,10 +7716,6 @@ packages:
resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==}
engines: {node: '>=14.16'}
- slice-ansi@3.0.0:
- resolution: {integrity: sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==}
- engines: {node: '>=8'}
-
slice-ansi@4.0.0:
resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==}
engines: {node: '>=10'}
@@ -8069,11 +7786,6 @@ packages:
resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==}
engines: {node: '>= 10.x'}
- sshpk@1.18.0:
- resolution: {integrity: sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==}
- engines: {node: '>=0.10.0'}
- hasBin: true
-
stackback@0.0.2:
resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
@@ -8168,10 +7880,6 @@ packages:
resolution: {integrity: sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==}
engines: {node: '>=10'}
- strip-final-newline@2.0.0:
- resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==}
- engines: {node: '>=6'}
-
strip-indent@4.1.1:
resolution: {integrity: sha512-SlyRoSkdh1dYP0PzclLE7r0M9sgbFKKMFXpFRUMNuKhQSbC6VQIGzq3E0qsfvGJaUFJPGv6Ws1NZ/haTAjfbMA==}
engines: {node: '>=12'}
@@ -8280,12 +7988,6 @@ packages:
resolution: {integrity: sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==}
engines: {node: ^14.18.0 || >=16.0.0}
- systeminformation@5.27.7:
- resolution: {integrity: sha512-saaqOoVEEFaux4v0K8Q7caiauRwjXC4XbD2eH60dxHXbpKxQ8kH9Rf7Jh+nryKpOUSEFxtCdBlSUx0/lO6rwRg==}
- engines: {node: '>=8.0.0'}
- os: [darwin, linux, win32, freebsd, openbsd, netbsd, sunos, android]
- hasBin: true
-
tabbable@6.4.0:
resolution: {integrity: sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==}
@@ -8344,12 +8046,6 @@ packages:
resolution: {integrity: sha512-4iMVL6HAINXWf1ZKZjIPcz5wYaOdPhtO8ATvZ+Xqp3BTdaqtAwQkNmKORqcIo5YkQqGXq5cwfswDwMqqQNrpJA==}
engines: {node: '>=20'}
- throttleit@1.0.1:
- resolution: {integrity: sha512-vDZpf9Chs9mAdfY046mcPt8fg5QSZr37hEH4TXYBnDF+izxgrbRGUAAaBvIk/fJm9aOFCGFd1EsNg5AZCbnQCQ==}
-
- through@2.3.8:
- resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==}
-
tiny-emitter@2.1.0:
resolution: {integrity: sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==}
@@ -8393,10 +8089,6 @@ packages:
resolution: {integrity: sha512-keinCnPbwXEUG3ilrWQZU+CqcTTzHq9m2HhoUP2l7Xmi8l1LuijAXLpAJ5zRW+ifKTNscs4NdCkfkDCBYm352w==}
hasBin: true
- tmp@0.2.5:
- resolution: {integrity: sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==}
- engines: {node: '>=14.14'}
-
to-regex-range@5.0.1:
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
engines: {node: '>=8.0'}
@@ -8447,10 +8139,6 @@ packages:
resolution: {integrity: sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==}
engines: {node: '>=18'}
- tree-kill@1.2.2:
- resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==}
- hasBin: true
-
ts-algebra@2.0.0:
resolution: {integrity: sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw==}
@@ -8513,12 +8201,6 @@ packages:
tslib@2.8.1:
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
- tunnel-agent@0.6.0:
- resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==}
-
- tweetnacl@0.14.5:
- resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==}
-
type-check@0.4.0:
resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
engines: {node: '>= 0.8.0'}
@@ -8527,14 +8209,6 @@ packages:
resolution: {integrity: sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==}
engines: {node: '>=10'}
- type-fest@0.21.3:
- resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==}
- engines: {node: '>=10'}
-
- type-fest@0.8.1:
- resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==}
- engines: {node: '>=8'}
-
type-fest@5.4.4:
resolution: {integrity: sha512-JnTrzGu+zPV3aXIUhnyWJj4z/wigMsdYajGLIYakqyOW1nPllzXEJee0QQbHj+CTIQtXGlAjuK0UY+2xTyjVAw==}
engines: {node: '>=20'}
@@ -8730,10 +8404,6 @@ packages:
until-async@3.0.2:
resolution: {integrity: sha512-IiSk4HlzAMqTUseHHe3VhIGyuFmN90zMTpD3Z3y8jeQbzLIq500MVM7Jq2vUAnTKAFPJrqwkzr6PoTcPhGcOiw==}
- untildify@4.0.0:
- resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==}
- engines: {node: '>=8'}
-
upath@1.2.0:
resolution: {integrity: sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==}
engines: {node: '>=4'}
@@ -8772,10 +8442,6 @@ packages:
resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==}
engines: {node: '>= 0.8'}
- verror@1.10.0:
- resolution: {integrity: sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==}
- engines: {'0': node >=0.6.0}
-
vite-node@2.1.9:
resolution: {integrity: sha512-AM9aQ/IPrW/6ENLQg3AGY4K1N2TGZdR5e4gu/MmmR2xR3Ll1+dib+nook92g4TV3PXVyeyxdWwtaCAiUL0hMxA==}
engines: {node: ^18.0.0 || >=20.0.0}
@@ -9180,9 +8846,6 @@ packages:
resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==}
engines: {node: '>=12'}
- yauzl@2.10.0:
- resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==}
-
yn@3.1.1:
resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==}
engines: {node: '>=6'}
@@ -9397,7 +9060,7 @@ snapshots:
'@babel/types': 7.29.0
'@jridgewell/remapping': 2.3.5
convert-source-map: 2.0.0
- debug: 4.4.3
+ debug: 4.4.3(supports-color@5.5.0)
gensync: 1.0.0-beta.2
json5: 2.2.3
semver: 6.3.1
@@ -9449,7 +9112,7 @@ snapshots:
'@babel/core': 7.29.0
'@babel/helper-compilation-targets': 7.28.6
'@babel/helper-plugin-utils': 7.28.6
- debug: 4.4.3
+ debug: 4.4.3(supports-color@5.5.0)
lodash.debounce: 4.0.8
resolve: 1.22.11
transitivePeerDependencies:
@@ -10021,7 +9684,7 @@ snapshots:
'@babel/parser': 7.29.0
'@babel/template': 7.28.6
'@babel/types': 7.29.0
- debug: 4.4.3
+ debug: 4.4.3(supports-color@5.5.0)
transitivePeerDependencies:
- supports-color
@@ -10348,42 +10011,6 @@ snapshots:
dependencies:
postcss-selector-parser: 7.1.1
- '@cypress/request@3.0.10':
- dependencies:
- aws-sign2: 0.7.0
- aws4: 1.13.2
- caseless: 0.12.0
- combined-stream: 1.0.8
- extend: 3.0.2
- forever-agent: 0.6.1
- form-data: 4.0.5
- http-signature: 1.4.0
- is-typedarray: 1.0.0
- isstream: 0.1.2
- json-stringify-safe: 5.0.1
- mime-types: 2.1.35
- performance-now: 2.1.0
- qs: 6.14.2
- safe-buffer: 5.2.1
- tough-cookie: 5.1.2
- tunnel-agent: 0.6.0
- uuid: 8.3.2
- optional: true
-
- '@cypress/vue@6.0.2(cypress@15.6.0)(vue@3.5.30(typescript@5.9.3))':
- dependencies:
- cypress: 15.6.0
- vue: 3.5.30(typescript@5.9.3)
- optional: true
-
- '@cypress/xvfb@1.2.4(supports-color@8.1.1)':
- dependencies:
- debug: 3.2.7(supports-color@8.1.1)
- lodash.once: 4.1.1
- transitivePeerDependencies:
- - supports-color
- optional: true
-
'@e18e/eslint-plugin@0.2.0(eslint@10.0.3(jiti@2.6.1))':
dependencies:
eslint-plugin-depend: 1.5.0(eslint@10.0.3(jiti@2.6.1))
@@ -10590,7 +10217,7 @@ snapshots:
'@eslint/config-array@0.21.2':
dependencies:
'@eslint/object-schema': 2.1.7
- debug: 4.4.3
+ debug: 4.4.3(supports-color@5.5.0)
minimatch: 3.1.5
transitivePeerDependencies:
- supports-color
@@ -10598,7 +10225,7 @@ snapshots:
'@eslint/config-array@0.23.3':
dependencies:
'@eslint/object-schema': 3.0.3
- debug: 4.4.3
+ debug: 4.4.3(supports-color@5.5.0)
minimatch: 10.2.4
transitivePeerDependencies:
- supports-color
@@ -10622,7 +10249,7 @@ snapshots:
'@eslint/eslintrc@3.3.5':
dependencies:
ajv: 6.14.0
- debug: 4.4.3
+ debug: 4.4.3(supports-color@5.5.0)
espree: 10.4.0
globals: 14.0.0
ignore: 5.3.2
@@ -12306,7 +11933,7 @@ snapshots:
'@tokenizer/inflate@0.4.1':
dependencies:
- debug: 4.4.3
+ debug: 4.4.3(supports-color@5.5.0)
token-types: 6.1.2
transitivePeerDependencies:
- supports-color
@@ -12504,12 +12131,6 @@ snapshots:
'@types/http-errors': 2.0.5
'@types/node': 22.19.15
- '@types/sinonjs__fake-timers@8.1.1':
- optional: true
-
- '@types/sizzle@2.3.10':
- optional: true
-
'@types/statuses@2.0.6':
optional: true
@@ -12531,20 +12152,12 @@ snapshots:
dependencies:
'@types/node': 24.12.0
- '@types/tmp@0.2.6':
- optional: true
-
'@types/tough-cookie@4.0.5': {}
'@types/trusted-types@2.0.7': {}
'@types/unist@3.0.3': {}
- '@types/yauzl@2.10.3':
- dependencies:
- '@types/node': 24.12.0
- optional: true
-
'@typescript-eslint/eslint-plugin@8.57.0(@typescript-eslint/parser@8.57.0(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)':
dependencies:
'@eslint-community/regexpp': 4.12.2
@@ -12583,7 +12196,7 @@ snapshots:
'@typescript-eslint/types': 8.57.0
'@typescript-eslint/typescript-estree': 8.57.0(typescript@5.9.3)
'@typescript-eslint/visitor-keys': 8.57.0
- debug: 4.4.3
+ debug: 4.4.3(supports-color@5.5.0)
eslint: 10.0.3(jiti@2.6.1)
typescript: 5.9.3
transitivePeerDependencies:
@@ -12595,7 +12208,7 @@ snapshots:
'@typescript-eslint/types': 8.57.0
'@typescript-eslint/typescript-estree': 8.57.0(typescript@5.9.3)
'@typescript-eslint/visitor-keys': 8.57.0
- debug: 4.4.3
+ debug: 4.4.3(supports-color@5.5.0)
eslint: 9.39.4(jiti@2.6.1)
typescript: 5.9.3
transitivePeerDependencies:
@@ -12605,7 +12218,7 @@ snapshots:
dependencies:
'@typescript-eslint/tsconfig-utils': 8.57.0(typescript@5.9.3)
'@typescript-eslint/types': 8.57.0
- debug: 4.4.3
+ debug: 4.4.3(supports-color@5.5.0)
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
@@ -12638,7 +12251,7 @@ snapshots:
'@typescript-eslint/types': 8.57.0
'@typescript-eslint/typescript-estree': 8.57.0(typescript@5.9.3)
'@typescript-eslint/utils': 8.57.0(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)
- debug: 4.4.3
+ debug: 4.4.3(supports-color@5.5.0)
eslint: 10.0.3(jiti@2.6.1)
ts-api-utils: 2.4.0(typescript@5.9.3)
typescript: 5.9.3
@@ -12650,7 +12263,7 @@ snapshots:
'@typescript-eslint/types': 8.57.0
'@typescript-eslint/typescript-estree': 8.57.0(typescript@5.9.3)
'@typescript-eslint/utils': 8.57.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)
- debug: 4.4.3
+ debug: 4.4.3(supports-color@5.5.0)
eslint: 9.39.4(jiti@2.6.1)
ts-api-utils: 2.4.0(typescript@5.9.3)
typescript: 5.9.3
@@ -12665,7 +12278,7 @@ snapshots:
'@typescript-eslint/tsconfig-utils': 8.57.0(typescript@5.9.3)
'@typescript-eslint/types': 8.57.0
'@typescript-eslint/visitor-keys': 8.57.0
- debug: 4.4.3
+ debug: 4.4.3(supports-color@5.5.0)
minimatch: 10.2.4
semver: 7.7.4
tinyglobby: 0.2.15
@@ -12853,7 +12466,7 @@ snapshots:
dependencies:
'@ampproject/remapping': 2.3.0
'@bcoe/v8-coverage': 0.2.3
- debug: 4.4.3
+ debug: 4.4.3(supports-color@5.5.0)
istanbul-lib-coverage: 3.2.2
istanbul-lib-report: 3.0.1
istanbul-lib-source-maps: 5.0.6
@@ -12871,7 +12484,7 @@ snapshots:
dependencies:
'@ampproject/remapping': 2.3.0
'@bcoe/v8-coverage': 0.2.3
- debug: 4.4.3
+ debug: 4.4.3(supports-color@5.5.0)
istanbul-lib-coverage: 3.2.2
istanbul-lib-report: 3.0.1
istanbul-lib-source-maps: 5.0.6
@@ -12889,7 +12502,7 @@ snapshots:
dependencies:
'@ampproject/remapping': 2.3.0
'@bcoe/v8-coverage': 0.2.3
- debug: 4.4.3
+ debug: 4.4.3(supports-color@5.5.0)
istanbul-lib-coverage: 3.2.2
istanbul-lib-report: 3.0.1
istanbul-lib-source-maps: 5.0.6
@@ -13184,12 +12797,6 @@ snapshots:
agent-base@7.1.4: {}
- aggregate-error@3.1.0:
- dependencies:
- clean-stack: 2.2.0
- indent-string: 4.0.0
- optional: true
-
ajv-draft-04@1.0.0(ajv@8.18.0):
optionalDependencies:
ajv: 8.18.0
@@ -13252,11 +12859,6 @@ snapshots:
ansi-colors@4.1.3: {}
- ansi-escapes@4.3.2:
- dependencies:
- type-fest: 0.21.3
- optional: true
-
ansi-escapes@7.3.0:
dependencies:
environment: 1.1.0
@@ -13286,9 +12888,6 @@ snapshots:
append-field@1.0.0: {}
- arch@2.2.0:
- optional: true
-
are-docs-informative@0.0.2: {}
arg@4.1.3: {}
@@ -13323,14 +12922,6 @@ snapshots:
minimalistic-assert: 1.0.1
safer-buffer: 2.1.2
- asn1@0.2.6:
- dependencies:
- safer-buffer: 2.1.2
- optional: true
-
- assert-plus@1.0.0:
- optional: true
-
assertion-error@2.0.1: {}
astral-regex@2.0.0: {}
@@ -13354,12 +12945,6 @@ snapshots:
'@fastify/error': 3.4.1
fastq: 1.20.1
- aws-sign2@0.7.0:
- optional: true
-
- aws4@1.13.2:
- optional: true
-
axios-retry@4.5.0(axios@1.13.6):
dependencies:
axios: 1.13.6
@@ -13405,11 +12990,6 @@ snapshots:
baseline-browser-mapping@2.10.0: {}
- bcrypt-pbkdf@1.0.2:
- dependencies:
- tweetnacl: 0.14.5
- optional: true
-
bignumber.js@9.3.1: {}
binary-extensions@2.3.0: {}
@@ -13420,19 +13000,13 @@ snapshots:
inherits: 2.0.4
readable-stream: 3.6.2
- blob-util@2.0.2:
- optional: true
-
- bluebird@3.7.2:
- optional: true
-
bn.js@4.12.3: {}
body-parser@2.2.2:
dependencies:
bytes: 3.1.2
content-type: 1.0.5
- debug: 4.4.3
+ debug: 4.4.3(supports-color@5.5.0)
http-errors: 2.0.1
iconv-lite: 0.7.2
on-finished: 2.4.1
@@ -13472,9 +13046,6 @@ snapshots:
node-releases: 2.0.36
update-browserslist-db: 1.2.3(browserslist@4.28.1)
- buffer-crc32@0.2.13:
- optional: true
-
buffer-equal-constant-time@1.0.1:
optional: true
@@ -13539,9 +13110,6 @@ snapshots:
keyv: 5.6.0
qified: 0.6.0
- cachedir@2.4.0:
- optional: true
-
call-bind-apply-helpers@1.0.2:
dependencies:
es-errors: 1.3.0
@@ -13567,9 +13135,6 @@ snapshots:
caniuse-lite@1.0.30001777: {}
- caseless@0.12.0:
- optional: true
-
ccount@2.0.1: {}
chai@5.3.3:
@@ -13643,9 +13208,6 @@ snapshots:
dependencies:
escape-string-regexp: 1.0.5
- clean-stack@2.2.0:
- optional: true
-
cli-cursor@3.1.0:
dependencies:
restore-cursor: 3.1.0
@@ -13656,25 +13218,12 @@ snapshots:
cli-spinners@2.9.2: {}
- cli-table3@0.6.1:
- dependencies:
- string-width: 4.2.3
- optionalDependencies:
- colors: 1.4.0
- optional: true
-
cli-table3@0.6.5:
dependencies:
string-width: 4.2.3
optionalDependencies:
'@colors/colors': 1.5.0
- cli-truncate@2.1.0:
- dependencies:
- slice-ansi: 3.0.0
- string-width: 4.2.3
- optional: true
-
cli-truncate@5.2.0:
dependencies:
slice-ansi: 8.0.0
@@ -13714,9 +13263,6 @@ snapshots:
colorette@2.0.20: {}
- colors@1.4.0:
- optional: true
-
combined-stream@1.0.8:
dependencies:
delayed-stream: 1.0.0
@@ -13727,9 +13273,6 @@ snapshots:
commander@4.1.1: {}
- commander@6.2.1:
- optional: true
-
comment-json@4.4.1:
dependencies:
array-timsort: 1.0.3
@@ -13798,9 +13341,6 @@ snapshots:
dependencies:
browserslist: 4.28.1
- core-util-is@1.0.2:
- optional: true
-
core-util-is@1.0.3: {}
cors@2.8.6:
@@ -13869,69 +13409,8 @@ snapshots:
csstype@3.2.3: {}
- cypress-vite@1.8.0(vite@7.3.1(@types/node@24.12.0)(jiti@2.6.1)(terser@5.46.0)(yaml@2.8.2)):
- dependencies:
- chokidar: 3.6.0
- debug: 4.4.3
- vite: 7.3.1(@types/node@24.12.0)(jiti@2.6.1)(terser@5.46.0)(yaml@2.8.2)
- transitivePeerDependencies:
- - supports-color
- optional: true
-
- cypress@15.6.0:
- dependencies:
- '@cypress/request': 3.0.10
- '@cypress/xvfb': 1.2.4(supports-color@8.1.1)
- '@types/sinonjs__fake-timers': 8.1.1
- '@types/sizzle': 2.3.10
- '@types/tmp': 0.2.6
- arch: 2.2.0
- blob-util: 2.0.2
- bluebird: 3.7.2
- buffer: 5.7.1
- cachedir: 2.4.0
- chalk: 4.1.2
- ci-info: 4.4.0
- cli-cursor: 3.1.0
- cli-table3: 0.6.1
- commander: 6.2.1
- common-tags: 1.8.2
- dayjs: 1.11.19
- debug: 4.4.3(supports-color@8.1.1)
- enquirer: 2.4.1
- eventemitter2: 6.4.7
- execa: 4.1.0
- executable: 4.1.1
- extract-zip: 2.0.1(supports-color@8.1.1)
- figures: 3.2.0
- fs-extra: 9.1.0
- hasha: 5.2.2
- is-installed-globally: 0.4.0
- listr2: 3.14.0(enquirer@2.4.1)
- lodash: 4.17.23
- log-symbols: 4.1.0
- minimist: 1.2.8
- ospath: 1.2.2
- pretty-bytes: 5.6.0
- process: 0.11.10
- proxy-from-env: 1.0.0
- request-progress: 3.0.0
- semver: 7.7.4
- supports-color: 8.1.1
- systeminformation: 5.27.7
- tmp: 0.2.5
- tree-kill: 1.2.2
- untildify: 4.0.0
- yauzl: 2.10.0
- optional: true
-
dargs@8.1.0: {}
- dashdash@1.14.1:
- dependencies:
- assert-plus: 1.0.0
- optional: true
-
data-uri-to-buffer@4.0.1: {}
data-urls@5.0.0:
@@ -13965,30 +13444,12 @@ snapshots:
de-indent@1.0.2: {}
- debug@3.2.7(supports-color@8.1.1):
- dependencies:
- ms: 2.1.3
- optionalDependencies:
- supports-color: 8.1.1
- optional: true
-
- debug@4.4.3:
- dependencies:
- ms: 2.1.3
-
debug@4.4.3(supports-color@5.5.0):
dependencies:
ms: 2.1.3
optionalDependencies:
supports-color: 5.5.0
- debug@4.4.3(supports-color@8.1.1):
- dependencies:
- ms: 2.1.3
- optionalDependencies:
- supports-color: 8.1.1
- optional: true
-
decimal.js@10.6.0: {}
decode-named-character-reference@1.3.0:
@@ -14096,12 +13557,6 @@ snapshots:
eastasianwidth@0.2.0: {}
- ecc-jsbn@0.1.2:
- dependencies:
- jsbn: 0.1.1
- safer-buffer: 2.1.2
- optional: true
-
ecdsa-sig-formatter@1.0.11:
dependencies:
safe-buffer: 5.2.1
@@ -14149,12 +13604,6 @@ snapshots:
graceful-fs: 4.2.11
tapable: 2.3.0
- enquirer@2.4.1:
- dependencies:
- ansi-colors: 4.1.3
- strip-ansi: 6.0.1
- optional: true
-
entities@4.5.0: {}
entities@6.0.1: {}
@@ -14357,11 +13806,6 @@ snapshots:
'@typescript-eslint/utils': 8.57.0(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)
eslint: 10.0.3(jiti@2.6.1)
- eslint-plugin-cypress@4.3.0(eslint@10.0.3(jiti@2.6.1)):
- dependencies:
- eslint: 10.0.3(jiti@2.6.1)
- globals: 15.15.0
-
eslint-plugin-depend@1.5.0(eslint@10.0.3(jiti@2.6.1)):
dependencies:
empathic: 2.0.0
@@ -14386,7 +13830,7 @@ snapshots:
'@es-joy/resolve.exports': 1.2.0
are-docs-informative: 0.0.2
comment-parser: 1.4.5
- debug: 4.4.3
+ debug: 4.4.3(supports-color@5.5.0)
escape-string-regexp: 4.0.0
eslint: 10.0.3(jiti@2.6.1)
espree: 11.2.0
@@ -14468,7 +13912,7 @@ snapshots:
'@eslint/core': 1.1.1
'@eslint/plugin-kit': 0.6.1
'@ota-meshi/ast-token-store': 0.3.0
- debug: 4.4.3
+ debug: 4.4.3(supports-color@5.5.0)
eslint: 10.0.3(jiti@2.6.1)
toml-eslint-parser: 1.0.3
transitivePeerDependencies:
@@ -14519,7 +13963,7 @@ snapshots:
'@eslint/core': 1.1.1
'@eslint/plugin-kit': 0.6.1
'@ota-meshi/ast-token-store': 0.3.0
- debug: 4.4.3
+ debug: 4.4.3(supports-color@5.5.0)
diff-sequences: 29.6.3
escape-string-regexp: 5.0.0
eslint: 10.0.3(jiti@2.6.1)
@@ -14570,7 +14014,7 @@ snapshots:
'@types/estree': 1.0.8
ajv: 6.14.0
cross-spawn: 7.0.6
- debug: 4.4.3
+ debug: 4.4.3(supports-color@5.5.0)
escape-string-regexp: 4.0.0
eslint-scope: 9.1.2
eslint-visitor-keys: 5.0.1
@@ -14610,7 +14054,7 @@ snapshots:
ajv: 6.14.0
chalk: 4.1.2
cross-spawn: 7.0.6
- debug: 4.4.3
+ debug: 4.4.3(supports-color@5.5.0)
escape-string-regexp: 4.0.0
eslint-scope: 8.4.0
eslint-visitor-keys: 4.2.1
@@ -14674,31 +14118,10 @@ snapshots:
etag@1.8.1: {}
- eventemitter2@6.4.7:
- optional: true
-
eventemitter3@5.0.4: {}
events@3.3.0: {}
- execa@4.1.0:
- dependencies:
- cross-spawn: 7.0.6
- get-stream: 5.2.0
- human-signals: 1.1.1
- is-stream: 2.0.1
- merge-stream: 2.0.0
- npm-run-path: 4.0.1
- onetime: 5.1.2
- signal-exit: 3.0.7
- strip-final-newline: 2.0.0
- optional: true
-
- executable@4.1.1:
- dependencies:
- pify: 2.3.0
- optional: true
-
expect-type@1.3.0: {}
express@5.2.1:
@@ -14709,7 +14132,7 @@ snapshots:
content-type: 1.0.5
cookie: 0.7.2
cookie-signature: 1.2.2
- debug: 4.4.3
+ debug: 4.4.3(supports-color@5.5.0)
depd: 2.0.0
encodeurl: 2.0.0
escape-html: 1.0.3
@@ -14738,20 +14161,6 @@ snapshots:
extend@3.0.2: {}
- extract-zip@2.0.1(supports-color@8.1.1):
- dependencies:
- debug: 4.4.3(supports-color@8.1.1)
- get-stream: 5.2.0
- yauzl: 2.10.0
- optionalDependencies:
- '@types/yauzl': 2.10.3
- transitivePeerDependencies:
- - supports-color
- optional: true
-
- extsprintf@1.3.0:
- optional: true
-
fast-check@3.23.2:
dependencies:
pure-rand: 6.1.0
@@ -14866,11 +14275,6 @@ snapshots:
dependencies:
format: 0.2.2
- fd-slicer@1.1.0:
- dependencies:
- pend: 1.2.0
- optional: true
-
fdir@6.5.0(picomatch@4.0.3):
optionalDependencies:
picomatch: 4.0.3
@@ -14880,11 +14284,6 @@ snapshots:
node-domexception: 1.0.0
web-streams-polyfill: 3.3.3
- figures@3.2.0:
- dependencies:
- escape-string-regexp: 1.0.5
- optional: true
-
file-entry-cache@11.1.2:
dependencies:
flat-cache: 6.1.20
@@ -14912,7 +14311,7 @@ snapshots:
finalhandler@2.1.1:
dependencies:
- debug: 4.4.3
+ debug: 4.4.3(supports-color@5.5.0)
encodeurl: 2.0.0
escape-html: 1.0.3
on-finished: 2.4.1
@@ -14967,9 +14366,6 @@ snapshots:
cross-spawn: 7.0.6
signal-exit: 4.1.0
- forever-agent@0.6.1:
- optional: true
-
fork-ts-checker-webpack-plugin@9.1.0(typescript@5.9.3)(webpack@5.104.1):
dependencies:
'@babel/code-frame': 7.29.0
@@ -15093,11 +14489,6 @@ snapshots:
dunder-proto: 1.0.1
es-object-atoms: 1.1.1
- get-stream@5.2.0:
- dependencies:
- pump: 3.0.4
- optional: true
-
get-symbol-description@1.1.0:
dependencies:
call-bound: 1.0.4
@@ -15108,11 +14499,6 @@ snapshots:
dependencies:
resolve-pkg-maps: 1.0.0
- getpass@0.1.7:
- dependencies:
- assert-plus: 1.0.0
- optional: true
-
giget@2.0.0:
dependencies:
citty: 0.1.6
@@ -15174,11 +14560,6 @@ snapshots:
dependencies:
ini: 4.1.1
- global-dirs@3.0.1:
- dependencies:
- ini: 2.0.0
- optional: true
-
global-modules@2.0.0:
dependencies:
global-prefix: 3.0.0
@@ -15277,12 +14658,6 @@ snapshots:
minimalistic-assert: 1.0.1
optional: true
- hasha@5.2.2:
- dependencies:
- is-stream: 2.0.1
- type-fest: 0.8.1
- optional: true
-
hashery@1.5.0:
dependencies:
hookified: 1.15.1
@@ -15347,29 +14722,19 @@ snapshots:
http-proxy-agent@7.0.2:
dependencies:
agent-base: 7.1.4
- debug: 4.4.3
+ debug: 4.4.3(supports-color@5.5.0)
transitivePeerDependencies:
- supports-color
- http-signature@1.4.0:
- dependencies:
- assert-plus: 1.0.0
- jsprim: 2.0.2
- sshpk: 1.18.0
- optional: true
-
http2-client@1.3.5: {}
https-proxy-agent@7.0.6:
dependencies:
agent-base: 7.1.4
- debug: 4.4.3
+ debug: 4.4.3(supports-color@5.5.0)
transitivePeerDependencies:
- supports-color
- human-signals@1.1.1:
- optional: true
-
husky@9.1.7: {}
iconv-lite@0.6.3:
@@ -15415,18 +14780,12 @@ snapshots:
imurmurhash@0.1.4: {}
- indent-string@4.0.0:
- optional: true
-
indent-string@5.0.0: {}
inherits@2.0.4: {}
ini@1.3.8: {}
- ini@2.0.0:
- optional: true
-
ini@4.1.1: {}
ini@4.1.3: {}
@@ -15523,12 +14882,6 @@ snapshots:
dependencies:
is-extglob: 2.1.1
- is-installed-globally@0.4.0:
- dependencies:
- global-dirs: 3.0.1
- is-path-inside: 3.0.3
- optional: true
-
is-interactive@1.0.0: {}
is-map@2.0.3: {}
@@ -15551,9 +14904,6 @@ snapshots:
is-obj@2.0.0: {}
- is-path-inside@3.0.3:
- optional: true
-
is-path-inside@4.0.0: {}
is-plain-obj@4.1.0: {}
@@ -15598,9 +14948,6 @@ snapshots:
dependencies:
which-typed-array: 1.1.20
- is-typedarray@1.0.0:
- optional: true
-
is-unicode-supported@0.1.0: {}
is-weakmap@2.0.2: {}
@@ -15622,9 +14969,6 @@ snapshots:
isexe@3.1.5: {}
- isstream@0.1.2:
- optional: true
-
istanbul-lib-coverage@3.2.2: {}
istanbul-lib-report@3.0.1:
@@ -15636,7 +14980,7 @@ snapshots:
istanbul-lib-source-maps@5.0.6:
dependencies:
'@jridgewell/trace-mapping': 0.3.31
- debug: 4.4.3
+ debug: 4.4.3(supports-color@5.5.0)
istanbul-lib-coverage: 3.2.2
transitivePeerDependencies:
- supports-color
@@ -15690,9 +15034,6 @@ snapshots:
dependencies:
argparse: 2.0.1
- jsbn@0.1.1:
- optional: true
-
jsdoc-type-pratt-parser@7.1.1: {}
jsdom@25.0.1:
@@ -15746,7 +15087,7 @@ snapshots:
json-schema-resolver@2.0.0:
dependencies:
- debug: 4.4.3
+ debug: 4.4.3(supports-color@5.5.0)
rfdc: 1.4.1
uri-js: 4.4.1
transitivePeerDependencies:
@@ -15760,9 +15101,6 @@ snapshots:
json-stable-stringify-without-jsonify@1.0.1: {}
- json-stringify-safe@5.0.1:
- optional: true
-
json5@2.2.3: {}
jsonc-eslint-parser@3.1.0:
@@ -15781,14 +15119,6 @@ snapshots:
jsonpointer@5.0.1: {}
- jsprim@2.0.2:
- dependencies:
- assert-plus: 1.0.0
- extsprintf: 1.3.0
- json-schema: 0.4.0
- verror: 1.10.0
- optional: true
-
jszip@3.10.1:
dependencies:
lie: 3.3.0
@@ -15856,20 +15186,6 @@ snapshots:
tinyexec: 1.0.2
yaml: 2.8.2
- listr2@3.14.0(enquirer@2.4.1):
- dependencies:
- cli-truncate: 2.1.0
- colorette: 2.0.20
- log-update: 4.0.0
- p-map: 4.0.0
- rfdc: 1.4.1
- rxjs: 7.8.2
- through: 2.3.8
- wrap-ansi: 7.0.0
- optionalDependencies:
- enquirer: 2.4.1
- optional: true
-
listr2@9.0.5:
dependencies:
cli-truncate: 5.2.0
@@ -15915,9 +15231,6 @@ snapshots:
lodash.mergewith@4.6.2: {}
- lodash.once@4.1.1:
- optional: true
-
lodash.snakecase@4.1.1: {}
lodash.sortby@4.7.0: {}
@@ -15935,14 +15248,6 @@ snapshots:
chalk: 4.1.2
is-unicode-supported: 0.1.0
- log-update@4.0.0:
- dependencies:
- ansi-escapes: 4.3.2
- cli-cursor: 3.1.0
- slice-ansi: 4.0.0
- wrap-ansi: 6.2.0
- optional: true
-
log-update@6.1.0:
dependencies:
ansi-escapes: 7.3.0
@@ -16323,7 +15628,7 @@ snapshots:
micromark@4.0.2:
dependencies:
'@types/debug': 4.1.12
- debug: 4.4.3
+ debug: 4.4.3(supports-color@5.5.0)
decode-named-character-reference: 1.3.0
devlop: 1.1.0
micromark-core-commonmark: 2.0.3
@@ -16598,11 +15903,6 @@ snapshots:
shell-quote: 1.8.3
string.prototype.padend: 3.1.6
- npm-run-path@4.0.1:
- dependencies:
- path-key: 3.1.1
- optional: true
-
nth-check@2.1.1:
dependencies:
boolbase: 1.0.0
@@ -16720,9 +16020,6 @@ snapshots:
strip-ansi: 6.0.1
wcwidth: 1.0.1
- ospath@1.2.2:
- optional: true
-
outvariant@1.4.3:
optional: true
@@ -16772,11 +16069,6 @@ snapshots:
dependencies:
p-limit: 3.1.0
- p-map@4.0.0:
- dependencies:
- aggregate-error: 3.1.0
- optional: true
-
package-json-from-dist@1.0.1: {}
package-manager-detector@1.6.0: {}
@@ -16850,16 +16142,10 @@ snapshots:
pathval@2.0.1: {}
- pend@1.2.0:
- optional: true
-
perfect-debounce@1.0.0: {}
perfect-debounce@2.1.0: {}
- performance-now@2.1.0:
- optional: true
-
pg-int8@1.0.1: {}
pg-protocol@1.13.0: {}
@@ -16884,9 +16170,6 @@ snapshots:
pidtree@0.3.1: {}
- pify@2.3.0:
- optional: true
-
pify@3.0.0: {}
pinia@2.3.1(typescript@5.9.3)(vue@3.5.30(typescript@5.9.3)):
@@ -17047,9 +16330,6 @@ snapshots:
process-warning@5.0.0: {}
- process@0.11.10:
- optional: true
-
protobufjs@7.5.4:
dependencies:
'@protobufjs/aspromise': 1.1.2
@@ -17085,9 +16365,6 @@ snapshots:
forwarded: 0.2.0
ipaddr.js: 1.9.1
- proxy-from-env@1.0.0:
- optional: true
-
proxy-from-env@1.1.0: {}
pstree.remy@1.1.8: {}
@@ -17105,11 +16382,6 @@ snapshots:
dependencies:
hookified: 1.15.1
- qs@6.14.2:
- dependencies:
- side-channel: 1.1.0
- optional: true
-
qs@6.15.0:
dependencies:
side-channel: 1.1.0
@@ -17250,18 +16522,13 @@ snapshots:
qs: 6.15.0
uuid: 8.3.2
- request-progress@3.0.0:
- dependencies:
- throttleit: 1.0.1
- optional: true
-
require-directory@2.1.1: {}
require-from-string@2.0.2: {}
require-in-the-middle@8.0.1:
dependencies:
- debug: 4.4.3
+ debug: 4.4.3(supports-color@5.5.0)
module-details-from-path: 1.0.4
transitivePeerDependencies:
- supports-color
@@ -17343,7 +16610,7 @@ snapshots:
router@2.2.0:
dependencies:
- debug: 4.4.3
+ debug: 4.4.3(supports-color@5.5.0)
depd: 2.0.0
is-promise: 4.0.0
parseurl: 1.3.3
@@ -17441,7 +16708,7 @@ snapshots:
send@1.2.1:
dependencies:
- debug: 4.4.3
+ debug: 4.4.3(supports-color@5.5.0)
encodeurl: 2.0.0
escape-html: 1.0.3
etag: 1.8.1
@@ -17589,13 +16856,6 @@ snapshots:
slash@5.1.0: {}
- slice-ansi@3.0.0:
- dependencies:
- ansi-styles: 4.3.0
- astral-regex: 2.0.0
- is-fullwidth-code-point: 3.0.0
- optional: true
-
slice-ansi@4.0.0:
dependencies:
ansi-styles: 4.3.0
@@ -17662,19 +16922,6 @@ snapshots:
split2@4.2.0: {}
- sshpk@1.18.0:
- dependencies:
- asn1: 0.2.6
- assert-plus: 1.0.0
- bcrypt-pbkdf: 1.0.2
- dashdash: 1.14.1
- ecc-jsbn: 0.1.2
- getpass: 0.1.7
- jsbn: 0.1.1
- safer-buffer: 2.1.2
- tweetnacl: 0.14.5
- optional: true
-
stackback@0.0.2: {}
statuses@2.0.1: {}
@@ -17798,9 +17045,6 @@ snapshots:
strip-comments@2.0.1: {}
- strip-final-newline@2.0.0:
- optional: true
-
strip-indent@4.1.1: {}
strip-json-comments@3.1.1: {}
@@ -17850,7 +17094,7 @@ snapshots:
cosmiconfig: 9.0.1(typescript@5.9.3)
css-functions-list: 3.3.3
css-tree: 3.2.1
- debug: 4.4.3
+ debug: 4.4.3(supports-color@5.5.0)
fast-glob: 3.3.3
fastest-levenshtein: 1.0.16
file-entry-cache: 11.1.2
@@ -17884,7 +17128,7 @@ snapshots:
dependencies:
component-emitter: 1.3.1
cookiejar: 2.1.4
- debug: 4.4.3
+ debug: 4.4.3(supports-color@5.5.0)
fast-safe-stringify: 2.1.1
form-data: 4.0.5
formidable: 3.5.4
@@ -17978,9 +17222,6 @@ snapshots:
dependencies:
'@pkgr/core': 0.2.9
- systeminformation@5.27.7:
- optional: true
-
tabbable@6.4.0: {}
table@6.9.0:
@@ -18035,12 +17276,6 @@ snapshots:
dependencies:
real-require: 0.2.0
- throttleit@1.0.1:
- optional: true
-
- through@2.3.8:
- optional: true
-
tiny-emitter@2.1.0: {}
tinybench@2.9.0: {}
@@ -18074,9 +17309,6 @@ snapshots:
tldts-core: 7.0.25
optional: true
- tmp@0.2.5:
- optional: true
-
to-regex-range@5.0.1:
dependencies:
is-number: 7.0.0
@@ -18123,9 +17355,6 @@ snapshots:
dependencies:
punycode: 2.3.1
- tree-kill@1.2.2:
- optional: true
-
ts-algebra@2.0.0: {}
ts-api-utils@2.4.0(typescript@5.9.3):
@@ -18195,26 +17424,12 @@ snapshots:
tslib@2.8.1: {}
- tunnel-agent@0.6.0:
- dependencies:
- safe-buffer: 5.2.1
- optional: true
-
- tweetnacl@0.14.5:
- optional: true
-
type-check@0.4.0:
dependencies:
prelude-ls: 1.2.1
type-fest@0.16.0: {}
- type-fest@0.21.3:
- optional: true
-
- type-fest@0.8.1:
- optional: true
-
type-fest@5.4.4:
dependencies:
tagged-tag: 1.0.0
@@ -18440,7 +17655,7 @@ snapshots:
'@antfu/utils': 0.7.10
'@rollup/pluginutils': 5.3.0(rollup@2.80.0)
chokidar: 3.6.0
- debug: 4.4.3
+ debug: 4.4.3(supports-color@5.5.0)
fast-glob: 3.3.3
local-pkg: 0.5.1
magic-string: 0.30.21
@@ -18469,9 +17684,6 @@ snapshots:
until-async@3.0.2:
optional: true
- untildify@4.0.0:
- optional: true
-
upath@1.2.0: {}
update-browserslist-db@1.2.3(browserslist@4.28.1):
@@ -18501,17 +17713,10 @@ snapshots:
vary@1.1.2: {}
- verror@1.10.0:
- dependencies:
- assert-plus: 1.0.0
- core-util-is: 1.0.2
- extsprintf: 1.3.0
- optional: true
-
vite-node@2.1.9(@types/node@22.19.15)(terser@5.46.0):
dependencies:
cac: 6.7.14
- debug: 4.4.3
+ debug: 4.4.3(supports-color@5.5.0)
es-module-lexer: 1.7.0
pathe: 1.1.2
vite: 5.4.21(@types/node@22.19.15)(terser@5.46.0)
@@ -18529,7 +17734,7 @@ snapshots:
vite-node@2.1.9(@types/node@24.12.0)(terser@5.46.0):
dependencies:
cac: 6.7.14
- debug: 4.4.3
+ debug: 4.4.3(supports-color@5.5.0)
es-module-lexer: 1.7.0
pathe: 1.1.2
vite: 5.4.21(@types/node@24.12.0)(terser@5.46.0)
@@ -18546,7 +17751,7 @@ snapshots:
vite-plugin-pwa@1.2.0(vite@7.3.1(@types/node@24.12.0)(jiti@2.6.1)(terser@5.46.0)(yaml@2.8.2))(workbox-build@7.4.0(@types/babel__core@7.20.5))(workbox-window@7.4.0):
dependencies:
- debug: 4.4.3
+ debug: 4.4.3(supports-color@5.5.0)
pretty-bytes: 6.1.1
tinyglobby: 0.2.15
vite: 7.3.1(@types/node@24.12.0)(jiti@2.6.1)(terser@5.46.0)(yaml@2.8.2)
@@ -18627,7 +17832,7 @@ snapshots:
'@vitest/spy': 2.1.9
'@vitest/utils': 2.1.9
chai: 5.3.3
- debug: 4.4.3
+ debug: 4.4.3(supports-color@5.5.0)
expect-type: 1.3.0
magic-string: 0.30.21
pathe: 1.1.2
@@ -18663,7 +17868,7 @@ snapshots:
'@vitest/spy': 2.1.9
'@vitest/utils': 2.1.9
chai: 5.3.3
- debug: 4.4.3
+ debug: 4.4.3(supports-color@5.5.0)
expect-type: 1.3.0
magic-string: 0.30.21
pathe: 1.1.2
@@ -18699,7 +17904,7 @@ snapshots:
'@vitest/spy': 2.1.9
'@vitest/utils': 2.1.9
chai: 5.3.3
- debug: 4.4.3
+ debug: 4.4.3(supports-color@5.5.0)
expect-type: 1.3.0
magic-string: 0.30.21
pathe: 1.1.2
@@ -18733,7 +17938,7 @@ snapshots:
vue-eslint-parser@10.4.0(eslint@10.0.3(jiti@2.6.1)):
dependencies:
- debug: 4.4.3
+ debug: 4.4.3(supports-color@5.5.0)
eslint: 10.0.3(jiti@2.6.1)
eslint-scope: 9.1.2
eslint-visitor-keys: 5.0.1
@@ -19094,12 +18299,6 @@ snapshots:
y18n: 5.0.8
yargs-parser: 21.1.1
- yauzl@2.10.0:
- dependencies:
- buffer-crc32: 0.2.13
- fd-slicer: 1.1.0
- optional: true
-
yn@3.1.1: {}
yocto-queue@0.1.0: {}