Takip et

Playwright waitForResponse: Ağ İsteklerini Güvenle Yönetin

Playwright’ın waitForResponse metodu ile asenkron web uygulamalarında ağ isteklerini nasıl güvenle bekleyeceğinizi ve testlerinizi veya web scraping işlemlerinizi daha kararlı hale getireceğinizi öğrenin. Bu makale, temel kullanımdan ileri düzey tekniklere kadar Playwright’ın güçlü ağ yönetimini adım adım açıklıyor.

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 waitForResponse kullanı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. waitForResponse bu ç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:

  1. Sayfaya Gitme: İlk olarak, e-ticaret sitesinin ana sayfasına gideceğiz.
  2. 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.
  3. 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. waitForResponse metodunu kullanarak bu spesifik API yanıtının gelmesini bekleyeceğiz.
  4. 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: timeout Parametresini 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 bir timeout değ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.all ile 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.all ile birden fazla waitForResponse ç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]+/details yerine 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, waitForResponse bir 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.
Uzman İpucu: Karşılaştığınız çoğu zorlukta, 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() === 200 koşulunu ekleyebilirsiniz.
  • Yanıt Başlıklarına Göre Filtreleme: Belirli bir Content-Type veya özel bir API başlığı (X-Request-ID gibi) 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() veya await response.text() kullanırken async anahtar 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. waitForResponse kullanarak, 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. waitForResponse ile 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. waitForResponse ile 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: waitForResponse ile waitForLoadState('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. waitForResponse ise ç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çin waitForResponse tercih edilirken, sayfanın genel olarak yüklendiğini ve tüm kaynakların geldiğini doğrulamak için waitForLoadState('networkidle') kullanılabilir.

  • SSS 2: waitForResponse bir fetch isteğ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, fetch API'si ile yapılan bir istek ve onun yanıtı da waitForResponse tarafından yakalanıp beklenebilir.

  • SSS 3: Yanıt içeriğini nasıl alırım?

    waitForResponse metodu, beklenen yanıt geldiğinde bir Response nesnesi döndürür. Bu nesne üzerinde response.json() veya response.text() gibi metodları kullanarak yanıtın gövdesini JSON veya metin olarak alabilirsiniz. Ancak bu metodlar asenkron olduğu için await ile kullanılmaları gerekir.

  • SSS 4: waitForResponse neden 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, waitForResponse o 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 timeout süresi içinde yanıt gelmemiş olabilir. Daha uzun bir timeout değeri deneyin veya uygulamanızın performansını inceleyin.
  • SSS 5: Aynı anda birden fazla waitForResponse kullanabilir 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.

Yorumlar
İçeriği beğendiniz mi? Bir tartışma başlatın veya görüşlerinizi paylaşın.
Yorum Yaz

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Gönder

E-posta Bülteni
Yazılım Topluluğuna Katılın
En son güncellemeleri, yaratıcı ipuçlarını ve özel kaynakları doğrudan e-posta kutunuza alın. Tasarım ve inovasyonun geleceğini birlikte keşfedelim.
Exit mobile version