Playwright Academy
0 dari 17
Fase 1 · FondasiModul 3 dari 17

Script Pertama

Buka browser, login ke TokoQA, lalu ambil screenshot. Semuanya jalan sendiri.

Di modul ini kamu menjalankan script yang membuka browser, login ke TokoQA, lalu menyimpan screenshot.

Browser, Context, dan Page

Playwright bekerja dalam tiga lapis, mirip Chrome yang membuka jendela incognito berisi beberapa tab.

Browser
chromium.launch()
BrowserContext
seperti jendela incognito
Page
satu tab
  • Browser adalah aplikasi browser-nya, misalnya Chromium.
  • BrowserContext seperti jendela incognito: login, cookies, dan datanya terpisah dari context lain.
  • Page adalah satu tab di dalam context.

Setiap test dapat context baru yang bersih, lalu context itu ditutup tanpa menutup browser. Karena itu setiap test bisa mulai bersih dengan cepat.

Di dunia QA

Saat mengetes login dua peran, kamu mungkin membuka satu jendela biasa untuk customer dan satu jendela incognito untuk admin, supaya sesinya tidak tercampur. BrowserContext adalah jendela terpisah seperti itu, dan Playwright membuat yang baru untuk setiap test.

Script pertamamu

Script ini membuka browser, login ke TokoQA, lalu menyimpan screenshot. Buat file-nya dulu:

  1. Di panel kiri VS Code, klik kanan folder kosong di bawah nama project, lalu pilih New Folder. Ketik scripts, lalu tekan Enter.
  2. Klik kanan folder scripts, pilih New File. Ketik m03_first_script.py, lalu tekan Enter.
  3. Salin kode di bawah ke file itu, lalu simpan dengan Ctrl+S (macOS: Cmd+S).
  4. Jalankan perintah di bawah kode lewat terminal VS Code.
  1. Di panel kiri VS Code, klik kanan folder kosong di bawah nama project, lalu pilih New Folder. Ketik scripts, lalu tekan Enter.
  2. Klik kanan folder scripts, pilih New File. Ketik m03-first-script.ts, lalu tekan Enter.
  3. Salin kode di bawah ke file itu, lalu simpan dengan Ctrl+S (macOS: Cmd+S).
  4. Jalankan perintah di bawah kode lewat terminal VS Code.

Script membaca URL playground dari BASE_URL di file .env kalau file itu ada (dibuat di Modul 11). Kalau belum ada, script memakai playground online.

scripts/m03_first_script.pyscripts/m03-first-script.tsLulus test
Memuat scripts/m03_first_script.py…
uv run python scripts/m03_first_script.py
Memuat scripts/m03-first-script.ts…
node scripts/m03-first-script.ts
Arti setiap baris
with sync_playwright() as p:
Menyalakan Playwright. Di akhir blok with, semuanya ditutup dengan rapi walau terjadi error.
p.chromium.launch(headless=False, slow_mo=500)
Membuka Chromium dengan jendela terlihat. slow_mo=500 memberi jeda 500 ms di setiap aksi supaya kamu bisa mengikutinya.
browser.new_page()
Membuat context baru sekaligus satu tab di dalamnya.
page.goto(f"{BASE_URL}/login-toko.html")
Membuka URL dan menunggu halaman selesai dimuat. Huruf f di depan teks membuat {BASE_URL} diganti isinya.
page.get_by_label("Username").fill("customer")
Mencari kolom berlabel Username, lalu mengetik customer.
page.get_by_role("button", name="Masuk").click()
Mencari tombol bertuliskan Masuk, lalu mengkliknya.
page.wait_for_url("**/shop.html")
Menunggu URL berganti ke halaman toko. ** artinya bagian depan URL boleh apa saja.
page.screenshot(path=..., full_page=True)
Memotret seluruh halaman, termasuk bagian yang harus digulir, lalu menyimpannya ke folder output/.
browser.close()
Menutup browser.
Arti setiap baris
import { chromium } from '@playwright/test'
Mengambil launcher untuk browser Chromium dari paket Playwright.
await chromium.launch({ headless: false, slowMo: 500 })
Membuka Chromium dengan jendela terlihat. slowMo: 500 memberi jeda 500 ms di setiap aksi supaya kamu bisa mengikutinya.
await browser.newPage()
Membuat context baru sekaligus satu tab di dalamnya.
await page.goto(...)
Membuka URL dan menunggu halaman selesai dimuat. URL-nya ditulis di antara tanda backtick, jadi ${BASE_URL} di dalamnya diganti isinya.
await page.getByLabel('Username').fill('customer')
Mencari kolom berlabel Username, lalu mengetik customer.
await page.getByRole('button', { name: 'Masuk' }).click()
Mencari tombol bertuliskan Masuk, lalu mengkliknya.
await page.waitForURL('**/shop.html')
Menunggu URL berganti ke halaman toko. ** artinya bagian depan URL boleh apa saja.
await page.screenshot({ path, fullPage: true })
Memotret seluruh halaman, termasuk bagian yang harus digulir, lalu menyimpannya ke folder output/.
await browser.close()
Menutup browser.

