vibes-plug 1.0.0 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/.github/workflows/publish.yml +20 -0
  2. package/AGENTS.md +66 -0
  3. package/BLUEPRINT.md +152 -60
  4. package/CHANGELOG.md +50 -0
  5. package/README.md +346 -194
  6. package/package.json +25 -25
  7. package/plugin.json +1 -1
  8. package/skills/ai-cost-token-optimizer/SKILL.md +52 -0
  9. package/skills/ai-llm-integration-expert/SKILL.md +180 -162
  10. package/skills/api-design-expert/SKILL.md +314 -310
  11. package/skills/app-analyzer-optimizer/SKILL.md +193 -189
  12. package/skills/apple-ecosystem-expert/SKILL.md +142 -0
  13. package/skills/async-queue-temporal-expert/SKILL.md +54 -0
  14. package/skills/authentication-identity-expert/SKILL.md +251 -20
  15. package/skills/auto-doc-updater/SKILL.md +214 -204
  16. package/skills/autonomous-chaos-monkey/SKILL.md +63 -0
  17. package/skills/autonomous-red-teamer/SKILL.md +59 -0
  18. package/skills/autonomous-swarm-director/SKILL.md +69 -0
  19. package/skills/autonomous-tdd-debugger/SKILL.md +65 -0
  20. package/skills/bootstrap-to-modern/SKILL.md +90 -86
  21. package/skills/brainstorming/SKILL.md +373 -353
  22. package/skills/browser-automation-expert/SKILL.md +46 -0
  23. package/skills/ci-cd-devops-architect/SKILL.md +72 -45
  24. package/skills/cloud-hosting-expert/SKILL.md +244 -244
  25. package/skills/coderabbit/SKILL.md +192 -192
  26. package/skills/cron-scheduler-expert/SKILL.md +298 -0
  27. package/skills/data-telemetry-expert/SKILL.md +213 -213
  28. package/skills/database-orm-expert/SKILL.md +294 -294
  29. package/skills/dependency-upgrade-migrator/SKILL.md +295 -0
  30. package/skills/design-system-architect/SKILL.md +27 -10
  31. package/skills/doku-mcp-server/SKILL.md +251 -0
  32. package/skills/doku-payment-gateway/SKILL.md +227 -0
  33. package/skills/e2e-testing-expert/SKILL.md +315 -315
  34. package/skills/edge-serverless-db-expert/SKILL.md +43 -0
  35. package/skills/email-notification-expert/SKILL.md +362 -0
  36. package/skills/error-resilience-expert/SKILL.md +480 -0
  37. package/skills/event-driven-architect/SKILL.md +81 -81
  38. package/skills/feature-flag-analytics-expert/SKILL.md +46 -0
  39. package/skills/file-upload-media-expert/SKILL.md +431 -0
  40. package/skills/form-validation-expert/SKILL.md +401 -0
  41. package/skills/fullstack-expert/SKILL.md +202 -202
  42. package/skills/fullstack-expert/references/api_design_guide.md +466 -466
  43. package/skills/fullstack-expert/references/multi_language_backend.md +528 -528
  44. package/skills/fullstack-expert/scripts/api_contract_validator.py +253 -253
  45. package/skills/fullstack-expert/scripts/architecture_analyzer.py +326 -326
  46. package/skills/gemini-agent-booster/SKILL.md +135 -135
  47. package/skills/global-a11y-i18n-expert/SKILL.md +81 -81
  48. package/skills/glsl-shader-expert/SKILL.md +101 -0
  49. package/skills/go-programming-expert/SKILL.md +295 -295
  50. package/skills/graphql-apollo-expert/SKILL.md +108 -0
  51. package/skills/hig/SKILL.md +188 -188
  52. package/skills/hyper-context-synthesizer/SKILL.md +55 -0
  53. package/skills/js-backend-expert/SKILL.md +34 -9
  54. package/skills/legacy-code-translator/SKILL.md +65 -0
  55. package/skills/llm-cost-arbitrage-router/SKILL.md +59 -0
  56. package/skills/logging-error-tracking-expert/SKILL.md +338 -0
  57. package/skills/mcp-client-orchestrator/SKILL.md +70 -0
  58. package/skills/mcp-server-architect/SKILL.md +194 -194
  59. package/skills/micro-frontend-architect/SKILL.md +106 -0
  60. package/skills/mobile-expo-expert/SKILL.md +186 -186
  61. package/skills/mobile-push-notification-expert/SKILL.md +51 -0
  62. package/skills/monday-design-aesthetic/SKILL.md +67 -67
  63. package/skills/monorepo-architect/SKILL.md +227 -227
  64. package/skills/mpa-orchestrator/SKILL.md +101 -101
  65. package/skills/multi-agent-orchestration/SKILL.md +234 -234
  66. package/skills/multiple-entry-points/SKILL.md +55 -55
  67. package/skills/mvc-expert/SKILL.md +231 -231
  68. package/skills/payment-gateway-expert/SKILL.md +45 -45
  69. package/skills/performance-web-vitals/SKILL.md +332 -332
  70. package/skills/post-quantum-crypto-migrator/SKILL.md +57 -0
  71. package/skills/prd-architect/SKILL.md +201 -191
  72. package/skills/proactive-background-watcher/SKILL.md +62 -0
  73. package/skills/production-ready-hardener/PRODUCTION_READINESS_REPORT.md +67 -0
  74. package/skills/production-ready-hardener/SKILL.md +173 -186
  75. package/skills/production-ready-hardener/references/production_checklist.md +161 -161
  76. package/skills/production-ready-hardener/scripts/production_readiness_scanner.py +881 -875
  77. package/skills/project-context-mapper/SKILL.md +79 -0
  78. package/skills/python-programming-expert/SKILL.md +263 -132
  79. package/skills/rate-limit-abuse-prevention/SKILL.md +371 -0
  80. package/skills/realtime-collaboration-expert/SKILL.md +45 -45
  81. package/skills/rust-programming-expert/SKILL.md +235 -235
  82. package/skills/saas-billing/SKILL.md +377 -377
  83. package/skills/saas-multi-tenant/SKILL.md +251 -237
  84. package/skills/saas-mvp-launcher/SKILL.md +10 -0
  85. package/skills/saas-transformer/SKILL.md +187 -144
  86. package/skills/saas-transformer/references/billing_integration_guide.md +401 -401
  87. package/skills/saas-transformer/references/feature_gating_patterns.md +137 -137
  88. package/skills/saas-transformer/references/saas_transformation_checklist.md +121 -121
  89. package/skills/saas-transformer/scripts/saas_transformation_scanner.py +39 -29
  90. package/skills/scalability-clean-code/SKILL.md +229 -229
  91. package/skills/self-evolving-memory-graph/SKILL.md +75 -0
  92. package/skills/self-healing-cloud-orchestrator/SKILL.md +57 -0
  93. package/skills/senior-frontend/SKILL.md +161 -161
  94. package/skills/senior-fullstack/SKILL.md +167 -167
  95. package/skills/seo/SKILL.md +235 -225
  96. package/skills/seo-geo/SKILL.md +188 -188
  97. package/skills/session-context-loader/SKILL.md +77 -0
  98. package/skills/session-handoff-resume/SKILL.md +158 -158
  99. package/skills/skill_baru/SKILL.md +172 -147
  100. package/skills/spa-orchestrator/SKILL.md +288 -288
  101. package/skills/state-management-expert/SKILL.md +272 -272
  102. package/skills/supabase-security-expert/SKILL.md +243 -243
  103. package/skills/tailwind-expert/SKILL.md +188 -188
  104. package/skills/tanstack-query-expert/SKILL.md +199 -199
  105. package/skills/token-saver/SKILL.md +119 -111
  106. package/skills/typescript-expert/SKILL.md +324 -279
  107. package/skills/ui-components-expert/SKILL.md +263 -46
  108. package/skills/ui-ux-pro-max/SKILL.md +202 -201
  109. package/skills/ui-ux-pro-max/scripts/__pycache__/core.cpython-310.pyc +0 -0
  110. package/skills/ui-ux-pro-max/scripts/__pycache__/design_system.cpython-310.pyc +0 -0
  111. package/skills/ui_ux_expert/SKILL.md +17 -6
  112. package/skills/vector-db-rag-expert/SKILL.md +52 -0
  113. package/skills/vibe-code-gardener/SKILL.md +181 -173
  114. package/skills/visual-qa-vision-agent/SKILL.md +65 -0
  115. package/skills/vue-frontend-expert/SKILL.md +126 -0
  116. package/skills/web-3d-graphics-expert/SKILL.md +131 -0
  117. package/skills/web-game-engine-expert/SKILL.md +96 -0
  118. package/skills/web-scraper/SKILL.md +207 -205
  119. package/skills/website-design-cloner/SKILL.md +174 -0
  120. package/skills/webxr-ar-vr-expert/SKILL.md +117 -0
  121. package/skills/zero-to-prod-orchestrator/SKILL.md +206 -180
  122. package/skills/zero-trust-secret-vault/SKILL.md +40 -0
  123. package/vibes-swarm-demo.gif +0 -0
