Skip to content

Commit a6a7468

Browse files
committed
Enhance project configuration and testing setup
- Updated .gitignore to include Playwright-related directories and output files. - Removed the test command from the Dockerfile to streamline the build process. - Modified Makefile targets to improve clarity and remove unnecessary dependencies. - Updated nuxt.config.ts to adjust HTTPS settings for development and improve Playwright compatibility. - Added Playwright installation scripts to package.json for easier setup. - Enhanced GitHub Actions workflow to better manage dependencies and testing in Docker. These changes improve the development workflow and ensure better integration with Playwright for end-to-end testing.
1 parent a60175c commit a6a7468

17 files changed

Lines changed: 418 additions & 30 deletions

.github/workflows/lint.yml

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,53 @@ on:
55
branches:
66
- '*'
77

8+
env:
9+
CI_IMG: ghcr.io/libertech-fr/sesame-gestion-mdp
10+
NODE_MODULES_VOL: sesame-gestion-mdp-node-modules
11+
PLAYWRIGHT_CACHE_VOL: sesame-gestion-mdp-playwright-cache
12+
813
jobs:
914
lint-app:
1015
runs-on: ubuntu-latest
1116

1217
steps:
1318
- name: Checkout code
14-
uses: actions/checkout@v2
19+
uses: actions/checkout@v4
1520

16-
- name: Install app dependencies
17-
run: yarn install
21+
- name: Réseau Docker dev
22+
run: docker network create dev || true
1823

19-
- name: Tests
20-
run: yarn test
24+
- name: Dépendances + Chromium Playwright (dans Docker)
25+
run: |
26+
docker run --rm \
27+
-u 0 \
28+
-e NODE_ENV=development \
29+
-e NODE_TLS_REJECT_UNAUTHORIZED=0 \
30+
-e DEBIAN_FRONTEND=noninteractive \
31+
--add-host host.docker.internal:host-gateway \
32+
--platform linux/amd64 \
33+
--network dev \
34+
-v "${GITHUB_WORKSPACE}:/data" \
35+
-v "${NODE_MODULES_VOL}:/data/node_modules" \
36+
-v "${PLAYWRIGHT_CACHE_VOL}:/root/.cache/ms-playwright" \
37+
-w /data \
38+
"${CI_IMG}" sh -lc 'yarn install --prefer-offline --non-interactive && yarn playwright:install-chromium'
2139
22-
- name: Build Nuxt
23-
run: yarn build
40+
- name: Tests + build (yarn ci dans Docker)
41+
run: |
42+
docker run --rm \
43+
-u 0 \
44+
-e CI=1 \
45+
-e NODE_ENV=development \
46+
-e NODE_TLS_REJECT_UNAUTHORIZED=0 \
47+
-e DEBIAN_FRONTEND=noninteractive \
48+
-e SESAME_HTTPS_ENABLED=false \
49+
-e BROWSERSLIST_IGNORE_OLD_DATA=1 \
50+
-e PLAYWRIGHT_BASE_URL=http://127.0.0.1:3000 \
51+
--platform linux/amd64 \
52+
--network dev \
53+
-v "${GITHUB_WORKSPACE}:/data" \
54+
-v "${NODE_MODULES_VOL}:/data/node_modules" \
55+
-v "${PLAYWRIGHT_CACHE_VOL}:/root/.cache/ms-playwright" \
56+
-w /data \
57+
"${CI_IMG}" sh -lc 'yarn playwright:install-deps && yarn ci'

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,7 @@ node_modules
44
.env
55
.DS_Store
66
src/components/.DS_Store
7-
.output/
7+
.output/
8+
test-results/
9+
playwright-report/
10+
playwright/.cache/

Dockerfile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ RUN yarn install \
3333
# && yarn autoclean --init \
3434
# && yarn autoclean --force
3535

36-
RUN yarn test
3736
RUN yarn build
3837

3938
EXPOSE 3000

