Episode ini membahas strategi locator berbasis text, role, CSS, dan XPath, interaksi dasar seperti click, fill, select, dan hover, submission formulir dan navigasi, serta cara auto-waiting dan retry-ability bekerja di balik setiap aksi.

Arsitektur sudah jelas, environment sudah siap. Sekarang tibalah skill paling inti dalam penulisan test: mengambil elemen di halaman dan berinteraksi dengannya. Episode 4 ini adalah tempat kalian belajar menulis aksi yang benar-benar dipakai setiap hari — klik, isi input, pilih opsi, hover, dan navigasi.
Kunci dari bagian ini adalah memilih locator yang tepat. Locator yang baik membuat test tahan lama, mudah dibaca, dan jarang patah saat aplikasi berubah. Locator yang buruk — seperti selector CSS yang bergantung pada struktur mendalam — menjadi sumber utama flaky tests dan maintenance nightmare. Mari kita pelajari caranya dari fondasi.
Cara paling manusiawi adalah mencari elemen berdasarkan teksnya:
await page.getByText('Selamat datang');
await page.getByText('Harga', { exact: true });
await page.getByLabel('Email');page.getByText() mencari elemen yang mengandung teks tertentu. Tambahkan { exact: true } jika kalian ingin pencocokan persis. page.getByLabel() sangat berguna untuk input form yang terasosiasi dengan label.
Role adalah pendekatan yang paling disarankan karena merefleksikan cara pengguna dan teknologi assistive memandang halaman:
await page.getByRole('button', { name: 'Masuk' });
await page.getByRole('link', { name: 'Daftar' });
await page.getByRole('heading', { level: 1 });
await page.getByRole('textbox', { name: 'Nama Lengkap' });page.getByRole('button', { name: 'Masuk' }) mencari tombol yang aksesibel namanya 'Masuk'. Pendekatan role membuat test tahan terhadap perubahan class CSS dan struktur DOM.
Untuk kasus yang tidak terjangkau role, kalian bisa memakai CSS biasa atau XPath:
await page.locator('.kartu-produk');
await page.locator('#harga-total');
await page.locator('xpath=//input[@name="qty"]');CSS selector adalah jalan pintas yang familiar, sementara XPath dipakai saat butuh logika traversal yang kompleks. Utamakan role dan text terlebih dahulu, baru turun ke CSS/XPath sebagai cadangan.
Setelah elemen ditemukan, kalian bisa berinteraksi dengannya:
await page.getByRole('button', { name: 'Beli' }).click();
await page.getByLabel('Email').fill('user@example.com');
await page.getByRole('combobox').selectOption({ label: 'Jabodetabek' });
await page.getByRole('menuitem').hover();click() mengeklik elemen.fill() mengisi input, menghapus nilai lama terlebih dahulu.selectOption() memilih opsi pada elemen select.hover() memindahkan pointer mouse ke atas elemen.Semua aksi di atas menerapkan auto-waiting: Playwright menunggu elemen ada, visible, enabled, dan stable sebelum menjalankan aksi.
Beberapa interaksi spesifik:
await page.getByRole('checkbox').check();
await page.getByLabel('Foto').setInputFiles('foto.jpg');
await page.getByLabel('Password').pressSequentially('rahasia123');setInputFiles() menangani upload file, dan pressSequentially() mengetik karakter satu per satu — berguna untuk menguji autocomplete.
Contoh test yang mengisi formulir login dan menavigasi setelah submit:
import { test, expect } from '@playwright/test';
test('login dan masuk ke dashboard', async ({ page }) => {
await page.goto('/login');
await page.getByLabel('Email').fill('user@example.com');
await page.getByLabel('Password').fill('rahasia123');
await page.getByRole('button', { name: 'Masuk' }).click();
await expect(page).toHaveURL(/dashboard/);
await expect(page.getByRole('heading', { name: 'Dashboard' })).toBeVisible();
});page.goto('/login') memakai baseURL dari konfigurasi, sehingga cukup menulis path relatif. Setelah submit, toHaveURL(/dashboard/) memastikan navigasi terjadi, dan toBeVisible() memastikan konten dashboard tampil.
Selain URL, kalian bisa memeriksa state halaman secara luas:
await expect(page).toHaveTitle(/Dashboard/);
await expect(page).toHaveScreenshot();
await expect(page.locator('.ringkasan')).toBeVisible();toHaveTitle() memeriksa judul dokumen, dan toHaveScreenshot() adalah gerbang menuju visual regression yang akan kita bahas di episode 16.
Setiap aksi Playwright bekerja dengan aturan: cari elemen, tunggu actionable, lakukan aksi, verifikasi. Kalau elemen belum muncul, Playwright menunggu sampai timeout assertion tercapai. Ini disebut retry-ability — action dan assertion mengulang evaluasi sampai sukses atau timeout.
Berbeda dengan Selenium yang sering gagal saat elemen belum ada, Playwright secara bawaan menunggu kondisi yang tepat. Artinya kalian jarang perlu menulis wait manual. Kalau toh butuh kendali waktu yang lebih presisi, itu akan kita bahas khusus di episode 5 tentang waits dan synchronization.
npx playwright test tests/interaksi.spec.tsPerintah npx playwright test tests/interaksi.spec.ts menjalankan file test interaksi. Jika ada test yang gagal, baca pesan timeout — itu adalah petunjuk pertama apakah locator salah atau elemen memang belum muncul.
Episode 4 melengkapi kalian dengan keterampilan inti: memilih locator berbasis text, role, CSS, dan XPath dengan hierarki yang benar, menjalankan interaksi dasar seperti click, fill, select, dan hover, menguji alur formulir dan navigasi, serta memahami auto-waiting dan retry-ability di balik setiap aksi.
Inti yang harus dibawa pulang:
getByRole dan getByLabel sebelum turun ke CSS atau XPath.fill membersihkan input sebelum mengetik, pressSequentially untuk autocomplete.toHaveURL dan toBeVisible untuk memverifikasi hasil aksi.Di episode 5 selanjutnya kita akan membahas waits dan synchronization — pemahaman mendalam auto-waiting default Playwright, eksplisit wait dengan waitForResponse dan waitForLoadState, menangani konten dinamis, serta cara membuat test stabil untuk aplikasi SPA dan real-time.