jsdom membuktikan struktur kartu produk Budi benar, tetapi ada yang belum terjawab: apakah halaman sungguhan benar-benar menampilkannya? Apakah klik tombol “Bayar” membawa pembeli ke halaman yang tepat? Pertanyaan seperti ini menyentuh peramban sebagai kesatuan — HTML, CSS, jaringan, skrip, dan interaksi manusia sekaligus — dan tidak bisa dijawab oleh tiruan DOM di dalam Node.
Lapisan E2E (end-to-end) menjawabnya dengan otomasi browser: program yang menjalankan browser sungguhan, membuka aplikasi, berperilaku seperti pengguna — mengetik, mengklik, menggulir — lalu mengklaim apa yang tampak. Framework yang paling banyak dipakai di ekosistem JavaScript untuk peran ini adalah Playwright, dan chapter ini memperkenalkan konsep-konsepnya sebagai peta untuk saat kita benar-benar membutuhkannya.
Playwright dalam Sekilas Pandang #
Playwright adalah framework pengujian E2E yang dikembangkan Microsoft, dipakai dari Node.js. Tiga karakteristiknya menentukan cara kerjanya:
- Browser sungguhan. Playwright mengendalikan Chromium, Firefox, dan WebKit — mesin yang sama dengan Chrome, Firefox, dan Safari. Uji berjalan di aplikasi yang benar-benar menghitung layout, memuat aset, dan mengeksekusi skrip halaman.
- Headless atau headed. Secara bawaan browser dijalankan headless (tanpa jendela tampilan) agar cepat dan cocok untuk server CI; opsi headed membuka jendela browser sungguhan saat kita ingin melihat ujinya berjalan.
- Runner dan asersi satu paket. Berbeda dari
node:testyang berpasangan dengannode:assert, Playwright membawa test runner sendiri beserta asersi yang menunggu — lebih lanjut di bawah.
Tiga Konsep Inti: browser, page, locator #
Hampir semua skrip Playwright dibangun dari tiga konsep. browser adalah instans aplikasi browser; page adalah satu tab di dalamnya; dan locator adalah resep pencari elemen — bukan elemen itu sendiri. Locator dievaluasi setiap kali dipakai, sehingga bila halaman berubah di tengah uji, pencarian dilakukan ulang pada kondisi terbaru. Ilustrasi berikut merangkai ketiganya untuk skenario pencarian produk:
import { test, expect } from '@playwright/test';
test('pencarian produk menampilkan hasil', async ({ page }) => {
await page.goto('https://toko.example.com');
const kolomCari = page.getByRole('textbox', { name: 'Cari produk' });
await kolomCari.fill('algoritma');
await page.getByRole('button', { name: 'Cari' }).click();
const kartu = page.locator('.kartu-produk');
await expect(kartu).toHaveCount(3);
await expect(kartu.first()).toContainText('Buku Algoritma');
});Mari kita telaah pola pentingnya:
import { test, expect } from '@playwright/test':testdi sini milik runner Playwright — bukannode:test— danexpectadalah asersinya. Keduanya datang dari satu paket yang juga menyediakan perintah menjalankannya.async ({ page }) => {...}: parameter berupa objek fixture. Playwright menyiapkanpagebaru untuk setiap uji — tab segar di browser terpisah — lalu membereskannya setelah uji selesai. Kita tidak pernah membuat dan menutup browser secara manual di tingkat ini.page.getByRole('textbox', { name: 'Cari produk' }): locator berbasis role aksesibilitas. Pencarian lewat peran dan nama yang dapat diakses sekaligus menegaskan bahwa halaman bisa dipakai pembaca layar — praktik yang sangat dianjurkan dibanding mengandalkan class CSS yang sering berubah.await kolomCari.fill('algoritma'): setiap aksi Playwright bersifat auto-waiting: fill menunggu elemen muncul, aktif, dan bisa diisi sebelum mengetik. Kita tidak menulis penungguan manual seperti pada banyak framework lama.await expect(kartu).toHaveCount(3): asersi Playwright juga menunggu — ia memeriksa ulang kondisi berkali-kali sampai benar atau habis batas waktu. Perilaku ini wajar untuk E2E karena hasil pencarian butuh waktu bervariasi untuk muncul; asersinode:assertyang memeriksa satu kali begitu saja akan sering gagal keliru.
Kombinasi fixture page, locator, dan asersi yang menunggu inilah yang membuat skrip E2E terbaca seperti cerita pengguna: buka, isi, klik, lalu pastikan hasilnya.
Menata Berkas dan Perintah Utama #
Dalam proyek nyata, Playwright dipasang sebagai dependensi pengembangan, dan berkas ujinya lazim dinamai *.spec.js di dalam folder tests/. Perintah-perintah yang dipakai sehari-hari:
npm install --save-dev @playwright/test # pasang framework
npx playwright install # unduh binary browser
npx playwright test # jalankan seluruh uji headless
npx playwright test --headed # jalankan dengan jendela terlihat
npx playwright test uji-cari.spec.js # jalankan satu berkas
npx playwright show-report # buka laporan hasil ujiRunner Playwright menjalankan berkas-berkas uji secara paralel di beberapa worker, sehingga rangkaian E2E yang panjang pun selesai dalam waktu wajar. Laporan HTML bawaan menampilkan setiap langkah uji beserta tangkapan layar saat kegagalan — bantuan yang sangat berharga karena kegagalan E2E jarang sesederhana 111000 !== 110000.
Kapan Uji E2E Ditulis #
Uji E2E adalah lapisan paling mahal di piramide: setiap uji menjalankan browser, memuat halaman, dan bisa gagal karena alasan yang berada jauh dari logika yang sedang diuji. Karena itu pakai secara hemat dan terarah:
- Jalur utama (smoke test). Satu-dua skenario yang harus selalu benar — cari produk, tambahkan ke keranjang, selesaikan pembayaran. Bila jalur ini putus, bisnis ikut berhenti.
- Perilaku lintas halaman. Hal-hal yang mustahil diuji dengan unit maupun jsdom: redirect, form multi-langkah, data yang mengalir antar halaman.
- Perubahan besar sebelum rilis. Uji E2E yang stabil adalah jaring pengaman terakhir.
Sebaliknya, jangan gunakan E2E untuk menguji rumus diskon atau format rupiah — pekerjaan itu sudah tuntas di uji unit yang berjalan ribuan kali lebih cepat. Selector yang rapuh juga wajib dijaga: memakai getByRole dan atribut data khusus uji membuat skrip tidak mudah patah setiap desain berubah.
Dengan ketiga lapisan piramide lengkap di peta — unit, integration, E2E — satu pertanyaan praktis tersisa untuk chapter berikutnya: seberapa banyak kode kita yang sebenarnya sudah disentuh uji?