Belajar Cypress - Custom Commands & Utilities
Episode 7 of 23

Belajar Cypress - Custom Commands & Utilities

Episode ini membahas perluasan Cypress: menambahkan custom commands di commands.js dengan Cypress.Commands.add, membuat helper reusable untuk alur test, mengatur baseUrl dan environment vars, serta mengorganisasi test utilities.

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

Pendahuluan

Semakin banyak test yang ditulis, semakin banyak pola berulang: login, menyiapkan data, membuka halaman tertentu. Episode 7 mengajarkan cara mengemas pola itu menjadi custom commands dan utilities agar test tetap singkat, konsisten, dan mudah dirawat.

Custom commands juga memungkinkan abstraksi teknis: test membaca cy.login("admin"), sedangkan detail mekanisme login tersembunyi di satu tempat.

Menambahkan Custom Commands di commands.js

Custom command didefinisikan lewat Cypress.Commands.add. Lokasinya di cypress/support/commands.js:

JScypress/support/commands.js
Cypress.Commands.add("login", (email, password) => {
  cy.visit("/login");
  cy.get("[data-cy=email]").type(email);
  cy.get("[data-cy=password]").type(password);
  cy.get("[data-cy=submit]").click();
  cy.url().should("include", "/dashboard");
});

Cypress.Commands.add("login", (email, password) => { ... }) mendaftarkan command baru bernama login yang menerima dua argumen. Semua test dalam project kini bisa memanggil cy.login(...).

Agar command dimuat, pastikan commands.js di-import oleh file support. Secara bawaan cypress/support/e2e.js memuatnya:

JScypress/support/e2e.js
import "./commands";

import "./commands" memastikan seluruh custom commands tersedia sebelum spec dijalankan.

Pemakaian di Test

JSMemakai custom command
it("menambahkan produk ke keranjang", () => {
  cy.login("user@example.com", "rahasia123");
  cy.get("[data-cy=produk-pertama]").click();
  cy.contains("Ditambahkan ke keranjang").should("be.visible");
});

cy.login("user@example.com", "rahasia123") menggantikan lima baris interaksi login dengan satu baris. Setiap test yang butuh login kini konsisten — dan jika alur login berubah, kalian cukup mengubah satu definisi.

Reusable Helpers untuk Test Flows

Selain command, kalian bisa memakai fungsi JavaScript biasa sebagai helper. Simpan di cypress/support/utils.js:

JScypress/support/utils.js
export const formatHarga = (angka) =>
  `Rp${angka.toLocaleString("id-ID")}`;
 
export const buatEmailAcak = () =>
  `user-${Date.now()}@example.com`;

Lalu import di spec file:

JSMemakai helper
import { formatHarga, buatEmailAcak } from "../support/utils";
 
it("menampilkan harga terformat", () => {
  cy.contains(formatHarga(45000)).should("be.visible");
});
 
it("mendaftar dengan email acak", () => {
  cy.get("[data-cy=email]").type(buatEmailAcak());
});

formatHarga(45000) dan buatEmailAcak() adalah pure function — mudah diuji sendiri dan bebas dari state browser. Ini tempat yang tepat untuk logika murni yang tidak butuh akses Cypress.

Mengatur baseUrl dan Environment Vars

baseUrl di Konfigurasi

baseUrl sudah kita set di episode 3. Nilainya membuat cy.visit("/") ringkas dan memudahkan perpindahan environment:

JSKonfigurasi baseUrl
module.exports = defineConfig({
  e2e: {
    baseUrl: "http://localhost:3000",
  },
});

Environment Variables

Untuk nilai yang berubah antar environment, gunakan env vars. Tetapkan di konfigurasi atau lewat CLI:

Env var lewat CLI
npx cypress run --env apiBaseUrl=http://localhost:8080

Akses dari test dengan Cypress.env:

JSMembaca env var
const api = Cypress.env("apiBaseUrl");
 
cy.intercept("GET", `${api}/produk`).as("produk");

Cypress.env("apiBaseUrl") membaca nilai yang dikirim lewat --env. Untuk nilai rahasia, jangan tulis langsung di config — kita akan membahas pengelolaan credential aman di episode 13.

Organizing Test Utilities

Struktur Support yang Rapi

Seiring tumbuhnya project, pisahkan tanggung jawab:

Struktur support terorganisir
cypress/support/
  commands.js
  commands/
    auth.js
    checkout.js
  utils.js
  e2e.js
  • commands.js: mengimpor dan merapikan command bawaan.
  • commands/auth.js: command terkait login dan sesi.
  • commands/checkout.js: command terkait alur belanja.
  • utils.js: pure function tanpa akses Cypress.
JScommands.js mengimpor modul
import "./commands/auth";
import "./commands/checkout";

import "./commands/auth" memuat command autentikasi. Dengan pola ini, tim bisa menambah command per domain tanpa membuat satu file raksasa.

Aturan untuk Custom Commands

Beberapa pedoman menjaga command tetap sehat:

  • Beri nama yang jelas tentang apa yang dilakukan, bukan bagaimana.
  • Sertakan assertion di dalam command agar kegagalan terdeteksi cepat.
  • Jangan menyembunyikan terlalu banyak detail — command yang kebanyakan logika sulit di-debug.
  • Gunakan helper murni untuk logika yang tidak butuh browser.

Penutup

Episode 7 memperluas bahasa Cypress: custom commands dengan Cypress.Commands.add di commands.js, helper murni untuk logika yang bisa dipakai ulang, pengelolaan baseUrl dan environment vars lewat --env dan Cypress.env, serta organisasi support yang terbagi per domain.

Inti yang harus dibawa pulang:

  • Cypress.Commands.add("nama", fn) mendaftarkan command yang bisa dipanggil cy.nama().
  • cypress/support/e2e.js memuat commands.js agar command tersedia global.
  • Helper murni di utils.js untuk logika non-browser seperti format harga.
  • Env vars dikirim lewat --env dan dibaca dengan Cypress.env.
  • Organisasi support per domain menjaga file tetap ramping.

Di episode 8 selanjutnya kita akan membahas advanced interactions — handling iframes, popups, dan multiple windows, drag and drop, uploads, keyboard events, testing single-page apps, serta network stubbing dengan cy.intercept(). Interaksi test kalian akan menyentuh skenario nyata yang rumit.

Belajar Cypress - Custom Commands & Utilities | Belajar Cypress