@@ -1,315 +1,315 @@
1
- ---
2
- name: e2e-testing-expert
3
- description: "Expert guide for End-to-End (E2E) testing with Playwright, unit/integration testing with Vitest, and CI/CD automated testing pipeline setup / Panduan ahli pengujian End-to-End (E2E) dengan Playwright, pengujian unit/integrasi dengan Vitest, dan otomatisasi CI/CD."
4
- author: "Roedy Rustam"
5
- ---
6
-
7
- # E2E Testing Expert (Playwright 1.49+ / Vitest 3 Edition)
8
-
9
- [English](#english) | [Bahasa Indonesia](#bahasa-indonesia)
10
-
11
- ---
12
-
13
- <a name="english"></a>
14
- ## English
15
-
16
- ### Description
17
- Expert guide for building comprehensive automated test suites using **Playwright 1.49+** (E2E + component testing), **Vitest 3** (unit/integration), and robust CI/CD pipelines. Covers modern testing patterns for Next.js 15, React 19, and API backends.
18
-
19
- ### Trigger Conditions
20
- - Writing E2E tests for web applications with Playwright.
21
- - Writing unit or integration tests with Vitest.
22
- - Setting up a full automated testing pipeline in GitHub Actions / GitLab CI.
23
- - Testing React components in isolation with Playwright Component Testing.
24
- - Mocking external services (APIs, databases) in tests.
25
- - Setting up visual regression tests.
26
-
27
- ### Playwright 1.49+ — Key Updates
28
-
29
- #### New in 2026
30
- - **`aria-snapshot`**: Assert the accessibility tree as a snapshot — more semantic than DOM snapshots.
31
- - **`page.addLocatorHandler()`**: Handle dynamic UI (modals, cookie banners) automatically.
32
- - **WebSocket testing**: Built-in `page.expectWebSocketEvent()`.
33
- - **Playwright MCP Server**: Expose a Playwright browser to AI agents via MCP tools.
34
-
35
- #### Project Configuration
36
- ```typescript
37
- // playwright.config.ts
38
- import { defineConfig, devices } from '@playwright/test';
39
-
40
- export default defineConfig({
41
- testDir: './tests/e2e',
42
- fullyParallel: true,
43
- forbidOnly: !!process.env.CI,
44
- retries: process.env.CI ? 2 : 0,
45
- workers: process.env.CI ? 4 : undefined,
46
- reporter: [
47
- ['html', { open: 'never' }],
48
- ['junit', { outputFile: 'results.xml' }],
49
- ],
50
- use: {
51
- baseURL: process.env.PLAYWRIGHT_BASE_URL ?? 'http://localhost:3000',
52
- trace: 'on-first-retry',
53
- screenshot: 'only-on-failure',
54
- video: 'on-first-retry',
55
- },
56
- projects: [
57
- // Setup: seed test DB
58
- { name: 'setup', testMatch: /.*\.setup\.ts/ },
59
- {
60
- name: 'chromium',
61
- use: { ...devices['Desktop Chrome'] },
62
- dependencies: ['setup'],
63
- },
64
- {
65
- name: 'mobile-chrome',
66
- use: { ...devices['Pixel 7'] },
67
- dependencies: ['setup'],
68
- },
69
- ],
70
- webServer: {
71
- command: 'npm run dev',
72
- url: 'http://localhost:3000',
73
- reuseExistingServer: !process.env.CI,
74
- },
75
- });
76
- ```
77
-
78
- #### Page Object Model (POM)
79
- ```typescript
80
- // tests/e2e/pages/LoginPage.ts
81
- import { type Page, type Locator, expect } from '@playwright/test';
82
-
83
- export class LoginPage {
84
- readonly page: Page;
85
- readonly emailInput: Locator;
86
- readonly passwordInput: Locator;
87
- readonly submitButton: Locator;
88
-
89
- constructor(page: Page) {
90
- this.page = page;
91
- this.emailInput = page.getByLabel('Email');
92
- this.passwordInput = page.getByLabel('Password');
93
- this.submitButton = page.getByRole('button', { name: 'Sign in' });
94
- }
95
-
96
- async goto() {
97
- await this.page.goto('/login');
98
- }
99
-
100
- async login(email: string, password: string) {
101
- await this.emailInput.fill(email);
102
- await this.passwordInput.fill(password);
103
- await this.submitButton.click();
104
- await this.page.waitForURL('/dashboard');
105
- }
106
- }
107
- ```
108
-
109
- #### API Mocking with `page.route()`
110
- ```typescript
111
- test('shows error when API fails', async ({ page }) => {
112
- // Intercept and mock API response
113
- await page.route('**/api/users', (route) => {
114
- route.fulfill({
115
- status: 500,
116
- body: JSON.stringify({ error: 'Internal server error' }),
117
- contentType: 'application/json',
118
- });
119
- });
120
-
121
- await page.goto('/users');
122
- await expect(page.getByRole('alert')).toContainText('Something went wrong');
123
- });
124
- ```
125
-
126
- #### Accessibility Assertions (aria-snapshot)
127
- ```typescript
128
- test('navigation is accessible', async ({ page }) => {
129
- await page.goto('/');
130
-
131
- // Assert accessibility tree structure
132
- await expect(page.locator('nav')).toMatchAriaSnapshot(`
133
- - navigation:
134
- - link "Home"
135
- - link "Products"
136
- - link "Pricing"
137
- - link "Sign in"
138
- `);
139
- });
140
- ```
141
-
142
- #### Auth State Reuse (storageState)
143
- ```typescript
144
- // tests/e2e/auth.setup.ts
145
- import { test as setup } from '@playwright/test';
146
-
147
- setup('authenticate', async ({ page }) => {
148
- await page.goto('/login');
149
- await page.getByLabel('Email').fill('test@example.com');
150
- await page.getByLabel('Password').fill('password');
151
- await page.getByRole('button', { name: 'Sign in' }).click();
152
- await page.waitForURL('/dashboard');
153
-
154
- // Save session state for reuse in all tests
155
- await page.context().storageState({ path: 'playwright/.auth/user.json' });
156
- });
157
-
158
- // tests/e2e/dashboard.spec.ts
159
- import { test } from '@playwright/test';
160
-
161
- test.use({ storageState: 'playwright/.auth/user.json' });
162
-
163
- test('dashboard loads correctly', async ({ page }) => {
164
- await page.goto('/dashboard');
165
- // Already authenticated — no login needed
166
- });
167
- ```
168
-
169
- ### Vitest 3 — Unit & Integration Testing
170
-
171
- #### Configuration
172
- ```typescript
173
- // vitest.config.ts
174
- import { defineConfig } from 'vitest/config';
175
- import react from '@vitejs/plugin-react';
176
-
177
- export default defineConfig({
178
- plugins: [react()],
179
- test: {
180
- environment: 'jsdom',
181
- globals: true,
182
- setupFiles: ['./tests/setup.ts'],
183
- coverage: {
184
- provider: 'v8',
185
- reporter: ['text', 'lcov', 'html'],
186
- thresholds: { lines: 80, functions: 80 },
187
- },
188
- },
189
- });
190
- ```
191
-
192
- #### React Component Testing
193
- ```typescript
194
- import { render, screen, userEvent } from '@testing-library/react';
195
- import { describe, it, expect, vi } from 'vitest';
196
- import { Counter } from './Counter';
197
-
198
- describe('Counter', () => {
199
- it('increments count on button click', async () => {
200
- const user = userEvent.setup();
201
- render(<Counter initialCount={0} />);
202
-
203
- await user.click(screen.getByRole('button', { name: 'Increment' }));
204
-
205
- expect(screen.getByText('Count: 1')).toBeInTheDocument();
206
- });
207
-
208
- it('calls onMaxReached when limit hit', async () => {
209
- const onMaxReached = vi.fn();
210
- const user = userEvent.setup();
211
- render(<Counter initialCount={9} max={10} onMaxReached={onMaxReached} />);
212
-
213
- await user.click(screen.getByRole('button', { name: 'Increment' }));
214
-
215
- expect(onMaxReached).toHaveBeenCalledOnce();
216
- });
217
- });
218
- ```
219
-
220
- #### Server Action / API Route Testing
221
- ```typescript
222
- import { describe, it, expect, beforeEach } from 'vitest';
223
- import { testClient } from 'hono/testing';
224
- import { app } from '../src/server';
225
- import { resetTestDb } from './helpers/db';
226
-
227
- describe('POST /api/users', () => {
228
- beforeEach(resetTestDb);
229
-
230
- it('creates a new user', async () => {
231
- const client = testClient(app);
232
- const res = await client.api.users.$post({
233
- json: { name: 'Alice', email: 'alice@example.com' },
234
- });
235
-
236
- expect(res.status).toBe(201);
237
- const data = await res.json();
238
- expect(data.email).toBe('alice@example.com');
239
- });
240
- });
241
- ```
242
-
243
- ### GitHub Actions CI Pipeline
244
- ```yaml
245
- # .github/workflows/test.yml
246
- name: CI Tests
247
-
248
- on: [push, pull_request]
249
-
250
- jobs:
251
- unit:
252
- runs-on: ubuntu-latest
253
- steps:
254
- - uses: actions/checkout@v4
255
- - uses: actions/setup-node@v4
256
- with: { node-version: '22', cache: 'pnpm' }
257
- - run: pnpm install --frozen-lockfile
258
- - run: pnpm run typecheck
259
- - run: pnpm run test:unit --coverage
260
-
261
- e2e:
262
- runs-on: ubuntu-latest
263
- steps:
264
- - uses: actions/checkout@v4
265
- - uses: actions/setup-node@v4
266
- with: { node-version: '22', cache: 'pnpm' }
267
- - run: pnpm install --frozen-lockfile
268
- - run: pnpm exec playwright install --with-deps chromium
269
- - run: pnpm run test:e2e
270
- - uses: actions/upload-artifact@v4
271
- if: failure()
272
- with:
273
- name: playwright-report
274
- path: playwright-report/
275
- ```
276
-
277
- ---
278
-
279
- <a name="bahasa-indonesia"></a>
280
- ## Bahasa Indonesia
281
-
282
- ### Deskripsi
283
- Panduan ahli untuk membangun test suite otomatis yang komprehensif menggunakan **Playwright 1.49+** (E2E + component testing), **Vitest 3** (unit/integrasi), dan pipeline CI/CD yang kuat. Mencakup pola pengujian modern untuk Next.js 15, React 19, dan backend API.
284
-
285
- ### Kondisi Pemicu
286
- - Menulis E2E test untuk aplikasi web dengan Playwright.
287
- - Menulis unit atau integration test dengan Vitest.
288
- - Menyiapkan pipeline pengujian otomatis di GitHub Actions / GitLab CI.
289
- - Menguji komponen React secara terisolasi.
290
- - Mocking layanan eksternal (API, database) dalam test.
291
- - Menyiapkan visual regression test.
292
-
293
- ### Playwright 1.49+ — Fitur Baru 2026
294
- - **`aria-snapshot`**: Assert accessibility tree sebagai snapshot.
295
- - **`page.addLocatorHandler()`**: Tangani UI dinamis (modal, cookie banner) secara otomatis.
296
- - **WebSocket testing**: `page.expectWebSocketEvent()` bawaan.
297
- - **Playwright MCP Server**: Ekspos browser Playwright ke agen AI via MCP.
298
-
299
- ### Page Object Model (POM)
300
- Enkapsulasi selektor dan tindakan halaman dalam kelas terpisah untuk mengurangi duplikasi dan meningkatkan keterbacaan test.
301
-
302
- ### Mocking API dengan `page.route()`
303
- Gunakan `page.route()` untuk mencegat permintaan jaringan dan mengembalikan respons palsu — mengisolasi frontend dari backend dalam E2E test.
304
-
305
- ### Aksesibilitas dengan aria-snapshot
306
- Gunakan `toMatchAriaSnapshot()` untuk memvalidasi struktur aksesibilitas navigasi, form, dan komponen interaktif — lebih semantis dari snapshot DOM biasa.
307
-
308
- ### Auth State Reuse (storageState)
309
- Gunakan `storageState` untuk menyimpan state sesi setelah login sekali dan menggunakannya kembali di semua test yang memerlukan autentikasi — menghemat waktu secara signifikan.
310
-
311
- ### Vitest 3 — Unit & Integration Testing
312
- Vitest 3 adalah test runner yang cepat berbasis Vite dengan kompatibilitas Jest penuh. Gunakan untuk unit test React component, server action, dan logika bisnis.
313
-
314
- ### Pipeline CI GitHub Actions
315
- Pisahkan job `unit` dan `e2e` untuk feedback paralel yang lebih cepat. Upload `playwright-report` sebagai artifact saat gagal untuk debugging.
1
+ ---
2
+ name: e2e-testing-expert
3
+ description: "Expert guide for End-to-End (E2E) testing with Playwright, unit/integration testing with Vitest, and CI/CD automated testing pipeline setup / Panduan ahli pengujian End-to-End (E2E) dengan Playwright, pengujian unit/integrasi dengan Vitest, dan otomatisasi CI/CD."
4
+ author: "Roedy Rustam"
5
+ ---
6
+
7
+ # E2E Testing Expert (Playwright 1.49+ / Vitest 3 Edition)
8
+
9
+ [English](#english) | [Bahasa Indonesia](#bahasa-indonesia)
10
+
11
+ ---
12
+
13
+ <a name="english"></a>
14
+ ## English
15
+
16
+ ### Description
17
+ Expert guide for building comprehensive automated test suites using **Playwright 1.49+** (E2E + component testing), **Vitest 3** (unit/integration), and robust CI/CD pipelines. Covers modern testing patterns for Next.js 15, React 19, and API backends.
18
+
19
+ ### Trigger Conditions
20
+ - Writing E2E tests for web applications with Playwright.
21
+ - Writing unit or integration tests with Vitest.
22
+ - Setting up a full automated testing pipeline in GitHub Actions / GitLab CI.
23
+ - Testing React components in isolation with Playwright Component Testing.
24
+ - Mocking external services (APIs, databases) in tests.
25
+ - Setting up visual regression tests.
26
+
27
+ ### Playwright 1.49+ — Key Updates
28
+
29
+ #### New in 2026
30
+ - **`aria-snapshot`**: Assert the accessibility tree as a snapshot — more semantic than DOM snapshots.
31
+ - **`page.addLocatorHandler()`**: Handle dynamic UI (modals, cookie banners) automatically.
32
+ - **WebSocket testing**: Built-in `page.expectWebSocketEvent()`.
33
+ - **Playwright MCP Server**: Expose a Playwright browser to AI agents via MCP tools.
34
+
35
+ #### Project Configuration
36
+ ```typescript
37
+ // playwright.config.ts
38
+ import { defineConfig, devices } from '@playwright/test';
39
+
40
+ export default defineConfig({
41
+ testDir: './tests/e2e',
42
+ fullyParallel: true,
43
+ forbidOnly: !!process.env.CI,
44
+ retries: process.env.CI ? 2 : 0,
45
+ workers: process.env.CI ? 4 : undefined,
46
+ reporter: [
47
+ ['html', { open: 'never' }],
48
+ ['junit', { outputFile: 'results.xml' }],
49
+ ],
50
+ use: {
51
+ baseURL: process.env.PLAYWRIGHT_BASE_URL ?? 'http://localhost:3000',
52
+ trace: 'on-first-retry',
53
+ screenshot: 'only-on-failure',
54
+ video: 'on-first-retry',
55
+ },
56
+ projects: [
57
+ // Setup: seed test DB
58
+ { name: 'setup', testMatch: /.*\.setup\.ts/ },
59
+ {
60
+ name: 'chromium',
61
+ use: { ...devices['Desktop Chrome'] },
62
+ dependencies: ['setup'],
63
+ },
64
+ {
65
+ name: 'mobile-chrome',
66
+ use: { ...devices['Pixel 7'] },
67
+ dependencies: ['setup'],
68
+ },
69
+ ],
70
+ webServer: {
71
+ command: 'npm run dev',
72
+ url: 'http://localhost:3000',
73
+ reuseExistingServer: !process.env.CI,
74
+ },
75
+ });
76
+ ```
77
+
78
+ #### Page Object Model (POM)
79
+ ```typescript
80
+ // tests/e2e/pages/LoginPage.ts
81
+ import { type Page, type Locator, expect } from '@playwright/test';
82
+
83
+ export class LoginPage {
84
+ readonly page: Page;
85
+ readonly emailInput: Locator;
86
+ readonly passwordInput: Locator;
87
+ readonly submitButton: Locator;
88
+
89
+ constructor(page: Page) {
90
+ this.page = page;
91
+ this.emailInput = page.getByLabel('Email');
92
+ this.passwordInput = page.getByLabel('Password');
93
+ this.submitButton = page.getByRole('button', { name: 'Sign in' });
94
+ }
95
+
96
+ async goto() {
97
+ await this.page.goto('/login');
98
+ }
99
+
100
+ async login(email: string, password: string) {
101
+ await this.emailInput.fill(email);
102
+ await this.passwordInput.fill(password);
103
+ await this.submitButton.click();
104
+ await this.page.waitForURL('/dashboard');
105
+ }
106
+ }
107
+ ```
108
+
109
+ #### API Mocking with `page.route()`
110
+ ```typescript
111
+ test('shows error when API fails', async ({ page }) => {
112
+ // Intercept and mock API response
113
+ await page.route('**/api/users', (route) => {
114
+ route.fulfill({
115
+ status: 500,
116
+ body: JSON.stringify({ error: 'Internal server error' }),
117
+ contentType: 'application/json',
118
+ });
119
+ });
120
+
121
+ await page.goto('/users');
122
+ await expect(page.getByRole('alert')).toContainText('Something went wrong');
123
+ });
124
+ ```
125
+
126
+ #### Accessibility Assertions (aria-snapshot)
127
+ ```typescript
128
+ test('navigation is accessible', async ({ page }) => {
129
+ await page.goto('/');
130
+
131
+ // Assert accessibility tree structure
132
+ await expect(page.locator('nav')).toMatchAriaSnapshot(`
133
+ - navigation:
134
+ - link "Home"
135
+ - link "Products"
136
+ - link "Pricing"
137
+ - link "Sign in"
138
+ `);
139
+ });
140
+ ```
141
+
142
+ #### Auth State Reuse (storageState)
143
+ ```typescript
144
+ // tests/e2e/auth.setup.ts
145
+ import { test as setup } from '@playwright/test';
146
+
147
+ setup('authenticate', async ({ page }) => {
148
+ await page.goto('/login');
149
+ await page.getByLabel('Email').fill('test@example.com');
150
+ await page.getByLabel('Password').fill('password');
151
+ await page.getByRole('button', { name: 'Sign in' }).click();
152
+ await page.waitForURL('/dashboard');
153
+
154
+ // Save session state for reuse in all tests
155
+ await page.context().storageState({ path: 'playwright/.auth/user.json' });
156
+ });
157
+
158
+ // tests/e2e/dashboard.spec.ts
159
+ import { test } from '@playwright/test';
160
+
161
+ test.use({ storageState: 'playwright/.auth/user.json' });
162
+
163
+ test('dashboard loads correctly', async ({ page }) => {
164
+ await page.goto('/dashboard');
165
+ // Already authenticated — no login needed
166
+ });
167
+ ```
168
+
169
+ ### Vitest 3 — Unit & Integration Testing
170
+
171
+ #### Configuration
172
+ ```typescript
173
+ // vitest.config.ts
174
+ import { defineConfig } from 'vitest/config';
175
+ import react from '@vitejs/plugin-react';
176
+
177
+ export default defineConfig({
178
+ plugins: [react()],
179
+ test: {
180
+ environment: 'jsdom',
181
+ globals: true,
182
+ setupFiles: ['./tests/setup.ts'],
183
+ coverage: {
184
+ provider: 'v8',
185
+ reporter: ['text', 'lcov', 'html'],
186
+ thresholds: { lines: 80, functions: 80 },
187
+ },
188
+ },
189
+ });
190
+ ```
191
+
192
+ #### React Component Testing
193
+ ```typescript
194
+ import { render, screen, userEvent } from '@testing-library/react';
195
+ import { describe, it, expect, vi } from 'vitest';
196
+ import { Counter } from './Counter';
197
+
198
+ describe('Counter', () => {
199
+ it('increments count on button click', async () => {
200
+ const user = userEvent.setup();
201
+ render(<Counter initialCount={0} />);
202
+
203
+ await user.click(screen.getByRole('button', { name: 'Increment' }));
204
+
205
+ expect(screen.getByText('Count: 1')).toBeInTheDocument();
206
+ });
207
+
208
+ it('calls onMaxReached when limit hit', async () => {
209
+ const onMaxReached = vi.fn();
210
+ const user = userEvent.setup();
211
+ render(<Counter initialCount={9} max={10} onMaxReached={onMaxReached} />);
212
+
213
+ await user.click(screen.getByRole('button', { name: 'Increment' }));
214
+
215
+ expect(onMaxReached).toHaveBeenCalledOnce();
216
+ });
217
+ });
218
+ ```
219
+
220
+ #### Server Action / API Route Testing
221
+ ```typescript
222
+ import { describe, it, expect, beforeEach } from 'vitest';
223
+ import { testClient } from 'hono/testing';
224
+ import { app } from '../src/server';
225
+ import { resetTestDb } from './helpers/db';
226
+
227
+ describe('POST /api/users', () => {
228
+ beforeEach(resetTestDb);
229
+
230
+ it('creates a new user', async () => {
231
+ const client = testClient(app);
232
+ const res = await client.api.users.$post({
233
+ json: { name: 'Alice', email: 'alice@example.com' },
234
+ });
235
+
236
+ expect(res.status).toBe(201);
237
+ const data = await res.json();
238
+ expect(data.email).toBe('alice@example.com');
239
+ });
240
+ });
241
+ ```
242
+
243
+ ### GitHub Actions CI Pipeline
244
+ ```yaml
245
+ # .github/workflows/test.yml
246
+ name: CI Tests
247
+
248
+ on: [push, pull_request]
249
+
250
+ jobs:
251
+ unit:
252
+ runs-on: ubuntu-latest
253
+ steps:
254
+ - uses: actions/checkout@v4
255
+ - uses: actions/setup-node@v4
256
+ with: { node-version: '22', cache: 'pnpm' }
257
+ - run: pnpm install --frozen-lockfile
258
+ - run: pnpm run typecheck
259
+ - run: pnpm run test:unit --coverage
260
+
261
+ e2e:
262
+ runs-on: ubuntu-latest
263
+ steps:
264
+ - uses: actions/checkout@v4
265
+ - uses: actions/setup-node@v4
266
+ with: { node-version: '22', cache: 'pnpm' }
267
+ - run: pnpm install --frozen-lockfile
268
+ - run: pnpm exec playwright install --with-deps chromium
269
+ - run: pnpm run test:e2e
270
+ - uses: actions/upload-artifact@v4
271
+ if: failure()
272
+ with:
273
+ name: playwright-report
274
+ path: playwright-report/
275
+ ```
276
+
277
+ ---
278
+
279
+ <a name="bahasa-indonesia"></a>
280
+ ## Bahasa Indonesia
281
+
282
+ ### Deskripsi
283
+ Panduan ahli untuk membangun test suite otomatis yang komprehensif menggunakan **Playwright 1.49+** (E2E + component testing), **Vitest 3** (unit/integrasi), dan pipeline CI/CD yang kuat. Mencakup pola pengujian modern untuk Next.js 15, React 19, dan backend API.
284
+
285
+ ### Kondisi Pemicu
286
+ - Menulis E2E test untuk aplikasi web dengan Playwright.
287
+ - Menulis unit atau integration test dengan Vitest.
288
+ - Menyiapkan pipeline pengujian otomatis di GitHub Actions / GitLab CI.
289
+ - Menguji komponen React secara terisolasi.
290
+ - Mocking layanan eksternal (API, database) dalam test.
291
+ - Menyiapkan visual regression test.
292
+
293
+ ### Playwright 1.49+ — Fitur Baru 2026
294
+ - **`aria-snapshot`**: Assert accessibility tree sebagai snapshot.
295
+ - **`page.addLocatorHandler()`**: Tangani UI dinamis (modal, cookie banner) secara otomatis.
296
+ - **WebSocket testing**: `page.expectWebSocketEvent()` bawaan.
297
+ - **Playwright MCP Server**: Ekspos browser Playwright ke agen AI via MCP.
298
+
299
+ ### Page Object Model (POM)
300
+ Enkapsulasi selektor dan tindakan halaman dalam kelas terpisah untuk mengurangi duplikasi dan meningkatkan keterbacaan test.
301
+
302
+ ### Mocking API dengan `page.route()`
303
+ Gunakan `page.route()` untuk mencegat permintaan jaringan dan mengembalikan respons palsu — mengisolasi frontend dari backend dalam E2E test.
304
+
305
+ ### Aksesibilitas dengan aria-snapshot
306
+ Gunakan `toMatchAriaSnapshot()` untuk memvalidasi struktur aksesibilitas navigasi, form, dan komponen interaktif — lebih semantis dari snapshot DOM biasa.
307
+
308
+ ### Auth State Reuse (storageState)
309
+ Gunakan `storageState` untuk menyimpan state sesi setelah login sekali dan menggunakannya kembali di semua test yang memerlukan autentikasi — menghemat waktu secara signifikan.
310
+
311
+ ### Vitest 3 — Unit & Integration Testing
312
+ Vitest 3 adalah test runner yang cepat berbasis Vite dengan kompatibilitas Jest penuh. Gunakan untuk unit test React component, server action, dan logika bisnis.
313
+
314
+ ### Pipeline CI GitHub Actions
315
+ Pisahkan job `unit` dan `e2e` untuk feedback paralel yang lebih cepat. Upload `playwright-report` sebagai artifact saat gagal untuk debugging.
@@ -0,0 +1,43 @@
1
+ ---
2
+ name: edge-serverless-db-expert
3
+ description: "Expert guide for Serverless & Edge Databases (Neon Serverless Postgres, Cloudflare D1, Turso/libsql, Upstash Redis), cold-start mitigation, and connection pooling / Panduan ahli database Serverless & Edge (Neon, Cloudflare D1, Turso, Upstash)."
4
+ author: "Roedy Rustam"
5
+ ---
6
+
7
+ # Edge & Serverless DB Expert
8
+
9
+ [English](#english) | [Bahasa Indonesia](#bahasa-indonesia)
10
+
11
+ ---
12
+
13
+ <a name="english"></a>
14
+ ## English
15
+
16
+ ### Purpose & Overview
17
+ Best practices for building ultra-low-latency applications powered by serverless and edge databases — Neon Serverless Postgres, Cloudflare D1 (SQLite at Edge), Turso (libsql distributed SQLite), Upstash Serverless Redis & Vector, HTTP connection pooling via Hyperdrive/Prisma Accelerate, and zero-cold-start strategies.
18
+
19
+ ### Key Capabilities
20
+ - **Neon & Cloudflare D1**: Serverless autoscaling Postgres with instant branching and distributed edge SQLite.
21
+ - **Connection Pooling**: WebSocket/HTTP proxy pooling (Neon Serverless Driver, Upstash Redis over HTTP) for edge workers without TCP pool exhaustion.
22
+ - **Embedded Replicas**: Syncing edge SQLite read-replicas with central cloud databases for sub-10ms queries.
23
+
24
+ ```typescript
25
+ import { neon } from '@neondatabase/serverless';
26
+ import { drizzle } from 'drizzle-orm/neon-http';
27
+
28
+ const sql = neon(process.env.DATABASE_URL!);
29
+ export const db = drizzle({ client: sql });
30
+ ```
31
+
32
+ ---
33
+
34
+ <a name="bahasa-indonesia"></a>
35
+ ## Bahasa Indonesia
36
+
37
+ ### Deskripsi
38
+ Praktik terbaik membangun aplikasi latensi rendah dengan database serverless dan edge — Neon Serverless Postgres, Cloudflare D1 (SQLite di Edge), Turso (libsql terdistribusi), Upstash Serverless Redis & Vector, connection pooling HTTP/WebSocket, dan mitigasi cold-start.
39
+
40
+ ### Fitur Utama
41
+ - **Neon & Cloudflare D1**: Serverless Postgres autoscaling dengan branching instan dan distributed edge SQLite.
42
+ - **Connection Pooling**: Proxy pooling HTTP/WebSocket untuk edge worker tanpa risiko kehabisan koneksi TCP.
43
+ - **Embedded Replicas**: Sinkronisasi read-replica SQLite di edge dengan database utama untuk query di bawah 10ms.