
Dans le chapitre précédent, vous avez vu que Cypress préconise l'utilisation de l'attribut data-* en tant que sélecteur. Dans ce chapitre, vous allez appliquer les bonnes pratiques de Cypress en suivant ces étapes :
Ouvrez le fichier contact.component.html.Â
Allez dans le menu Edit de VSCode.Â
Cliquez sur Find in Files.
Dans la boßte de recherche, tapez contact-page.
SĂ©lectionnez la premiĂšre proposition. Cela devrait ĂȘtre contact.component.html.Â
La page sâouvre et vous allez pouvoir modifier vos Ă©lĂ©ments.Â
Ajoutez les attributs data-cy à vos Ă©lĂ©ments, comme ci-dessous :Â
<div id="contact-page" data-cy="contact-page">
<section id="contact-form" [formGroup]="form" data-cy="contact-form">
<h2 data-cy="title-contact-us">Contactez-nous</h2>
<form>
<p>
<label for="name">Nom</label>
<input type="text" name="name" id="name" formControlName="name" data-cy="name" />
</p>
<p>
<label for="email">Adresse e-mail</label>
<input type="email" name="email" id="email" formControlName="email" data-cy="email" />
</p>
<p>
<label for="message">Message</label>
<textarea name="message" id="message" formControlName="message" data-cy="message"></textarea>
</p>
<button (click)="send()" data-cy="sendButton">Envoyer</button>
<p class="success" *ngIf="success" data-cy="successMessage">Message envoyé avec succÚs.</p>
</form>
</section>
<section id="contact-place" data-cy="contact-place">
<h2 data-cy="title-where-find-us">OĂč nous trouver</h2>
<iframe width="100%" height="280" frameborder="0" scrolling="no" marginheight="0" marginwidth="0"
src="https://maps.google.com/maps?width=100%25&height=600&hl=fr&q=4%20Rue%20de%20la%20R%C3%A9publique,%2030900%20N%C3%AEmes,%20France+(Tech&Buy)&t=&z=15&ie=UTF8&iwloc=B&output=embed"><a
href="https://www.maps.ie/distance-area-calculator.html">distance maps</a></iframe>
<p><strong>Tech&Buy</strong></p>
<div class="contact-address">
<p data-cy="address">4 Rue de la République<br>30900 Nßmes<br>France</p>
<button (click)="openItinerary()" data-cy="itinerary-button">Itinéraire</button>
</div>
</section>
</div>Exécutez à nouveau la commande  docker-compose up .
AprĂšs la compilation, rendez-vous sur lâURL du formulaire :Â http://localhost:8080/#/contact.Â
GrĂące Ă lâoutil de dĂ©veloppement, vous pouvez voir que les data-cy sont prĂ©sents :Â

Reprenez le test que vous avez écrit précédemment et remplacez les sélecteurs :
describe('contact page', () => {
it('it navigate to the contact page', () => {
cy.visit('http://localhost:8080/#/contact')
cy.get('[data-cy="name"]').type('name')
cy.get('[data-cy="email"]').type('test@test.fr')
cy.get('[data-cy="message"]').type('Bonjour, votre site est génial !')
cy.get('[data-cy="sendButton"]').click()
cy.get('[data-cy="successMessage"]').should('be.visible').should('contain', 'Message envoyé avec succÚs.')
})
})Et le test réussit toujours :

