Playwright Academy
0 dari 17
Fase 2 · Jurus IntiModul 5 dari 17

Actions

Klik, ketik, pilih dropdown, centang, hover, keyboard, upload, serta drag & drop.

Sebelum beraksi, Playwright mengecek elemennya siap: terlihat, tidak bergerak, tidak tertutup, dan bisa diklik. Pengecekan ini disebut actionability checks, dan karena itu test Playwright jarang butuh sleep.

Di dunia QA

Saat testing manual, kamu tidak mengklik tombol yang masih tertutup loading. Kamu menunggu sampai tombolnya muncul, berhenti bergerak, dan bisa ditekan. Actionability checks adalah kebiasaan yang sama, dilakukan Playwright sebelum setiap aksi.

Daftar aksi yang bisa dilakukan

Menampilkan Python. Ganti bahasa di bagian atas untuk melihat TypeScript.Menampilkan TypeScript. Ganti bahasa di bagian atas untuk melihat Python.

Mau apaPythonTypeScript
Klik.click().click()
Klik dua kali.dblclick().dblclick()
Klik kanan.click(button="right").click({ button: 'right' })
Isi kolom (sekaligus).fill("teks").fill('teks')
Ketik huruf demi huruf.press_sequentially("teks").pressSequentially('teks')
Tekan tombol keyboard.press("Enter").press('Enter')
Kosongkan kolom.clear().clear()
Centang / hapus centang.check() / .uncheck().check() / .uncheck()
Centang sesuai nilai.set_checked(True).setChecked(true)
Pilih isi dropdown.select_option("python").selectOption('python')
Arahkan kursor (hover).hover().hover()
Pindahkan fokus.focus().focus()
Unggah file.set_input_files(path).setInputFiles(path)
Seret lalu lepas.drag_to(target).dragTo(target)
Gulir sampai kelihatan.scroll_into_view_if_needed().scrollIntoViewIfNeeded()

Setiap aksi punya latihan tepat setelah penjelasannya. Buka Arena Latihan di tab lain, coba manual dulu, tulis test-nya, lalu buka jawabannya. Semua jawaban lulus test di tiga browser.

Macam-macam klik

tombol = page.get_by_role("button", name="Klik aku")  # simpan locator tombol
tombol.click()  # klik biasa
tombol.click(click_count=3)                       # triple click (misal untuk select-all teks)
page.get_by_role("button", name="Klik dua kali").dblclick()  # klik dua kali
page.get_by_text("Klik kanan di sini").click(button="right")  # klik kanan
tombol.click(modifiers=["Shift"])                 # shift + klik
const tombol = page.getByRole('button', { name: 'Klik aku' }); // simpan locator tombol
await tombol.click(); // klik biasa
await tombol.click({ clickCount: 3 });            // triple click (misal untuk select-all teks)
await page.getByRole('button', { name: 'Klik dua kali' }).dblclick(); // klik dua kali
await page.getByText('Klik kanan di sini').click({ button: 'right' }); // klik kanan
await tombol.click({ modifiers: ['Shift'] });     // shift + klik
Latihan 1

Klik biasa

Di Arena (jurus 1), klik Klik aku tiga kali, lalu pastikan penghitungnya (test id click-count) menjadi 3.

Hasil3

Latihan 2

Klik dua kali

Klik dua kali tombol Klik dua kali di jurus 1, lalu cek teks hasilnya (test id dbl-result).

HasilDouble click terdeteksi!

Latihan 3

Klik kanan

Klik kanan area bergaris di jurus 1, lalu cek teks hasilnya (test id ctx-result).

HasilMenu konteks dibuka

Mengisi formulir

