Les objets JavaScript stockent les données de test, les réponses API, les fixtures Playwright et les configurations sous forme de paires clé-valeur. La déstructuration permet d'en extraire des valeurs précises proprement, sans répéter les accès aux propriétés.
Qu'est-ce qu'un objet ?
Un objet est une collection de paires clé-valeur. Les clés sont des strings ; les valeurs peuvent être de n'importe quel type :
const user = {
id: 1,
email: 'alice@example.com',
role: 'admin',
isActive: true,
};Accédez aux valeurs avec la notation par point ou par crochet :
console.log(user.email); // 'alice@example.com'
console.log(user['role']); // 'admin'
console.log(user.id); // 1Modifiez les valeurs de la même façon :
user.email = 'newalice@example.com';
user.role = 'member';Les objets dans les données de test
La plupart des données de test dans les tests Playwright s'expriment sous forme d'objets ou de tableaux d'objets :
const loginCredentials = {
email: 'qa_test@example.com',
password: 'ValidPass123!',
};
await page.fill('[data-testid="email"]', loginCredentials.email);
await page.fill('[data-testid="password"]', loginCredentials.password);Collections de cas de test :
const INVALID_EMAILS = [
{ input: '', description: 'empty' },
{ input: 'not-an-email', description: 'missing @' },
{ input: 'missing@', description: 'missing domain' },
{ input: 'a@b', description: 'no TLD' },
];Chaque INVALID_EMAILS[0] est un objet avec les propriétés input et description.
La déstructuration : ce que c'est
La déstructuration permet d'extraire des valeurs d'un objet (ou d'un tableau) dans des variables individuelles en une seule ligne, au lieu de plusieurs.
Sans déstructuration :const user = { id: 1, name: 'Alice', email: 'alice@test.com', role: 'admin' };
const id = user.id;
const name = user.name;
const email = user.email;
const role = user.role;const { id, name, email, role } = user;Même résultat : quatre variables avec les mêmes valeurs, mais une ligne au lieu de quatre.
Renommer lors de la déstructuration
Pour que la variable porte un nom différent de la clé :
const config = {
database_host: 'localhost',
database_port: 5432,
};
const { database_host: host, database_port: port } = config;
console.log(host); // 'localhost'
console.log(port); // 5432Valeurs par défaut dans la déstructuration
Si une clé risque de ne pas exister, on peut fournir une valeur par défaut :
const product = { name: 'Laptop', price: 999 };
const { name, price, discount = 0 } = product;
// discount = 0 (n'était pas dans product, utilise la valeur par défaut)Déstructuration dans les paramètres de fonctions
C'est là que vous verrez le plus souvent la déstructuration dans Playwright : dans les fonctions de test.
// Sans déstructuration
test('user can log in', async (args) => {
const page = args.page;
const request = args.request;
// ...
});
// Avec déstructuration (pattern standard Playwright)
test('user can log in', async ({ page, request }) => {
// page et request disponibles directement
});C'est de la déstructuration d'objet dans le paramètre de la fonction. La syntaxe { page, request } extrait ces propriétés depuis l'objet fixture que Playwright fournit.
C'est pour ça que le code de test Playwright semble avoir des "variables magiques" : elles sont déstructurées automatiquement depuis l'objet fixture.
Fixtures personnalisées : la déstructuration en pratique
Quand vous créez des fixtures personnalisées, vous écrirez ce pattern :
export const test = base.extend<{ loginPage: LoginPage }>({
loginPage: async ({ page }, use) => {
const loginPage = new LoginPage(page);
await use(loginPage);
},
});
// Puis dans un test :
test('login works', async ({ page, loginPage }) => {
// ^^^ déstructuré depuis l'objet fixture
await loginPage.login('user@test.com', 'pass');
});Comprendre la déstructuration rend les fixtures compréhensibles.
Déstructuration imbriquée
Les objets peuvent contenir d'autres objets. On peut déstructurer plusieurs niveaux à la fois :
const apiResponse = {
status: 200,
data: {
user: {
id: 123,
email: 'alice@test.com',
},
token: 'eyJhbGciOiJIUzI1NiJ9...',
},
};
// Déstructuration imbriquée
const { status, data: { user: { id, email }, token } } = apiResponse;
console.log(status); // 200
console.log(id); // 123
console.log(email); // 'alice@test.com'
console.log(token); // 'eyJhbGciOiJIUzI1NiJ9...'Ça peut sembler complexe au premier abord. En pratique, on va rarement au-delà de 2 niveaux. Si ça devient difficile à lire, déstructurez en plusieurs étapes :
const { data } = apiResponse;
const { user, token } = data;
const { id, email } = user;Même résultat, plus lisible.
Déstructuration de tableaux (en bref)
Les tableaux utilisent [] au lieu de {} :
const coordinates = [40.7128, -74.0060];
const [latitude, longitude] = coordinates;
// latitude = 40.7128, longitude = -74.0060Ignorez des éléments avec des virgules :
const [first, , third] = ['a', 'b', 'c'];
// first = 'a', third = 'c'L'opérateur de propagation avec les objets
L'opérateur de propagation (...) copie toutes les propriétés d'un objet dans un autre :
const baseUser = {
role: 'member',
isActive: true,
};
const adminUser = {
...baseUser, // copie role et isActive
email: 'admin@test.com',
role: 'admin', // écrase la valeur propagée
};
// { role: 'admin', isActive: true, email: 'admin@test.com' }Créer des variantes de données de test
const defaultUser = {
email: 'test@example.com',
password: 'ValidPass1',
role: 'member',
isActive: true,
};
const adminUser = { ...defaultUser, role: 'admin' };
const inactiveUser = { ...defaultUser, isActive: false };
const customEmail = { ...defaultUser, email: 'custom@example.com' };Ce pattern, "objet de base + surcharges", est très courant dans les fabriques de données de test. On définit l'état valide par défaut une seule fois et on le propage pour créer des variantes.
Patterns pratiques dans les tests Playwright
Déstructurer le body d'une réponse API
const response = await request.post('/api/users', {
data: { email: 'new@test.com', password: 'ValidPass1' },
});
const { id, email, role, created_at } = await response.json();
expect(id).toBeTruthy();
expect(email).toBe('new@test.com');
expect(role).toBe('member');Passer des paramètres objets aux helpers
async function fillLoginForm(page: Page, { email, password }: { email: string; password: string }) {
await page.fill('[data-testid="email"]', email);
await page.fill('[data-testid="password"]', password);
}
// Appel :
await fillLoginForm(page, { email: 'user@test.com', password: 'pass' });Fusionner des configurations de test
const baseConfig = {
baseURL: 'https://lab.becomeqa.com',
timeout: 30000,
};
const ciConfig = {
...baseConfig,
timeout: 60000, // plus lent en CI
video: 'retain-on-failure',
};Erreurs fréquentes
Déstructurer depuis undefined :const response = await fetch('/api/user');
const { id } = await response.json(); // Si response est null/undefined, ça planteToujours vérifier que la valeur existe avant de déstructurer des objets imbriqués profondément.
Modifier une copie propagée ne modifie pas l'original :const original = { name: 'Alice', data: { score: 100 } };
const copy = { ...original };
copy.name = 'Bob'; // ✅ original.name reste 'Alice'
copy.data.score = 200; // ⚠️ original.data.score change aussi !La propagation est une copie superficielle. Les objets imbriqués restent des références partagées.
Récapitulatif
| Syntaxe | Ce qu'elle fait |
|---------|----------------|
| const { a, b } = obj | Extraire a et b depuis obj |
| const { a: x } = obj | Extraire a depuis obj, le nommer x |
| const { a = 5 } = obj | Extraire a, valeur par défaut 5 si absent |
| async ({ page, request }) => {} | Déstructurer les fixtures Playwright |
| { ...obj, key: 'value' } | Propager obj, surcharger ou ajouter key |
Les objets et la déstructuration sont omniprésents dans le JavaScript et TypeScript modernes. Le piège le plus courant : la propagation est superficielle. Modifier un objet imbriqué dans une copie propagée modifie aussi l'original, ce qui peut corrompre des données de test partagées entre plusieurs cas.
→ See also: JavaScript pour les QA Engineers: Le Minimum pour Commencer à Automatiser | Arrays JavaScript: map, filter, find et forEach — Le Guide de Terrain du QA | TypeScript pour QA: Pourquoi les Types Statiques Améliorent Vos Tests