Mise en place de tests utilisateurs avec playwright pour la partie angular + corrections au niveau des labels avec for et id pour cliquer dessus
Some checks failed
E2E Tests / e2e (push) Failing after 5m30s
Some checks failed
E2E Tests / e2e (push) Failing after 5m30s
This commit is contained in:
@@ -43,8 +43,9 @@
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label>Titre de l'arc *</label>
|
||||
<label for="arc-edit-name">Titre de l'arc *</label>
|
||||
<input
|
||||
id="arc-edit-name"
|
||||
type="text"
|
||||
formControlName="name"
|
||||
placeholder="Ex: L'Ombre du Nord"
|
||||
@@ -53,8 +54,9 @@
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label>Synopsis de l'arc</label>
|
||||
<label for="arc-edit-description">Synopsis de l'arc</label>
|
||||
<textarea
|
||||
id="arc-edit-description"
|
||||
formControlName="description"
|
||||
placeholder="Décrivez l'histoire principale de cet arc narratif..."
|
||||
rows="5">
|
||||
@@ -63,16 +65,18 @@
|
||||
|
||||
<div class="field-row">
|
||||
<div class="field">
|
||||
<label>Thèmes principaux</label>
|
||||
<label for="arc-edit-themes">Thèmes principaux</label>
|
||||
<textarea
|
||||
id="arc-edit-themes"
|
||||
formControlName="themes"
|
||||
placeholder="Quels sont les thèmes explorés dans cet arc ? (trahison, rédemption...)"
|
||||
rows="4">
|
||||
</textarea>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Enjeux globaux</label>
|
||||
<label for="arc-edit-stakes">Enjeux globaux</label>
|
||||
<textarea
|
||||
id="arc-edit-stakes"
|
||||
formControlName="stakes"
|
||||
placeholder="Quels sont les enjeux majeurs de cet arc pour les personnages ?"
|
||||
rows="4">
|
||||
@@ -81,8 +85,9 @@
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label>Notes et planification du MJ</label>
|
||||
<label for="arc-edit-gm-notes">Notes et planification du MJ</label>
|
||||
<textarea
|
||||
id="arc-edit-gm-notes"
|
||||
formControlName="gmNotes"
|
||||
placeholder="Vos notes sur la direction de l'arc, les twists prévus, les révélations importantes..."
|
||||
rows="5">
|
||||
@@ -91,8 +96,9 @@
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label>Récompenses et progression</label>
|
||||
<label for="arc-edit-rewards">Récompenses et progression</label>
|
||||
<textarea
|
||||
id="arc-edit-rewards"
|
||||
formControlName="rewards"
|
||||
placeholder="Quelles récompenses les joueurs obtiendront-ils ? Objets, niveaux, connaissances, contacts..."
|
||||
rows="4">
|
||||
@@ -100,8 +106,9 @@
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label>Dénouement prévu</label>
|
||||
<label for="arc-edit-resolution">Dénouement prévu</label>
|
||||
<textarea
|
||||
id="arc-edit-resolution"
|
||||
formControlName="resolution"
|
||||
placeholder="Comment cet arc devrait-il se terminer ? Quelles sont les issues possibles ?"
|
||||
rows="4">
|
||||
|
||||
@@ -11,8 +11,9 @@
|
||||
<form [formGroup]="form" (ngSubmit)="submit()">
|
||||
|
||||
<div class="field">
|
||||
<label>Nom de la campagne *</label>
|
||||
<label for="campaign-name">Nom de la campagne *</label>
|
||||
<input
|
||||
id="campaign-name"
|
||||
type="text"
|
||||
formControlName="name"
|
||||
placeholder="Ex: L'Ombre du Nord, Les Héritiers Oubliés..."
|
||||
@@ -21,8 +22,9 @@
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label>Description / Pitch</label>
|
||||
<label for="campaign-description">Description / Pitch</label>
|
||||
<textarea
|
||||
id="campaign-description"
|
||||
formControlName="description"
|
||||
placeholder="Résumez l'intrigue principale de votre campagne..."
|
||||
rows="5"
|
||||
@@ -30,13 +32,13 @@
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label>Nombre de joueurs</label>
|
||||
<input type="number" formControlName="playerCount" min="1" />
|
||||
<label for="campaign-player-count">Nombre de joueurs</label>
|
||||
<input id="campaign-player-count" type="number" formControlName="playerCount" min="1" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label>Univers associé</label>
|
||||
<select formControlName="loreId">
|
||||
<label for="campaign-lore">Univers associé</label>
|
||||
<select id="campaign-lore" formControlName="loreId">
|
||||
<option value="">— Aucun univers (campagne libre) —</option>
|
||||
<option *ngFor="let lore of availableLores" [value]="lore.id">{{ lore.name }}</option>
|
||||
</select>
|
||||
@@ -47,8 +49,8 @@
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label>Système de JDR</label>
|
||||
<select formControlName="gameSystemId">
|
||||
<label for="campaign-game-system">Système de JDR</label>
|
||||
<select id="campaign-game-system" formControlName="gameSystemId">
|
||||
<option value="">— Aucun (campagne générique) —</option>
|
||||
<option *ngFor="let gs of availableGameSystems" [value]="gs.id">{{ gs.name }}</option>
|
||||
</select>
|
||||
|
||||
@@ -43,8 +43,9 @@
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label>Titre du chapitre *</label>
|
||||
<label for="chapter-edit-name">Titre du chapitre *</label>
|
||||
<input
|
||||
id="chapter-edit-name"
|
||||
type="text"
|
||||
formControlName="name"
|
||||
placeholder="Ex: Chapitre 1: Les Disparitions"
|
||||
@@ -53,8 +54,9 @@
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label>Synopsis du chapitre</label>
|
||||
<label for="chapter-edit-description">Synopsis du chapitre</label>
|
||||
<textarea
|
||||
id="chapter-edit-description"
|
||||
formControlName="description"
|
||||
placeholder="Décrivez brièvement ce qui se passe dans ce chapitre..."
|
||||
rows="5">
|
||||
@@ -62,8 +64,9 @@
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label>Notes du Maître de Jeu</label>
|
||||
<label for="chapter-edit-gm-notes">Notes du Maître de Jeu</label>
|
||||
<textarea
|
||||
id="chapter-edit-gm-notes"
|
||||
formControlName="gmNotes"
|
||||
placeholder="Vos notes privées sur le déroulement du chapitre, les événements clés, les rebondissements..."
|
||||
rows="6">
|
||||
@@ -73,16 +76,18 @@
|
||||
|
||||
<div class="field-row">
|
||||
<div class="field">
|
||||
<label>Objectifs des joueurs</label>
|
||||
<label for="chapter-edit-player-objectives">Objectifs des joueurs</label>
|
||||
<textarea
|
||||
id="chapter-edit-player-objectives"
|
||||
formControlName="playerObjectives"
|
||||
placeholder="Que doivent accomplir les joueurs dans ce chapitre ?"
|
||||
rows="4">
|
||||
</textarea>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Enjeux narratifs</label>
|
||||
<label for="chapter-edit-narrative-stakes">Enjeux narratifs</label>
|
||||
<textarea
|
||||
id="chapter-edit-narrative-stakes"
|
||||
formControlName="narrativeStakes"
|
||||
placeholder="Quels sont les enjeux dramatiques ?"
|
||||
rows="4">
|
||||
|
||||
@@ -43,8 +43,9 @@
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label>Titre de la scène *</label>
|
||||
<label for="scene-edit-name">Titre de la scène *</label>
|
||||
<input
|
||||
id="scene-edit-name"
|
||||
type="text"
|
||||
formControlName="name"
|
||||
placeholder="Ex: Arrivée au village"
|
||||
@@ -53,8 +54,9 @@
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label>Description courte *</label>
|
||||
<label for="scene-edit-description">Description courte *</label>
|
||||
<textarea
|
||||
id="scene-edit-description"
|
||||
formControlName="description"
|
||||
placeholder="Résumé en une ou deux phrases de ce qui se passe..."
|
||||
rows="3">
|
||||
@@ -65,17 +67,18 @@
|
||||
<app-expandable-section title="Contexte et ambiance" icon="📍" [initiallyOpen]="true">
|
||||
<div class="field-row">
|
||||
<div class="field">
|
||||
<label>Lieu</label>
|
||||
<input type="text" formControlName="location" placeholder="Ex: Taverne du Dragon d'Or" />
|
||||
<label for="scene-edit-location">Lieu</label>
|
||||
<input id="scene-edit-location" type="text" formControlName="location" placeholder="Ex: Taverne du Dragon d'Or" />
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Moment</label>
|
||||
<input type="text" formControlName="timing" placeholder="Ex: Soir, à la tombée de la nuit" />
|
||||
<label for="scene-edit-timing">Moment</label>
|
||||
<input id="scene-edit-timing" type="text" formControlName="timing" placeholder="Ex: Soir, à la tombée de la nuit" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Ambiance et atmosphère</label>
|
||||
<label for="scene-edit-atmosphere">Ambiance et atmosphère</label>
|
||||
<textarea
|
||||
id="scene-edit-atmosphere"
|
||||
formControlName="atmosphere"
|
||||
placeholder="Décrivez l'ambiance générale de la scène (sons, odeurs, lumière, émotions...)"
|
||||
rows="4">
|
||||
@@ -179,12 +182,13 @@
|
||||
<!-- Section : Combat ou rencontre -->
|
||||
<app-expandable-section title="Combat ou rencontre" icon="⚔️">
|
||||
<div class="field">
|
||||
<label>Difficulté estimée</label>
|
||||
<input type="text" formControlName="combatDifficulty" placeholder="Ex: Moyenne, 3 gobelins niveau 2" />
|
||||
<label for="scene-edit-combat-difficulty">Difficulté estimée</label>
|
||||
<input id="scene-edit-combat-difficulty" type="text" formControlName="combatDifficulty" placeholder="Ex: Moyenne, 3 gobelins niveau 2" />
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Ennemis et créatures</label>
|
||||
<label for="scene-edit-enemies">Ennemis et créatures</label>
|
||||
<textarea
|
||||
id="scene-edit-enemies"
|
||||
formControlName="enemies"
|
||||
placeholder="Liste des ennemis présents dans cette scène..."
|
||||
rows="4">
|
||||
|
||||
@@ -11,8 +11,9 @@
|
||||
<form [formGroup]="form" (ngSubmit)="submit()">
|
||||
|
||||
<div class="field">
|
||||
<label>Nom de l'univers *</label>
|
||||
<label for="lore-name">Nom de l'univers *</label>
|
||||
<input
|
||||
id="lore-name"
|
||||
type="text"
|
||||
formControlName="name"
|
||||
placeholder="Ex: Royaume des Ombres, Cyberpunk 2157..."
|
||||
@@ -21,8 +22,9 @@
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label>Description</label>
|
||||
<label for="lore-description">Description</label>
|
||||
<textarea
|
||||
id="lore-description"
|
||||
formControlName="description"
|
||||
placeholder="Décrivez brièvement votre univers, son ambiance, son genre..."
|
||||
rows="5"
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
|
||||
<!-- Titre -->
|
||||
<div class="field">
|
||||
<label>Titre de la page *</label>
|
||||
<input type="text" formControlName="title" placeholder="Ex: Maître Eldrin, La Cité d'Argent..." />
|
||||
<label for="page-title">Titre de la page *</label>
|
||||
<input id="page-title" type="text" formControlName="title" placeholder="Ex: Maître Eldrin, La Cité d'Argent..." />
|
||||
</div>
|
||||
|
||||
<!-- Template -->
|
||||
@@ -42,10 +42,10 @@
|
||||
|
||||
<!-- Dossier de destination -->
|
||||
<div class="field">
|
||||
<label>Dossier de destination *</label>
|
||||
<label for="page-node">Dossier de destination *</label>
|
||||
|
||||
<ng-container *ngIf="nodes.length; else emptyFolders">
|
||||
<select formControlName="nodeId" [attr.disabled]="preselectedNodeId ? true : null">
|
||||
<select id="page-node" formControlName="nodeId">
|
||||
<option value="" disabled>Sélectionnez un dossier</option>
|
||||
<option *ngFor="let node of nodes" [value]="node.id">{{ node.name }}</option>
|
||||
</select>
|
||||
|
||||
@@ -88,9 +88,12 @@ export class PageCreateComponent implements OnInit, OnDestroy {
|
||||
this.templates = data.templates;
|
||||
this.layoutService.show(buildLoreSidebarConfig(data));
|
||||
|
||||
// Si nodeId fourni par l'URL, on verrouille la valeur du formulaire.
|
||||
// Si nodeId fourni par l'URL, on fige la valeur ET on désactive le
|
||||
// contrôle de formulaire (FormControl.disable, pas attr.disabled qui
|
||||
// serait cosmétique). La valeur reste incluse dans les submits.
|
||||
if (this.preselectedNodeId) {
|
||||
this.form.patchValue({ nodeId: this.preselectedNodeId });
|
||||
this.form.get('nodeId')?.disable();
|
||||
}
|
||||
|
||||
this.restoreDraft();
|
||||
@@ -152,7 +155,7 @@ export class PageCreateComponent implements OnInit, OnDestroy {
|
||||
|
||||
submit(): void {
|
||||
if (!this.canSubmit) return;
|
||||
const raw = this.form.value;
|
||||
const raw = this.form.getRawValue();
|
||||
this.pageService.create({
|
||||
loreId: this.loreId,
|
||||
nodeId: raw.nodeId,
|
||||
@@ -206,7 +209,7 @@ export class PageCreateComponent implements OnInit, OnDestroy {
|
||||
return;
|
||||
}
|
||||
this.wizardError = null;
|
||||
const raw = this.form.value;
|
||||
const raw = this.form.getRawValue();
|
||||
// Le backend POST /api/pages ne prend pas `values` — on crée d'abord la
|
||||
// coquille, puis on PUT immédiatement avec les valeurs extraites.
|
||||
// 2 roundtrips, mais zéro modification backend nécessaire.
|
||||
|
||||
@@ -11,20 +11,20 @@
|
||||
<div class="col-left">
|
||||
|
||||
<div class="field">
|
||||
<label>Nom du template *</label>
|
||||
<input type="text" formControlName="name" placeholder="Ex: Auberge, Artefact, Monstre..." />
|
||||
<label for="template-name">Nom du template *</label>
|
||||
<input id="template-name" type="text" formControlName="name" placeholder="Ex: Auberge, Artefact, Monstre..." />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label>Description</label>
|
||||
<textarea formControlName="description" rows="4" placeholder="À quoi sert ce template ?"></textarea>
|
||||
<label for="template-description">Description</label>
|
||||
<textarea id="template-description" formControlName="description" rows="4" placeholder="À quoi sert ce template ?"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label>Dossier par défaut *</label>
|
||||
<label for="template-default-node">Dossier par défaut *</label>
|
||||
|
||||
<ng-container *ngIf="nodes.length; else emptyFolders">
|
||||
<select formControlName="defaultNodeId">
|
||||
<select id="template-default-node" formControlName="defaultNodeId">
|
||||
<option value="" disabled>Sélectionnez un dossier</option>
|
||||
<option *ngFor="let node of nodes" [value]="node.id">{{ node.name }}</option>
|
||||
</select>
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
<div class="col-left">
|
||||
|
||||
<div class="field">
|
||||
<label>Nom</label>
|
||||
<input type="text" formControlName="name" />
|
||||
<label for="template-edit-name">Nom</label>
|
||||
<input id="template-edit-name" type="text" formControlName="name" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label>Dossier par défaut</label>
|
||||
<select formControlName="defaultNodeId">
|
||||
<label for="template-edit-default-node">Dossier par défaut</label>
|
||||
<select id="template-edit-default-node" formControlName="defaultNodeId">
|
||||
<option value="">-- Aucun --</option>
|
||||
<option *ngFor="let node of nodes" [value]="node.id">{{ node.name }}</option>
|
||||
</select>
|
||||
@@ -31,8 +31,8 @@
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label>Description</label>
|
||||
<textarea formControlName="description" rows="6"></textarea>
|
||||
<label for="template-edit-description">Description</label>
|
||||
<textarea id="template-edit-description" formControlName="description" rows="6"></textarea>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user