Skip to main content
BlogWeb Dev

Cara Membuat Smoke Test Playwright di GitHub Actions

Cara membuat smoke test Playwright untuk pemula: pasang, tulis tiga pengecekan jalur utama, jalankan di GitHub Actions, lalu unggah report HTML-nya.

Matthews Wong

Software Engineer

Oktober 20269 menit baca
Cara Membuat Smoke Test Playwright di GitHub Actions

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 --version

Hasilnya: 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-report

Jika 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: 14

Di 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.

GejalaPenyebabPerbaikan
Run gagal sebelum tes pertama, dengan pesan soal webServer yang tidak menjawabAlamat di url tidak menjawab dalam batas waktu (bawaannya 60000 ms): app belum di-build, atau port tidak sama dengan commandJalankan 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 webServerreuseExistingServer bernilai false dan ada server lain yang sudah mendengarkan di alamat ituMatikan server lama, atau pakai reuseExistingServer: !process.env.CI agar lokal memakai ulang server yang berjalan
Browser tidak ditemukan saat tes diluncurkan di CILangkah install browser belum ada, atau berjalan sebelum npm ci sehingga versinya tidak cocokTambahkan npx playwright install --with-deps chromium setelah npm ci, di job yang sama
Tes untuk Firefox atau WebKit gagal di CIConfig bawaan menjalankan tiga browser, padahal workflow hanya memasang ChromiumSisakan project chromium saja di config, atau pasang semua browser yang dipakai
Tes gagal tetapi tidak ada report di ArtifactsLangkah upload tanpa kondisi dilewati karena langkah sebelumnya gagalTambahkan if dengan !cancelled() pada langkah upload-artifact
index.html dari report terbuka tetapi kosongReport HTML dibuka langsung dari file, padahal butuh web serverJalankan 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.

FAQ

Pertanyaan Umum

Jawaban singkat untuk pertanyaan yang paling sering diajukan pembaca tentang topik ini.

Apa itu smoke test Playwright dan apa bedanya dengan unit test?

Smoke test membuka app hasil build di browser sungguhan dan memeriksa beberapa hal yang wajib jalan, seperti halaman utama dan navigasi utama. Unit test memanggil fungsi langsung dan tidak pernah memuat bundle. Karena itu smoke test bisa menangkap halaman yang berhasil dikompilasi tetapi tampil kosong, yang tidak terlihat oleh unit test.

Kenapa tes Playwright lulus di lokal tapi gagal di GitHub Actions?

Penyebab yang paling umum adalah langkah install browser yang belum ada, app yang belum di-build sebelum tes, atau port yang berbeda antara command, url, dan baseURL. Di CI, reuseExistingServer bernilai false, jadi server baru harus menyala dan menjawab dalam batas waktu webServer. Unduh artifact playwright-report dan buka trace untuk melihat langkah yang gagal.

Apakah semua browser harus dipasang di GitHub Actions?

Tidak. Smoke test cukup satu browser, jadi pasang Chromium saja dengan npx playwright install --with-deps chromium dan sisakan project chromium di playwright.config.ts. Jika config masih memuat Firefox dan WebKit, tes untuk keduanya gagal karena browsernya tidak terpasang.

Berapa banyak tes yang sebaiknya ada di smoke test?

Cukup beberapa pengecekan di jalur terpenting, misalnya tiga sampai lima. Smoke test adalah kawat jebakan, jadi kegagalannya harus berarti ada yang jelas rusak. Tes yang lebih banyak menambah peluang gagal karena alasan yang tidak berhubungan dan membuat run lebih lama.

Bagaimana cara membuka report Playwright setelah run gagal?

Buka run di GitHub, unduh artifact playwright-report dari bagian Artifacts, lalu ekstrak zip-nya. Setelah itu jalankan npx playwright show-report diikuti nama foldernya. Membuka index.html langsung tidak berfungsi karena report butuh web server.