Belajar Playwright - Waits & Synchronization
Episode 5 of 23

Belajar Playwright - Waits & Synchronization

Episode ini mengupas mekanisme auto-waiting default Playwright, eksplisit wait dengan waitForResponse dan waitForLoadState, cara menangani konten dinamis dan update asinkron, serta strategi menjaga stabilitas test untuk aplikasi SPA dan real-time.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Pendahuluan

Salah satu penyebab terbesar test end-to-end gagal adalah masalah timing: elemen belum muncul saat aksi dijalankan, atau response belum kembali saat assertion dicek. Episode 5 ini membahas bagaimana Playwright menyelesaikan masalah ini secara otomatis, dan kapan kalian perlu menambahkan kontrol waktu secara eksplisit.

Filosofi Playwright sederhana: test tidak boleh bergantung pada guess timing. Semua mekanisme — auto-waiting, eksplisit wait, dan assertion yang retry-able — dirancang untuk menggantikan sleep acak yang sering dipakai di framework lama. Setelah episode ini, kalian akan tahu kapan cukup percaya pada default, dan kapan harus turun tangan.

Memahami Default Auto-Waiting Playwright

Apa yang Dicari Sebelum Aksi

Saat kalian memanggil click() atau fill(), Playwright menjalankan rangkaian pengecekan secara otomatis:

  • Elemen attached ke DOM.
  • Elemen visible di viewport.
  • Elemen enabled dan tidak disabled.
  • Elemen stable — tidak berubah posisi dalam waktu tertentu.
  • Elemen tidak terhalang elemen lain yang menghalangi aksi.

Hanya jika semua kondisi terpenuhi, aksi dieksekusi. Jika tidak, Playwright menunggu sampai batas waktu dan memberikan pesan timeout yang deskriptif.

Assertion Juga Menunggu

Hal yang sama berlaku untuk assertion. expect(page.getByRole('button')).toBeVisible() tidak hanya mengecek sekali — dia menunggu hingga kondisi terpenuhi atau timeout expect.timeout tercapai. Inilah yang membuat test Playwright terasa tenang dibanding framework yang melempar error langsung.

Eksplisit Wait untuk Kasus Khusus

waitForResponse

Saat kalian butuh menunggu response dari request tertentu, pasang listener sebelum memicu aksi:

JSMenunggu response API
import { test, expect } from '@playwright/test';
 
test('menunggu response login', async ({ page }) => {
  const responsePromise = page.waitForResponse(
    (response) => response.url().includes('/api/login') &&
      response.status() === 200
  );
  await page.getByRole('button', { name: 'Masuk' }).click();
  const response = await responsePromise;
  expect(response.ok()).toBeTruthy();
});

page.waitForResponse() mengembalikan promise yang selesai saat response yang cocok tiba. Pola set listener dulu, baru aksi ini menghindari race condition klasik.

waitForLoadState

Untuk menunggu tahap loading halaman:

JSMenunggu load state
await page.goto('/produk');
await page.waitForLoadState('networkidle');
await page.waitForLoadState('domcontentloaded');

Perlu diingat: networkidle dianggap tidak stabil untuk aplikasi yang terus menerus melakukan polling, karena network-nya tidak pernah benar-benar idle.

Menangani Konten Dinamis

Antipattern sleep dan Solusinya

page.waitForTimeout() adalah jalur terakhir yang sebaiknya dihindari:

JSHindari waitForTimeout
await page.waitForTimeout(3000);

Alih-alih menebak waktu, tunggu kondisi yang menandakan konten muncul:

JSTunggu kondisi, bukan waktu
await expect(page.getByText('Pembayaran berhasil')).toBeVisible();
await expect(page.locator('.spinner')).toHaveCount(0);

Menunggu elemen hasil — atau elemen loading yang hilang — jauh lebih deterministik daripada menebak durasi. Jika satu kondisi saja bisa dipantau, selalu pilih itu.

waitForSelector sebagai Alternatif

Untuk kasus di luar assertion, waitForSelector masih bisa dipakai:

JSwaitForSelector
await page.waitForSelector('#data-produk', { state: 'visible' });

page.waitForSelector('#data-produk', { state: 'visible' }) menunggu elemen dengan state tertentu. Dalam banyak kasus, assertion berbasis locator lebih disarankan karena sekaligus memverifikasi — gunakan waitForSelector untuk logika non-assertion.

Stabilitas Test untuk SPA dan Real-time Apps

Masalah Khas Aplikasi Modern

Aplikasi SPA (Single Page Application) dan aplikasi real-time — chat, dashboard live, notifikasi push — memicu masalah unik: DOM berubah terus-menerus, jaringan tidak pernah idle, dan konten muncul asinkron tanpa reload halaman. Test yang memakai sleep atau mengandalkan load event akan mudah patah.

Pola yang Terbukti Stabil

Gunakan pola berikut untuk aplikasi dinamis:

  1. Tunggu elemen hasil, bukan elemen perantara. Misalnya tunggu baris tabel muncul setelah data dimuat.
  2. Manfaatkan waitForResponse untuk operasi yang mengirim request yang jelas.
  3. Hindari networkidle pada aplikasi polling; lebih baik tunggu kondisi UI.
  4. Set timeout assertion lebih besar hanya untuk titik sinkronisasi yang memang lambat.
Cek durasi dan stabilitas suite
npx playwright test --reporter=list

npx playwright test --reporter=list menampilkan durasi setiap test secara berurutan. Test yang sering mengalami timeout dekat batas adalah kandidat untuk investigasi sinkronisasi lebih lanjut.

Penutup

Episode 5 menjelaskan mengapa Playwright jarang kalah melawan timing: auto-waiting default memastikan elemen actionable sebelum aksi, assertion bersifat retry-able, dan waitForResponse serta waitForLoadState memberi kendali eksplisit saat dibutuhkan. Untuk konten dinamis dan aplikasi real-time, kuncinya adalah menunggu kondisi, bukan menebak waktu.

Inti yang harus dibawa pulang:

  • Auto-waiting menunggu elemen attached, visible, enabled, dan stable.
  • Assertion Playwright menunggu kondisi sampai timeout, bukan gagal instan.
  • Pasang waitForResponse sebelum memicu aksi untuk menghindari race condition.
  • Gantikan waitForTimeout dengan menunggu elemen hasil atau elemen loading hilang.
  • Hindari networkidle pada aplikasi yang terus menerus polling.

Di episode 6 selanjutnya kita akan membahas page object model dan test structure — mengorganisasi test dengan pola Page Object, membuat reusable page classes dan helper methods, menangani multi-page flows dan shared fixtures, serta menjaga maintainability dan readability test suite.