page.get_by_label("Nama lengkap").fill("Rina")  # isi kolom teks sekaligus
page.get_by_label("Catatan").fill("Belajar Playwright itu seru!")  # kolom teks banyak baris
page.get_by_label("Menengah").check()                                  # radio button
page.get_by_label("Bahasa favorit").select_option("python")           # berdasarkan value
page.get_by_label("Bahasa favorit").select_option(label="TypeScript") # berdasarkan teks yang terlihat
page.get_by_label("Browser yang dites").select_option(["Chromium", "WebKit"])  # multi-select
page.get_by_label("Tanggal mulai").fill("2026-10-04")                 # input date: format YYYY-MM-DD
page.get_by_label("Berlangganan newsletter").check()  # centang checkbox
await page.getByLabel('Nama lengkap').fill('Rina'); // isi kolom teks sekaligus
await page.getByLabel('Catatan').fill('Belajar Playwright itu seru!'); // kolom teks banyak baris
await page.getByLabel('Menengah').check();                                    // radio button
await page.getByLabel('Bahasa favorit').selectOption('python');               // berdasarkan value
await page.getByLabel('Bahasa favorit').selectOption({ label: 'TypeScript' }); // berdasarkan teks yang terlihat
await page.getByLabel('Browser yang dites').selectOption(['Chromium', 'WebKit']); // multi-select
await page.getByLabel('Tanggal mulai').fill('2026-10-04');                    // input date: format YYYY-MM-DD
await page.getByLabel('Berlangganan newsletter').check(); // centang checkbox
Arti setiap baris
fill("Rina")
Mengosongkan kolom lalu memasukkan teks sekaligus. Paling sering dipakai.
check()
Mencentang checkbox atau memilih radio button. Kalau sudah tercentang, tidak ada yang berubah.
select_option("python")
Memilih opsi dropdown berdasarkan atribut value-nya.
select_option(label="TypeScript")
Memilih opsi dropdown berdasarkan teks yang terlihat pengguna.
select_option(["Chromium", "WebKit"])
Dropdown yang boleh memilih banyak: kirim daftar opsinya.
fill("2026-10-04") di kolom tanggal | Kolom tanggal selalu diisi format YYYY-MM-DD, apa pun tampilannya di layar.
Arti setiap baris
fill('Rina')
Mengosongkan kolom lalu memasukkan teks sekaligus. Paling sering dipakai.
check()
Mencentang checkbox atau memilih radio button. Kalau sudah tercentang, tidak ada yang berubah.
selectOption('python')
Memilih opsi dropdown berdasarkan atribut value-nya.
selectOption({ label: 'TypeScript' })
Memilih opsi dropdown berdasarkan teks yang terlihat pengguna.
selectOption(['Chromium', 'WebKit'])
Dropdown yang boleh memilih banyak: kirim daftar opsinya.
fill('2026-10-04') di kolom tanggal | Kolom tanggal selalu diisi format YYYY-MM-DD, apa pun tampilannya di layar.

fill memasukkan teks sekaligus, dan ini yang paling sering dipakai. press_sequentially / pressSequentially mengetik huruf demi huruf, untuk kolom yang bereaksi setiap ketikan seperti pencarian dengan saran otomatis. type() sudah tidak dianjurkan.

Latihan 4

Isi lalu kosongkan kolom teks

Isi Nama lengkap dengan Rina, kosongkan lagi, lalu isi Catatan dengan dua baris teks (pakai \n). Cek isinya di setiap langkah.

Hasilisi kolom sesuai di setiap langkah

Latihan 5

Ketik huruf demi huruf

Ketik halo huruf demi huruf di kolom Ketik di sini (jurus 12), lalu cek isinya dan tombol terakhir yang tercatat.

Hasilisi halo, tombol terakhir o

Latihan 6

Radio dan checkbox

Pilih level Menengah, centang lalu lepas Berlangganan newsletter, lalu centang lagi dengan set_checked(True) / setChecked(true).

Hasilstatus centang sesuai di setiap langkah

Latihan 7

Pilih isi dropdown

Pilih TypeScript di Bahasa favorit berdasarkan teks yang terlihat, lalu pilih lagi berdasarkan value java.

Hasilnilai typescript, lalu java

Latihan 8

Pilih banyak sekaligus

Pilih Chromium dan WebKit sekaligus di Browser yang dites.

Hasilnilai terpilih ["Chromium", "WebKit"]

Latihan 9

Isi kolom tanggal

Isi Tanggal mulai dengan 2026-11-03, lalu pastikan nilainya tersimpan dengan format yang sama.