Browser terbuka dan bergerak pelan, lalu terminal mencetak judul halaman dan URL toko. Screenshot-nya tersimpan di folder output/.

Jangan lupa `await`

Hampir semua perintah Playwright di TypeScript butuh waktu, dan await artinya "tunggu sampai selesai". Tanpa await, baris berikutnya jalan sebelum perintah sebelumnya beres. Akibatnya error yang aneh, atau test lulus padahal tidak mengecek apa-apa. Linter bisa mengingatkan (Modul 15).

Lebih jauh (opsional)Gaya async di Python

Playwright Python punya dua gaya: sync (sync_playwright, yang kita pakai) dan async (async_playwright dengan await). Untuk test dengan pytest, gaya sync paling sederhana. Gaya async berguna untuk program yang menjalankan banyak hal bersamaan.

Python
import asyncio  # pustaka bawaan Python untuk menjalankan kode async
from playwright.async_api import async_playwright  # Playwright gaya async

async def main():  # fungsi async boleh memakai await
    async with async_playwright() as p:  # nyalakan Playwright
        browser = await p.chromium.launch()  # buka Chromium tanpa jendela
        page = await browser.new_page()  # buka satu tab
        await page.goto("https://playground.aminhamzah.com/login-toko.html")  # buka halaman login
        print(await page.title())  # cetak judul tab
        await browser.close()  # tutup browser

asyncio.run(main())  # jalankan fungsi main sampai selesai

Headed atau headless?

  • Headed (headless=False): jendela browser terlihat. Cocok untuk belajar dan mencari masalah.
  • Headless (bawaan): browser jalan tanpa jendela. Lebih cepat, dan dipakai di server CI.
browser = p.chromium.launch()                                 # headless (default)

# Pilihan lain, aktifkan salah satu sebagai pengganti baris di atas:
# browser = p.chromium.launch(headless=False, slow_mo=300)    # terlihat + pelan
# browser = p.firefox.launch()                                # ganti browser semudah ini
# browser = p.chromium.launch(channel="chrome")               # pakai Google Chrome asli di laptop
const browser = await chromium.launch();                                    // headless (default)

// Pilihan lain, aktifkan salah satu sebagai pengganti baris di atas:
// const browser = await chromium.launch({ headless: false, slowMo: 300 }); // terlihat + pelan
// const browser = await firefox.launch();                                  // ganti browser (import firefox dulu)
// const browser = await chromium.launch({ channel: 'chrome' });            // pakai Google Chrome asli di laptop

Dari script menjadi test

Script tadi belum bisa disebut test: tidak ada pengecekan, dan tidak ada laporan lulus atau gagal. Test runner (pytest atau Playwright Test) menambahkan keduanya.

Di dunia QA

