Playwright e2e tesztek megbízható várakozással.

Megbízható end-to-end tesztek készítése instabil várakozások nélkül

Sziasztok! Ma egy olyan témával jövök, ami mindannyiunk idegeire megy: az end-to-end (e2e) tesztek, amik néha úgy viselkednek, mint egy türelmetlen gyerek a bolti pénztárnál – váratlanul megállnak, időzítési problémákba futnak, és flakkoló eredményt produkálnak. Pedig az e2e tesztelés a quality biztosítás egyik legértékesebb eszköze, mert a valós felhasználói élményt modellezi. A kérdés: hogyan készítsünk olyan teszteket, amelyek stabilak és nem esznek be az instabil várakozások miatt?

Miért okoznak problémát a várakozások?

Amikor e2e teszteket írunk, a böngésző és az alkalmazás aszinkron viselkedése gyakran összezavarja a tesztkódot. A klasszikus hiba: a teszt megpróbál kattintani egy elemre, ami még nincs betöltve, vagy megvárja a 10 másodpercet, de az elem már 0,5 másodperc alatt megjelenik. Mindkét eset rossz: vagy fals negatív eredményt kapunk, vagy feleslegesen lassú lesz a tesztcsomagunk.

Itt jön képbe a Playwright, ami modern eszközként okos várakozási mechanizmusokat kínál. De az eszköz használata önmagában nem garancia – a megfelelő szemléletmód kell.

Az okos várakozás filozófiája

A kulcs a *feltételes várakozás*. Ne mondd meg a tesztnek, hogy „várj 5 másodpercet”, hanem azt, hogy „várj, amíg ez az elem elérhető lesz”. A Playwright beépített módszereivel ezt elegánsan megoldhatjuk.

// PHP backend példa: egy egyszerű API, amin tesztelünk
class CheckoutController {
    public function processOrder(Request $request) {
        // Szimuláljunk egy rövid feldolgozási időt
        usleep(200000); // 0.2 másodperc
        
        $orderId = Order::create($request->all())->id;
        
        return response()->json([
            'success' => true,
            'order_id' => $orderId,
            'redirect_url' => '/order-confirmation/' . $orderId
        ]);
    }
}

A fenti backend logika változó ideig tarthat, attól függően, hogy a rendszer mennyire terhelt. Frontend oldalon nem feltételezhetünk fix időt.

Gyakorlati példa: várás helyett állapotfigyelés

// jQuery/Bootstrap frontend - nem fix timeout-ok használata
$(document).ready(function() {
    $('#checkout-button').on('click', function() {
        const $button = $(this);
        const $spinner = $('#loading-spinner');
        const $message = $('#status-message');
        
        // UI állapot változás
        $button.prop('disabled', true);
        $spinner.removeClass('d-none'); // Bootstrap elrejtés/megjelenítés
        $message.text('Feldolgozás...').removeClass('alert-success alert-danger');
        
        $.ajax({
            url: '/api/checkout',
            method: 'POST',
            data: $('#order-form').serialize(),
            success: function(response) {
                // Sikeres válasz - automatikus átirányítás helyett állapotváltozás
                $message.text('Sikeres rendelés! Átirányítás...').addClass('alert-success');
                
                // Innen már a teszt figyelheti a státuszüzenetet
                // VAGY a redirect_url használata
                window.location.href = response.redirect_url;
            },
            error: function() {
                $message.text('Hiba történt').addClass('alert-danger');
                $button.prop('disabled', false);
                $spinner.addClass('d-none');
            }
        });
    });
});
// SCSS a terhelhető állapotok jelzésére
#status-message {
    transition: all 0.3s ease;
    
    &.alert-success {
        @include bootstrap-alert-variant(theme-color-level('success', -10), theme-color-level('success', -9), theme-color('success'));
    }
    
    &.alert-danger {
        @include bootstrap-alert-variant(theme-color-level('danger', -10), theme-color-level('danger', -9), theme-color('danger'));
    }
}

#loading-spinner {
    opacity: 0;
    transition: opacity 0.2s;
    
    &:not(.d-none) {
        opacity: 1;
    }
}