Hasilnilai 2026-11-03

Keyboard

kotak = page.get_by_label("Ketik di sini")  # kolom latihan keyboard
kotak.press("Enter")  # tekan Enter
kotak.press("Control+A")           # kombinasi (di macOS pakai "Meta+A")
kotak.press("Shift+ArrowLeft")  # Shift + panah kiri
page.keyboard.type("halo dunia")   # mengetik ke elemen yang sedang fokus
page.keyboard.press("Tab")         # pindah fokus ke elemen berikutnya
const kotak = page.getByLabel('Ketik di sini'); // kolom latihan keyboard
await kotak.press('Enter'); // tekan Enter
await kotak.press('Control+A');           // kombinasi (di macOS pakai "Meta+A")
await kotak.press('Shift+ArrowLeft'); // Shift + panah kiri
await page.keyboard.type('halo dunia');   // mengetik ke elemen yang sedang fokus
await page.keyboard.press('Tab');         // pindah fokus ke elemen berikutnya

Nama tombol yang sering dipakai: Enter, Tab, Escape, Backspace, Delete, ArrowUp/Down/Left/Right, Home, End, PageDown, F1 sampai F12, Control, Shift, Alt, Meta. Ada juga ControlOrMeta, yang otomatis menjadi Ctrl di Windows/Linux dan Cmd di Mac.

Latihan 10

Tekan tombol dan kombinasi tombol

Di kolom Ketik di sini, tekan Enter, lalu kombinasi Shift dan panah kiri. Cek tombol terakhir setiap kali.

HasilEnter, lalu Shift+ArrowLeft

Hover (arahkan kursor)

Menu atau keterangan yang baru muncul saat kursor berada di atasnya dibuka dengan hover():

page.get_by_role("button", name="Arahkan ke sini").hover()  # arahkan kursor tanpa klik
expect(page.get_by_role("tooltip")).to_be_visible()  # tooltip muncul

page.get_by_role("button", name="Menu Produk").hover()   # menu dropdown muncul
page.get_by_role("link", name="Furnitur").click()  # klik isi menu yang muncul
await page.getByRole('button', { name: 'Arahkan ke sini' }).hover(); // arahkan kursor tanpa klik
await expect(page.getByRole('tooltip')).toBeVisible(); // tooltip muncul

await page.getByRole('button', { name: 'Menu Produk' }).hover(); // menu dropdown muncul
await page.getByRole('link', { name: 'Furnitur' }).click(); // klik isi menu yang muncul
Latihan 11

Tooltip dan menu yang muncul saat hover

Di jurus 3, arahkan kursor ke Arahkan ke sini dan cek tooltip-nya, lalu ke Menu Produk dan pastikan link Furnitur terlihat.

Hasiltooltip berisi Halo dari tooltip! 👋, dan link Furnitur terlihat

Unggah file

upload = page.get_by_label("Pilih file")  # kolom pilih file
upload.set_input_files("data/foto.png")                    # satu file dari disk
upload.set_input_files(["a.txt", "b.txt"])                 # beberapa file
upload.set_input_files(files=[{                            # file dibuat di memori, tanpa file fisik
    "name": "laporan.txt", "mimeType": "text/plain", "buffer": b"isi laporan",  # nama, jenis, dan isi file
}])
upload.set_input_files([])                                 # kosongkan pilihan
const upload = page.getByLabel('Pilih file'); // kolom pilih file
await upload.setInputFiles('data/foto.png');               // satu file dari disk
await upload.setInputFiles(['a.txt', 'b.txt']);            // beberapa file
await upload.setInputFiles({                               // file dibuat di memori, tanpa file fisik
  name: 'laporan.txt', mimeType: 'text/plain', buffer: Buffer.from('isi laporan'), // nama, jenis, dan isi file
});
await upload.setInputFiles([]);                            // kosongkan pilihan
Kalau tombol unggahnya dihias