Makefile

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,12 @@ IMG_NAME = ghcr.io/libertech-fr/sesame-gestion-mdp
88
BASE_NAME = sesame
99
APP_NAME = sesame-gestion-mdp
1010
# Volume dédié : évite de monter les node_modules du mac dans le conteneur Linux.
11-
# Flux : pas de yarn install sur le Mac — make exec puis yarn install / yarn add (lockfile + package.json sur l’hôte via le montage).
12-
# Puis make build | make dev | make test (Vitest) | make verify (tests + build Nuxt).
11+
# Réseau Docker « dev » : créer une fois (make network-dev ou docker network create dev).
12+
# Flux : pas de yarn sur le Mac — make exec puis yarn install ; e2e / CI : docker dans .github/workflows/lint.yml.
13+
# Chaque « make test » / « verify » : nouveau conteneur → yarn playwright:install-deps puis tests (prérequis : node_modules + cache Playwright remplis, ex. étapes du workflow ou exec).
1314
NODE_MODULES_VOLUME = sesame-gestion-mdp-node-modules
15+
# Cache Chromium Playwright (Linux) entre les « make exec » — pas sur le Mac.
16+
PLAYWRIGHT_CACHE_VOLUME = sesame-gestion-mdp-playwright-cache
1417

1518
-include .env
1619

@@ -33,7 +36,7 @@ SESAME_SENTRY_DSN ?=
3336
$(shell mkdir -p $(CERT_DIR))
3437

3538
.PHONY: network-dev
36-
network-dev: ## Créer le réseau Docker « dev » s’il n’existe pas
39+
network-dev: ## Créer le réseau Docker « dev » s’il n’existe pas (à lancer une fois après install machine)
3740
@docker network inspect dev >/dev/null 2>&1 || docker network create dev
3841

