diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5ac89cfb0..a9cad426b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -130,8 +130,8 @@ jobs: with: CONF_PATH: ./.github/labeler/build.yml - cypress-tests: - uses: ./.github/workflows/tests-e2e.yml + playwright-tests: + uses: ./.github/workflows/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 @@ -140,19 +140,19 @@ jobs: 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' }}" - playwright-tests: - uses: ./.github/workflows/playwright.yml + cypress-tests: + uses: ./.github/workflows/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: - - cypress-tests + - 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' }}" deploy-tests: uses: ./.github/workflows/tests-deploy.yml diff --git a/.gitignore b/.gitignore index 2400989d9..15d918380 100644 --- a/.gitignore +++ b/.gitignore @@ -53,7 +53,6 @@ keycloak/data # dist dist build -auto-imports.d.ts components.d.ts *.tsbuildinfo diff --git a/apps/client/Dockerfile b/apps/client/Dockerfile index f836ac584..eb76167dd 100644 --- a/apps/client/Dockerfile +++ b/apps/client/Dockerfile @@ -5,6 +5,7 @@ WORKDIR /app COPY --chown=node:root package.json ./ +# Install pnpm version defined in package.json "packageManager" property RUN npm install --global corepack@latest && corepack enable && corepack enable pnpm COPY --chown=node:root pnpm-workspace.yaml pnpm-lock.yaml ./ @@ -15,9 +16,6 @@ COPY --chown=node:root packages/shared/package.json ./packages/shared/package.js COPY --chown=node:root packages/test-utils/package.json ./packages/test-utils/package.json COPY --chown=node:root packages/tsconfig/package.json ./packages/tsconfig/package.json -# Install pnpm version defined in package.json "packageManager" property -RUN npm install --global corepack@latest && corepack enable && corepack enable pnpm - RUN pnpm install --ignore-scripts # --no-optional COPY --chown=node:root packages/ ./packages/ diff --git a/apps/client/cypress/e2e/specs/01-logs.e2e.ts b/apps/client/cypress/e2e/specs/01-logs.e2e.ts deleted file mode 100644 index 909e2ba83..000000000 --- a/apps/client/cypress/e2e/specs/01-logs.e2e.ts +++ /dev/null @@ -1,70 +0,0 @@ -import type { ProjectV2 } from '@cpn-console/shared' -import { getModel } from '../support/func.js' - -const projects = getModel('project') - -const betaapp = projects.find(({ name }) => name === 'betaapp') as ProjectV2 -const candilib = projects.find(({ name }) => name === 'candilib') as ProjectV2 - -describe('Project Logs', () => { - beforeEach(() => { - }) - - it('Should display project logs as owner', () => { - cy.kcLogin('test') - cy.intercept('GET', '/api/v1/logs?*').as('listLogs') - cy.intercept('PUT', `/api/v1/projects/${betaapp.id}/hooks`).as('replayHooks') - - cy.goToProjects() - cy.getByDataTestid(`projectTile-${betaapp.slug}`).click() - cy.getByDataTestid('test-tab-logs') - .should('be.visible') - .click() - - cy.get('#panel-logs') - .should('be.visible') - .within(() => { - cy.get('span').should('contain', '1 - 2 sur 2') - }) - cy.getByDataTestid('replayHooksBtn') - .click() - cy.wait('@replayHooks') - cy.wait('@listLogs') - cy.get('#panel-logs') - .should('be.visible') - .within(() => { - cy.get('span').should('contain', '1 - 3 sur 3') - }) - }) - - it('Should handle display project logs as manager or member of project', () => { - cy.kcLogin('tcolin') - cy.intercept('GET', '/api/v1/logs?*').as('listLogs') - - // as owner - cy.goToProjects() - cy.getByDataTestid(`projectTile-${betaapp.slug}`).click() - cy.wait('@listLogs') - cy.getByDataTestid('test-tab-logs') - .should('be.visible') - .click() - cy.get('#panel-logs') - .should('be.visible') - .within(() => { - cy.get('span').should('contain', '1 - 3 sur 3') - }) - - // as member - cy.goToProjects() - cy.getByDataTestid(`projectTile-${candilib.slug}`).click() - cy.wait('@listLogs') - cy.getByDataTestid('test-tab-logs') - .should('be.visible') - .click() - cy.get('#panel-logs') - .should('be.visible') - .within(() => { - cy.get('span').should('contain', '0 - 0 sur 0') - }) - }) -}) diff --git a/apps/client/package.json b/apps/client/package.json index e694edeff..7e5f9d0ed 100644 --- a/apps/client/package.json +++ b/apps/client/package.json @@ -26,7 +26,7 @@ "test:e2e": "cypress open --browser=firefox", "test:e2e-ci": "cypress run --browser=firefox", "kube:e2e-ci": "CLIENT_HOST=console.dso.local CLIENT_PORT=80 cypress run", - "type-check": "vue-tsc --noEmit -p tsconfig.json || exit 0" + "type-check": "vue-tsc --noEmit -p tsconfig.json" }, "dependencies": { "@cpn-console/shared": "workspace:^", diff --git a/apps/client/src/auto-imports.d.ts b/apps/client/src/auto-imports.d.ts new file mode 100644 index 000000000..4372345fd --- /dev/null +++ b/apps/client/src/auto-imports.d.ts @@ -0,0 +1,173 @@ +/* eslint-disable */ +/* prettier-ignore */ +// @ts-nocheck +// noinspection JSUnusedGlobalSymbols +// Generated by unplugin-auto-import +// biome-ignore lint: disable +export {} +declare global { + const EffectScope: typeof import('vue')['EffectScope'] + const acceptHMRUpdate: typeof import('pinia')['acceptHMRUpdate'] + const computed: typeof import('vue')['computed'] + const createApp: typeof import('vue')['createApp'] + const createPinia: typeof import('pinia')['createPinia'] + const customRef: typeof import('vue')['customRef'] + const defineAsyncComponent: typeof import('vue')['defineAsyncComponent'] + const defineComponent: typeof import('vue')['defineComponent'] + const defineStore: typeof import('pinia')['defineStore'] + const effectScope: typeof import('vue')['effectScope'] + const getActivePinia: typeof import('pinia')['getActivePinia'] + const getCurrentInstance: typeof import('vue')['getCurrentInstance'] + const getCurrentScope: typeof import('vue')['getCurrentScope'] + const h: typeof import('vue')['h'] + const inject: typeof import('vue')['inject'] + const isProxy: typeof import('vue')['isProxy'] + const isReactive: typeof import('vue')['isReactive'] + const isReadonly: typeof import('vue')['isReadonly'] + const isRef: typeof import('vue')['isRef'] + const mapActions: typeof import('pinia')['mapActions'] + const mapGetters: typeof import('pinia')['mapGetters'] + const mapState: typeof import('pinia')['mapState'] + const mapStores: typeof import('pinia')['mapStores'] + const mapWritableState: typeof import('pinia')['mapWritableState'] + const markRaw: typeof import('vue')['markRaw'] + const nextTick: typeof import('vue')['nextTick'] + const onActivated: typeof import('vue')['onActivated'] + const onBeforeMount: typeof import('vue')['onBeforeMount'] + const onBeforeRouteLeave: typeof import('vue-router')['onBeforeRouteLeave'] + const onBeforeRouteUpdate: typeof import('vue-router')['onBeforeRouteUpdate'] + const onBeforeUnmount: typeof import('vue')['onBeforeUnmount'] + const onBeforeUpdate: typeof import('vue')['onBeforeUpdate'] + const onDeactivated: typeof import('vue')['onDeactivated'] + const onErrorCaptured: typeof import('vue')['onErrorCaptured'] + const onMounted: typeof import('vue')['onMounted'] + const onRenderTracked: typeof import('vue')['onRenderTracked'] + const onRenderTriggered: typeof import('vue')['onRenderTriggered'] + const onScopeDispose: typeof import('vue')['onScopeDispose'] + const onServerPrefetch: typeof import('vue')['onServerPrefetch'] + const onUnmounted: typeof import('vue')['onUnmounted'] + const onUpdated: typeof import('vue')['onUpdated'] + const onWatcherCleanup: typeof import('vue')['onWatcherCleanup'] + const provide: typeof import('vue')['provide'] + const reactive: typeof import('vue')['reactive'] + const readonly: typeof import('vue')['readonly'] + const ref: typeof import('vue')['ref'] + const resolveComponent: typeof import('vue')['resolveComponent'] + const setActivePinia: typeof import('pinia')['setActivePinia'] + const setMapStoreSuffix: typeof import('pinia')['setMapStoreSuffix'] + const shallowReactive: typeof import('vue')['shallowReactive'] + const shallowReadonly: typeof import('vue')['shallowReadonly'] + const shallowRef: typeof import('vue')['shallowRef'] + const storeToRefs: typeof import('pinia')['storeToRefs'] + const toRaw: typeof import('vue')['toRaw'] + const toRef: typeof import('vue')['toRef'] + const toRefs: typeof import('vue')['toRefs'] + const toValue: typeof import('vue')['toValue'] + const triggerRef: typeof import('vue')['triggerRef'] + const unref: typeof import('vue')['unref'] + const useAttrs: typeof import('vue')['useAttrs'] + const useCssModule: typeof import('vue')['useCssModule'] + const useCssVars: typeof import('vue')['useCssVars'] + const useId: typeof import('vue')['useId'] + const useLink: typeof import('vue-router')['useLink'] + const useModel: typeof import('vue')['useModel'] + const useRoute: typeof import('vue-router')['useRoute'] + const useRouter: typeof import('vue-router')['useRouter'] + const useScheme: typeof import('@gouvminint/vue-dsfr')['useScheme'] + const useSlots: typeof import('vue')['useSlots'] + const useTabs: typeof import('@gouvminint/vue-dsfr')['useTabs'] + const useTemplateRef: typeof import('vue')['useTemplateRef'] + const watch: typeof import('vue')['watch'] + const watchEffect: typeof import('vue')['watchEffect'] + const watchPostEffect: typeof import('vue')['watchPostEffect'] + const watchSyncEffect: typeof import('vue')['watchSyncEffect'] +} +// for type re-export +declare global { + // @ts-ignore + export type { Component, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue' + import('vue') +} + +// for vue template auto import +import { UnwrapRef } from 'vue' +declare module 'vue' { + interface GlobalComponents {} + interface ComponentCustomProperties { + readonly EffectScope: UnwrapRef + readonly acceptHMRUpdate: UnwrapRef + readonly computed: UnwrapRef + readonly createApp: UnwrapRef + readonly createPinia: UnwrapRef + readonly customRef: UnwrapRef + readonly defineAsyncComponent: UnwrapRef + readonly defineComponent: UnwrapRef + readonly defineStore: UnwrapRef + readonly effectScope: UnwrapRef + readonly getActivePinia: UnwrapRef + readonly getCurrentInstance: UnwrapRef + readonly getCurrentScope: UnwrapRef + readonly h: UnwrapRef + readonly inject: UnwrapRef + readonly isProxy: UnwrapRef + readonly isReactive: UnwrapRef + readonly isReadonly: UnwrapRef + readonly isRef: UnwrapRef + readonly mapActions: UnwrapRef + readonly mapGetters: UnwrapRef + readonly mapState: UnwrapRef + readonly mapStores: UnwrapRef + readonly mapWritableState: UnwrapRef + readonly markRaw: UnwrapRef + readonly nextTick: UnwrapRef + readonly onActivated: UnwrapRef + readonly onBeforeMount: UnwrapRef + readonly onBeforeRouteLeave: UnwrapRef + readonly onBeforeRouteUpdate: UnwrapRef + readonly onBeforeUnmount: UnwrapRef + readonly onBeforeUpdate: UnwrapRef + readonly onDeactivated: UnwrapRef + readonly onErrorCaptured: UnwrapRef + readonly onMounted: UnwrapRef + readonly onRenderTracked: UnwrapRef + readonly onRenderTriggered: UnwrapRef + readonly onScopeDispose: UnwrapRef + readonly onServerPrefetch: UnwrapRef + readonly onUnmounted: UnwrapRef + readonly onUpdated: UnwrapRef + readonly onWatcherCleanup: UnwrapRef + readonly provide: UnwrapRef + readonly reactive: UnwrapRef + readonly readonly: UnwrapRef + readonly ref: UnwrapRef + readonly resolveComponent: UnwrapRef + readonly setActivePinia: UnwrapRef + readonly setMapStoreSuffix: UnwrapRef + readonly shallowReactive: UnwrapRef + readonly shallowReadonly: UnwrapRef + readonly shallowRef: UnwrapRef + readonly storeToRefs: UnwrapRef + readonly toRaw: UnwrapRef + readonly toRef: UnwrapRef + readonly toRefs: UnwrapRef + readonly toValue: UnwrapRef + readonly triggerRef: UnwrapRef + readonly unref: UnwrapRef + readonly useAttrs: UnwrapRef + readonly useCssModule: UnwrapRef + readonly useCssVars: UnwrapRef + readonly useId: UnwrapRef + readonly useLink: UnwrapRef + readonly useModel: UnwrapRef + readonly useRoute: UnwrapRef + readonly useRouter: UnwrapRef + readonly useScheme: UnwrapRef + readonly useSlots: UnwrapRef + readonly useTabs: UnwrapRef + readonly useTemplateRef: UnwrapRef + readonly watch: UnwrapRef + readonly watchEffect: UnwrapRef + readonly watchPostEffect: UnwrapRef + readonly watchSyncEffect: UnwrapRef + } +} \ No newline at end of file diff --git a/apps/client/src/components/AdminRoleForm.vue b/apps/client/src/components/AdminRoleForm.vue index 0f1c14916..e576aed06 100644 --- a/apps/client/src/components/AdminRoleForm.vue +++ b/apps/client/src/components/AdminRoleForm.vue @@ -157,6 +157,7 @@ function closeModal() { diff --git a/apps/client/src/components/ClusterForm.vue b/apps/client/src/components/ClusterForm.vue index bb26eac02..21930412a 100644 --- a/apps/client/src/components/ClusterForm.vue +++ b/apps/client/src/components/ClusterForm.vue @@ -381,7 +381,7 @@ const isConnectionDetailsShown = ref(true) :required="true" data-testid="memoryInput" :placeholder="ONE_TENTH_STR" - @update:model-value="(value: string) => localCluster.memory = localeParseFloat(value)" + @update:model-value="(value: string | number | undefined) => localCluster.memory = localeParseFloat(value as string)" />
+ value: globalThis.Ref description: string | undefined name: string disabled: boolean @@ -50,7 +50,7 @@ function set(data: string) { :placeholder="props.options.placeholder || 'Non défini'" data-testid="input" :disabled="props.options.disabled" - @update:model-value="(event: string) => set(event)" + @update:model-value="(event: string | number | undefined) => set(event as string)" /> { :required="true" data-testid="memoryInput" :placeholder="ONE_TENTH_STR" - @update:model-value="(value: string) => localEnvironment.memory = localeParseFloat(value)" + @update:model-value="(value: string | number | undefined) => localEnvironment.memory = localeParseFloat(value as string)" /> { :required="true" data-testid="cpuInput" :placeholder="ONE_TENTH_STR" - @update:model-value="(value: string) => localEnvironment.cpu = localeParseFloat(value)" + @update:model-value="(value: string | number | undefined) => localEnvironment.cpu = localeParseFloat(value as string)" /> { :required="true" data-testid="gpuInput" :placeholder="ONE_TENTH_STR" - @update:model-value="(value: string) => localEnvironment.gpu = localeParseFloat(value)" + @update:model-value="(value: string | number | undefined) => localEnvironment.gpu = localeParseFloat(value as string)" /> -import type { Project } from '@/utils/project-utils.js' +import type { Project, ProjectOperations } from '@/utils/project-utils.js' defineProps<{ project?: Project @@ -8,7 +8,10 @@ defineProps<{