Belajar Cypress - Advanced Interactions
Episode 8 of 23

Belajar Cypress - Advanced Interactions

Episode ini membahas interaksi lanjutan: handling iframes, popups, dan multiple windows, drag and drop, uploads, keyboard events, testing single-page apps dengan konten dinamis, serta network stubbing dengan cy.intercept.

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

Pendahuluan

Test mulai diuji saat aplikasi punya hal-hal rumit: iframe dari pihak ketiga, popup, window baru, drag and drop, upload file, dan konten yang berubah dinamis. Episode 8 memandu kalian menghadapi skenario itu satu per satu dengan teknik yang benar.

Ini adalah episode paling berbau "pekerjaan nyata" sejauh ini. Setelah menguasainya, jarang ada interaksi web yang tidak bisa kalian otomasi.

Handling Iframes, Popups, dan Multiple Windows

Bekerja dengan Iframe

Konten di dalam iframe terpisah dari DOM utama. Untuk iframe dari domain yang sama, akses langsung lewat cy.iframe() dari plugin cypress-iframe, atau seleksi manual dengan cy.get("iframe"). Untuk iframe lintas domain, gunakan cy.origin() yang tersedia sejak Cypress 12:

JSMemakai cy.origin untuk domain berbeda
cy.origin("https://auth.example.com", () => {
  cy.get("[data-cy=login-oauth]").click();
});

cy.origin("https://auth.example.com", () => { ... }) memungkinkan Cypress menjalankan perintah di dalam konteks domain lain — mengatasi batasan "satu domain per test" yang lama. Perhatikan bahwa argumen dan variabel yang dipakai dari luar harus dikirim eksplisit lewat parameter fungsi.

Popups dan Multiple Windows

Popup dan window baru adalah tantangan klasik. Kunci utamanya: jangan bergantung pada tab browser baru. Sebagai gantinya, tangkap window.open dan periksa URL-nya:

JSMencegat window.open
cy.window().then((win) => {
  cy.stub(win, "open").as("openWindow");
});
 
cy.get("[data-cy=link-dokumentasi]").click();
cy.get("@openWindow").should("be.calledWith", "/docs");

cy.stub(win, "open").as("openWindow") menggantikan fungsi window.open dengan stub yang bisa di-assert. Alih-alih pindah ke tab baru yang sulit dikontrol, test memverifikasi bahwa aplikasi memang memanggil open dengan URL yang benar.

Drag and Drop, Uploads, dan Keyboard Events

Drag and Drop

Drag and drop di browser menembakkan event sequence. Cara paling andal memakai .trigger() untuk meniru urutan event:

JSSimulasi drag and drop
cy.get("[data-cy=item]").trigger("dragstart");
cy.get("[data-cy=dropzone]").trigger("drop");

cy.trigger("dragstart") dan cy.trigger("drop") membangkitkan event DOM secara langsung. Untuk library drag-and-drop tertentu yang butuh koordinat, kombinasikan dengan .trigger("dragstart", { clientX: 0, clientY: 0 }) lalu .trigger("drop", { clientX: 200, clientY: 200 }).

Upload File

cy.selectFile memungkinkan upload file nyata tanpa plugin tambahan:

JSUpload file
cy.get("[data-cy=input-avatar]").selectFile("cypress/fixtures/avatar.png");
cy.contains("Avatar terunggah").should("be.visible");

cy.selectFile("cypress/fixtures/avatar.png") menempelkan file ke input upload dan memicu event perubahan. Siapkan file contoh di folder fixtures agar test tidak bergantung pada file pengembang.

Keyboard Events

Untuk aksi papan ketik seperti shortcut:

JSShortcut keyboard
cy.get("[data-cy=editor]").type("{ctrl}s");
cy.contains("Tersimpan").should("be.visible");

cy.type("{ctrl}s") menekan kombinasi tombol. Sintaks seperti {enter}, {esc}, {backspace}, dan {shift}tab tersedia untuk kebutuhan lain.

Testing Single-Page Apps dan Dynamic Content

SPA (single-page app) merender konten secara dinamis tanpa reload halaman penuh. Ini menguntungkan: state halaman relatif stabil. Yang perlu diperhatikan adalah elemen yang muncul bergantian — spinner, skeleton, dan konten yang diganti.

JSMenunggu konten dinamis SPA
cy.intercept("GET", "/api/produk").as("produk");
 
cy.get("[data-cy=tab-terbaru]").click();
cy.wait("@produk");
cy.get("[data-cy=list-produk]").children().should("have.length.gt", 0);

Di sini cy.wait("@produk") menunggu data terbaru selesai diambil sebelum memeriksa daftar. Menunggu event jaringan adalah cara paling deterministik untuk konten dinamis — jauh lebih baik daripada menebak durasi animasi.

Network Stubbing dengan cy.intercept

cy.intercept adalah alat paling kuat untuk konten dinamis: kalian bisa mengontrol respons jaringan sepenuhnya:

JSStub dan kontrol respons
cy.intercept("GET", "/api/produk/*", (req) => {
  req.reply({ statusCode: 500, body: { error: "server down" } });
}).as("produkGagal");
 
cy.get("[data-cy=muat-produk]").click();
cy.contains("Gagal memuat produk").should("be.visible");

req.reply({ statusCode: 500, body: ... }) memaksa aplikasi menerima kegagalan server. Skenario seperti retry dan fallback flow bisa diuji tanpa menurunkan server sungguhan — kita akan membedah ini lebih dalam di episode 12.

Tip

Atur cy.intercept di beforeEach agar seluruh test di satu describe konsisten. Pastikan pola URL-nya spesifik — * yang terlalu luas bisa menangkap request yang tidak diinginkan dan membuat test saling memengaruhi.

Penutup

Episode 8 memperluas jangkauan interaksi: iframe lintas domain lewat cy.origin(), popup dan window baru dengan men-stub window.open, drag and drop lewat trigger, upload dengan cy.selectFile, keyboard events dengan cy.type, konten dinamis SPA dengan cy.wait("@alias"), dan kontrol penuh jaringan lewat cy.intercept.

Inti yang harus dibawa pulang:

  • cy.origin() membuka kunci pengujian domain berbeda.
  • Stub window.open agar popup bisa di-assert tanpa berpindah tab.
  • cy.selectFile menangani upload file nyata.
  • cy.type("{ctrl}s") meniru shortcut keyboard.
  • Konten dinamis ditunggu lewat event jaringan, bukan menebak waktu.

Di episode 9 selanjutnya kita akan membahas component testing — menguji komponen React, Vue, dan Angular secara terisolasi, menyiapkan environment component, assertion berbasis perilaku komponen, serta integrasi dengan Storybook. Test kalian mulai turun satu level dari halaman penuh ke komponen.

Belajar Cypress - Advanced Interactions | Belajar Cypress