Skip to content

Feat: Smoke test untuk menu dashboard dan dashboard demografi#1056

Open
pandigresik wants to merge 42 commits into
rilis-devfrom
feat/smoketest
Open

Feat: Smoke test untuk menu dashboard dan dashboard demografi#1056
pandigresik wants to merge 42 commits into
rilis-devfrom
feat/smoketest

Conversation

@pandigresik

@pandigresik pandigresik commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Pull Request: Smoke Test dengan Pest Browser (Playwright) untuk Dashboard dan Demografi

Deskripsi

Menambahkan smoke test otomatis menggunakan Pest v4 + pest-plugin-browser (Playwright) untuk memastikan fungsionalitas inti halaman Dashboard dan Dashboard Demografi berjalan dengan benar. Test menggunakan MSW (Mock Service Worker) untuk mengintersep request API eksternal dan mengembalikan data fixture, sehingga test berjalan cepat, deterministik, dan tidak bergantung pada koneksi jaringan.

Perubahan yang dilakukan:

  1. Testing Infrastructure: Menambahkan Pest v4 + pest-plugin-browser sebagai test runner dengan Playwright backend
  2. Mock Service Worker (MSW): Mengembangkan sistem mock AJAX berbasis service worker (MswSetup.php) yang mengintersep fetch/XHR requests dan mengembalikan data dari JSON fixtures
  3. Smoke Test - Login: Test login page, valid/invalid credentials, dan session restoration (SmokeLoginTest.php)
  4. Smoke Test - Dashboard: Test elemen dashboard, filter kabupaten via AJAX, card values, dan filter interaction (SmokeDashboardTest.php)
  5. Smoke Test - Dashboard Demografi: Test chart rendering, chart titles, AJAX data loading, dan filter interaction (SmokeDashboardDemografiTest.php)
  6. Test Helpers: SessionState.php (session management & quick login), FixtureReader.php (JSON fixture reader), ScreenshotHelper.php (optional screenshot capture)
  7. data-testid Attributes: Penambahan data-testid di Blade templates untuk selector yang stabil dan resilient
  8. Vendor Patching: Script apply-patch.sh untuk menginjek MSW init script ke pest-plugin-browser's InitScript.php via composer hook
  9. Documentation: Dokumentasi lengkap (docs/smoke-test-browser.md) tentang arsitektur, setup, dan best practices
  10. Route & Config Updates: Penambahan quick login route untuk testing, perbaikan route names yang duplikat, dan dependency upgrades

Alasan perubahan:

  • Poin 1: Issue Buatkan Smoke test untuk menu dashboard dan dashboard demografi #1055 meminta smoke test untuk memastikan fungsionalitas inti Dashboard dan Dashboard Demografi berjalan. Tanpa automated testing, regressions sulit dideteksi secara dini
  • Poin 2: Menggunakan Playwright via pest-plugin-browser memberikan testing browser yang cepat, reliable, dan terintegrasi dengan ekosistem Pest PHP
  • Poin 3: MSW digunakan untuk mock API calls agar test tidak bergantung pada layanan eksternal (database gabungan) yang bisa berubah atau tidak tersedia saat testing
  • Poin 4: Select2 dropdown memerlukan pendekatan khusus dalam testing — menggunakan assertScript dengan DOM queries langsung alih-alih Playwright's built-in select interactions

Dampak perubahan:

Smoke Test Coverage: Dashboard, Dashboard Demografi, dan Login page tercoverage oleh automated browser tests
CI/CD Integration: Test bisa dijalankan di CI/CD pipeline untuk mendeteksi regressions
Deterministic Testing: MSW mock memastikan test selalu menggunakan data yang konsisten
data-testid Convention: Establishes testing contract antara developer dan tester melalui explicit test selectors
Documentation: Panduan lengkap untuk developer lain menambahkan test baru atau route mock baru

Masalah Terkait (Related Issue)

  • Solusi untuk issue #1055

Detail Perubahan File

Testing Infrastructure (New Files)