3942
.DEFAULT_GOAL := help
@@ -42,7 +45,7 @@ help:
4245
@grep -h -E '^[-a-zA-Z0-9_\.\/]+:.*?## .*$$' $(MAKEFILE_LIST) \
4346
| sort | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[32m%-18s\033[0m %s\n", $$1, $$2}'
4447

45-
build: ## Image Docker (Dockerfile : yarn test puis yarn build ; pas de tests dans le script build)
48+
build: ## Image Docker (yarn build dans l’image ; pas de Playwright dans l’image — voir workflow GitHub)
4649
@docker build --platform $(PLATFORM) -t $(IMG_NAME) --no-cache --progress=plain \
4750
--build-arg BUILD_VERSION=$(DOCKER_TAG) \
4851
--build-arg GIT_BRANCH=$(GIT_BRANCH) \
@@ -51,7 +54,7 @@ build: ## Image Docker (Dockerfile : yarn test puis yarn build ; pas de tests da
5154
.
5255

5356
# Mode « simulation » : image déjà buildée, env + certificats montés (sans écraser tout le code par le bind-mount complet)
54-
simulation: network-dev ## Lancer en NODE_ENV=production avec montages ciblés (.env, certificats, hash)
57+
simulation: ## Lancer en NODE_ENV=production avec montages ciblés (.env, certificats, hash)
5558
@touch $(CURDIR)/.env.hash
5659
@docker run --rm -it \
5760
-e NODE_ENV=production \
@@ -71,7 +74,7 @@ simulation: network-dev ## Lancer en NODE_ENV=production avec montages ciblés (
7174
-v $(CURDIR)/.env.hash:/data/.env.hash \
7275
$(IMG_NAME) yarn start:prod
7376

74-
prod: network-dev ## Production : bind-mount du dépôt sur /data
77+
prod: ## Production : bind-mount du dépôt sur /data
7578
@docker run --rm -it \
7679
-e NODE_ENV=production \
7780
-e NODE_TLS_REJECT_UNAUTHORIZED=0 \
@@ -88,7 +91,7 @@ prod: network-dev ## Production : bind-mount du dépôt sur /data
8891
-v $(CURDIR):/data \
8992
$(IMG_NAME) yarn start:prod
9093

91-
dev: network-dev ## Développement : nuxt dev (deps : make exec → yarn install / yarn add)
94+
dev: ## Développement : nuxt dev (premier lancement : make network-dev, make exec → yarn install)
9295
@docker run --rm -it \
9396
-e NODE_ENV=development \
9497
-e NODE_TLS_REJECT_UNAUTHORIZED=0 \
@@ -106,7 +109,7 @@ dev: network-dev ## Développement : nuxt dev (deps : make exec → yarn install
106109
-v $(NODE_MODULES_VOLUME):/data/node_modules \
107110
$(IMG_NAME) yarn dev
108111

109-
debug: network-dev ## Idem dev + inspecteur Node (9229) ; deps via make exec → yarn install / yarn add
112+
debug: ## Idem dev + inspecteur Node (9229)
110113
@docker run --rm -it \
111114
-e NODE_ENV=development \
112115
-e NODE_TLS_REJECT_UNAUTHORIZED=0 \
@@ -126,7 +129,7 @@ debug: network-dev ## Idem dev + inspecteur Node (9229) ; deps via make exec →
126129
-v $(NODE_MODULES_VOLUME):/data/node_modules \
127130
$(IMG_NAME) sh -lc 'NODE_OPTIONS="--inspect=0.0.0.0:9229" yarn dev'
128131

129-
exec: network-dev ## Shell : yarn install, yarn add [-D] <pkg>, yarn remove… (package.json / lock sur l’hôte ; node_modules dans le volume)
132+
exec: ## Shell interactif (yarn install, yarn add, …)
130133
@docker run -it --rm \
131134
-e NODE_ENV=development \
132135
-e NODE_TLS_REJECT_UNAUTHORIZED=0 \
@@ -136,6 +139,7 @@ exec: network-dev ## Shell : yarn install, yarn add [-D] <pkg>, yarn remove… (
136139
-e SESAME_SENTRY_DSN=$(SESAME_SENTRY_DSN) \
137140
-v $(CURDIR):/data \
138141
-v $(NODE_MODULES_VOLUME):/data/node_modules \
142+
-v $(PLAYWRIGHT_CACHE_VOLUME):/root/.cache/ms-playwright \
139143
$(IMG_NAME) bash
140144

141145
stop: ## Arrêter le conteneur applicatif
@@ -147,27 +151,41 @@ stop-all: ## Arrêter le conteneur applicatif (équivalent ici, pas de stack BDD
147151
run-lint: ## Rejouer le job GitHub Actions « lint-app » avec act (nécessite nektos/act)
148152
act --container-architecture=linux/amd64 -j lint-app
149153

150-
test: network-dev ## Tests : nuxt prepare + Vitest (pas de build Nuxt — voir make verify)
154+
test: ## Tests : paquets système Chromium puis prepare + Vitest + E2E (yarn install + Chromium : voir lint.yml)
151155
@docker run --rm \
156+
-u 0 \
157+
-e CI=1 \
152158
-e NODE_ENV=development \
153159
-e NODE_TLS_REJECT_UNAUTHORIZED=0 \
160+
-e DEBIAN_FRONTEND=noninteractive \
161+
-e SESAME_HTTPS_ENABLED=false \
162+
-e BROWSERSLIST_IGNORE_OLD_DATA=1 \
163+
-e PLAYWRIGHT_BASE_URL=http://127.0.0.1:3000 \
154164
--platform $(PLATFORM) \
155165
--network dev \
156166
-v $(CURDIR):/data \
157167
-v $(NODE_MODULES_VOLUME):/data/node_modules \
168+
-v $(PLAYWRIGHT_CACHE_VOLUME):/root/.cache/ms-playwright \
158169
-w /data \
159170
$(IMG_NAME) yarn test
160171

161-
verify: network-dev ## CI locale : yarn test puis yarn build (comme le workflow GitHub)
172+
verify: ## CI locale : paquets système Chromium puis yarn ci (même prérequis que test)
162173
@docker run --rm \
174+
-u 0 \
175+
-e CI=1 \
163176
-e NODE_ENV=development \
164177
-e NODE_TLS_REJECT_UNAUTHORIZED=0 \
178+
-e DEBIAN_FRONTEND=noninteractive \
179+
-e SESAME_HTTPS_ENABLED=false \
180+
-e BROWSERSLIST_IGNORE_OLD_DATA=1 \
181+
-e PLAYWRIGHT_BASE_URL=http://127.0.0.1:3000 \
165182
--platform $(PLATFORM) \
166183
--network dev \
167184
-v $(CURDIR):/data \
168185
-v $(NODE_MODULES_VOLUME):/data/node_modules \
186+
-v $(PLAYWRIGHT_CACHE_VOLUME):/root/.cache/ms-playwright \
169187
-w /data \
170-
$(IMG_NAME) sh -lc 'yarn test && yarn build'
188+
$(IMG_NAME) yarn ci
171189

172190
ncu: ## Vérifier les mises à jour des dépendances
173191
@npx npm-check-updates
@@ -200,3 +218,4 @@ hibp-key-hex: ## Générer une clé 32 octets (64 caractères hex)
200218

201219
hibp-key-b64: ## Générer une clé 32 octets (base64)
202220
@printf "SESAME_PASSWORD_HISTORY_HIBP_KEY=%s\n" "$$(openssl rand -base64 32)"
221+

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# sesame-gestion-mdp
22
Gestion des mot de passe sesame
3+
4+
Les commandes **yarn** (install, test, build, etc.) se font dans **Docker** : `make build` puis `make exec`, puis par exemple `yarn install` et `yarn playwright:install` dans le shell du conteneur. Sur la CI, **`make ci-github`** enchaîne tout sans yarn sur le runner.
5+
36
## build release
47
Construire une release :
58

nuxt.config.ts

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
1-
import { readFileSync, writeFileSync } from 'fs'
1+
import { readFileSync } from 'fs'
22
import consola from 'consola'
33

4-
let https = {}
4+
/** `https: {}` active souvent du TLS par défaut ; `false` force le HTTP en dev (sonde Playwright sur http://127.0.0.1:3000). */
5+
let devHttps: false | { key: string; cert: string } = false
56
if (/yes|1|on|true/i.test(`${process.env.SESAME_HTTPS_ENABLED}`)) {
67
try {
7-
https = {
8+
devHttps = {
89
key: readFileSync(`${process.env.SESAME_HTTPS_PATH_KEY}`, 'utf8'),
910
cert: readFileSync(`${process.env.SESAME_HTTPS_PATH_CERT}`, 'utf8'),
10-
};
11+
}
1112
consola.info('[Nuxt] SSL certificates loaded successfully')
1213
} catch (error) {
1314
consola.warn('[Nuxt] Error while reading SSL certificates', error)
@@ -17,10 +18,36 @@ if (/yes|1|on|true/i.test(`${process.env.SESAME_HTTPS_ENABLED}`)) {
1718
// https://nuxt.com/docs/api/configuration/nuxt-config
1819
export default defineNuxtConfig({
1920
compatibilityDate: '2024-04-03',
20-
devtools: { enabled: true },
21+
/** Quasar + vite-node : sans ça, `__QUASAR_SSR_SERVER__` reste non défini (hook vite insuffisant). Mode SPA adapté à cette UI. */
22+
ssr: false,
23+
/** E2E : moins de sockets (devtools) → moins de `write EPIPE` quand Playwright coupe les connexions. */
24+
devtools: { enabled: process.env.E2E_TEST !== '1' },
2125
modules: ["nuxt-quasar-ui","@nuxt-alt/proxy"],
26+
vite: {
27+
define: {
28+
// Constantes lues par `quasar/.../Platform.js` (import ESM, hors bundles vite:extendConfig).
29+
__QUASAR_SSR__: false,
30+
__QUASAR_SSR_SERVER__: false,
31+
__QUASAR_SSR_CLIENT__: false,
32+
__QUASAR_SSR_PWA__: false,
33+
},
34+
// E2E (Playwright) : évite « optimized deps changed → reload » + coupure TCP pendant les tests.
35+
server: {
36+
hmr: process.env.E2E_TEST !== '1',
37+
...(process.env.E2E_TEST === '1'
38+
? {
39+
/** Pas de watch FS : moins d’activité réseau / rechargements pendant les e2e. */
40+
watch: null,
41+
}
42+
: {}),
43+
},
44+
optimizeDeps: {
45+
include: ['fast-password-entropy', 'hibp'],
46+
holdUntilCrawlEnd: true,
47+
},
48+
},
2249
devServer: {
23-
https,
50+
https: devHttps,
2451
},
2552
srcDir: "src",
2653
appConfig: {
@@ -83,5 +110,5 @@ export default defineNuxtConfig({
83110
plugins: [
84111
'Notify'
85112
]
86-
}
113+
},
87114
})

package.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@
77
"dev": "nuxt dev --host 0.0.0.0",
88
"lint": "yarn nuxt prepare",
99
"test:unit": "yarn vitest run",
10-
"test": "yarn lint && yarn test:unit",
10+
"playwright:install-deps": "playwright install-deps chromium",
11+
"playwright:install-chromium": "playwright install chromium",
12+
"playwright:install": "playwright install --with-deps chromium",
13+
"test:e2e": "playwright test",
14+
"test": "yarn lint && yarn test:unit && yarn test:e2e",
1115
"ci": "yarn test && yarn build",
1216
"generate": "nuxt generate",
1317
"preview": "nuxt preview",
@@ -16,6 +20,7 @@
1620
"start": "node .output/server/index.mjs"
1721
},
1822
"devDependencies": {
23+
"@playwright/test": "^1.51.1",
1924
"vitest": "^3.2.4"
2025
},
2126
"dependencies": {

playwright.config.ts

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import { defineConfig, devices } from '@playwright/test'
2+
3+
const baseURL = process.env.PLAYWRIGHT_BASE_URL ?? 'http://127.0.0.1:3000'
4+
/** URL exacte pour la sonde de démarrage (évite blocage si baseURL sans slash final). */
5+
const webServerUrl = new URL('/', baseURL).href
6+
7+
/** Désactive le webServer intégré (tu lances déjà `yarn dev` à part). */
8+
const skipWebServer = !!process.env.PLAYWRIGHT_SKIP_WEB_SERVER
9+
10+
/**
11+
* Le serveur Nuxt doit répondre en HTTP sur baseURL : désactive HTTPS pour l’e2e
12+
* (sinon Playwright attend du HTTP alors que Nuxt écoute en HTTPS → attente infinie).
13+
*/
14+
const webServerEnv = {
15+
CI: 'true',
16+
/** Lu par `nuxt.config` : pas de HMR pendant le serveur lancé par Playwright (évite reload + ECONNRESET). */
17+
E2E_TEST: '1',
18+
/** Vue menu avec « Changer mon mot de passe » / « J'ai oublié… » (`LoginMenu.vue`, `action === 'menu'`). */
19+
ACTION: 'menu',
20+
BROWSERSLIST_IGNORE_OLD_DATA: '1',
21+
SESAME_HTTPS_ENABLED: 'false',
22+
SESAME_HTTPS_PATH_KEY: '',
23+
SESAME_HTTPS_PATH_CERT: '',
24+
} as const
25+
26+
export default defineConfig({
27+
testDir: 'tests/e2e',
28+
/** Un seul worker + pas de parallélisme de fichiers : un seul client sur le `yarn dev` partagé (évite EPIPE / races). */
29+
fullyParallel: false,
30+
forbidOnly: !!process.env.CI,
31+
retries: process.env.CI ? 1 : 0,
32+
workers: 1,
33+
reporter: process.env.CI ? 'github' : 'list',
34+
timeout: 60_000,
35+
expect: { timeout: 15_000 },
36+
use: {
37+
baseURL,
38+
trace: 'on-first-retry',
39+
ignoreHTTPSErrors: true,
40+
launchOptions: {
41+
args: ['--disable-dev-shm-usage', '--no-sandbox'],
42+
},
43+
},
44+
projects: [{ name: 'chromium', use: { ...devices['Desktop Chrome'] } }],
45+
...(skipWebServer
46+
? {}
47+
: {
48+
webServer: {
49+
command: 'yarn dev',
50+
url: webServerUrl,
51+
reuseExistingServer: !process.env.CI,
52+
timeout: 300_000,
53+
/** Réduit les EPIPE côté transport Playwright ↔ sous-processus (plus de pipe stdout/stderr). */
54+
stdout: 'ignore',
55+
stderr: 'ignore',
56+
env: {
57+
...Object.fromEntries(
58+
Object.entries(process.env).filter((e): e is [string, string] => e[1] !== undefined),
59+
),
60+
...webServerEnv,
61+
},
62+
},
63+
}),
64+
})

0 commit comments

Comments
 (0)