Félicitations, vous avez maintenant réussi un test qui utilise les bonnes pratiques de Cypress !
Retrouvez le détail de cette manipulation en vidéo :
Minute papillon ! Je suis sĂ»r quâon a parlĂ© d'une potentielle faille XSS dans un formulaire, on ne va pas tester cette faille ?
Oui, vous avez raison, il est temps de tester cette faille XSS !
Pour savoir si le formulaire est vulnĂ©rable, le test est assez simple du cĂŽtĂ© de Cypress : il faut entrer  <script>alert('XSS');</script> dans le champ texte message puis envoyer le formulaire.Â
Le test est donc :
it('it did not contain XSS vulnerability', () => {
cy.visit('http://localhost:8080/#/contact')
cy.get('[data-cy="name"]').type('name')
cy.get('[data-cy="email"]').type('test@test.fr')
cy.get('[data-cy="message"]').type('<script>alert("XSS");</script>')
cy.get('[data-cy="sendButton"]').click()
cy.get('[data-cy="successMessage"]').should('be.visible').should('contain', 'Message envoyé avec succÚs.')
cy.on('window:alert', () => {
throw new Error('Une fenĂȘtre d\'alerte s\'est affichĂ©e !');
});
})Sâil y a une faille, vous allez voir un pop-up alert(âXSSâ). Dans le cas du formulaire de Tech&Buy, il ne semble pas contenir de faille XSS.Â
Les hooks dans Cypress sont des fonctions spĂ©ciales qui vous permettent d'effectuer des actions avant ou aprĂšs l'exĂ©cution de certaines Ă©tapes dans vos tests. Ils sont utilisĂ©s pour :Â
configurer l'environnement ;
initialiser des données ;
nettoyer des ressources ;
ou effectuer d'autres tĂąches spĂ©cifiques.Â
Les hooks aident à maintenir un code de test organisé, réutilisable et efficace.
Voici quelques types de hooks couramment utilisés dans Cypress :
1. before et after : Ces hooks s'exécutent avant et aprÚs l'ensemble de vos tests. Ils sont utiles pour des tùches globales comme la configuration initiale et le nettoyage intégral.
before(() => {
// Configuration initiale, par exemple : se connecter Ă l'application
});
after(() => {
// Nettoyage global, par exemple : se déconnecter et fermer l'application
});2. beforeEach et afterEach : Ces hooks s'exécutent avant et aprÚs chaque test individuel. Ils sont utilisés pour configurer l'état de départ et nettoyer aprÚs chaque test.
beforeEach(() => {
// Configuration avant chaque test, par exemple : réinitialiser les données
});
afterEach(() => {
// Nettoyage aprÚs chaque test, par exemple : restaurer l'état initial
});3. beforeAll et afterAll : Ces hooks s'exécutent avant le premier test et aprÚs le dernier test d'une suite donnée. Ils sont utiles pour des tùches globales avant de commencer les tests d'une suite et pour le nettoyage final.
beforeAll(() => {
// Tùches globales avant le premier test, par exemple : chargement de données
});
afterAll(() => {
// Nettoyage final aprÚs le dernier test, par exemple : sauvegarder les données
});4. context : Ce hook permet de crĂ©er des groupes de tests logiquement organisĂ©s. Il peut ĂȘtre utilisĂ© pour encapsuler des Ă©tapes communes.
context('Cas de test pour une fonctionnalité spécifique', () => {
beforeEach(() => {
// Configuration spécifique pour ce groupe de tests
});
it('Test 1', () => {
// Test spécifique
});
it('Test 2', () => {
// Test spécifique
});
afterEach(() => {
// Nettoyage spécifique aprÚs chaque test de ce groupe
});
});En utilisant les hooks de Cypress, vous pouvez donc :
structurer vos tests de maniĂšre modulaire ;
éviter la duplication de code ;
configurer et nettoyer l'environnement de test de maniÚre cohérente ;
maintenir un flux de travail efficace dans le développement automatisé.
TrĂšs bien, mais oĂč placer ces hooks ?
Prenons lâexemple du hook before pour se connecter Ă lâapplication.Â
Vous pouvez placer le hook before de plusieurs maniÚres :
1. Au niveau global : Vous pouvez le placer au niveau global dans le fichier de configuration cypress/support/index.js pour qu'il s'exécute avant tous les tests de votre suite. Voici un exemple :
// dans le fichier cypress/support/index.js
before(() => {Â
// Code Ă exĂ©cuter avant tous les testsÂ
});2. Au niveau du bloc describe : Vous pouvez également le placer au niveau d'un bloc describe spécifique pour qu'il s'exécute avant tous les tests contenus dans ce bloc. Par exemple :
describe("Suite de tests", () => {
// Avant chaque test dans cette suite
beforeEach(() => {
// Code avant chaque test
});
before(() => {
// Code à exécuter avant tous les tests de cette suite
});
it("Test 1", () => {
// Test 1
});
it("Test 2", () => {
// Test 2
});
});3. Au niveau du bloc it : Si vous avez besoin d'un hook before spécifique à un test particulier, vous pouvez le placer directement au niveau de ce test. Par exemple :
it("Test avec before", () => {
// Test avec son propre before
// Ce code sera exécuté avant ce test spécifique
before(() => {
// Code à exécuter avant ce test
});
});La bonne pratique de Cypress est de nettoyer lâĂ©tat de vos tests avant lâexĂ©cution de vos tests et donc, de ne pas utiliser after ou afterEach pour nettoyer lâĂ©tat.Â
Dans Cypress, les spies et les stubs sont des fonctionnalitĂ©s qui permettent de gĂ©rer et de contrĂŽler le comportement des appels de fonction et des requĂȘtes rĂ©seau pendant les tests automatisĂ©s. Ces fonctionnalitĂ©s sont essentielles pour simuler des comportements spĂ©cifiques et isoler les dĂ©pendances externes lors de l'exĂ©cution des tests.
Un spy (espion) est utilisé pour "espionner" une fonction existante pour voir comment elle est appelée pendant l'exécution des tests sans la modifier. L'idée est d'observer les appels à cette fonction et d'enregistrer des informations à leur sujet, telles que le nombre d'appels, les arguments utilisés et les valeurs de retour. Cela permet de vérifier si la fonction est appelée correctement et de mieux comprendre son comportement pendant le test.
Un stub (substitut) est utilisĂ© pour remplacer une fonction existante par une implĂ©mentation alternative pendant l'exĂ©cution des tests. Cela vous permet de contrĂŽler le comportement dâune fonction et de simuler diffĂ©rentes situations, comme des rĂ©ponses de requĂȘtes rĂ©seau simulĂ©es, sans effectuer rĂ©ellement ces requĂȘtes. Les stubs vous sont utiles pour crĂ©er des scĂ©narios spĂ©cifiques sans dĂ©pendre d'un serveur externe ou pour simuler des erreurs rĂ©seau, par exemple.
 Pour en savoir plus sur les spies et les stubs, consultez la documentation Cypress.

Pour cet exercice, vous devez tester que le formulaire ne sâenvoie pas quand il est vide.
Créez votre cas de test.
Indice : vous allez avoir besoin des assertions should(âhave.classâ) et should(ânot.existâ).Â
Consultez la suggestion de corrigé.
Pour respecter les bonnes pratiques de Cypress, il faut ajouter les sélecteurs dans le code.
Vous pouvez tester des notions de cybersĂ©curitĂ© (faille XSS) avec Cypress. Â
Les hooks de Cypress sont des fonctions spéciales qui permettent d'exécuter des actions avant ou aprÚs des étapes spécifiques dans les tests. Ils aident à configurer, nettoyer et structurer l'environnement de test pour maintenir des tests organisés, réutilisables et efficaces.
Le spy est utilisĂ© pour observer et enregistrer les appels d'une fonction sans la modifier, tandis que le stub est utilisĂ© pour remplacer la fonction par une implĂ©mentation alternative afin de contrĂŽler son comportement pendant les tests.          Â
Vous en savez maintenant plus sur les bonnes pratiques de Cypress, mais comment tester des API ? Vous allez le voir tout de suite dans un nouveau chapitre !