Günümüzün modern web uygulamaları, kullanıcı deneyimini zenginleştirmek ve hızlı etkileşimler sağlamak için büyük ölçüde asenkron operasyonlara dayanır. Tek Sayfa Uygulamaları (SPA’lar) ve karmaşık etkileşimli arayüzler, arka planda sürekli olarak API çağrıları yapar, veri çeker, kullanıcı etkileşimlerine yanıt verir ve DOM’u dinamik olarak günceller. Bu dinamik yapı, otomasyon süreçlerinde, özellikle test otomasyonu ve web scraping senaryolarında ciddi zorluklar yaratır. Bir elementin sayfada görünmesi, o elementin bağlı olduğu verinin veya arka plan işleminin gerçekten tamamlandığı anlamına gelmeyebilir. Kullanıcı bir butona bastığında, arayüzde bir yükleme animasyonu belirebilir ancak verinin sunucudan gelmesi ve sayfanın bu veriyi işlemesi birkaç yüz milisaniye hatta saniye sürebilir. Bu “bekle ve gör” durumu, otomasyon scriptlerinin en büyük düşmanlarından biridir.
Geleneksel otomasyon yaklaşımlarında, bu tür asenkron işlemleri beklemek için setTimeout gibi sabit gecikmeler kullanılabilir. Ancak bu yöntemler son derece güvenilmezdir. Ağ koşulları, sunucu yanıt süreleri veya uygulamanın kendisindeki performans dalgalanmaları nedeniyle sabit bir bekleme süresi ya çok kısa kalıp testin başarısız olmasına yol açar ya da gereğinden uzun olup otomasyon sürecini yavaşlatır. Sürekli bir “nerede beklemeliyim?” veya “ne kadar beklemeliyim?” sorusuyla boğuşmak, geliştiriciler ve otomasyon mühendisleri için zaman kaybı ve moral bozukluğu kaynağıdır. Playwright gibi modern otomasyon araçları, bu tür sorunları çözmek için gelişmiş ağ yönetim yetenekleri sunar. Bu yetenekler arasında waitForRequest, waitForResponse ve route gibi metodlar öne çıkar. Özellikle waitForResponse, belirli bir ağ isteğinin başarıyla tamamlanmasını ve bir yanıtın alınmasını beklemek için kritik bir araçtır. Bu sayede, otomasyon senaryoları gerçekten uygulamanın mantıksal akışını takip edebilir ve sadece görsel elementlerin varlığına değil, aynı zamanda arka plandaki veri akışına da odaklanabilir. Playwright’ın ağ yakalama mekanizmaları, testlerin daha sağlam, daha hızlı ve daha güvenilir olmasını sağlayarak, geliştirme ve kalite güvence süreçlerini önemli ölçüde iyileştirir. Bu, özellikle karmaşık API bağımlılıkları olan veya dış hizmetlerle yoğun bir şekilde entegre olan uygulamalar için hayati öneme sahiptir. Böylece, gereksiz ve tahmini gecikmelerden kaçınarak, yalnızca ihtiyaç duyulan anda ve ihtiyaç duyulan süre kadar bekleme stratejileri uygulanabilir.
Playwright’ın waitForResponse Metodu Nedir ve Nasıl Çalışır?
Playwright’ın waitForResponse metodu, web otomasyon dünyasında bir kurtarıcı niteliğindedir. Temel olarak, tarayıcının belirli bir ağ isteğine yönelik bir yanıtı başarıyla tamamlamasını beklemek için tasarlanmıştır. Bu metot sayesinde, otomasyon scriptleriniz, arka planda gerçekleşen ve genellikle gözle görülemeyen HTTP/HTTPS isteklerinin tamamlandığından emin olana kadar bekleyebilir. Bu, özellikle bir kullanıcı eyleminin (örneğin, bir butona tıklama veya bir form gönderme) bir veya daha fazla API çağrısını tetiklediği ve bu çağrıların yanıtlarına bağımlı olarak sayfanın içeriğinin veya durumunun değiştiği senaryolarda hayati önem taşır. waitForResponse metodu, beklenecek yanıtı tanımlamak için çeşitli parametreler kabul eder, bu da onu son derece esnek kılar. En yaygın kullanılan parametre, yanıtın URL’sidir. Bu URL’yi düz bir string olarak, bir regex (düzenli ifade) olarak veya bir predicate fonksiyonu (bir koşul döndüren bir fonksiyon) olarak belirtebilirsiniz.
Peki, waitForResponse ne zaman kullanılmalı? Birkaç örnekle açıklayalım:
-
API Çağrılarının Tamamlanmasını Bekleme: Bir ürün listesinin yüklendiği veya bir kullanıcının profil bilgilerinin güncellendiği durumlarda, ilgili API yanıtının gelmesini beklemek için
waitForResponsekullanılır. - Veri Yükleme Durumlarını Kontrol Etme: Uzun süren veri çekme işlemleri veya dosya yüklemeleri gibi durumlarda, işlemin tamamlandığını gösteren spesifik bir yanıt kodunu veya yanıt içeriğini beklemek için idealdir.
-
Sayfa Navigasyonu Sonrası Arka Plan İsteklerini İzleme: Bazen bir sayfaya gittikten hemen sonra bile, sayfa içeriğini doldurmak için ek API çağrıları yapılır.
waitForResponsebu çağrıların tamamlandığından emin olmanızı sağlar. - İsteğe Bağlı Veri Yüklemeleri: Infinite scroll gibi durumlarda, kullanıcı aşağı kaydırdıkça yeni verilerin yüklenmesi için yapılan isteklerin yanıtını beklemek için kullanılır.
Metodun temel çalışma prensibi, Playwright’ın tarayıcının ağ trafiğini sürekli olarak izlemesine dayanır. Siz waitForResponse‘u çağırdığınızda, Playwright bu anda tarayıcıdan gelen tüm ağ yanıtlarını dinlemeye başlar. Belirttiğiniz URL veya predicate koşuluna uyan ilk yanıtı aldığında, bu yanıt nesnesini döndürür ve bekleme sona erer. Eğer belirtilen bir zaman aşımı süresi içinde eşleşen bir yanıt gelmezse, metot bir hata fırlatır. Bu, özellikle testlerin veya scraping operasyonlarının kararlılığını artırmak için kritik bir özelliktir. Aşağıdaki basit kod bloğu, waitForResponse‘un temel kullanımını göstermektedir:
import {{ test, expect }} from '@playwright/test';
test('Bir API çağrısının yanıtını başarıyla beklemeli', async ({{ page }}) => {
// Sayfaya gitmeden önce veya bir eylem gerçekleştirmeden hemen önce waitForResponse'u çağırın.
// Bu, Playwright'ın isteği dinlemeye başlamasını sağlar.
const responsePromise = page.waitForResponse(response =>
response.url().includes('/api/data') && response.status() === 200
);
// API çağrısını tetikleyecek bir eylem gerçekleştirin.
// Örneğin, bir butona tıklayın veya doğrudan bir URL'ye gidin.
await page.goto('https://example.com/data-page');
// Yanıtın gelmesini bekleyin.
const response = await responsePromise;
// Yanıtın içeriğini veya durumunu kontrol edebilirsiniz.
expect(response.status()).toBe(200);
const data = await response.json();
expect(data.length).toBeGreaterThan(0);
console.log(API'den gelen veri sayısı: ${{ data.length }});
});
Bu örnekte, page.waitForResponse çağrısı, response.url().includes('/api/data') ile URL'sinde /api/data geçen ve response.status() === 200 ile HTTP durum kodu 200 olan bir yanıtı bekler. Bu yaklaşım, sadece URL'ye bakmak yerine, yanıtın içeriği veya durumu gibi daha derinlemesine koşullara göre de bekleme yapabilmenizi sağlar, bu da otomasyonlarınızı daha sağlam ve hataya daha dayanıklı hale getirir.
Gerçek Dünya Senaryolarında waitForResponse Kullanımı: Bir Vaka Analizi
Bir e-ticaret sitesinde ürün filtreleme işlevi, waitForResponse metodunun gücünü göstermek için harika bir gerçek dünya senaryosudur. Genellikle, kullanıcı bir kategori seçtiğinde veya bir filtre uyguladığında (örneğin, fiyata göre, markaya göre), tarayıcı arka planda bir API çağrısı yapar. Bu API çağrısı, filtrelenmiş ürün listesini JSON formatında döndürür ve sayfa, bu veriyi kullanarak ürünleri dinamik olarak günceller. Eğer otomasyon scriptiniz, filtreleme işlemi tamamlanmadan ürün sayısını saymaya veya yeni ürünleri kontrol etmeye çalışırsa, ya eski verilerle karşılaşır ya da bir elementin bulunamaması hatası alır. İşte bu noktada waitForResponse devreye girer.
Senaryo: Bir e-ticaret sitesinde belirli bir "Elektronik" kategorisine gidip, ardından "Fiyat: Yüksekten Alçağa" filtresini uyguladıktan sonra, filtrelenmiş ürün listesinin başarıyla yüklendiğini ve en az bir ürünün gösterildiğini doğrulamak istiyoruz.
Adım Adım Uygulama:
- Sayfaya Gitme: İlk olarak, e-ticaret sitesinin ana sayfasına gideceğiz.
- Kategoriye Gitme: "Elektronik" kategorisine tıklayarak ilgili sayfaya ulaşacağız. Bu navigasyon sırasında da bir API çağrısı tetiklenebilir, ancak biz asıl filtreleme isteğine odaklanacağız.
-
Filtreyi Uygulama ve Yanıtı Bekleme: "Fiyat: Yüksekten Alçağa" filtresini seçtiğimizde, sayfanın ürünleri yeniden yüklemek için bir API çağrısı yapmasını bekleyeceğiz. Bu API çağrısının URL'si genellikle "/api/products?category=electronics&sort=price_desc" gibi bir yapıda olacaktır.
waitForResponsemetodunu kullanarak bu spesifik API yanıtının gelmesini bekleyeceğiz. - Gelen Veriyi Kontrol Etme: Yanıt başarıyla alındığında, yanıtın HTTP durum kodunu kontrol edip, içeriğinin beklenen ürün verilerini içerdiğinden emin olabiliriz. Son olarak, sayfadaki ürün listesinin güncellendiğini doğrulamak için, yeni filtreye göre sıralanmış ürünlerin varlığını kontrol edeceğiz.
Aşağıdaki kod örneği, bu vaka analizini Playwright ile nasıl uygulayacağımızı göstermektedir:
import {{ test, expect }} from '@playwright/test';
test('E-ticaret sitesinde ürün filtrelemesi sonrası API yanıtını doğrulamalı', async ({{ page }}) => {
await page.goto('https://ecommerce.example.com'); // Örnek bir e-ticaret sitesi
// 1. "Elektronik" kategorisine tıklayın
await page.locator('a:has-text("Elektronik")').click();
await page.waitForLoadState('networkidle'); // Kategori sayfası yüklendiğinden emin olun
// 2. Filtreleme API yanıtını beklemeye başlayın.
// Genellikle filtreleme sonrası ürünleri çeken API'nin URL'si belirli bir desene sahiptir.
// Örneğin, '/api/products' içermesi ve bir 'sort' parametresi olması gibi.
const filterResponsePromise = page.waitForResponse(response =>
response.url().includes('/api/products') && response.request().method() === 'GET' &&
response.url().includes('sort=price_desc') && response.status() === 200
);
// 3. "Fiyat: Yüksekten Alçağa" filtresini uygulayın.
// Bu bir dropdown, radio button veya link olabilir.
await page.selectOption('select#sort-by', 'price_desc'); // ID'si 'sort-by' olan bir select kutusu varsayalım
// 4. Filtreleme API yanıtının gelmesini bekleyin
const response = await filterResponsePromise;
// 5. Yanıtın başarıyla alındığını ve içeriğini kontrol edin
expect(response.status()).toBe(200);
const productsData = await response.json();
expect(productsData).toBeInstanceOf(Array);
expect(productsData.length).toBeGreaterThan(0);
console.log(Filtrelenmiş ürün sayısı (API'den): ${{ productsData.length }});
// 6. Sayfadaki ürün listesinin güncellendiğini görsel olarak veya DOM üzerinden doğrulayın.
// Örneğin, ilk ürünün fiyatının gerçekten en yüksek olduğunu kontrol edebiliriz.
const firstProductPriceText = await page.locator('.product-list .product-item:first-child .price').innerText();
const firstProductPrice = parseFloat(firstProductPriceText.replace(/[^0-9.-]+/g,""));
// Beklenen ürün fiyatının yüksek olduğunu varsayımsal olarak kontrol edin.
// Gerçek bir senaryoda, API yanıtındaki ilk ürünün fiyatı ile karşılaştırırdık.
expect(firstProductPrice).toBeGreaterThan(500); // Varsayımsal bir değer
// En az bir ürün elementinin sayfada görünür olduğunu kontrol edin
await expect(page.locator('.product-list .product-item')).toHaveCount(productsData.length);
console.log('Filtreleme ve doğrulama başarılı.');
});
Bu vaka analizi, waitForResponse metodunun sadece testlerin daha güvenilir olmasını sağlamakla kalmayıp, aynı zamanda otomasyon akışını gerçek kullanıcı deneyimiyle daha uyumlu hale getirdiğini açıkça göstermektedir. Bu sayede, uygulamanın arka planındaki veri akışına bağımlı olan her türlü eylemi güvenle otomatikleştirebiliriz.
waitForResponse ile Karşılaşılabilecek Zorluklar ve Çözümleri Nelerdir?
waitForResponse metodu ne kadar güçlü olursa olsun, asenkron web dünyasının karmaşıklığı bazen beklenmedik zorluklar ortaya çıkarabilir. Ancak bu zorlukların çoğu, doğru yaklaşımlar ve Playwright'ın sunduğu esneklik ile kolayca aşılabilir. İşte sıkça karşılaşılan bazı zorluklar ve bunlara yönelik çözümler:
Zorluk 1: Yanlış URL Eşleşmesi veya Birden Fazla Benzer İstek
Bazen beklediğiniz API isteği, aynı URL yapısına sahip başka, alakasız bir istekle karıştırılabilir. Veya aynı eylem birden fazla benzer API çağrısını tetikleyebilir ve siz yanlış olanı yakalamak isteyebilirsiniz.
-
Çözüm: Daha Spesifik Regex Kullanımı: URL'yi tam eşleştirmek yerine, sorgu parametrelerini de içeren daha spesifik bir düzenli ifade (regex) kullanabilirsiniz. Örneğin,
/api/products\\?category=electronics.*gibi. - Çözüm: Predicate Fonksiyonu ile Payload/Status Kontrolü: En güçlü yaklaşım, bir predicate fonksiyonu kullanmaktır. Bu fonksiyon, yanıtın URL'si, HTTP durumu, başlıkları veya hatta yanıt gövdesinin kendisi gibi tüm detaylarına erişmenizi sağlar. Böylece, sadece doğru URL'ye sahip değil, aynı zamanda beklenen HTTP durum koduna (örneğin, 200 OK) sahip ve hatta belirli bir veri yapısını içeren yanıtı bekleyebilirsiniz.
// Örnek: Sadece 200 OK dönen ve belirli bir product ID içeren yanıtı bekleme
const specificProductResponse = await page.waitForResponse(async response => {
return response.url().includes('/api/products/') &&
response.status() === 200 &&
(await response.json()).data.id === 'expectedProductId123';
});
Zorluk 2: Zaman Aşımı (Timeout) Sorunları
Ağ koşulları veya sunucu gecikmeleri nedeniyle bir API yanıtının beklenenden daha uzun sürmesi, waitForResponse metodunun zaman aşımına uğramasına neden olabilir.
-
Çözüm:
timeoutParametresini Ayarlama: Playwright'ın varsayılan zaman aşımı genellikle 30 saniyedir. Eğer belirli bir işlem daha uzun sürebiliyorsa,waitForResponse'a daha uzun birtimeoutdeğeri geçirebilirsiniz. Ancak, bu değeri gereksiz yere artırmamak önemlidir, aksi takdirde testleriniz yavaşlar. -
Çözüm: Retry Mekanizmaları: Zaman zaman meydana gelen ağ dalgalanmaları için, test çatınızın veya özel bir util fonksiyonun parçası olarak
waitForResponseçağrısını belirli sayıda tekrar deneme (retry) mekanizması içine alabilirsiniz.
// Örnek: Zaman aşımını 60 saniyeye çıkarma
const longResponse = await page.waitForResponse(
'**/api/long-running-task',
{{ timeout: 60000 }} // 60 saniye
);
Zorluk 3: İsteklerin Sırası ve Dinamik URL'ler
Bazı durumlarda, aynı eylem birden fazla API isteğini tetikler ve bu isteklerin sırası değişebilir. Veya URL'ler, oturum ID'leri veya diğer dinamik parametreler içerdiğinden, her zaman aynı kalmayabilir.
-
Çözüm:
Promise.allile Birden Fazla İsteği Bekleme: Eğer bir eylem birden fazla farklı API yanıtını tetikliyorsa ve bunların hepsinin tamamlandığından emin olmak istiyorsanız,Promise.allile birden fazlawaitForResponseçağrısını paralel olarak bekleyebilirsiniz. -
Çözüm: URL'nin Sadece Değişmeyen Kısmını Kullanma: Dinamik URL'ler için, URL'nin sabit kalan kısmını veya bir regex kullanarak dinamik kısımları eşleştirmeyebilirsiniz. Örneğin,
/api/users/[0-9]+/detailsyerine sadece/api/users/ile başlayan tüm istekleri yakalayıp predicate fonksiyonu ile içindeki veriye bakabilirsiniz. -
Çözüm: Global
page.on('response')ile Daha Esnek Yakalama: Çok karmaşık senaryolarda,waitForResponsebir eylemi tetiklemeden önce bir Promise oluşturmanızı gerektirirken,page.on('response')olayıyla daha reaktif bir yaklaşım sergileyebilirsiniz. Bu, belirli bir koşulu karşılayan *her* yanıtı dinlemenizi sağlar. Ancak bu genellikle daha düşük seviyeli bir yaklaşımdır ve dikkatli kullanılmalıdır.
waitForResponse metodunun predicate fonksiyonu parametresi en güçlü çözüm ortağınız olacaktır. Yanıtın URL'si, durumu, başlıkları ve hatta gövdesini (eğer JSON veya metin tabanlıysa) kullanarak çok spesifik koşullar tanımlayabilirsiniz. Bu, otomasyonlarınızın hem güvenilirliğini hem de esnekliğini dramatik bir şekilde artırır.
Bu çözümler, waitForResponse'un potansiyel tuzaklarından kaçınmanıza ve Playwright otomasyonlarınızı daha sağlam ve öngörülebilir hale getirmenize yardımcı olacaktır.
İleri Düzey waitForResponse Teknikleri: Performans ve Güvenilirlik İçin İpuçları
waitForResponse metodunun temel kullanımlarını anladıktan sonra, otomasyonlarınızı bir üst seviyeye taşımak için bazı ileri düzey tekniklere ve ipuçlarına göz atalım. Bu teknikler, testlerinizin veya scraping scriptlerinizin performansını artırırken aynı zamanda hata toleransını ve güvenilirliğini de yükseltecektir.
Predicate Fonksiyonunun Gücü: Sadece URL Değil, Yanıtın Kendisi Üzerinden Filtreleme
Daha önce de değindiğimiz gibi, waitForResponse metoduna geçirilen predicate fonksiyonu, basit URL eşleştirmesinin ötesine geçerek yanıtın tüm özelliklerini incelemenizi sağlar. Bu, özellikle aynı URL'ye sahip ancak farklı içerik veya durum kodları dönen yanıtlar arasında ayrım yapmanız gerektiğinde kritik öneme sahiptir.
-
HTTP Durum Koduna Göre Filtreleme: Sadece başarılı (200 OK) yanıtları beklemek için
response.status() === 200koşulunu ekleyebilirsiniz. -
Yanıt Başlıklarına Göre Filtreleme: Belirli bir
Content-Typeveya özel bir API başlığı (X-Request-IDgibi) içeren yanıtları bekleyebilirsiniz:response.headers()['content-type'].includes('application/json'). -
Yanıt Gövdesine Göre Filtreleme: En güçlü yaklaşımlardan biri, yanıtın gövdesini incelemektir. Özellikle JSON tabanlı API'ler için, yanıtın içindeki belirli bir alanın varlığını veya değerini kontrol edebilirsiniz. Ancak bu, yanıt gövdesinin tamamının okunmasını gerektirdiğinden, performansı düşürebilir ve yalnızca gerçekten gerektiğinde kullanılmalıdır.
await response.json()veyaawait response.text()kullanırkenasyncanahtar kelimesini predicate fonksiyonunuzda kullanmayı unutmayın.
// Örnek: Sadece 'application/json' Content-Type'ına sahip ve belirli bir veri içeren yanıtı bekleme
const jsonResponseWithSpecificData = await page.waitForResponse(async response => {
if (response.url().includes('/api/items') && response.request().method() === 'POST') {
const headers = response.headers();
if (headers['content-type'] && headers['content-type'].includes('application/json')) {
const body = await response.json();
return body && body.status === 'success' && body.id; // Yanıt gövdesinde 'status' ve 'id' kontrolü
}
}
return false;
});
Birden Fazla İsteği Aynı Anda Bekleme: Promise.all ile
Bir kullanıcı eylemi bazen birden fazla bağımsız API çağrısını tetikleyebilir. Örneğin, bir ürün sayfasının yüklenmesi hem ürün detayları API'sini hem de ilgili ürünler API'sini çağırabilir. Bu durumda, her iki yanıtın da geldiğinden emin olmak isteyebilirsiniz. Promise.all ile birden fazla waitForResponse promise'ını aynı anda bekleyebilirsiniz.
// Örnek: Aynı anda iki farklı API yanıtını bekleme
const [productDetailsResponse, relatedProductsResponse] = await Promise.all([
page.waitForResponse(response => response.url().includes('/api/product-details')),
page.waitForResponse(response => response.url().includes('/api/related-products'))
]);
expect(productDetailsResponse.status()).toBe(200);
expect(relatedProductsResponse.status()).toBe(200);
İstek ve Yanıt Yakalama Arasındaki Farklar: waitForRequest vs waitForResponse
Playwright, ağ trafiğini yakalamak için waitForRequest ve waitForResponse olmak üzere iki ana metod sunar.
-
waitForRequest(İstek Bekleme): Tarayıcının belirli bir URL'ye istek göndermesini bekler. Bu, isteğin gönderildiğini ancak henüz bir yanıt gelmediğini doğrulamak istediğinizde kullanışlıdır. Özellikle, bir isteğin hiç gönderilip gönderilmediğini veya doğru parametrelerle gönderilip gönderilmediğini kontrol etmek için idealdir. -
waitForResponse(Yanıt Bekleme): Belirli bir isteğe ait yanıtın tarayıcıya ulaşmasını bekler. Bu, isteğin tamamlandığını ve bir sunucu yanıtının alındığını doğrulamak istediğinizde kullanılır. Çoğu zaman, uygulamanın durumunun veya içeriğinin değiştiği asenkron işlemler için bu metot daha uygundur.
Genel kural olarak, eğer bir eylemin belirli bir API çağrısını tetiklediğinden emin olmak istiyorsanız waitForRequest'i, ancak bu API çağrısının başarılı bir şekilde tamamlandığından ve sayfanın güncellendiğinden emin olmak istiyorsanız waitForResponse'u tercih edin.
Mocklama ve Manipülasyon: page.route ile Birleştirerek Yanıtları Taklit Etme
waitForResponse metodunu page.route ile birleştirmek, ileri düzey test senaryoları ve hata simülasyonları için inanılmaz derecede güçlü bir kombinasyondur. page.route ile belirli bir URL'ye yapılan istekleri kesebilir ve kendi taklit (mock) yanıtlarınızı döndürebilirsiniz. Bu, Playwright test ortamında sunucu tarafındaki davranışları simüle etmenizi sağlar.
// Örnek: Bir API yanıtını mock'layarak hata durumunu test etme
test('API hatası durumunda hata mesajını göstermeli', async ({{ page }}) => {
// '/api/user-profile' isteklerini kes ve 500 status code ile boş bir yanıt döndür.
await page.route('**/api/user-profile', async route => {
await route.fulfill({
status: 500,
contentType: 'application/json',
body: JSON.stringify({ error: 'Internal Server Error' })
});
});
// Kullanıcının profil sayfasına gitmesini tetikleyecek bir eylem
await page.goto('https://example.com/profile');
// Hata API yanıtını bekle
const errorResponse = await page.waitForResponse(response =>
response.url().includes('/api/user-profile') && response.status() === 500
);
expect(errorResponse.status()).toBe(500);
// Hata mesajının sayfada görünür olduğunu doğrula
await expect(page.locator('text=Profil yüklenemedi')).toBeVisible();
});
Bu ileri düzey teknikler, Playwright otomasyonlarınızın hem daha sağlam hem de daha esnek olmasını sağlar. Uygulamalarınızın karmaşıklığı arttıkça, bu araçları etkin bir şekilde kullanmak, test sürenizi ve hata ayıklama çabanızı önemli ölçüde azaltacaktır.
Mobil Uyumlu Testler ve waitForResponse: Nasıl Yapılır?
Günümüzde web sitelerinin büyük bir çoğunluğu, farklı cihaz boyutlarına ve ekran çözünürlüklerine uyum sağlayabilen mobil uyumlu (responsive) tasarımlara sahiptir. Bu durum, otomasyon testlerinde ek bir boyut getirir: bir web uygulamasının yalnızca masaüstü görünümünde değil, mobil cihazlarda da beklendiği gibi çalıştığından emin olmak. Playwright, bu ihtiyacı karşılamak için güçlü cihaz emülasyon yetenekleri sunar ve waitForResponse metodu, mobil uyumlu testlerde de kritik bir rol oynar.
Playwright ile mobil uyumlu testler yaparken, page.setViewportSize() veya browser.newContext() metodu ile önceden tanımlanmış cihaz presetlerini (örneğin, devices['iPhone 11']) kullanarak farklı ekran boyutlarını ve kullanıcı aracısı (user-agent) dizelerini taklit edebilirsiniz. Bu emülasyonlar, sayfanın CSS medya sorgularını (media queries) tetiklemesini ve mobil cihazlara özgü düzenleri, etkileşimleri ve bazen de farklı ağ isteklerini tetiklemesini sağlar.
Peki, waitForResponse mobil uyumlu testlerde nasıl bir fark yaratır?
-
Farklı Ağ Davranışları: Bazı web siteleri, mobil cihazlardan erişildiğinde farklı API uç noktalarına veya farklı veri formatlarına sahip API'lere istek gönderebilir. Örneğin, daha az veri içeren veya mobil cihazlara özel optimize edilmiş bir API'den veri çekebilirler.
waitForResponsekullanarak, bu mobil özel API isteklerinin doğru bir şekilde tetiklendiğini ve yanıtlandığını doğrulayabilirsiniz. -
Performans Kontrolü: Mobil ağ koşulları genellikle masaüstü fiber internet kadar hızlı değildir.
waitForResponseile belirli API yanıtlarının mobil ortamda da kabul edilebilir sürelerde tamamlandığını test edebilirsiniz. Uzun süren yanıtlar için zaman aşımı değerlerini mobil test senaryolarına özel olarak ayarlamak gerekebilir. -
Medya Sorguları ve İçerik Yüklemesi: Mobil cihazlarda, bazı içerikler sadece belirli bir viewport boyutunda yüklenirken, bazıları hiç yüklenmeyebilir veya farklı kaynaklardan yüklenebilir.
waitForResponseile bu dinamik yüklemelerin doğruluğunu ve zamanlamasını kontrol edebilirsiniz.
Örnek Senaryo: Bir e-ticaret sitesinin ürün detay sayfası, mobil görünümde, daha küçük resim çözünürlükleri için farklı bir API uç noktası kullanıyor olabilir. Ayrıca, mobil görünümde "Benzer Ürünler" bölümü yalnızca kullanıcı sayfanın sonuna kaydırdığında yükleniyor olabilir. waitForResponse ile bu mobil özel davranışları test edebiliriz.
import {{ test, expect, devices }} from '@playwright/test';
test('Mobil görünümde ürün detay sayfasının API çağrılarını kontrol etmeli', async ({{ page }}) => {
// Bir iPhone 13 Pro Max emülasyonu başlat
const mobilePage = await page.context().newPage({{ ...devices['iPhone 13 Pro Max'] }});
// Mobil özel resim API yanıtını beklemeye başla
const mobileImageApiResponsePromise = mobilePage.waitForResponse(response =>
response.url().includes('/api/mobile-images') && response.status() === 200
);
// Ürün detay sayfasına git
await mobilePage.goto('https://example.com/product/awesome-phone-1');
// API yanıtının gelmesini bekle
const mobileImageApiResponse = await mobileImageApiResponsePromise;
expect(mobileImageApiResponse.status()).toBe(200);
const imageData = await mobileImageApiResponse.json();
expect(imageData.resolution).toBe('mobile'); // API'den gelen verinin mobil çözünürlükte olduğunu doğrula
// Sayfayı aşağı kaydırarak 'Benzer Ürünler' bölümünü tetikle
await mobilePage.evaluate(() => window.scrollTo(0, document.body.scrollHeight));
// 'Benzer Ürünler' API yanıtını bekle
const relatedProductsApiResponsePromise = mobilePage.waitForResponse(response =>
response.url().includes('/api/related-products-mobile') && response.status() === 200
);
const relatedProductsApiResponse = await relatedProductsApiResponsePromise;
expect(relatedProductsApiResponse.status()).toBe(200);
const relatedProducts = await relatedProductsApiResponse.json();
expect(relatedProducts.length).toBeGreaterThan(0);
// Mobil görünümde ilgili ürünlerin sayfada yüklendiğini kontrol et
await expect(mobilePage.locator('.related-products-section .product-item')).toBeVisible();
console.log('Mobil uyumlu API yanıtları başarıyla doğrulandı.');
});
Playwright'ın emülasyon yetenekleri sayesinde, gerçek bir mobil cihaz kullanmadan mobil davranışları test edebiliriz. waitForResponse ise bu emülasyon ortamında ağ isteklerinin doğruluğunu ve zamanlamasını garanti etmemize yardımcı olur.
CSS Media Query Örneği:
Bir web sayfasında mobil uyumluluğun temelini oluşturan CSS medya sorguları, waitForResponse ile doğrudan ilişkili olmasa da, mobil test senaryolarının bağlamını oluşturur. İşte basit bir örnek:
Bu CSS örneği, farklı ekran boyutlarında nasıl farklı görsellerin veya elementlerin yüklenebileceğini göstermektedir. Playwright'ın waitForResponse metodu, bu senaryolarda mobile-hero.jpg gibi mobil özel kaynakların başarılı bir şekilde yüklendiğini doğrulamak için kullanılabilir. Mobil uyumlu testler, web uygulamalarınızın tüm kullanıcılar için kusursuz bir deneyim sunmasını sağlamanın kritik bir parçasıdır ve waitForResponse bu süreçte güvenilir bir yardımcıdır.
Sonuç: Playwright waitForResponse ile Daha Sağlam Testler
Bu makalede, Playwright'ın waitForResponse metodunun modern web otomasyonu için ne kadar hayati bir araç olduğunu derinlemesine inceledik. Asenkron web uygulamalarının karmaşık dünyasında, otomasyon scriptlerinin ağ isteklerini güvenilir bir şekilde beklemesi, testlerin veya web scraping operasyonlarının başarısı için kilit öneme sahiptir. waitForResponse, sabit gecikmelerden veya kırılgan element bekleme stratejilerinden kaçınarak, gerçek API yanıtlarına dayalı sağlam ve kararlı otomasyonlar oluşturmamızı sağlar.
waitForResponse'un temel prensiplerinden başlayarak, bir e-ticaret filtreleme senaryosunda gerçek dünya uygulamalarını gördük. Karşılaşılabilecek zorlukları (yanlış eşleşmeler, zaman aşımı, dinamik URL'ler) ve bunları predicate fonksiyonları, Promise.all gibi Playwright'ın esnek mekanizmalarıyla nasıl aşabileceğimizi ele aldık. Ayrıca, waitForRequest ile farklarını ve page.route ile birleştiğinde ortaya çıkan ileri düzey test senaryolarını da keşfettik. Son olarak, mobil uyumlu testlerin önemini ve waitForResponse'un farklı cihaz emülasyonlarında dahi ağ davranışlarını nasıl doğrulayabileceğimizi vurguladık.
Özetle, waitForResponse metodu Playwright kullanıcılarına şunları sunar:
- Güvenilirlik: Asenkron işlemlerin gerçekten tamamlandığından emin olun.
- Performans: Gereksiz bekleme sürelerinden kaçınarak testlerinizi hızlandırın.
- Esneklik: URL, durum kodu, başlıklar ve hatta yanıt gövdesi gibi çeşitli kriterlere göre yanıtları filtreleyin.
- Kararlılık: Ağ koşullarındaki veya sunucu yanıtlarındaki dalgalanmalara karşı testlerinizi daha dayanıklı hale getirin.
Modern web otomasyonunda, dinamik içerik yüklemesi ve API bağımlılıkları kaçınılmazdır. waitForResponse gibi araçlar, geliştiricilerin ve otomasyon mühendislerinin bu zorlukların üstesinden gelmesini sağlayarak, daha kaliteli yazılımlar üretmelerine ve daha hızlı geri bildirim döngüleri oluşturmalarına yardımcı olur. Playwright'ın bu güçlü özelliğini ustaca kullanmak, otomasyon stratejinizin temel taşlarından biri olmalıdır.
Sıkça Sorulan Sorular
-
SSS 1:
waitForResponseilewaitForLoadState('networkidle')arasındaki fark nedir?waitForLoadState('networkidle'), Playwright'ın son 500 ms içinde 0 ağ bağlantısının devam ettiğini algılamasını bekler. Yani, tüm ağ trafiğinin durulduğu bir durumu ifade eder.waitForResponseise çok daha spesifiktir; belirli bir URL'ye veya koşula uyan *tek bir* yanıtı bekler. Genellikle, spesifik bir API çağrısının tamamlandığından emin olmak içinwaitForResponsetercih edilirken, sayfanın genel olarak yüklendiğini ve tüm kaynakların geldiğini doğrulamak içinwaitForLoadState('networkidle')kullanılabilir. -
SSS 2:
waitForResponsebirfetchisteğini bekleyebilir mi?Evet, kesinlikle. Playwright, tarayıcı tarafından yapılan tüm ağ isteklerini (XMLHttpRequest, Fetch API, resim, CSS, JS yüklemeleri vb.) izler. Dolayısıyla,
fetchAPI'si ile yapılan bir istek ve onun yanıtı dawaitForResponsetarafından yakalanıp beklenebilir. -
SSS 3: Yanıt içeriğini nasıl alırım?
waitForResponsemetodu, beklenen yanıt geldiğinde birResponsenesnesi döndürür. Bu nesne üzerinderesponse.json()veyaresponse.text()gibi metodları kullanarak yanıtın gövdesini JSON veya metin olarak alabilirsiniz. Ancak bu metodlar asenkron olduğu içinawaitile kullanılmaları gerekir. -
SSS 4:
waitForResponseneden bazen çalışmaz?waitForResponse'un çalışmamasının birkaç yaygın nedeni vardır:- Yanlış URL/Predicate: Beklediğiniz isteğin URL'si veya predicate koşulu, gerçek istek ile tam olarak eşleşmiyor olabilir. Regex'inizi veya fonksiyonunuzu kontrol edin.
- Zamanlama Sorunu:
waitForResponseçağrısını, ilgili eylemi tetiklemeden *önce* başlatmanız gerekir. Eğer eylem zaten isteği göndermişse,waitForResponseo isteği yakalayamaz. - Yanlış İstek: Beklediğinizden farklı bir API çağrısı tetikleniyor olabilir veya hiç çağrı yapılmıyor olabilir. Tarayıcının geliştirici araçlarındaki Ağ (Network) sekmesini kullanarak gerçek trafiği gözlemleyin.
- Zaman Aşımı: Belirtilen
timeoutsüresi içinde yanıt gelmemiş olabilir. Daha uzun birtimeoutdeğeri deneyin veya uygulamanızın performansını inceleyin.
-
SSS 5: Aynı anda birden fazla
waitForResponsekullanabilir miyim?Evet, kullanabilirsiniz. Eğer bir kullanıcı eylemi birden fazla bağımsız API yanıtını tetikliyorsa, her bir
waitForResponseçağrısını ayrı bir Promise olarak başlatıp, ardından bunlarıPromise.all()kullanarak aynı anda bekleyebilirsiniz. Bu, tüm ilgili asenkron işlemlerin tamamlandığından emin olmanızı sağlar.