És most a lényeg – a Playwright teszt instabil várakozások nélkül:

// Playwright teszt - okos várakozásokkal
test('Teljes rendelési folyamat', async ({ page }) => {
  // 1. Ne használjunk page.waitForTimeout(5000)-ot!
  // Helyette:
  await page.goto('https://példa.hu/webshop');
  
  // 2. Várjunk konkrét elemekre, ne időre
  await page.waitForSelector('#product-list', { state: 'visible' });
  
  // 3. Interakció, ami további várakozást igényel
  await page.click('#add-to-cart-1');
  
  // Várjuk a kosár frissítésének visszajelzését
  await page.waitForSelector('.cart-notification', { state: 'visible' });
  
  // 4. Töltőképernyő kezelése
  await page.click('#checkout-button');
  
  // Fontos: ne fix timeout, hanem várjuk, hogy a gomb disabled legyen
  // ez jelzi, hogy a kérés elindult
  await page.waitForSelector('#checkout-button:disabled');
  
  // 5. Várjuk a sikeres státuszüzenetet
  await page.waitForSelector('#status-message.alert-success', {
    state: 'visible',
    timeout: 10000 // Maximum timeout, de előbb is befejeződhet
  });
  
  // 6. Alternatív megoldás: várjuk az URL változást
  // await page.waitForURL('**/order-confirmation/*');
});

Gyakori buktatók és megoldásaik

1. Túl korai interakció: A leggyakoribb hiba, hogy a teszt túl korán próbál kattintani. Használd a waitForSelector-t, de ne csak a láthatóságot, hanem az állapotot is figyeld (pl. :not([disabled])).

2. Hálózati késleltetések szimulálása: A Playwright lehetővé teszi a hálózati feltételek beállítását. Használd a page.route()-ot, hogy meghatározd maximális késleltetéseket, és így teszteld a realisztikus forgatókönyveket.

3. Animációk problémái: CSS animációk megzavarhatják a teszteket. A Playwright-ban beállíthatod, hogy a teszt figyelmen kívül hagyja az animációkat, vagy várjon az animációk befejeződésére specifikus CSS osztályok alapján.

4. Párhuzamos tesztfuttatás: Ha párhuzamosan futtatod a teszteket, győződj meg arról, hogy az állapotok (pl. bejelentkezés) nem ütköznek. Minden tesztnek legyen saját, izolált kontextusa.

5. Aflakoló tartalom: Modern webalkalmazások gyakran használnak lazy load-ot. A page.waitForFunction() használatával tudsz egyedi JavaScript feltételeket ellenőrizni a DOM-ban.

Mit tegyünk, ha mégis flakkol a teszt?

Először is: ne azonnal növeld a timeout-ot! Inkább vizsgáld meg: – Valóban elérhető-e a tesztkörnyezet? – Megváltozott-e a UI vagy a business logic? – Van-e olyan animáció vagy állapotváltás, amit nem vettünk figyelembe?

Naplózzatok minden lépést screenshotokkal vagy videófelvétellel. A Playwright ezeket beépítetten támogatja, és óriási segítség a flakkoló tesztek debugolásában.

Összegzés

A megbízható e2e tesztek írása nem a legnagyobb timeout beállításáról szól, hanem arról, hogy okosan kommunikáljunk az alkalmazásunkkal. Várjunk konkrét állapotokra, ne időintervallumokra. Használjuk ki a modern eszközök (mint a Playwright) beépített várakozási mechanizmusait, és írjunk teszteket, amelyek rugalmasan alkalmazkodnak az alkalmazás változó válaszidejeihez.

Ezzel a megközelítéssel nem csak stabilabb teszteket kapsz, hanem gyorsabbakat is, mert a teszt nem vár feleslegesen. A quality mérnöki munka legnagyobb részét így a teszt tervezése adja, nem a futtatása.

Mert ugye mi is utáljuk várakozni – a teszteink is.

A weboldalon megjelenő szöveges és vizuális tartalmak előállításához mesterséges intelligenciát (AI) használunk.