diff --git a/.env.dev.defaults b/.env.dev.defaults index f6f9a942e8..38107ddb95 100644 --- a/.env.dev.defaults +++ b/.env.dev.defaults @@ -24,7 +24,7 @@ MONITORFISH_API_KEY=dummy-monitorfish-key RAPPORTNAV_URL=http://localhost:8083 # OICD -MONITORENV_OIDC_ENABLED=false +MONITORENV_OIDC_ENABLED=true MONITORENV_OIDC_LOGIN_URL=/oauth2/authorization/proconnect MONITORENV_OIDC_SUCCESS_URL=http://localhost:3000 MONITORENV_OIDC_ERROR_URL=http://localhost:3000/register @@ -138,7 +138,7 @@ FRONTEND_METABASE_URL=https://metabase.din.developpement-durable.gouv.fr/ ################################################################################ # OICD -FRONTEND_OIDC_ENABLED=false +FRONTEND_OIDC_ENABLED=true ################################################################################ # MATOMO @@ -158,3 +158,9 @@ MONITORENV_EXT_PASSWORD=Mot de passe MonitorEnvExt # PERF MONITORENV_BATCH_SIZE=30 + +################################################################################ +# Cypress Tests + +MONITORENV_OIDC_PROXY_URL=http://localhost:8085 +MONITORENV_KEYCLOAK_PROXY_ENABLED=false diff --git a/.env.infra.example b/.env.infra.example index 485ec1c1db..f2bf846647 100644 --- a/.env.infra.example +++ b/.env.infra.example @@ -152,3 +152,9 @@ MONITORENV_EXT_PASSWORD= # PERF MONITORENV_BATCH_SIZE=100 + +################################################################################ +# Cypress Tests + +MONITORENV_OIDC_PROXY_URL= +MONITORENV_KEYCLOAK_PROXY_ENABLED= \ No newline at end of file diff --git a/.env.test.defaults b/.env.test.defaults index 11c995c909..9fe674c41e 100644 --- a/.env.test.defaults +++ b/.env.test.defaults @@ -2,7 +2,7 @@ BACKEND_HTTP_PORT=8880 ENVIRONMENT=test PROJECT_NAME=monitorenv MONITORENV_IMAGE=monitorenv-app -MONITORENV_URL=http://localhost:8880 +MONITORENV_URL=127.0.0.1 MONITORENV_VERSION=0.0.0 MONITORENV_API_KEY=DUMMY-API-KEY @@ -23,22 +23,22 @@ MONITORFISH_API_KEY=dummy-monitorfish-key RAPPORTNAV_URL=http://mock-rapportnav:8080 # OICD -MONITORENV_OIDC_ENABLED=false +MONITORENV_OIDC_ENABLED=true MONITORENV_OIDC_LOGIN_URL=/oauth2/authorization/proconnect -MONITORENV_OIDC_SUCCESS_URL=http://localhost:3000 -MONITORENV_OIDC_ERROR_URL=http://localhost:3000/register +MONITORENV_OIDC_SUCCESS_URL=http://localhost:8880 +MONITORENV_OIDC_ERROR_URL=http://localhost:8880/register MONITORENV_OIDC_AUTHORIZED_SIRETS=1234567890,0987654321 MONITORENV_OIDC_CLIENT_ID=monitorenv MONITORENV_OIDC_CLIENT_SECRET=PNKVjpo4DNCVMCVYUZiS3wepPJdtdFhH MONITORENV_OIDC_REDIRECT_URI=http://localhost:8880/login/oauth2/code/proconnect # Backend server-side calls go directly to Keycloak -MONITORENV_OIDC_ISSUER_URI=http://localhost:8085/realms/monitor +MONITORENV_OIDC_ISSUER_URI=http://keycloak:8080/realms/monitor # Browser-facing authorization URL uses backend proxy (rewrites Keycloak URLs) MONITORENV_OIDC_AUTHORIZATION_URI=http://localhost:8880/realms/monitor/protocol/openid-connect/auth # Server-side token exchange goes directly to Keycloak -MONITORENV_OIDC_TOKEN_URI=http://localhost:8085/realms/monitor/protocol/openid-connect/token -MONITORENV_OIDC_USER_INFO_URI=http://localhost:8085/realms/monitor/protocol/openid-connect/userinfo -MONITORENV_OIDC_JWK_SET_URI=http://localhost:8085/realms/monitor/protocol/openid-connect/certs +MONITORENV_OIDC_TOKEN_URI=http://keycloak:8080/realms/monitor/protocol/openid-connect/token +MONITORENV_OIDC_USER_INFO_URI=http://keycloak:8080/realms/monitor/protocol/openid-connect/userinfo +MONITORENV_OIDC_JWK_SET_URI=http://keycloak:8080/realms/monitor/protocol/openid-connect/certs MONITORENV_OIDC_PROVIDER=proconnect # External issuer for JWT validation (tokens from Docker Keycloak have this issuer) MONITORENV_OIDC_ISSUER_URI_EXTERNAL=http://keycloak:8080/realms/monitor @@ -130,7 +130,7 @@ FRONTEND_METABASE_URL=https://metabase.din.developpement-durable.gouv.fr ################################################################################ # OICD -FRONTEND_OIDC_ENABLED=false +FRONTEND_OIDC_ENABLED=true ################################################################################ @@ -152,3 +152,9 @@ MONITORENV_EXT_PASSWORD= # PERF MONITORENV_BATCH_SIZE=100 + +################################################################################ +# Cypress Tests + +MONITORENV_OIDC_PROXY_URL=http://keycloak:8080 +MONITORENV_KEYCLOAK_PROXY_ENABLED=true \ No newline at end of file diff --git a/.github/workflows/cicd-app.yml b/.github/workflows/cicd-app.yml index 57555240f9..82e8fa3fe6 100644 --- a/.github/workflows/cicd-app.yml +++ b/.github/workflows/cicd-app.yml @@ -208,6 +208,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} MONITORENV_VERSION: ${{ needs.version.outputs.VERSION }} VERSION: ${{needs.version.outputs.VERSION}} + VITE_CYPRESS_PORT: 8880 PUPPETEER_SKIP_DOWNLOAD: "true" steps: - name: Checkout @@ -230,17 +231,12 @@ jobs: cache-dependency-path: ./frontend/package-lock.json node-version: 20 - - name: Setup Firefox - uses: browser-actions/setup-firefox@latest - with: - firefox-version: 119.0.1 - - name: Curl stubbed geoserver check run: until $(curl --output /dev/null --silent --fail "http://localhost:8081/geoserver/wfs?service=WFS&version=1.1.0&request=GetFeature&typename=monitorenv:regulations&outputFormat=application/json&CQL_FILTER=topic=%27Ouest%20Cotentin%20Bivalves%27%20AND%20zone=%27Praires%20Ouest%20cotentin%27"); do printf '.'; sleep 5; done; - uses: cypress-io/github-action@v6 with: - browser: firefox + browser: chrome cache-key: cypress-${{ hashFiles('package-lock.json') }} config-file: config/cypress.config.ts env: PORT=8880 diff --git a/Makefile b/Makefile index c1ec3aa810..5484db35b0 100644 --- a/Makefile +++ b/Makefile @@ -135,7 +135,7 @@ docker-push-app: test-init-infra-env: npm i @import-meta-env/prepare@0.1.13 && npx import-meta-env-prepare -u -x ./.env.infra.example -p ./.env.test.defaults test-run-infra-for-frontend: - export MONITORENV_VERSION=$(VERSION) && docker compose --profile=test -f docker-compose.yml -f docker-compose-test.yml up -d + export MONITORENV_VERSION=$(VERSION) && docker compose --profile=test -f docker-compose.yml -f docker-compose-test.yml -f docker-compose-cypress.yml up -d test: test-back cd frontend && CI=true npm run test:unit diff --git a/backend/build.gradle.kts b/backend/build.gradle.kts index 9f4345f790..8348ba541f 100644 --- a/backend/build.gradle.kts +++ b/backend/build.gradle.kts @@ -127,6 +127,7 @@ dependencies { // Devtools runtimeOnly("org.springframework.boot:spring-boot-devtools") + implementation("org.springframework.cloud:spring-cloud-gateway-proxyexchange-webmvc:4.3.0") // Testing testImplementation("org.springframework.security:spring-security-test") diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/config/CustomProxyExchangeConfig.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/config/CustomProxyExchangeConfig.kt new file mode 100644 index 0000000000..712f455279 --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/config/CustomProxyExchangeConfig.kt @@ -0,0 +1,25 @@ +package fr.gouv.cacem.monitorenv.config + +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.cloud.gateway.mvc.config.ProxyExchangeArgumentResolver +import org.springframework.context.annotation.Configuration +import org.springframework.web.client.RestTemplate +import org.springframework.web.method.support.HandlerMethodArgumentResolver +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer + +/** + * Used by the Keycloak proxy + */ +@Configuration +@ConditionalOnProperty( + value = ["monitorfish.keycloak.proxy.enabled"], + havingValue = "true", + matchIfMissing = false, +) +class CustomProxyExchangeConfig( + private val restTemplate: RestTemplate, +) : WebMvcConfigurer { + override fun addArgumentResolvers(resolvers: MutableList) { + resolvers.add(ProxyExchangeArgumentResolver(restTemplate)) + } +} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/config/KeycloakProxyProperties.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/config/KeycloakProxyProperties.kt new file mode 100644 index 0000000000..f4768133f0 --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/config/KeycloakProxyProperties.kt @@ -0,0 +1,30 @@ +package fr.gouv.cacem.monitorenv.config + +import org.springframework.boot.context.properties.ConfigurationProperties +import org.springframework.context.annotation.Configuration + +/** + * ⚠️ DEVELOPMENT ONLY - Keycloak Proxy Configuration + * + * This configuration is ONLY used for local development and E2E testing. + * It controls whether the KeycloakProxyController is enabled to proxy + * authentication requests to a Keycloak server during development. + * + * ❌ This should NEVER be enabled in production environments. + * ✅ Only used for local development and Cypress E2E tests. + */ +@Configuration +@ConfigurationProperties(prefix = "monitorenv.keycloak.proxy") +class KeycloakProxyProperties { + /** + * ⚠️ DEVELOPMENT ONLY - Enable Keycloak proxy controller + * + * This property is only used in development: local environment and cypress tests. + * When enabled, the KeycloakProxyController will proxy authentication requests + * to a Keycloak server and rewrite URLs for local development. + * + * Default: false (disabled) + * Production: Must always be false + */ + var enabled: Boolean = false +} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/config/OIDCProperties.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/config/OIDCProperties.kt index cd815c0974..7d06a9ac22 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/config/OIDCProperties.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/config/OIDCProperties.kt @@ -35,7 +35,7 @@ class OIDCProperties { * ⚠️ DEVELOPMENT ONLY - Keycloak proxy URL * * This property is only used when running Keycloak locally in E2E tests - * and local development. It specifies the URL of the build.gtKeycloak server + * and local development. It specifies the URL of the Keycloak server * that the KeycloakProxyController should proxy requests to. * * Example: "http://localhost:8085" diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/config/SecurityConfig.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/config/SecurityConfig.kt index 210b3c6247..e47f81aada 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/config/SecurityConfig.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/config/SecurityConfig.kt @@ -122,6 +122,9 @@ class SecurityConfig( "/robots.txt", "/favicon-32.ico", "/asset-manifest.json", + "/proxy/**", + "/realms/**", + "/resources/**", "/swagger-ui/**", "v3/**", // Used to redirect to the frontend SPA, see Spa.kt diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/development/KeycloakProxy.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/development/KeycloakProxy.kt index 20cb0ed0ca..352f6cfaef 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/development/KeycloakProxy.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/development/KeycloakProxy.kt @@ -18,7 +18,7 @@ import java.nio.charset.StandardCharsets * ⚠️ DEVELOPMENT ONLY - Keycloak Authentication Proxy * * This controller is ONLY used for local development and E2E testing. - * It provides a proxy between the monitorenv application and a Keycloak server + * It provides a proxy between the MonitorEnv application and a Keycloak server * to handle authentication flows during development. * * ❌ This controller is NEVER enabled in production environments. diff --git a/backend/src/main/resources/application.yml b/backend/src/main/resources/application.yml index 8c46f2cd21..55c874e4a0 100644 --- a/backend/src/main/resources/application.yml +++ b/backend/src/main/resources/application.yml @@ -1,5 +1,6 @@ server: port: 8880 + use-forward-headers: true forward-headers-strategy: framework compression: enabled: true @@ -51,6 +52,9 @@ monitorenv: legicem: id: ${MONITORENV_LEGICEM_ID} password: ${MONITORENV_LEGICEM_PASSWORD} + keycloak: + proxy: + enabled: ${MONITORENV_KEYCLOAK_PROXY_ENABLED:false} spring: jmx: diff --git a/docker-compose-cypress.yml b/docker-compose-cypress.yml new file mode 100644 index 0000000000..ebcc31b9aa --- /dev/null +++ b/docker-compose-cypress.yml @@ -0,0 +1,41 @@ +services: + app: + environment: + - MONITORENV_OIDC_PROXY_URL=${MONITORENV_OIDC_PROXY_URL} + - MONITORENV_KEYCLOAK_PROXY_ENABLED=${MONITORENV_KEYCLOAK_PROXY_ENABLED} + - SPRING_CLOUD_GATEWAY_MVC_FORM_FILTER_ENABLED=false + depends_on: + keycloak: + condition: service_healthy + keycloak: + container_name: monitorenv_keycloak + profiles: [ test ] + image: quay.io/keycloak/keycloak:23.0.0 + environment: + - KEYCLOAK_ADMIN=admin + - KEYCLOAK_ADMIN_PASSWORD=admin + - KC_HOSTNAME_STRICT=false # See https://www.keycloak.org/server/reverseproxy for vars below + - KC_HOSTNAME=keycloak:8080 + - KC_HTTP_ENABLED=true + - PROXY_ADDRESS_FORWARDING=true + - KC_PROXY=edge + - KC_PROXY_HEADERS=forwarded + - KC_HEALTH_ENABLED=true + - KC_FRONTEND_URL=http://localhost:8880/ + healthcheck: + test: [ "CMD-SHELL", + "exec 3<>/dev/tcp/localhost/8080 && echo -e 'GET /health/ready HTTP/1.1\\r\\nHost: localhost\\r\\nConnection: close\\r\\n\\r\\n' >&3 && cat <&3 | grep -q '200 OK'" ] + interval: 30s + timeout: 5s + retries: 20 + networks: + - backend_network + ports: + - "8085:8080" + volumes: + - ./infra/configurations/keycloack:/opt/keycloak/data/import + command: + - start-dev + - --import-realm + + \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 8d5f240459..92ef981a77 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -128,7 +128,7 @@ services: keycloak: container_name: monitorenv_keycloak profiles: [ dev ] - image: quay.io/keycloak/keycloak:latest + image: quay.io/keycloak/keycloak:23.0.0 environment: - KEYCLOAK_ADMIN=admin - KEYCLOAK_ADMIN_PASSWORD=admin diff --git a/frontend/config/cypress.config.ts b/frontend/config/cypress.config.ts index fb977a0958..0031546186 100644 --- a/frontend/config/cypress.config.ts +++ b/frontend/config/cypress.config.ts @@ -2,12 +2,11 @@ import { defineConfig } from 'cypress' const IS_CI = Boolean(process.env.CI) -const WEBAPP_PORT = IS_CI ? 8880 : 3000 -const WEBAPP_HOST = 'localhost' export default defineConfig({ + chromeWebSecurity: false, e2e: { - baseUrl: `http://${WEBAPP_HOST}:${WEBAPP_PORT}`, + baseUrl: `http://${IS_CI ? '0.0.0.0:8880' : 'localhost:3000'}`, specPattern: ['cypress/e2e/**/*.spec.ts'] }, pageLoadTimeout: 120000, diff --git a/frontend/cypress/e2e/back_office/administration_form.spec.ts b/frontend/cypress/e2e/back_office/administration_form.spec.ts index 9f987e32b1..a028828e44 100644 --- a/frontend/cypress/e2e/back_office/administration_form.spec.ts +++ b/frontend/cypress/e2e/back_office/administration_form.spec.ts @@ -1,9 +1,8 @@ context('Back Office > Administration Form', () => { beforeEach(() => { + cy.login('superuser') cy.intercept('GET', `/api/v1/administrations`).as('getAdministrations') - cy.visit(`/backoffice/administrations`) - cy.wait('@getAdministrations') }) diff --git a/frontend/cypress/e2e/back_office/administration_table/filters.spec.ts b/frontend/cypress/e2e/back_office/administration_table/filters.spec.ts index 8670ffb6e7..ebb3b50d53 100644 --- a/frontend/cypress/e2e/back_office/administration_table/filters.spec.ts +++ b/frontend/cypress/e2e/back_office/administration_table/filters.spec.ts @@ -1,5 +1,6 @@ context('Back Office > Administration Table > Filters', () => { beforeEach(() => { + cy.login('superuser') cy.intercept('GET', `/api/v1/administrations`).as('getAdministrations') cy.visit(`/backoffice/administrations`) diff --git a/frontend/cypress/e2e/back_office/administration_table/row_actions.spec.ts b/frontend/cypress/e2e/back_office/administration_table/row_actions.spec.ts index d8d487a0a4..9fa6c02bba 100644 --- a/frontend/cypress/e2e/back_office/administration_table/row_actions.spec.ts +++ b/frontend/cypress/e2e/back_office/administration_table/row_actions.spec.ts @@ -1,6 +1,7 @@ // Successful archiving and deleting use cases are tested in `administration_form.spec.ts` for Test Idempotency purpose context('Back Office > Administration Table > Row Actions', () => { beforeEach(() => { + cy.login('superuser') cy.intercept('GET', `/api/v1/administrations`).as('getAdministrations') cy.visit(`/backoffice/administrations`) diff --git a/frontend/cypress/e2e/back_office/control_unit_form.spec.ts b/frontend/cypress/e2e/back_office/control_unit_form.spec.ts index fbfe9ae9ab..7cb074e851 100644 --- a/frontend/cypress/e2e/back_office/control_unit_form.spec.ts +++ b/frontend/cypress/e2e/back_office/control_unit_form.spec.ts @@ -2,10 +2,9 @@ import { expectPathToBe } from '../utils/expectPathToBe' context('Back Office > Control Unit Form', () => { beforeEach(() => { + cy.login('superuser') cy.intercept('GET', `/api/v2/control_units`).as('getControlUnits') - cy.visit(`/backoffice/control_units`) - cy.wait('@getControlUnits') }) diff --git a/frontend/cypress/e2e/back_office/control_unit_table/filters.spec.ts b/frontend/cypress/e2e/back_office/control_unit_table/filters.spec.ts index 38923260f9..ab7c920860 100644 --- a/frontend/cypress/e2e/back_office/control_unit_table/filters.spec.ts +++ b/frontend/cypress/e2e/back_office/control_unit_table/filters.spec.ts @@ -1,5 +1,6 @@ context('Back Office > Control Unit Table > Filters', () => { beforeEach(() => { + cy.login('superuser') cy.intercept('GET', `/api/v2/control_units`).as('getControlUnits') cy.visit(`/backoffice/control_units`) diff --git a/frontend/cypress/e2e/back_office/control_unit_table/row_actions.spec.ts b/frontend/cypress/e2e/back_office/control_unit_table/row_actions.spec.ts index 4cd1b6e835..541efabac8 100644 --- a/frontend/cypress/e2e/back_office/control_unit_table/row_actions.spec.ts +++ b/frontend/cypress/e2e/back_office/control_unit_table/row_actions.spec.ts @@ -1,6 +1,7 @@ // Successful archiving and deleting use cases are tested in `control_unit_form.spec.ts` for Test Idempotency purpose context('Back Office > Control Unit Table > Row Actions', () => { beforeEach(() => { + cy.login('superuser') cy.intercept('GET', `/api/v2/control_units`).as('getControlUnits') cy.visit(`/backoffice/control_units`) diff --git a/frontend/cypress/e2e/back_office/station_form.spec.ts b/frontend/cypress/e2e/back_office/station_form.spec.ts index 0e34828520..2e416f05be 100644 --- a/frontend/cypress/e2e/back_office/station_form.spec.ts +++ b/frontend/cypress/e2e/back_office/station_form.spec.ts @@ -2,10 +2,9 @@ import { faker } from '@faker-js/faker' context('Back Office > Station Form', () => { beforeEach(() => { + cy.login('superuser') cy.intercept('GET', `/api/v1/stations`).as('getStations') - cy.visit(`/backoffice/stations`) - cy.wait('@getStations') }) diff --git a/frontend/cypress/e2e/back_office/station_table/filters.spec.ts b/frontend/cypress/e2e/back_office/station_table/filters.spec.ts index 78512def94..fc06fbc6f4 100644 --- a/frontend/cypress/e2e/back_office/station_table/filters.spec.ts +++ b/frontend/cypress/e2e/back_office/station_table/filters.spec.ts @@ -1,5 +1,6 @@ context('Back Office > Station Table > Filters', () => { beforeEach(() => { + cy.login('superuser') cy.intercept('GET', `/api/v1/stations`).as('getStations') cy.visit(`/backoffice/stations`) diff --git a/frontend/cypress/e2e/back_office/station_table/row_actions.spec.ts b/frontend/cypress/e2e/back_office/station_table/row_actions.spec.ts index ded5307fee..76a78f2e06 100644 --- a/frontend/cypress/e2e/back_office/station_table/row_actions.spec.ts +++ b/frontend/cypress/e2e/back_office/station_table/row_actions.spec.ts @@ -1,6 +1,7 @@ // Successful archiving and deleting use cases are tested in `base_form.spec.ts` for Test Idempotency purpose context('Back Office > Station Table > Row Actions', () => { beforeEach(() => { + cy.login('superuser') cy.intercept('GET', `/api/v1/stations`).as('getStations') cy.visit(`/backoffice/stations`) diff --git a/frontend/cypress/e2e/main_window/control_unit_list_dialog/filters.spec.ts b/frontend/cypress/e2e/main_window/control_unit_list_dialog/filters.spec.ts index 8645a7c101..6097dfdce4 100644 --- a/frontend/cypress/e2e/main_window/control_unit_list_dialog/filters.spec.ts +++ b/frontend/cypress/e2e/main_window/control_unit_list_dialog/filters.spec.ts @@ -2,6 +2,7 @@ import { FAKE_MAPBOX_RESPONSE } from '../../constants' context('Main Window > Control Unit List Dialog > Filters', () => { beforeEach(() => { + cy.login('superuser') cy.intercept('GET', 'https://api.mapbox.com/**', FAKE_MAPBOX_RESPONSE) cy.visit(`/`).wait(1000) diff --git a/frontend/cypress/e2e/main_window/dashboard/dashboard.spec.ts b/frontend/cypress/e2e/main_window/dashboard/dashboard.spec.ts index 381336b29e..070c00152b 100644 --- a/frontend/cypress/e2e/main_window/dashboard/dashboard.spec.ts +++ b/frontend/cypress/e2e/main_window/dashboard/dashboard.spec.ts @@ -1,9 +1,8 @@ -import { FAKE_MAPBOX_RESPONSE } from '../../constants' +import { goToMainWindow } from '../utils' context('Dashboard', () => { beforeEach(() => { - cy.intercept('GET', 'https://api.mapbox.com/**', FAKE_MAPBOX_RESPONSE) - cy.visit('/#@-394744.20,6104201.66,8.72') + goToMainWindow() }) describe('dashboard', () => { diff --git a/frontend/cypress/e2e/main_window/interest_point.spec.ts b/frontend/cypress/e2e/main_window/interest_point.spec.ts index 776fb9b41f..5cab746fc2 100644 --- a/frontend/cypress/e2e/main_window/interest_point.spec.ts +++ b/frontend/cypress/e2e/main_window/interest_point.spec.ts @@ -1,9 +1,8 @@ -import { FAKE_MAPBOX_RESPONSE } from '../constants' +import { goToMainWindow } from './utils' context('InterestPoint', () => { beforeEach(() => { - cy.intercept('GET', 'https://api.mapbox.com/**', FAKE_MAPBOX_RESPONSE) - cy.visit('/#@-824534.42,6082993.21,8.70') + goToMainWindow() }) describe('An interest point', () => { diff --git a/frontend/cypress/e2e/main_window/layerTree/amp_layers.spec.ts b/frontend/cypress/e2e/main_window/layerTree/amp_layers.spec.ts index b7c6f24ef0..8ec6d5457e 100644 --- a/frontend/cypress/e2e/main_window/layerTree/amp_layers.spec.ts +++ b/frontend/cypress/e2e/main_window/layerTree/amp_layers.spec.ts @@ -1,13 +1,14 @@ import { Layers } from 'domain/entities/layers/constants' -import { FAKE_MAPBOX_RESPONSE, PAGE_CENTER_PIXELS } from '../../constants' +import { PAGE_CENTER_PIXELS } from '../../constants' +import { goToMainWindow } from '../utils' context('LayerTree > AMP Layers', () => { beforeEach(() => { - cy.intercept('GET', 'https://api.mapbox.com/**', FAKE_MAPBOX_RESPONSE) cy.intercept('GET', '/bff/v1/amps').as('getAmps') cy.intercept('GET', '/bff/v1/regulatory').as('getRegulatoryAreas') - cy.visit(`/`) + goToMainWindow() + cy.wait(['@getAmps', '@getRegulatoryAreas']) cy.clickButton('Arbre des couches').wait(1000) }) diff --git a/frontend/cypress/e2e/main_window/layerTree/regulatory_layers.spec.ts b/frontend/cypress/e2e/main_window/layerTree/regulatory_layers.spec.ts index d5df147188..301774d498 100644 --- a/frontend/cypress/e2e/main_window/layerTree/regulatory_layers.spec.ts +++ b/frontend/cypress/e2e/main_window/layerTree/regulatory_layers.spec.ts @@ -1,14 +1,14 @@ import { Layers } from 'domain/entities/layers/constants' -import { FAKE_MAPBOX_RESPONSE, PAGE_CENTER_PIXELS } from '../../constants' +import { PAGE_CENTER_PIXELS } from '../../constants' +import { goToMainWindow } from '../utils' context('LayerTree > Regulatory Layers', () => { beforeEach(() => { - cy.intercept('GET', 'https://api.mapbox.com/**', FAKE_MAPBOX_RESPONSE) cy.intercept('GET', '/bff/v1/amps').as('getAmps') cy.intercept('GET', '/bff/v1/regulatory').as('getRegulatoryAreas') - cy.visit('/#@-481936.30,6137793.76,8.69') + goToMainWindow() cy.wait(['@getAmps', '@getRegulatoryAreas']) cy.clickButton('Arbre des couches') diff --git a/frontend/cypress/e2e/main_window/layerTree/search_zone.spec.ts b/frontend/cypress/e2e/main_window/layerTree/search_zone.spec.ts index 50ad65f4a0..e5205a095a 100644 --- a/frontend/cypress/e2e/main_window/layerTree/search_zone.spec.ts +++ b/frontend/cypress/e2e/main_window/layerTree/search_zone.spec.ts @@ -1,12 +1,11 @@ -import { FAKE_MAPBOX_RESPONSE } from '../../constants' +import { goToMainWindow } from '../utils' context('LayerTree > Search zone', () => { beforeEach(() => { - cy.intercept('GET', 'https://api.mapbox.com/**', FAKE_MAPBOX_RESPONSE) cy.intercept('GET', '/bff/v1/amps').as('getAmps') cy.intercept('GET', '/bff/v1/regulatory').as('getRegulatoryAreas') cy.intercept('GET', '/bff/v1/vigilance_areas').as('getVigilanceAreas') - cy.visit('/#@-196785.63,5515456.96,7.26') + goToMainWindow() cy.wait(['@getAmps', '@getRegulatoryAreas', '@getVigilanceAreas']) cy.clickButton('Arbre des couches').wait(1000) }) diff --git a/frontend/cypress/e2e/main_window/layerTree/vigilance_area_layers.spec.ts b/frontend/cypress/e2e/main_window/layerTree/vigilance_area_layers.spec.ts index ec3b8347b5..711df0fd62 100644 --- a/frontend/cypress/e2e/main_window/layerTree/vigilance_area_layers.spec.ts +++ b/frontend/cypress/e2e/main_window/layerTree/vigilance_area_layers.spec.ts @@ -1,16 +1,14 @@ import { Layers } from 'domain/entities/layers/constants' -import { FAKE_MAPBOX_RESPONSE, PAGE_CENTER_PIXELS } from '../../constants' -// import { getBaseLayerSnapShot } from '../utils' +import { PAGE_CENTER_PIXELS } from '../../constants' +import { goToMainWindow } from '../utils' context('LayerTree > Vigilance Area Layers', () => { beforeEach(() => { cy.intercept('GET', '/bff/v1/amps').as('getAmps') cy.intercept('GET', '/bff/v1/regulatory').as('getRegulatoryAreas') cy.intercept('GET', '/bff/v1/vigilance_areas').as('getVigilanceAreas') - cy.intercept('GET', 'https://api.mapbox.com/**', FAKE_MAPBOX_RESPONSE) - - cy.visit('/#@-444365.78,6153753.97,7.20') + goToMainWindow() cy.wait(['@getAmps', '@getRegulatoryAreas']) cy.wait('@getVigilanceAreas').then(({ response }) => expect(response?.statusCode).equal(200)) diff --git a/frontend/cypress/e2e/main_window/measurements_tools.spec.ts b/frontend/cypress/e2e/main_window/measurements_tools.spec.ts index 5a83bdd917..627feb64f2 100644 --- a/frontend/cypress/e2e/main_window/measurements_tools.spec.ts +++ b/frontend/cypress/e2e/main_window/measurements_tools.spec.ts @@ -1,9 +1,8 @@ -import { FAKE_MAPBOX_RESPONSE } from '../constants' +import { goToMainWindow } from './utils' context('Measurement tools', () => { beforeEach(() => { - cy.intercept('GET', 'https://api.mapbox.com/**', FAKE_MAPBOX_RESPONSE) - cy.visit('/#@-824534.42,6082993.21,8.70') + goToMainWindow() }) it('A user measure a distance with line tool', () => { diff --git a/frontend/cypress/e2e/main_window/monitor-ext.spec.ts b/frontend/cypress/e2e/main_window/monitor-ext.spec.ts index 88f3ba5375..83db23d1dd 100644 --- a/frontend/cypress/e2e/main_window/monitor-ext.spec.ts +++ b/frontend/cypress/e2e/main_window/monitor-ext.spec.ts @@ -2,6 +2,7 @@ import { FAKE_MAPBOX_RESPONSE } from '../constants' context('MonitorExt', () => { beforeEach(() => { + cy.login('monitorenv') cy.intercept('GET', 'https://api.mapbox.com/**', FAKE_MAPBOX_RESPONSE) cy.intercept('GET', '/bff/v1/semaphores').as('getSemaphores') diff --git a/frontend/cypress/e2e/main_window/recentActivity/filters.spec.ts b/frontend/cypress/e2e/main_window/recentActivity/filters.spec.ts index 061d47c085..8f2a59c454 100644 --- a/frontend/cypress/e2e/main_window/recentActivity/filters.spec.ts +++ b/frontend/cypress/e2e/main_window/recentActivity/filters.spec.ts @@ -1,7 +1,7 @@ import { customDayjs } from '@mtes-mct/monitor-ui' -import { FAKE_MAPBOX_RESPONSE } from '../../constants' import { getUtcDateInMultipleFormats } from '../../utils/getUtcDateInMultipleFormats' +import { goToMainWindow } from '../utils' function setDateRangeWithControlsFilter(): { endDateFilter: string @@ -19,9 +19,8 @@ function setDateRangeWithControlsFilter(): { context('Recent Activity -> Filters', () => { beforeEach(() => { cy.intercept('GET', '/api/v1/themes').as('getThemes') - cy.intercept('GET', 'https://api.mapbox.com/**', FAKE_MAPBOX_RESPONSE) cy.intercept('POST', `/bff/v1/recent-activity/controls`).as('postRecentActivityControls') - cy.visit('/#@57126.60,5961745.35,6.50') + goToMainWindow() cy.clickButton("Voir l'activité récente") cy.wait('@getThemes') diff --git a/frontend/cypress/e2e/main_window/reporting/create_reporting.spec.ts b/frontend/cypress/e2e/main_window/reporting/create_reporting.spec.ts index 5acd245f38..43532f0053 100644 --- a/frontend/cypress/e2e/main_window/reporting/create_reporting.spec.ts +++ b/frontend/cypress/e2e/main_window/reporting/create_reporting.spec.ts @@ -1,23 +1,15 @@ import { omit } from 'lodash' -import { FAKE_MAPBOX_RESPONSE } from '../../constants' import { createReporting } from '../../utils/createReporting' import { getUtcDateInMultipleFormats } from '../../utils/getUtcDateInMultipleFormats' +import { goToMainWindow } from '../utils' context('Reporting', () => { beforeEach(() => { - cy.intercept('GET', 'https://api.mapbox.com/**', FAKE_MAPBOX_RESPONSE) cy.intercept('GET', '/bff/v1/reportings*').as('getReportings') cy.intercept('GET', '/api/v1/stations').as('getStations') - cy.viewport(1580, 1024) - - cy.visit(`/`, { - onBeforeLoad() { - Cypress.env('CYPRESS_REPORTING_FORM_AUTO_SAVE_ENABLED', 'true') - } - }) - + goToMainWindow() cy.wait(['@getReportings', '@getStations']) }) diff --git a/frontend/cypress/e2e/main_window/search_places.spec.ts b/frontend/cypress/e2e/main_window/search_places.spec.ts index 5ad9a43e62..84cb30d4ee 100644 --- a/frontend/cypress/e2e/main_window/search_places.spec.ts +++ b/frontend/cypress/e2e/main_window/search_places.spec.ts @@ -1,9 +1,8 @@ -import { FAKE_MAPBOX_RESPONSE } from '../constants' +import { goToMainWindow } from './utils' context('Search Places', () => { beforeEach(() => { - cy.intercept('GET', 'https://api.mapbox.com/**', FAKE_MAPBOX_RESPONSE) - cy.visit('/#@-824534.42,6082993.21,8.70') + goToMainWindow() }) it('A user can search a place and zoom on it when it is selected', () => { diff --git a/frontend/cypress/e2e/main_window/utils.ts b/frontend/cypress/e2e/main_window/utils.ts index 78e9173f27..4acfd163eb 100644 --- a/frontend/cypress/e2e/main_window/utils.ts +++ b/frontend/cypress/e2e/main_window/utils.ts @@ -2,6 +2,12 @@ import { FAKE_MAPBOX_RESPONSE } from '../constants' export function goToMainWindow() { cy.intercept('GET', 'https://api.mapbox.com/**', FAKE_MAPBOX_RESPONSE) - - cy.visit(`/`).wait(1000) + cy.login('superuser') + cy.visit(`/`, { + onBeforeLoad() { + Cypress.env('CYPRESS_REPORTING_FORM_AUTO_SAVE_ENABLED', 'true') + Cypress.env('CYPRESS_REPORTING_FORM_AUTO_UPDATE', 'true') + } + }) + cy.wait(1000) } diff --git a/frontend/cypress/e2e/main_window/vigilance_area/create_vigilance_area.spec.ts b/frontend/cypress/e2e/main_window/vigilance_area/create_vigilance_area.spec.ts index b74311aeb3..2edc50e4a0 100644 --- a/frontend/cypress/e2e/main_window/vigilance_area/create_vigilance_area.spec.ts +++ b/frontend/cypress/e2e/main_window/vigilance_area/create_vigilance_area.spec.ts @@ -1,22 +1,20 @@ import { VigilanceArea } from '@features/VigilanceArea/types' import { Layers } from '../../../../src/domain/entities/layers/constants' -import { FAKE_MAPBOX_RESPONSE } from '../../constants' import { getFutureDate } from '../../utils/getFutureDate' import { getUtcDateInMultipleFormats } from '../../utils/getUtcDateInMultipleFormats' +import { goToMainWindow } from '../utils' const startDate = getFutureDate(7, 'day') const endDate = getFutureDate(31, 'day') describe('Create Vigilance Area', () => { beforeEach(() => { - cy.intercept('GET', 'https://api.mapbox.com/**', FAKE_MAPBOX_RESPONSE) cy.intercept('GET', '/bff/v1/amps').as('getAmps') cy.intercept('GET', '/bff/v1/regulatory').as('getRegulatoryAreas') cy.intercept('GET', '/bff/v1/vigilance_areas').as('getVigilanceAreas') - cy.viewport(1580, 1024) - cy.visit('/') + goToMainWindow() cy.wait(['@getAmps', '@getRegulatoryAreas', '@getVigilanceAreas']) cy.intercept('PUT', '/bff/v1/vigilance_areas').as('createVigilanceArea') diff --git a/frontend/cypress/e2e/main_window/vigilance_area/delete_vigilance_area.spec.ts b/frontend/cypress/e2e/main_window/vigilance_area/delete_vigilance_area.spec.ts index 806cbfe20b..f208c7b486 100644 --- a/frontend/cypress/e2e/main_window/vigilance_area/delete_vigilance_area.spec.ts +++ b/frontend/cypress/e2e/main_window/vigilance_area/delete_vigilance_area.spec.ts @@ -1,5 +1,6 @@ import { getFutureDate } from '../../utils/getFutureDate' import { getUtcDateInMultipleFormats } from '../../utils/getUtcDateInMultipleFormats' +import { goToMainWindow } from '../utils' describe('Create Vigilance Area', () => { beforeEach(() => { @@ -7,8 +8,7 @@ describe('Create Vigilance Area', () => { cy.intercept('GET', '/bff/v1/regulatory').as('getRegulatoryAreas') cy.intercept('GET', '/bff/v1/vigilance_areas').as('getVigilanceAreas') - cy.viewport(1580, 1024) - cy.visit('/#@-1049081.65,5909154.00,6.00') + goToMainWindow() cy.wait(['@getAmps', '@getRegulatoryAreas', '@getVigilanceAreas']) cy.intercept('PUT', '/bff/v1/vigilance_areas').as('createVigilanceArea') diff --git a/frontend/cypress/e2e/main_window/vigilance_area/edit_vigilance_area.spec.ts b/frontend/cypress/e2e/main_window/vigilance_area/edit_vigilance_area.spec.ts index 85139e0469..be52f7f83c 100644 --- a/frontend/cypress/e2e/main_window/vigilance_area/edit_vigilance_area.spec.ts +++ b/frontend/cypress/e2e/main_window/vigilance_area/edit_vigilance_area.spec.ts @@ -1,13 +1,12 @@ -import { FAKE_MAPBOX_RESPONSE } from '../../constants' +import { goToMainWindow } from '../utils' describe('Edit Vigilance Area', () => { beforeEach(() => { - cy.intercept('GET', 'https://api.mapbox.com/**', FAKE_MAPBOX_RESPONSE) cy.intercept('GET', '/bff/v1/amps').as('getAmps') cy.intercept('GET', '/bff/v1/regulatory').as('getRegulatoryAreas') cy.intercept('GET', '/bff/v1/vigilance_areas').as('getVigilanceAreas') - cy.viewport(1580, 1024) + goToMainWindow() }) it('Should successfully update a vigilance area', () => { cy.visit('/#@-192242.97,5819420.73,9.93') diff --git a/frontend/cypress/e2e/side_window/dashboard/edit_dashboard.spec.ts b/frontend/cypress/e2e/side_window/dashboard/edit_dashboard.spec.ts index c9144d0681..984931524a 100644 --- a/frontend/cypress/e2e/side_window/dashboard/edit_dashboard.spec.ts +++ b/frontend/cypress/e2e/side_window/dashboard/edit_dashboard.spec.ts @@ -4,7 +4,6 @@ import { visitSideWindow } from '../../utils/visitSideWindow' context('Side Window > Dashboard > Edit Dashboard', () => { beforeEach(() => { cy.intercept('GET', '/bff/v1/dashboards').as('getDashboards') - cy.viewport(1280, 1024) visitSideWindow() cy.clickButton('Tableaux de bord') cy.wait('@getDashboards') diff --git a/frontend/cypress/e2e/side_window/dashboard_list/filters.spec.ts b/frontend/cypress/e2e/side_window/dashboard_list/filters.spec.ts index b30c071422..87a6de4b73 100644 --- a/frontend/cypress/e2e/side_window/dashboard_list/filters.spec.ts +++ b/frontend/cypress/e2e/side_window/dashboard_list/filters.spec.ts @@ -7,7 +7,6 @@ context('Side Window > Dashboard List > Filter Bar', () => { beforeEach(() => { cy.intercept('GET', '/bff/v1/dashboards').as('getDashboards') cy.intercept('GET', '/bff/v1/regulatory').as('getRegulatoryAreas') - cy.viewport(1280, 1024) visitSideWindow() cy.clickButton('Tableaux de bord') cy.wait(['@getDashboards', '@getRegulatoryAreas']) diff --git a/frontend/cypress/e2e/side_window/mission_form/attach_actions_to_reportings_in_mission.spec.ts b/frontend/cypress/e2e/side_window/mission_form/attach_actions_to_reportings_in_mission.spec.ts index c5b38cd907..bfb21bdefe 100644 --- a/frontend/cypress/e2e/side_window/mission_form/attach_actions_to_reportings_in_mission.spec.ts +++ b/frontend/cypress/e2e/side_window/mission_form/attach_actions_to_reportings_in_mission.spec.ts @@ -3,21 +3,15 @@ import { getFormattedReportingId } from '@features/Reportings/utils' import { createMissionWithAttachedReportingAndAttachedAction } from '../../utils/createMissionWithAttachedReportingAndAttachedAction' import { createReportingOnSideWindow } from '../../utils/createReportingOnSideWindow' +import { visitSideWindow } from '../../utils/visitSideWindow' const dispatch = action => cy.window().its('store').invoke('dispatch', action) context('Side Window > Mission Form > Attach action to reporting', () => { beforeEach(() => { - cy.viewport(1280, 1024) cy.intercept('GET', '/bff/v1/missions*').as('getMissions') - cy.visit(`/side_window`, { - onBeforeLoad: () => { - Cypress.env('CYPRESS_MISSION_FORM_AUTO_SAVE_ENABLED', 'true') - Cypress.env('CYPRESS_MISSION_FORM_AUTO_UPDATE', 'true') - Cypress.env('CYPRESS_REPORTING_FORM_AUTO_SAVE_ENABLED', 'true') - } - }) + visitSideWindow() cy.fill('Période', 'Année en cours') cy.wait('@getMissions') }) diff --git a/frontend/cypress/e2e/side_window/mission_form/delete_mission.spec.ts b/frontend/cypress/e2e/side_window/mission_form/delete_mission.spec.ts index 73d4c25949..e67c7b9da3 100644 --- a/frontend/cypress/e2e/side_window/mission_form/delete_mission.spec.ts +++ b/frontend/cypress/e2e/side_window/mission_form/delete_mission.spec.ts @@ -90,8 +90,6 @@ context('Side Window > Mission Form > Delete Mission', () => { }) it('A mission should be deleted and attached reportings should be detached', () => { - visitSideWindow() - createMissionWithAttachedReportingAndAttachedAction().then(response => { const missionId = response.body.id cy.intercept('PUT', `/bff/v1/missions/${missionId}`).as('updateMission') diff --git a/frontend/cypress/e2e/side_window/mission_form/mission_actions.spec.ts b/frontend/cypress/e2e/side_window/mission_form/mission_actions.spec.ts index 7c4d24783e..38cd84636a 100644 --- a/frontend/cypress/e2e/side_window/mission_form/mission_actions.spec.ts +++ b/frontend/cypress/e2e/side_window/mission_form/mission_actions.spec.ts @@ -4,6 +4,7 @@ import { setGeometry } from 'domain/shared_slices/Draw' import { createPendingMission } from '../../utils/createPendingMission' import { getFutureDate } from '../../utils/getFutureDate' +import { visitSideWindow } from '../../utils/visitSideWindow' import type { EnvActionControl, EnvActionSurveillance, Infraction } from 'domain/entities/missions' import type { GeoJSON } from 'domain/types/GeoJSON' @@ -28,15 +29,10 @@ context('Side Window > Mission Form > Mission actions', () => { beforeEach(() => { cy.viewport(1280, 1024) cy.intercept('GET', '/bff/v1/missions*').as('getMissions') - cy.visit(`/side_window`, { - onBeforeLoad: () => { - Cypress.env('CYPRESS_MISSION_FORM_AUTO_SAVE_ENABLED', 'true') - Cypress.env('CYPRESS_MISSION_FORM_AUTO_UPDATE', 'true') - Cypress.env('CYPRESS_REPORTING_FORM_AUTO_UPDATE', 'true') - } - }) - cy.fill('Période', 'Année en cours') - cy.wait('@getMissions') + visitSideWindow() + cy.fill('Période', 'Année en cours') + + cy.wait('@getMissions') }) it('An infraction Should be duplicated', () => { diff --git a/frontend/cypress/e2e/side_window/mission_form/mission_dates_validation.spec.ts b/frontend/cypress/e2e/side_window/mission_form/mission_dates_validation.spec.ts index 487a139590..d39df5f85c 100644 --- a/frontend/cypress/e2e/side_window/mission_form/mission_dates_validation.spec.ts +++ b/frontend/cypress/e2e/side_window/mission_form/mission_dates_validation.spec.ts @@ -4,6 +4,7 @@ import { setGeometry } from 'domain/shared_slices/Draw' import { getFutureDate } from '../../utils/getFutureDate' import { getUtcDateInMultipleFormats } from '../../utils/getUtcDateInMultipleFormats' +import { visitSideWindow } from '../../utils/visitSideWindow' import type { GeoJSON } from 'domain/types/GeoJSON' @@ -25,13 +26,9 @@ const surveillanceGeometry: GeoJSON.Geometry = { } context('Side Window > Mission Form > Mission dates', () => { beforeEach(() => { - cy.viewport(1280, 1024) - cy.visit(`/side_window`, { - onBeforeLoad: () => { - Cypress.env('CYPRESS_MISSION_FORM_AUTO_SAVE_ENABLED', 'true') - Cypress.env('CYPRESS_MISSION_FORM_AUTO_UPDATE', 'true') - } - }) + cy.intercept('GET', '/bff/v1/missions*').as('getMissions') + visitSideWindow() + cy.wait('@getMissions') }) it('A mission should be created with surveillances and valid dates', () => { diff --git a/frontend/cypress/e2e/side_window/mission_form/mission_zone.spec.ts b/frontend/cypress/e2e/side_window/mission_form/mission_zone.spec.ts index 0b90178e3c..be0955fb57 100644 --- a/frontend/cypress/e2e/side_window/mission_form/mission_zone.spec.ts +++ b/frontend/cypress/e2e/side_window/mission_form/mission_zone.spec.ts @@ -5,6 +5,7 @@ import { import { setGeometry } from '../../../../src/domain/shared_slices/Draw' import { getFutureDate } from '../../utils/getFutureDate' +import { visitSideWindow } from '../../utils/visitSideWindow' import type { GeoJSON } from '../../../../src/domain/types/GeoJSON' @@ -26,13 +27,7 @@ const surveillanceGeometry: GeoJSON.Geometry = { } context('Side Window > Mission Form > Mission zone', () => { beforeEach(() => { - cy.viewport(1280, 1024) - cy.visit(`/side_window`, { - onBeforeLoad: () => { - Cypress.env('CYPRESS_MISSION_FORM_AUTO_SAVE_ENABLED', 'true') - Cypress.env('CYPRESS_MISSION_FORM_AUTO_UPDATE', 'true') - } - }) + visitSideWindow() // Create mission with surveillance cy.clickButton('Ajouter une nouvelle mission') diff --git a/frontend/cypress/e2e/side_window/mission_list/filters.spec.ts b/frontend/cypress/e2e/side_window/mission_list/filters.spec.ts index 95f762d5b5..eb5b843044 100644 --- a/frontend/cypress/e2e/side_window/mission_list/filters.spec.ts +++ b/frontend/cypress/e2e/side_window/mission_list/filters.spec.ts @@ -1,13 +1,16 @@ import { customDayjs } from '@mtes-mct/monitor-ui' import { getUtcDateInMultipleFormats } from '../../utils/getUtcDateInMultipleFormats' +import { visitSideWindow } from '../../utils/visitSideWindow' const today = encodeURIComponent(customDayjs().utc().endOf('day').toISOString()) context('Side Window > Mission List > Filter Bar', () => { beforeEach(() => { - cy.viewport(1280, 1024) - cy.visit(`/side_window`).wait(1000) + cy.intercept('GET', '/bff/v1/missions').as('getMissions') + visitSideWindow() + + cy.wait('@getMissions') }) afterEach(() => { diff --git a/frontend/cypress/e2e/side_window/mission_list/missions.spec.ts b/frontend/cypress/e2e/side_window/mission_list/missions.spec.ts index c9f79a72f1..9eaf4bfd4d 100644 --- a/frontend/cypress/e2e/side_window/mission_list/missions.spec.ts +++ b/frontend/cypress/e2e/side_window/mission_list/missions.spec.ts @@ -1,13 +1,15 @@ +import { visitSideWindow } from '../../utils/visitSideWindow' + context('Missions', () => { beforeEach(() => { - cy.viewport(1280, 1024) + cy.intercept('GET', '/bff/v1/missions').as('getMissions') + visitSideWindow() + cy.wait('@getMissions') }) it('Control Unit filter should not contain archived control units', () => { cy.intercept('GET', `/api/v1/control_units`).as('getControlUnits') - cy.visit(`/side_window`).wait(1000) - cy.wait('@getControlUnits').then(({ response }) => { expect(response && response.statusCode).to.equal(200) const archivedControlUnit = response && response.body.find(controlUnit => controlUnit.name === 'BGC Ajaccio') diff --git a/frontend/cypress/e2e/side_window/mission_list/missions_navigation.spec.ts b/frontend/cypress/e2e/side_window/mission_list/missions_navigation.spec.ts index dc6acc9371..e97a677f53 100644 --- a/frontend/cypress/e2e/side_window/mission_list/missions_navigation.spec.ts +++ b/frontend/cypress/e2e/side_window/mission_list/missions_navigation.spec.ts @@ -1,6 +1,6 @@ context('Mission', () => { beforeEach(() => { - cy.viewport(1280, 1024) + cy.login('superuser') }) it('Missions should be created and saved in store When auto-save is not enabled', () => { diff --git a/frontend/cypress/e2e/side_window/reporting/create_reporting.spec.ts b/frontend/cypress/e2e/side_window/reporting/create_reporting.spec.ts index 9c588fe1da..4d903a2ef4 100644 --- a/frontend/cypress/e2e/side_window/reporting/create_reporting.spec.ts +++ b/frontend/cypress/e2e/side_window/reporting/create_reporting.spec.ts @@ -1,6 +1,7 @@ import { setGeometry } from '../../../../src/domain/shared_slices/Draw' import { FAKE_API_PUT_RESPONSE } from '../../constants' import { getUtcDateInMultipleFormats } from '../../utils/getUtcDateInMultipleFormats' +import { visitSideWindow } from '../../utils/visitSideWindow' import type { GeoJSON } from '../../../../src/domain/types/GeoJSON' @@ -8,13 +9,8 @@ const dispatch = action => cy.window().its('store').invoke('dispatch', action) context('Reportings', () => { beforeEach(() => { - cy.viewport(1280, 1024) - cy.visit(`/side_window`, { - onBeforeLoad() { - Cypress.env('CYPRESS_REPORTING_FORM_AUTO_SAVE_ENABLED', 'true') - } - }) cy.intercept('GET', '/bff/v1/reportings*').as('getReportings') + visitSideWindow() cy.clickButton('Signalements') cy.wait('@getReportings') }) diff --git a/frontend/cypress/e2e/side_window/reporting/filters.spec.ts b/frontend/cypress/e2e/side_window/reporting/filters.spec.ts index cfda81ab28..6146206ac4 100644 --- a/frontend/cypress/e2e/side_window/reporting/filters.spec.ts +++ b/frontend/cypress/e2e/side_window/reporting/filters.spec.ts @@ -1,13 +1,13 @@ import { ReportingSourceLabels } from '../../../../src/domain/entities/reporting' import { SeaFrontLabel } from '../../../../src/domain/entities/seaFrontType' +import { visitSideWindow } from '../../utils/visitSideWindow' context('Reportings', () => { beforeEach(() => { - cy.viewport(1280, 1024) cy.intercept('GET', '/bff/v1/reportings*').as('getReportings') cy.intercept('GET', '/api/v2/control_units').as('getControlUnits') cy.intercept('GET', '/api/v1/themes*').as('getThemes') - cy.visit(`/side_window`) + visitSideWindow() cy.clickButton('Signalements') cy.wait(['@getReportings', '@getControlUnits', '@getThemes']) diff --git a/frontend/cypress/e2e/side_window/vigilance_areas_list/filters.spec.ts b/frontend/cypress/e2e/side_window/vigilance_areas_list/filters.spec.ts index 221ea4ab99..b825e76871 100644 --- a/frontend/cypress/e2e/side_window/vigilance_areas_list/filters.spec.ts +++ b/frontend/cypress/e2e/side_window/vigilance_areas_list/filters.spec.ts @@ -1,11 +1,11 @@ +import { visitSideWindow } from '../../utils/visitSideWindow' + context('Side Window > Vigilance Areas List > Filter Bar', () => { beforeEach(() => { cy.intercept('GET', '/bff/v1/amps').as('getAmps') cy.intercept('GET', '/bff/v1/regulatory').as('getRegulatoryAreas') cy.intercept('GET', '/bff/v1/vigilance_areas').as('getVigilanceAreas') - cy.viewport(1280, 1024) - cy.visit(`/side_window`) - cy.wait(250) + visitSideWindow() cy.clickButton('Zones de vigilance') }) diff --git a/frontend/cypress/e2e/utils/visitSideWindow.ts b/frontend/cypress/e2e/utils/visitSideWindow.ts index 284c321fcd..cb42b102e5 100644 --- a/frontend/cypress/e2e/utils/visitSideWindow.ts +++ b/frontend/cypress/e2e/utils/visitSideWindow.ts @@ -1,6 +1,7 @@ import EventSource, { sources } from 'eventsourcemock' export function visitSideWindow(isAutoSaveEnabled = 'true') { + cy.login('superuser') cy.visit(`/side_window`, { onBeforeLoad(window: Cypress.AUTWindow & { env: { [key: string]: string } }) { Object.defineProperty(window, 'EventSource', { value: EventSource }) diff --git a/frontend/cypress/support/commands.ts b/frontend/cypress/support/commands.ts index c46d601231..14120500da 100644 --- a/frontend/cypress/support/commands.ts +++ b/frontend/cypress/support/commands.ts @@ -1,6 +1,7 @@ import { registerMonitorUiCustomCommands } from '@mtes-mct/monitor-ui/cypress' import { getFeaturesFromLayer } from './commands/getFeaturesFromLayer' +import { login } from './commands/login' registerMonitorUiCustomCommands() function unquote(str: string): string { @@ -8,6 +9,7 @@ function unquote(str: string): string { } Cypress.Commands.add('getFeaturesFromLayer', getFeaturesFromLayer) +Cypress.Commands.add('login', login) Cypress.Commands.add( 'before', { diff --git a/frontend/cypress/support/commands/login.ts b/frontend/cypress/support/commands/login.ts new file mode 100644 index 0000000000..aa0cb03c93 --- /dev/null +++ b/frontend/cypress/support/commands/login.ts @@ -0,0 +1,39 @@ +export function login(user: string) { + cy.session(user, () => { + // We use a Cypress session to inject a Local Storage key + // so that we can detect when the browser app is running in Cypress. + // https://docs.cypress.io/faq/questions/using-cypress-faq#How-do-I-preserve-cookies--localStorage-in-between-my-tests + cy.window().then(window => { + window.localStorage.setItem('IS_CYPRESS', 'true') + }) + cy.wait(100) + + cy.visit('/login') + cy.wait(500) + + cy.intercept('GET', '/realms/monitor/**').as('authRequest') + cy.intercept('**/realms/monitor/**').as('authResponse') + + cy.clickButton("S'identifier avec ProConnect") + + cy.wait(5000) + + cy.wait('@authRequest').then(interception => { + cy.log(`Status: ${interception?.response?.statusCode}`) + cy.log(`Headers: ${JSON.stringify(interception?.response?.headers)}`) + }) + cy.wait('@authResponse').then(interception => { + cy.log(`Status: ${interception?.response?.statusCode}`) + cy.log(`Headers: ${JSON.stringify(interception?.response?.headers)}`) + }) + + cy.wait(5000) + + // Login with Keycloak + cy.get('[name="username"]').type(user) + cy.get('[name="password"]').type('monitorenv') + cy.get('[name="login"]').click() + + cy.wait(5000) + }) +} diff --git a/frontend/cypress/support/e2e.ts b/frontend/cypress/support/e2e.ts index 636981c3fb..c07e15a8ed 100644 --- a/frontend/cypress/support/e2e.ts +++ b/frontend/cypress/support/e2e.ts @@ -20,6 +20,7 @@ declare global { ): void getFeaturesFromLayer(layerName: string, layerPixel: [number, number]): Cypress.Chainable> loadPath(path: string): void + login(user: string): void } } } diff --git a/frontend/package.json b/frontend/package.json index 6281423494..009ea38058 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -15,8 +15,8 @@ "dev": "import-meta-env-prepare -x .env.frontend.example -p ../.env.dev.defaults && vite --port 3000", "prepare": "cd .. && ./frontend/node_modules/.bin/husky ./frontend/config/husky", "start": "vite preview --port 3000", - "test:e2e": "cypress run --browser firefox --config-file ./config/cypress.config.ts --e2e", - "test:e2e:open": "cypress open --browser firefox --config-file ./config/cypress.config.ts --e2e", + "test:e2e": "cypress run --browser chrome --config-file ./config/cypress.config.ts --e2e", + "test:e2e:open": "cypress open --browser chrome --config-file ./config/cypress.config.ts --e2e", "test:lint": "eslint --config=./.eslintrc.cjs ./src", "test:lint:fix": "npm run test:lint -- --fix", "test:multi-windows:open": "IS_HEADLESS=false jest --config=./config/multi-windows/jest.config.js", diff --git a/frontend/src/pages/Login.tsx b/frontend/src/pages/Login.tsx index 8bd6bf4777..f3b4207b98 100644 --- a/frontend/src/pages/Login.tsx +++ b/frontend/src/pages/Login.tsx @@ -18,9 +18,10 @@ export function Login() {