Kolom file asli kadang disembunyikan dan diganti tombol lain. Jendela pilih file milik sistem operasi tidak bisa dikendalikan Playwright, jadi tangkap file chooser-nya dulu. Python: with page.expect_file_chooser() as fc: tombol.click() lalu fc.value.set_files(...). TypeScript: const fc = page.waitForEvent('filechooser'), klik tombolnya, lalu (await fc).setFiles(...).

Latihan 12

Unggah dua file sekaligus

Unggah file a.txt dan b.txt sekaligus ke Pilih file (jurus 7). File bisa dibuat langsung di memori. Cek hasilnya (test id upload-result).

HasilFile terpilih: a.txt, b.txt

Seret lalu lepas (drag & drop)

page.get_by_text("Apel", exact=True).drag_to(page.get_by_test_id("basket"))  # seret Apel lalu lepas di keranjang
await page.getByText('Apel', { exact: true }).dragTo(page.getByTestId('basket')); // seret Apel lalu lepas di keranjang

Untuk gerakan yang lebih detail, misalnya slider, atur mouse langkah demi langkah: hover() di elemen asal, page.mouse.down(), hover() di tujuan, lalu page.mouse.up().

Latihan 13

Seret dua buah ke keranjang

Di jurus 9, seret Jeruk lalu Mangga ke keranjang, lalu cek isinya (test id drag-result).

HasilIsi keranjang: Jeruk, Mangga

Soal force=True

Pilihan force=True / { force: true } melewati semua pengecekan tadi. Padahal pengguna sungguhan juga tidak bisa mengklik tombol yang tertutup, jadi bisa jadi itu bug sungguhan.

Di dunia QA

Memakai force mirip menutup bug report dengan alasan "di laptop saya bisa". Test-nya hijau, tapi pengguna tetap tidak bisa mengklik tombol itu.

Jangan langsung pakai force

Cari tahu dulu kenapa elemennya tidak bisa diklik. Mungkin ada lapisan loading, animasi, atau banner cookie yang menutupi. Pakai force hanya kalau kamu yakin perilaku itu memang disengaja.

Gabungkan semuanya

Latihan 14

Isi formulir lengkap

Isi nama Rina, level Mahir, bahasa Java, newsletter tidak dicentang, lalu tekan Kirim formulir dan cek kalimat hasilnya.

HasilTerkirim: Rina | level Mahir | bahasa java | browser - | newsletter tidak

Semua contoh dalam file asli

tests/academy/test_m05_interactions.pytests/academy/m05-interactions.spec.tsLulus test
Memuat tests/academy/test_m05_interactions.py…
uv run pytest tests/academy/test_m05_interactions.py --headed --slowmo 300
Memuat tests/academy/m05-interactions.spec.ts…
npx playwright test m05-interactions --project=chromium --headed
Lebih jauh (opsional)Trik komunitas
  • add_locator_handler() (v1.42+) menangani pop-up yang muncul tiba-tiba, misalnya banner cookie atau survei, setiap kali pop-up itu menghalangi. Test utamanya jadi tetap rapi.
  • ControlOrMeta di press() otomatis menjadi Ctrl di Windows/Linux dan Cmd di Mac. Satu test, jalan di semua laptop.
  • page.clock untuk interaksi yang bergantung waktu, misalnya hitung mundur atau sesi habis, tanpa perlu menunggu sungguhan. Contohnya ada di Modul 9.
  • Versi terbaru juga punya locator.drop() (v1.60+) untuk menguji area tempat menjatuhkan file.
page.add_locator_handler(  # setiap kali tombol ini menghalangi...
    page.get_by_role("button", name="Terima cookie"),
    lambda tombol: tombol.click(),  # ...klik tombolnya, lalu lanjutkan test
)
page.get_by_label("Username").press("ControlOrMeta+A")  # Ctrl+A di Windows, Cmd+A di Mac
await page.addLocatorHandler(page.getByRole('button', { name: 'Terima cookie' }), async (tombol) => { // setiap kali tombol ini menghalangi, klik tombolnya
  await tombol.click(); // klik tombolnya, lalu lanjutkan test
});
await page.getByLabel('Username').press('ControlOrMeta+A'); // Ctrl+A di Windows, Cmd+A di Mac