Gate yang Dites dari Luar: Submit Tanpa Pilar Nggak Sampai Server
Nulis test e2e yang assertion-nya bukan isi halaman, tapi jumlah request yang keluar: form pendaftaran tanpa pilar harus diblokir di klien. Plus satu edge tan
Ringkasan
Form daftar layanan wajib pilih pilar, kalau kosong harus keblok di browser bukan server, jadi test Playwright ngecek error muncul dan request gak kekirim sama sekali. Agak ribet karena harus login dev dulu, beresin wizard, isi semua field kecuali pilar baru submit. Sekalian ada fix filter tanggal biar data hari ini tetap muncul pas pilih rentang hari ini.
Assertion-nya Bukan Isi Halaman
Test e2e-nya selesai nge-render form, semua field udah keisi rapi, dan yang saya cek bukan teks sukses di layar. Yang saya cek: array submissions yang isinya harus nol. Kalau ada satu saja POST ke endpoint pendaftaran yang lolos, test itu gagal. Persisnya di baris expect(submissions).toHaveLength(0).
Konteksnya: acceptance criteria Slice A bilang form pendaftaran layanan wajib punya pilar layanan, dan submit tanpa pilar harus diblokir di klien. Bukan diblokir di server terus dikasih pesan error. Diblokir lebih dulu di browser, inline error tampil, dan request nggak pernah dikirim. Untuk AC kayak gini, ngecek isi DOM doang nggak cukup, karena yang divalidasi adalah sisi jaringan.
Playwright bikin pola ini gampang. Test e2e itu pada dasarnya runner, assertions, isolasi, dan paralelisasi dalam satu paket [1], dan di sini yang kepakai justru bagian yang jarang dipakai orang: page.route("**/layanan/registrations", ...) buat mencegat request dan mencatat URL-nya, sebelum diteruskan. Rutenya jadi saksi.
Ada detail kecil yang nggak kepikiran sebelum nulis test-nya. Sesi login buat test ini datangnya dari dev-login yang cuma aktif di APP_ENV=development; di lingkungan lain test langsung skip. Dan karena profil akun dev belum lengkap, wizard data diri malah muncul lebih dulu. Test-nya jadi harus siap ngisi wizard sebelum nyampe ke form pendaftaran. Test yang di dokumen kelihatan satu langkah, ternyata tiga.
Fill Semua Dulu, Biar yang Hilang Cuma Satu
Supaya assertion-nya bener-bener menguji gate pilar, semua field lain harus keisi dulu: bidang, kontak (yang di mode wizard kadang nggak dirender karena udah keisi dari profil, jadi test-nya ngecek dulu sebelum isi), alamat, deskripsi. Kecuali pilar. Satu-satunya yang sengaja hilang.
Klik submit, lalu dua hal dicek berurutan: inline error di field bidang harus tampil, dan submissions harus tetap nol. Kalau cuma ngecek error-nya, ada satu celah: form bisa aja tetap mengirim request sambil manis-manis nampilin pesan error. Ini bukan skenario paranoid — form yang bilang "validasi gagal" tapi tetap nge-POST itu bug yang nyata dan sering kelewat.
Edge Tanggal yang Nit Review
Di commit yang sama ada satu revisi kecil berstatus nit review: TestListFilterTanggal ditambah edge case yang mengunci perilaku filter tanggal. Baris yang dibuat hari ini harus tetap muncul pas rentang from dan to-nya sama-sama hari ini. Kalau batas atas ditulis operator kurang-dari murni terhadap tanggal, baris ber-tanggal hari ini keluar dari hasil; padahal user yang milih rentang "hari ini sampai hari ini" jelas berharap datanya ikut.
Batas atasnya emang nggak ditulis pakai kurang-dari-sama-dengan mentah-mentah. Kalau kolomnya bertipe datetime, <= '2026-10-03' bikin baris siang dan malam hari itu hilang dari hasil karena jamnya dianggap 00:00:00. Pola yang dipakai: batas atas < DATE_ADD(?, INTERVAL 1 DAY) — hari to dihitung penuh, dari tengah malam sampai sebelum tengah malam besok. DATE_ADD() sendiri fungsinya menambah nilai waktu (interval) ke sebuah tanggal [3], dan operator perbandingan MySQL tetap mengembalikan TRUE/FALSE/NULL biasa [2], jadi boundary-nya behaviour yang bisa dites. Commit ini tugasnya menguncinya di test, biar nggak ada yang ubah balik diam-diam.
Pola ini sama dengan yang saya pakai di artikel filter tanggal sebelumnya: batas atas eksklusif menuju hari+1. Pedagang rentang tanggal selalu kena di boundary, dan sekarang edge-nya terkunci di test.
Angka di INDEX.md Ikut Naik
Yang bikin commit ini menarik bukan salah satu test-nya, tapi apa yang ikut berubah di sekitarnya. Baris spec layanan di tabel indeks unit testing di-update: dari cuma "login gate" jadi "submit tanpa pilar diblokir klien (error inline, request tak terkirim)". Test yang dijalankan CI jadi kontrak tertulis, dan run_page.sh layanan jadi panggilan yang bisa diulang siapa saja.
Saya dulu sempat menganggap test semacam ini overkill. Nge-route, nge-hitung request, buat ngeyakinin form nggak kirim sesuatu yang kelihatan nggak dikirim. Tapi kalau kamu pernah nyeret bug "form valid kok tapi datanya masuk dua kali" sampai tengah malam, kamu tahu celahnya di mana: di antara yang kelihatan diblokir dan yang buktinya nggak dikirim. Test ini isi celah itu. Dan dia nggak perlu akses server buat ngebuktiin.
Sumber