Belajar Cypress - Automatic Waiting & Retries
Episode 5 of 23

Belajar Cypress - Automatic Waiting & Retries

Episode ini membedah automatic waiting Cypress: cara menunggu elemen tanpa sleep manual, retry-ability pada commands dan assertions, mengatasi timing issues, serta best practices untuk test yang andal dan tidak flaky.

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

Pendahuluan

Salah satu alasan utama orang pindah dari Selenium ke Cypress adalah: tidak perlu lagi menulis sleep acak di mana-mana. Episode 5 menjelaskan mengapa. Kalian akan memahami automatic waiting, retry-ability pada commands dan assertions, serta cara menghindari pola yang justru membuat test lambat dan flaky.

Pemahaman di episode ini adalah pembeda antara test yang hidup di tim selamanya dan test yang dihapus karena terlalu sering gagal.

Konsep Automatic Waiting

Cypress tidak menjalankan perintah secara membuta. Saat sebuah perintah tidak bisa langsung berhasil — misalnya elemen belum muncul karena fetch masih berjalan — Cypress menunggu dan mencoba lagi sampai berhasil atau waktu habis.

JSMenunggu elemen tanpa sleep
cy.visit("/dashboard");
 
cy.get("[data-cy=grafik]").should("be.visible");
cy.get("[data-cy=loading-spinner]").should("not.exist");

cy.get("[data-cy=grafik]") akan menunggu sampai elemen muncul di DOM, sementara .should("not.exist") menunggu sampai spinner benar-benar hilang. Tidak ada cy.wait(3000) — Cypress tahu kapan keadaan sudah terpenuhi.

Batas Waktu Tunggu

Automatic waiting tidak berjalan tanpa batas. Batasnya diatur defaultCommandTimeout, secara bawaan 4000 milidetik. Kalian bisa menyesuaikan per perintah:

JSMenyesuaikan timeout per perintah
cy.get("[data-cy=hasil-analisis]", { timeout: 15000 }).should("be.visible");

{ timeout: 15000 } memperpanjang tunggu untuk perintah ini saja menjadi 15 detik — berguna untuk proses yang memang lambat seperti komputasi atau loading besar.

Mengatasi Timing Issues Tanpa Explicit Waits

Pola klasik yang menimbulkan flakiness adalah menebak waktu:

JSPola yang harus dihindari
cy.wait(5000);
cy.get("[data-cy=hasil]").should("be.visible");

cy.wait(5000) menunggu angka tebakan. Di mesin cepat cukup, di mesin lambat tidak. Ganti pola tersebut dengan assertion yang menunggu sampai kondisi terpenuhi:

JSPola yang benar
cy.get("[data-cy=hasil]").should("be.visible");

Untuk loading asinkron yang jelas sumbernya, tunggu event jaringan yang sudah ditangkap cy.intercept() — bukan menebak waktu. Kita akan membahas ini mendalam di episode 12.

Jangan Menunggu Elemen yang Bisa Menghilang

Hati-hati dengan elemen yang muncul lalu hilang dengan cepat. Menunggu sampai ada lalu berharap masih ada di aksi berikutnya bisa rawan. Lebih aman menunggu kondisi akhir, misalnya konten hasil sudah terlihat, daripada elemen perantara.

Retry-Ability pada Commands dan Assertions

Perintah yang Bisa Di-retry

Tidak semua perintah di-retry. Yang bisa: cy.get, cy.contains, cy.find, cy.should, dan assertion. Yang tidak di-retry: cy.visit, cy.request, cy.then, dan action seperti cy.click — action hanya dijalankan sekali terhadap elemen yang sudah ditemukan.

JSRetry pada assertion
cy.get("[data-cy=judul]").should("have.text", "Selamat datang");
 
cy.wrap([1, 2, 3]).should("have.length", 3);

.should("have.text", "Selamat datang") di-retry: Cypress membaca ulang teks elemen sampai cocok atau timeout. Begitu pula cy.wrap(...).should(...) — assertion di dalam should dijalankan ulang secara otomatis.

Callback di dalam should

Untuk logika yang lebih kompleks, pakai callback. Penting: callback harus memakai expect, bukan assert, agar retry bekerja:

JSAssertion dengan callback
cy.get("[data-cy=daftar-produk]").should(($items) => {
  expect($items).to.have.length(8);
});

expect($items).to.have.length(8) di dalam callback memungkinkan Cypress me-retry seluruh callback sampai assertion lulus. Inilah cara yang benar untuk memvalidasi beberapa elemen sekaligus tanpa menebak waktu render.

Best Practices untuk Reliable Tests

Mulai dari Apa yang Benar-Benar Perlu

Semakin sedikit asumsi timing, semakin stabil test. Prioritaskan:

  • Selalu assert hasil akhir yang terlihat pengguna, bukan elemen internal.
  • Gunakan cy.intercept() dan cy.wait("@alias") untuk alur jaringan.
  • Set defaultCommandTimeout sesuai kebutuhan aplikasi, bukan memaksakan timeout pendek.
  • Hindari cy.wait(ms) dengan angka tebakan.

Contoh Test yang Stabil

JSPola test stabil
it("menampilkan hasil pencarian", () => {
  cy.intercept("GET", "/api/search*").as("search");
 
  cy.get("[data-cy=query]").type("buku");
  cy.get("[data-cy=cari]").click();
 
  cy.wait("@search");
  cy.get("[data-cy=hasil]").should("have.length.gt", 0);
});

Di sini cy.wait("@search") menunggu respons API selesai, lalu assertion memastikan hasil benar-benar dirender. Tidak ada satupun sleep acak — setiap langkah menunggu sampai kondisinya nyata.

Penutup

Episode 5 mengubah cara kalian berpikir tentang timing: Cypress menunggu kondisi, bukan menebak waktu. Automatic waiting bekerja lewat retry-ability — perintah pencarian elemen dan assertion di-retry sampai berhasil atau timeout. Timing issues diatasi dengan menunggu kondisi akhir, bukan cy.wait(ms) acak.

Inti yang harus dibawa pulang:

  • Automatic waiting menghilangkan kebutuhan sleep manual.
  • defaultCommandTimeout (bawaan 4000 ms) membatasi tunggu; bisa di-override per perintah.
  • Hanya perintah pencarian dan assertion yang di-retry, bukan action atau cy.visit.
  • cy.wait(ms) dengan angka tebakan adalah sumber flakiness — hindari.
  • Tunggu event jaringan via cy.intercept() untuk alur asinkron.

Di episode 6 selanjutnya kita akan membahas fixtures dan test data — mengelola data test dengan fixtures, memuat JSON lewat cy.fixture(), data-driven testing dengan dataset eksternal, serta mocking data dan request stubs. Test kalian akan mulai memisahkan data dari logika.

Belajar Cypress - Automatic Waiting & Retries | Belajar Cypress