Aller au contenu principal

Jeton JWT

Dans un groupe de tests (describe), il est possible de définir une fonction qui doit être exécutée avant chaque test du groupe.

Comme vu précédemment, pour accéder à certaines pages de l'application, il est nécessaire d'avoir un jeton dans le localstorage. Il est possible d'ajouter manuellement un jeton au localstorage lorsque Playwright effectue ses tests et que ce jeton soit ajouté à tous les tests du groupe.

Ajouter le jeton au localStorage avant chaque test

On peut ajouter une fonction beforeEach dans le groupe de tests pour ajouter le jeton avant chaque test.

tests/projets.spec.ts
test.describe('Tests des projets', () => {
test.beforeEach(async ({ page }) => {
// Un jeton JWT valide
const jwtToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOjE0LCJjb3VycmllbCI6ImJlbm9pdC50cmVtYmxheTJAY2VnZXBkcnVtbW9uZC5jYSIsIm5vbVV0aWxpc2F0ZXVyIjoiYmVudHJlbWJsYXkyIiwicm9sZSI6InV0aWxpc2F0ZXVyIiwiaWF0IjoxNzMyMTEzMjUwLCJleHAiOjE3MzQ3MDUyNTB9.qZKT1Y4JUK6dZVnKN57lMAXqOZsV6wIzRMzfg_v5kLc';

// Ajout du jeton au localStorage
await page.addInitScript((token) => {
localStorage.setItem('access_token', token);
}, jwtToken);
});

//...

On peut essayer de rerouler le test maintenant.

Le test passe! Par contre, en observant le rendu, on voit qu'il y a une erreur de chargement.

img

C'est que l'API ne roule pas, nous y reviendront!

Créer un jeton pour les tests

Le problème avec la méthode précédente, c'est qu'elle s'appuie sur un jeton qui eventuellement expirera. Pour les tests, on peut se créer localement un jeton qui expire dans un long délai afin d'éviter cette situation. De plus, la signature du jeton n'a même pas à être valide puisque le jeton ne se rendra jamais au serveur (un peu plus d'info bientôt là-dessus ;) )

  1. Installer jose qui permettra de créer un jeton localement
    npm install --save-dev jose
  2. Créer un fichier auth-helper.ts sous tests/helpers (vous devrez créer le dossier helpers)
  3. Créez une fonction pour générer un jeton avec des informations de test
    import * as jose from 'jose';

    export async function generateTestToken() {
    const payload = {
    sub: "1",
    courriel: "benoit.tremblay@cegepdrumond.ca",
    nomUtilisateur: "bentremblay",
    iat: Math.floor(Date.now() / 1000),
    exp: Math.floor(Date.now() / 1000) + (365 * 24 * 60 * 60 * 100) // 100 ans!
    };

    // Peut importe la clé secrète, ce jeton ne sera utilisé que localement pour l'authentification angular
    const secret = new TextEncoder().encode('test-secret-key');
    const token = await new jose.SignJWT(payload)
    .setProtectedHeader({ alg: 'HS256', typ: 'JWT' })
    .sign(secret);

    return token;
    }
  4. Remplacer le jeton codé en dur par celui généré dynamiquement
    test.describe('Tests des projets', () => {
    test.beforeEach(async ({ page }) => {
    // Un jeton JWT valide
    const jwtToken = await generateTestToken();

On peut résessayer le test.

Le test passe encore! Par contre, en observant le rendu, on voit qu'il y a une erreur de chargement.

img

C'est que l'API ne roule pas et donc il est impossible de récupérer les projets. C'est OK que l'API ne soit pas démarrée, on veut exécuter les tests dans un environnement contrôlé et ce qu'on veut vérifier c'est que l'application client se comporte comme attendu si elle reçoit les données attendues.

Il nous faudra simuler un retour d'API valide!