Ringkasan Utama
Cara membuat smoke test Playwright: pasang dengan npm init playwright@latest, tulis tiga pengecekan di jalur terpenting, biarkan webServer di playwright.config.ts menyalakan app hasil build, lalu jalankan npx playwright test di GitHub Actions dan unggah folder playwright-report sebagai artifact. Jaga tetap kecil agar cepat dan tidak rewel.
Build hijau, semua unit test lulus, kamu deploy, lalu halaman utama ternyata kosong karena satu skrip melempar error di browser. Tidak ada tes yang melihatnya, sebab tidak ada tes yang pernah membuka browser. Smoke test dibuat untuk menutup celah itu: ia membuka app hasil build dan memastikan beberapa hal yang wajib jalan memang jalan.
Artikel ini membimbingmu dari nol sampai smoke test Playwright berjalan di setiap pull request. Semua perintah dan opsi diverifikasi ke dokumentasi resmi Playwright dan GitHub, dan polanya sama dengan workflow game-smoke.yml yang menjaga halaman game di situs ini.
Ingin paham alasan di balik tiap langkah, termasuk loop tunggu server dan log saat gagal? Ikuti pelajaran gratis Smoke test Playwright di GitHub Actions. Artikel ini adalah versi praktiknya, langkah demi langkah.
Yang kamu butuhkan
Tidak banyak. Contoh di sini memakai project Next.js, tetapi pola yang sama berlaku untuk app web apa pun yang bisa di-build dan dijalankan dengan satu perintah.
- Node.js dan project web yang punya skrip npm run build dan npm run start.
- Repositori di GitHub, supaya GitHub Actions bisa menjalankan tes.
- Terminal dan sedikit kenyamanan dengan npm. Kamu tidak perlu pernah memakai Playwright sebelumnya.
Langkah 1: Pasang Playwright
Jalankan satu perintah di folder project. Playwright akan bertanya beberapa hal: TypeScript atau JavaScript, nama folder tes, apakah ingin dibuatkan workflow GitHub Actions, dan apakah browser langsung dipasang. Jawab tidak untuk workflow, karena kita menulisnya sendiri di Langkah 5 supaya kamu paham isinya.
# Run inside your existing project folder
npm init playwright@latest
# The prompts ask for: TypeScript or JavaScript, the tests folder name
# (tests by default), a GitHub Actions workflow, and whether to install browsers.
# Answer no to the workflow question: we write our own in step 5.
# Check what got installed
npx playwright --versionHasilnya: file playwright.config.ts, folder tes dengan satu contoh tes, dan Playwright tercatat di package.json beserta lockfile. Hapus contoh tesnya, karena ia membuka situs milik orang lain. Kita akan menulis tes untuk app kamu sendiri.
Langkah 2: Tulis smoke test pertama
Buat tests/smoke.spec.ts. Setiap tes membuka halaman dan memeriksa sesuatu yang dilihat pengguna: judul, heading utama, dan satu klik di jalur terpenting. Ganti My App dan Blog dengan teks yang benar-benar ada di app kamu. Playwright menunggu elemen siap sebelum bertindak, jadi kamu tidak perlu menaruh sleep di mana pun.
// tests/smoke.spec.ts
import { test, expect } from '@playwright/test';
test('home page has the right title', async ({ page }) => {
// baseURL from playwright.config.ts is prepended to '/'
await page.goto('/');
await expect(page).toHaveTitle(/My App/);
});
test('home page shows its main heading', async ({ page }) => {
await page.goto('/');
await expect(page.getByRole('heading', { level: 1 })).toBeVisible();
});
test('the Blog link opens the blog', async ({ page }) => {
await page.goto('/');
await page.getByRole('link', { name: 'Blog' }).first().click();
await expect(page.getByRole('heading', { name: 'Blog' })).toBeVisible();
});Satu kebiasaan yang sering salah di awal: memakai isVisible() lalu membandingkannya sendiri. Ia hanya bertanya sekali pada saat itu juga. Pakai assertion yang menunggu, yaitu await expect(...).toBeVisible(), yang menurut dokumentasi akan menunggu sampai kondisinya terpenuhi.
// Wrong: isVisible() answers once, right now. If the page is still
// rendering, the test fails even though the heading appears a moment later.
expect(await page.getByRole('heading', { level: 1 }).isVisible()).toBe(true);
// Right: a web-first assertion keeps retrying until the heading shows up
// or the timeout runs out.
await expect(page.getByRole('heading', { level: 1 })).toBeVisible();Langkah 3: Atur config dan webServer
Di playwright.config.ts, bagian webServer memberi tahu Playwright cara menyalakan app dan alamat yang harus ia periksa. Playwright menunggu alamat itu menjawab dulu, baru menjalankan tes, jadi kamu tidak perlu menulis loop tunggu sendiri. baseURL membuat page.goto('/') menuju app kamu. Kita juga membatasi project ke chromium saja, karena smoke test cukup satu browser.
// playwright.config.ts
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
testDir: 'tests',
// Fail the run on CI if test.only was left in the source
forbidOnly: !!process.env.CI,
// Retry on CI only; a retry is what records a trace
retries: process.env.CI ? 2 : 0,
reporter: 'html',
use: {
baseURL: 'http://localhost:3000',
trace: 'on-first-retry',
},
// One browser is enough for a smoke test
projects: [{ name: 'chromium', use: { ...devices['Desktop Chrome'] } }],
webServer: {
// The app must already be built: npm run build comes first
command: 'npm run start',
url: 'http://localhost:3000',
// Reuse your own running server locally, always start fresh on CI
reuseExistingServer: !process.env.CI,
},
});Tiga hal penting dari config ini. Pertama, port di command, url, dan baseURL harus sama. Kedua, timeout webServer bawaannya 60000 ms. Ketiga, reuseExistingServer dibuat true di lokal agar server yang sedang kamu jalankan dipakai ulang, dan false di CI agar selalu mulai dari server baru.
Langkah 4: Jalankan di komputermu dulu
Jangan langsung ke CI. Build dulu, lalu jalankan tes di lokal, karena kegagalan di sini jauh lebih cepat dibaca daripada lewat log GitHub. Secara bawaan tes berjalan headless, jadi tambahkan --headed jika ingin melihat browsernya bergerak.
# Build once, then run the smoke test (headless by default)
npm run build
npx playwright test
# Watch the browser do it
npx playwright test --headed
# Only the chromium project, or only one file
npx playwright test --project=chromium
npx playwright test tests/smoke.spec.ts
# Open the HTML report (it opens by itself only when something failed)
npx playwright show-reportJika semua lulus, terminal merangkum jumlah tes yang lulus. Jika ada yang gagal, report HTML terbuka sendiri dan menunjukkan langkah mana yang gagal. Kalau Playwright mengeluh soal webServer, hampir selalu karena npm run build belum dijalankan.
Langkah 5: Jalankan di GitHub Actions
Buat .github/workflows/smoke.yml. Urutannya: checkout, pasang Node, npm ci, build, pasang Chromium, jalankan tes, unggah report. Browser dipasang setelah npm ci karena setiap versi Playwright membutuhkan versi binary browser tertentu, jadi perintah install harus membaca versi yang benar-benar terpasang.
# .github/workflows/smoke.yml
name: smoke
on:
push:
branches: [main]
pull_request:
# A new push cancels the older run of the same branch
concurrency:
group: smoke-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
smoke:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
# After npm ci, so the browser build matches the installed Playwright
- name: Install Chromium
run: npx playwright install --with-deps chromium
# webServer in playwright.config.ts starts the app and waits for it
- name: Smoke test
run: npx playwright test
- name: Upload report
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: playwright-report
path: playwright-report/
retention-days: 14Di situs ini, game-smoke.yml mengerjakan hal serupa dengan cara lain: ia menyalakan npm start di latar belakang dan menunggu dengan loop curl, bukan lewat webServer. Keduanya sah, dan pelajaran gratis di bawah membahas versi loop itu. Workflow ini juga sama dalam tiga hal: hanya memasang Chromium, membatalkan run lama di branch yang sama, dan hanya memberi izin baca ke isi repositori.
Langkah upload report harus memakai if dengan !cancelled(). Tanpa itu, langkah yang datang setelah tes gagal akan dilewati, dan justru pada saat tes gagal kamu paling membutuhkan reportnya.
Langkah 6: Unduh dan baca report saat gagal
Saat run gagal, buka halaman run di GitHub, cari bagian Artifacts, dan unduh playwright-report. Ekstrak zip-nya, lalu sajikan lewat Playwright. Report HTML butuh web server, sehingga membuka index.html langsung dari folder tidak akan berfungsi.
# 1. In the failed run, open Artifacts and download playwright-report (a zip)
# 2. Extract it, ideally inside a folder where Playwright is installed
# 3. Serve it with Playwright, passing the extracted folder name
npx playwright show-report playwright-report
# Wrong: double-clicking index.html. The report needs a web server.Di config kita, retries bernilai 2 di CI dan trace dicatat pada retry pertama. Jadi tes yang gagal akan membawa trace yang bisa dibuka dari report: kamu melihat setiap langkah beserta tampilan halamannya, tanpa menebak dari teks error.
Langkah 7: Jaga tetap kecil
Smoke test adalah kawat jebakan, bukan suite regresi. Tiga sampai lima pengecekan di jalur terpenting sudah cukup: halaman utama tampil, navigasi utama bekerja, dan satu aksi inti selesai. Dokumentasi Playwright menyarankan hanya menguji apa yang kamu kendalikan.
// Wrong: testing a site you do not control. It goes red when they have a bad day.
await page.goto('https://playwright.dev/');
// Right: only your own app, through baseURL.
await page.goto('/');Setiap tes tambahan adalah satu lagi cara gagal karena alasan yang tidak berhubungan dengan perubahanmu. Kalau app memanggil layanan pihak ketiga, dokumentasi menyarankan memakai Network API Playwright untuk memastikan respons yang dibutuhkan, supaya situs luar tidak membuat run menjadi merah. Pengujian yang lebih dalam taruh di tempat lain.
Error umum dan cara memperbaikinya
Enam masalah yang paling sering membuat smoke test baru gagal di CI, dengan penyebab dan perbaikannya.
| Gejala | Penyebab | Perbaikan |
|---|---|---|
| Run gagal sebelum tes pertama, dengan pesan soal webServer yang tidak menjawab | Alamat di url tidak menjawab dalam batas waktu (bawaannya 60000 ms): app belum di-build, atau port tidak sama dengan command | Jalankan npm run build di langkah sebelum tes, samakan port di command, url, dan baseURL. Naikkan timeout hanya jika server memang lambat |
| Error bahwa sesuatu sudah berjalan di alamat webServer | reuseExistingServer bernilai false dan ada server lain yang sudah mendengarkan di alamat itu | Matikan server lama, atau pakai reuseExistingServer: !process.env.CI agar lokal memakai ulang server yang berjalan |
| Browser tidak ditemukan saat tes diluncurkan di CI | Langkah install browser belum ada, atau berjalan sebelum npm ci sehingga versinya tidak cocok | Tambahkan npx playwright install --with-deps chromium setelah npm ci, di job yang sama |
| Tes untuk Firefox atau WebKit gagal di CI | Config bawaan menjalankan tiga browser, padahal workflow hanya memasang Chromium | Sisakan project chromium saja di config, atau pasang semua browser yang dipakai |
| Tes gagal tetapi tidak ada report di Artifacts | Langkah upload tanpa kondisi dilewati karena langkah sebelumnya gagal | Tambahkan if dengan !cancelled() pada langkah upload-artifact |
| index.html dari report terbuka tetapi kosong | Report HTML dibuka langsung dari file, padahal butuh web server | Jalankan npx playwright show-report diikuti nama folder hasil ekstrak |
Checklist sebelum kamu push
- npm run build lalu npx playwright test lulus di komputermu.
- Hanya ada tiga sampai lima tes, semuanya di jalur terpenting, dan tidak ada yang memuat situs milik orang lain.
- Port di command, url, dan baseURL sama, dan project dibatasi ke browser yang dipasang.
- Workflow memasang browser setelah npm ci dan membuild sebelum tes.
- Langkah upload report memakai if dengan !cancelled(), dan forbidOnly aktif di CI.
Belajar lebih dalam
Pelajaran gratis Smoke test Playwright di GitHub Actions membahas cara lain menyalakan server sendiri dengan loop curl, lalu mencetak log server saat tes gagal. Kalau kamu tertarik pada agent AI yang mengendalikan browser, bandingkan pendekatannya di Playwright MCP vs Browser Use vs Stagehand.
Aturan yang bisa kamu bawa: smoke test adalah beberapa pengecekan di jalur terpenting, dijalankan terhadap app hasil build di browser sungguhan, dengan report yang selalu diunggah saat gagal. Mulai dengan tiga tes, dan tambahkan hanya kalau kegagalan yang terlewat membuktikan perlunya.