File Deskripsi
tests/Pest.php Konfigurasi Pest: browser timeout 30s, disable Google Fonts di testing
tests/Browser/MswSetup.php Generator MSW init script JS — mendefinisikan route mapping ke fixture files (exact & regex patterns)
tests/Browser/SessionState.php Session management: create/get admin user, quick login via /_pest/login/{id}, apply/clear filter
tests/Browser/FixtureReader.php Membaca JSON fixtures: kabupaten names, chart keys, chart labels, categories values
tests/Browser/ScreenshotHelper.php Optional screenshot capture via SCREENSHOT_ON_SUCCESS env var
tests/Browser/apply-patch.sh Composer hook script — patch vendor/pestphp/pest-plugin-browser/src/Playwright/InitScript.php untuk inject MSW init script
public/mockServiceWorker.js MSW service worker file (generated by npx msw init)

Smoke Tests (New Files)

File Test Cases
tests/Browser/SmokeLoginTest.php 4 tests: login page display, valid login, invalid credentials, session restore
tests/Browser/SmokeDashboardTest.php 4 tests: dashboard elements, kabupaten AJAX options, card values, filter interaction
tests/Browser/SmokeDashboardDemografiTest.php 5 tests: dashboard elements, kabupaten AJAX options, chart titles, chart rendering, filter interaction

JSON Fixtures (New Files — 19 files)

Data mock untuk semua API endpoints yang di-intercept oleh MSW:

Fixture Endpoint Pattern
kabupaten.json /api/v1/statistik-web/get-list-kabupaten
kecamatan-50.01.json, kecamatan-50.02.json, kecamatan-5271.json, kecamatan-5272.json /api/v1/statistik-web/get-list-kecamatan/{id}
desa-50.01.01.json, desa-50.01.02.json, desa-5271010.json, desa-5271020.json /api/v1/statistik-web/get-list-desa/{id}
data-website.json /api/v1/data-website
penduduk.json /api/v1/wilayah/penduduk
coordinates.json /api/v1/statistik-web/get-list-coordinate
dasbor.json /api/v1/dasbor
statistik-penduduk-*.json (9 files) /api/v1/statistik/penduduk?filter[id]={key}

View Changes (data-testid additions)

Penambahan data-testid attributes untuk testing contract:

File Elemen
resources/views/components/wilayah_filter.blade.php filter-kabupaten, filter-kecamatan, filter-desa, bt-filter, bt-clear-filter
resources/views/dasbor/category_item.blade.php summary-card-{key}, summary-value-{key}, summary-label-{key}, summary-link-{key}
resources/views/dasbor/summary.blade.php summary-block
resources/views/dasbor/peta.blade.php peta
resources/views/dasbor/tabel_penduduk.blade.php tabel-penduduk-block
resources/views/dasbor/data-desa.blade.php summary-penduduk
resources/views/demografi/chart_item.blade.php chart-item-{key}, chart-title-{key}, chart-content-{key}

Configuration & Dependency Changes

File Perubahan
composer.json Tambah pestphp/pest:^4.0, pestphp/pest-plugin-browser:^4.0; upgrade PHP ke ^8.4, Laravel ke ^13.0; tambah composer hook apply-patch.sh
package.json Tambah msw:^2.14.6, playwright:^1.60.0; tambah config msw.workerDirectory
.gitignore Tambah tests/Browser/Screenshots/, tests/Browser/.session_state.json, public/mockServiceWorker.js
routes/web.php Tambah quick login route /_pest/login/{userId} untuk testing; perbaikan route names yang duplikat

Documentation (New File)

File Deskripsi
docs/smoke-test-browser.md Panduan lengkap 888 baris: arsitektur, instalasi, MSW setup, penulisan test, session management, troubleshooting, best practices

Arsitektur Testing