Script tadi seperti tester yang menjalankan langkah tanpa mengisi kolom Actual result dan Status. Test runner mengisi keduanya: membandingkan hasil dengan expected result, lalu menulis passed atau failed.

  1. Klik kanan folder tests, pilih New Folder, ketik academy, lalu tekan Enter.
  2. Klik kanan folder academy, pilih New File, ketik test_m03_first_test.py, lalu tekan Enter.
  3. Salin kode di bawah, simpan, lalu jalankan perintah di bawahnya.
  1. Klik kanan folder tests, pilih New Folder, ketik academy, lalu tekan Enter.
  2. Klik kanan folder academy, pilih New File, ketik m03-first-test.spec.ts, lalu tekan Enter.
  3. Salin kode di bawah, simpan, lalu jalankan perintah di bawahnya.
tests/academy/test_m03_first_test.pytests/academy/m03-first-test.spec.tsLulus test
Memuat tests/academy/test_m03_first_test.py…
uv run pytest tests/academy/test_m03_first_test.py --headed
Memuat tests/academy/m03-first-test.spec.ts…
npx playwright test tests/academy/m03-first-test.spec.ts --headed --project=chromium
  • Tidak ada launch(), new_page(), atau close(). Test runner menyiapkan page (disebut fixture), lalu membereskannya setelah test selesai.
  • URL cukup ditulis sebagai path, misalnya /login-toko.html, karena base URL sudah diatur di konfigurasi (base_url/baseURL).
  • expect(...) adalah assertion, langkah "periksa hasil" dari Modul 1. Kalau judulnya tidak sesuai, test gagal dan menunjukkan bedanya.

Screenshot yang lebih spesifik

page.screenshot(path="output/layar.png")                         # yang terlihat di layar
page.screenshot(path="output/full.png", full_page=True)          # seluruh halaman
page.get_by_role("heading").first.screenshot(path="output/judul.png")  # satu elemen saja
await page.screenshot({ path: 'output/layar.png' });                     // yang terlihat di layar
await page.screenshot({ path: 'output/full.png', fullPage: true });      // seluruh halaman
await page.getByRole('heading').first().screenshot({ path: 'output/judul.png' }); // satu elemen saja
Lebih jauh (opsional)Trik komunitas
  • page.pause() menghentikan test sementara dan membuka Inspector di baris itu. Cara tercepat untuk melihat kondisi halaman saat itu.
  • playwright open <url> membuka browser lengkap dengan Inspector, tanpa menulis kode. Cocok untuk mengenal halaman baru.
  • Screenshot yang stabil: animations="disabled" mematikan animasi, dan mask=[locator] menutupi bagian yang selalu berganti (jam, iklan, nomor acak).
  • Tampilkan jendela hanya saat perlu. Headless lebih cepat. Kalau ingin tahu apa yang terjadi, rekam trace (Modul 12) lalu putar ulang seperti video.
# Animasi dimatikan, dan sapaan (yang berisi nama) ditutup kotak warna supaya screenshot selalu sama
page.screenshot(path="output/toko.png", animations="disabled", mask=[page.get_by_test_id("greeting")])
// Animasi dimatikan, dan sapaan (yang berisi nama) ditutup kotak warna supaya screenshot selalu sama
await page.screenshot({ path: 'output/toko.png', animations: 'disabled', mask: [page.getByTestId('greeting')] });

Latihan

Tulis jawabanmu di folder tests/ project-mu, jalankan, lalu bandingkan dengan jawaban. Semua jawaban di bawah sudah lulus test.

Latihan 1

Login, cari produk, lalu simpan screenshot

Login sebagai customer / rahasia123, ketik mouse di kolom Cari produk, pastikan hanya 1 kartu produk tersisa, lalu simpan screenshot m03-cari.png.

Hasiltest lulus dan file m03-cari.png terbentuk

Latihan 2

Cetak dan periksa judul halaman

Buka halaman login TokoQA, cetak judulnya ke terminal, lalu pastikan judulnya persis Login — TokoQA.

Hasiljudul tercetak di terminal dan test lulus

Latihan 3

Jalankan di browser lain

Jalankan file latihan Modul 3 di Firefox, lalu di WebKit (mesin Safari), tanpa mengubah kodenya.

Hasiltest lulus di kedua browser