Pest PHP (tests/Browser/*.php)
    |
    v
pest-plugin-browser
    |
    v
Playwright Server (WebSocket)
    |
    v
Chromium Browser + MSW Service Worker
    |  (intercepts fetch/XHR requests)
    v
Laravel HTTP Server (amphp)
    |
    v
Aplikasi Laravel

Request Flow during Tests:

Browser Page (JS)
    |
    +-- fetch('/api/v1/data-website')
    |       |
    |       v
    |   MSW Interceptor (init script)
    |       |
    |       +-- Route match -> return fixture JSON
    |       +-- No match -> forward to real server
    |
    +-- Page renders with mock data

Teknis Detail

MSW Route Matching

MSW menggunakan dua jenis route matching:

Exact Routes — URL statis tanpa parameter:

private const ROUTES = [
    '/api/v1/statistik-web/get-list-kabupaten' => 'kabupaten.json',
    '/api/v1/data-website' => 'data-website.json',
];

Regex Routes — URL dengan parameter dinamik:

private const REGEX_ROUTES = [
    '#/api/v1/statistik-web/get-list-kecamatan/([\d.]+)$#' => 'kecamatan-*.json',
    '#/api/v1/statistik/penduduk\?.*filter(?:\[id\]|%5Bid%5D)=([^&]+)#' => 'statistik-penduduk-*.json',
];

Select2 Dropdown Testing

Karena dropdown menggunakan Select2 (hidden <select> + custom UI), testing menggunakan JavaScript DOM queries langsung:

// Wait for AJAX options to load via polling Promise
$page->assertScript(
    "new Promise((resolve) => {
        const check = () => {
            const count = document.querySelectorAll('#filter_kabupaten option').length;
            if (count > 1) { resolve(true); } else { setTimeout(check, 200); }
        };
        check();
    })",
    true
);

// Verify each option exists
$page->assertScript(
    "Array.from(document.querySelectorAll('#filter_kabupaten option'))
        .some(o => o.textContent.trim() === 'Kota Mataram')",
    true
);

Chart Rendering Detection

Test mendeteksi chart rendering melalui phase-based polling:

  1. Phase 1: Tunggu loading text ("Sedang memuat data...") muncul (AJAX started)
  2. Phase 2: Tunggu canvas element muncul dan loading text hilang (AJAX completed + chart rendered)

Vendor Patching

apply-patch.sh diperlukan karena pest-plugin-browser tidak menyediakan hook untuk menambahkan init script custom. Script ini:

  1. Backup InitScript.php original ke InitScript.php.bak
  2. Generate MSW init script JS via PHP
  3. Patch InitScript.php untuk memanggil MswSetup::getInitScriptJs()
  4. Otomatis dijalankan oleh composer hook (post-install-cmd, post-update-cmd)

Dependencies yang ditambahkan

PHP (Composer)

  • pestphp/pest: ^4.0 — Pest PHP testing framework
  • pestphp/pest-plugin-browser: ^4.0 — Browser testing via Playwright
  • react/http: ^0.4.0 — HTTP server untuk Pest browser

JavaScript (npm)

  • msw: ^2.14.6 — Mock Service Worker untuk intercept API calls
  • playwright: ^1.60.0 — Browser automation

Upgrades

  • PHP: ^8.1 -> ^8.4
  • Laravel: ^10.48 -> ^13.0
  • PHPUnit: ^10.1 -> ^12.0

Langkah untuk Mereproduksi (Steps to Reproduce)

Setup:

  1. Clone repository dan switch ke branch feat/smoketest
  2. Jalankan composer install (akan otomatis menjalankan apply-patch.sh)
  3. Jalankan npm install && npx msw init public/ --save
  4. Copy .env.testing dari .env dan set APP_ENV=testing

Menjalankan Smoke Tests:

# Semua smoke tests
php vendor/bin/pest --filter=Smoke

# Dashboard saja
php vendor/bin/pest --filter=SmokeDashboardTest

# Dashboard Demografi saja
php vendor/bin/pest --filter=SmokeDashboardDemografiTest

# Login saja
php vendor/bin/pest --filter=SmokeLoginTest

Hasil yang diharapkan:

  • Semua test pass (13 tests, ~50+ assertions)
  • Test berjalan dalam ~60 detik (termasuk startup server & browser)
  • Screenshot otomatis tersimpan saat test gagal (di tests/Browser/Screenshots/)

Daftar Periksa (Checklist)

  • Saya telah mematuhi aturan penulisan script
  • Saya telah mengikuti proses review pull request
  • Saya telah membuat automated tests untuk memverifikasi perbaikan (13 smoke tests)
  • Testing manual telah dilakukan di environment development
  • Tidak ada console error atau warning
  • Code sudah di-review

Testing

Automated Testing — Smoke Tests

Test File Test Cases Coverage
SmokeLoginTest.php 4 Login page, valid/invalid credentials, session restore
SmokeDashboardTest.php 4 Dashboard elements, kabupaten AJAX, card values, filter
SmokeDashboardDemografiTest.php 5 Dashboard elements, kabupaten AJAX, chart titles, chart rendering, filter

Checklist Fungsionalitas (sesuai Issue #1055)

Menu Dashboard

  • Halaman berhasil dibuka
  • Filter Kota tampil
  • Filter Kecamatan tampil
  • Filter Desa tampil
  • Tombol Tampilkan tampil
  • Kartu Kecamatan tampil
  • Kartu Desa tampil
  • Kartu Jumlah Penduduk tampil
  • Kartu Jumlah Keluarga tampil
  • Peta tampil
  • Tabel Data Desa tampil
  • Pilih Kota, Klik Tampilkan, Halaman tidak error, Peta tetap tampil, Tabel tetap tampil

Menu Dashboard Demografi

  • Halaman berhasil dibuka
  • Filter Kota tampil
  • Filter Kecamatan tampil
  • Filter Desa tampil
  • Tombol Tampilkan tampil
  • Komposisi Rentang Umur tampil
  • Komposisi Status Perkawinan tampil
  • Komposisi Pendidikan Dalam KK tampil
  • Komposisi Golongan Darah tampil
  • Komposisi Penyakit Menahun tampil
  • Komposisi Agama tampil
  • Komposisi Jenis Kelamin tampil
  • Komposisi Suku / Etnis tampil
  • Komposisi Penyandang Cacat tampil
  • Seluruh chart berhasil dirender
  • Pilih Kota, Klik Tampilkan, Halaman tidak error, Semua chart tetap tampil

Breaking Changes

Tidak ada breaking changes untuk functionality aplikasi. Perubahan yang bersifat breaking:

  • PHP Version: Minimum PHP 8.4 (sebelumnya 8.1)
  • Laravel Version: Upgrade ke Laravel 13 (sebelumnya 10)
  • Route Names: Beberapa route names yang duplikat diperbaiki (impact ke route references yang menggunakan nama lama)

Migration Guide

  1. Pastikan environment menggunakan PHP 8.4+
  2. Jalankan composer update untuk mendapatkan dependencies baru
  3. Jalankan npx msw init public/ --save untuk generate MSW service worker
  4. Jalankan bash tests/Browser/apply-patch.sh (otomatis via composer hook)
  5. Untuk route names yang berubah, pastikan tidak ada hardcoded references ke nama lama

References


Catatan tambahan:

  • Test renders chart content from fixture data di SmokeDashboardDemografiTest.php memerlukan pendekatan khusus karena chart loading memiliki 3 phase: initial canvas (HTML) → "Sedang memuat data..." (AJAX beforeSend) → canvas baru (AJAX success). Polling menunggu transisi phase 1→2→3 untuk memastikan AJAX telah selesai sebelum assertion dijalankan.
  • Select2 dropdown testing dilakukan via JavaScript DOM queries langsung (document.querySelectorAll) karena Playwright's built-in select methods tidak kompatibel dengan Select2's hidden <select> pattern.
  • MSW init script di-inject ke browser via vendor patching (apply-patch.sh) karena pest-plugin-browser belum menyediakan hook untuk custom init scripts. Long-term solution: contribute PR ke pest-plugin-browser untuk menambahkan pest()->browser()->initScript() API.

Screenshots / Video

php artisan test --testsuite=Browser

image

- Upgrade composer deps melalui 3 fase (L10→L11→L12→L13)
- Bump 12 package ke major version baru (slug, datatables, CSP, image, dll)
- Migrasi Intervention Image v2→v3 (Image::make → read, resize → scale)
- Migrasi Spatie CSP v2→v3 (Policy → Preset, addDirective → add, config format)
- Tambah helper csp_nonce() (dihilangkan di CSP v3)
- Tambah CspExclusion middleware untuk route exclusion
- Publikasikan ulang config/image.php, config/jsvalidation.php
- Update CustomCSPPolicy → CustomCspPreset implement Preset interface
- Update CSP test untuk v3 API
- Catat temuan post-upgrade di UPGRADE_LARAVEL_13_PLAN.md
@github-actions

Copy link
Copy Markdown

🔄 AI PR Review sedang antri di server...

Proses review akan segera dimulai di background — hasil akan muncul sebagai komentar setelah selesai.
Powered by CrewAI · PR #1056

@pandigresik pandigresik changed the title Feat/smoketest Feat: Smoke test untuk menu dashboard dan dashboard demografi Jun 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant