vibes-plug 1.0.0 → 2.11.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 (183) hide show
  1. package/.claude/rules/vibes-plug-core.md +32 -0
  2. package/.cursor/rules/vibes-plug-core.mdc +51 -0
  3. package/.cursorrules +42 -0
  4. package/AGENTS.md +96 -0
  5. package/BLUEPRINT.md +309 -125
  6. package/CHANGELOG.md +183 -1
  7. package/CLAUDE.md +70 -0
  8. package/LICENSE +1 -1
  9. package/README.md +641 -263
  10. package/index.js +19 -0
  11. package/package.json +61 -25
  12. package/plugin.json +24 -7
  13. package/scripts/generate_swarm_gif.py +295 -0
  14. package/scripts/install.js +201 -0
  15. package/skills/accessibility-testing-expert/SKILL.md +116 -0
  16. package/skills/ai-cost-token-optimizer/SKILL.md +82 -0
  17. package/skills/ai-evals-benchmark-expert/SKILL.md +188 -0
  18. package/skills/ai-llm-integration-expert/SKILL.md +147 -122
  19. package/skills/ai-media-generation-expert/SKILL.md +172 -0
  20. package/skills/ai-prompt-engineering-expert/SKILL.md +84 -0
  21. package/skills/angular-expert/SKILL.md +148 -0
  22. package/skills/api-design-expert/SKILL.md +316 -309
  23. package/skills/api-gateway-proxy-expert/SKILL.md +81 -0
  24. package/skills/app-analyzer-optimizer/SKILL.md +195 -188
  25. package/skills/apple-ecosystem-expert/SKILL.md +145 -0
  26. package/skills/{asisten_ramah → asisten-ramah}/SKILL.md +7 -1
  27. package/skills/astro-framework-expert/SKILL.md +200 -0
  28. package/skills/async-queue-temporal-expert/SKILL.md +240 -0
  29. package/skills/authentication-identity-expert/SKILL.md +279 -45
  30. package/skills/auto-doc-updater/SKILL.md +219 -203
  31. package/skills/autonomous-chaos-monkey/SKILL.md +63 -0
  32. package/skills/autonomous-red-teamer/SKILL.md +203 -0
  33. package/skills/autonomous-tdd-debugger/SKILL.md +71 -0
  34. package/skills/background-jobs-queue-expert/SKILL.md +235 -0
  35. package/skills/biome-linter-formatter-expert/SKILL.md +89 -0
  36. package/skills/blockchain-web3-expert/SKILL.md +115 -0
  37. package/skills/bootstrap-to-modern/SKILL.md +93 -86
  38. package/skills/brainstorming/SKILL.md +381 -353
  39. package/skills/browser-automation-expert/SKILL.md +222 -0
  40. package/skills/bun-runtime-expert/SKILL.md +7 -1
  41. package/skills/chatbot-messaging-expert/SKILL.md +114 -0
  42. package/skills/ci-cd-devops-architect/SKILL.md +81 -45
  43. package/skills/cloud-hosting-expert/SKILL.md +249 -243
  44. package/skills/coderabbit/SKILL.md +197 -191
  45. package/skills/compliance-gdpr-privacy-expert/SKILL.md +85 -0
  46. package/skills/cron-scheduler-expert/SKILL.md +304 -0
  47. package/skills/data-pipeline-etl-expert/SKILL.md +84 -0
  48. package/skills/data-telemetry-expert/SKILL.md +218 -212
  49. package/skills/data-visualization-expert/SKILL.md +154 -0
  50. package/skills/database-migration-versioning-expert/SKILL.md +90 -0
  51. package/skills/database-orm-expert/SKILL.md +303 -293
  52. package/skills/dependency-upgrade-migrator/SKILL.md +301 -0
  53. package/skills/design-system-architect/SKILL.md +278 -242
  54. package/skills/desktop-electron-expert/SKILL.md +128 -0
  55. package/skills/documentation-site-expert/SKILL.md +59 -0
  56. package/skills/doku-mcp-server/SKILL.md +257 -0
  57. package/skills/doku-payment-gateway/SKILL.md +233 -0
  58. package/skills/domain-driven-design-expert/SKILL.md +82 -0
  59. package/skills/e2e-testing-expert/SKILL.md +320 -314
  60. package/skills/ecommerce-expert/SKILL.md +87 -0
  61. package/skills/edge-serverless-db-expert/SKILL.md +99 -0
  62. package/skills/email-notification-expert/SKILL.md +368 -0
  63. package/skills/error-resilience-expert/SKILL.md +486 -0
  64. package/skills/event-driven-architect/SKILL.md +86 -80
  65. package/skills/feature-flag-analytics-expert/SKILL.md +66 -0
  66. package/skills/file-upload-media-expert/SKILL.md +437 -0
  67. package/skills/firebase-security-expert/SKILL.md +7 -1
  68. package/skills/form-validation-expert/SKILL.md +407 -0
  69. package/skills/fullstack-expert/SKILL.md +260 -201
  70. package/skills/fullstack-expert/references/api_design_guide.md +466 -466
  71. package/skills/fullstack-expert/references/multi_language_backend.md +528 -528
  72. package/skills/fullstack-expert/scripts/api_contract_validator.py +253 -253
  73. package/skills/fullstack-expert/scripts/architecture_analyzer.py +326 -326
  74. package/skills/gemini-agent-booster/SKILL.md +142 -104
  75. package/skills/geospatial-maps-expert/SKILL.md +80 -0
  76. package/skills/global-a11y-i18n-expert/SKILL.md +86 -80
  77. package/skills/glsl-shader-expert/SKILL.md +107 -0
  78. package/skills/go-programming-expert/SKILL.md +300 -294
  79. package/skills/graph-rag-knowledge-expert/SKILL.md +159 -0
  80. package/skills/graphql-apollo-expert/SKILL.md +114 -0
  81. package/skills/headless-cms-expert/SKILL.md +181 -0
  82. package/skills/hig/SKILL.md +193 -187
  83. package/skills/js-backend-expert/SKILL.md +218 -191
  84. package/skills/legacy-code-translator/SKILL.md +71 -0
  85. package/skills/local-slm-edge-ai-expert/SKILL.md +167 -0
  86. package/skills/logging-error-tracking-expert/SKILL.md +344 -0
  87. package/skills/mcp-client-orchestrator/SKILL.md +76 -0
  88. package/skills/mcp-server-architect/SKILL.md +226 -126
  89. package/skills/micro-frontend-architect/SKILL.md +112 -0
  90. package/skills/mobile-expo-expert/SKILL.md +191 -185
  91. package/skills/mobile-push-notification-expert/SKILL.md +71 -0
  92. package/skills/modern-css-native-expert/SKILL.md +189 -0
  93. package/skills/monday-design-aesthetic/SKILL.md +72 -66
  94. package/skills/monorepo-architect/SKILL.md +232 -226
  95. package/skills/mpa-orchestrator/SKILL.md +120 -101
  96. package/skills/multi-agent-orchestration/SKILL.md +173 -153
  97. package/skills/multiple-entry-points/SKILL.md +91 -55
  98. package/skills/mvc-expert/SKILL.md +237 -231
  99. package/skills/n8n-automation-expert/SKILL.md +89 -0
  100. package/skills/nextjs-app-router-expert/SKILL.md +148 -0
  101. package/skills/openapi-swagger-codegen-expert/SKILL.md +67 -0
  102. package/skills/payment-gateway-expert/SKILL.md +129 -45
  103. package/skills/pdf-document-generation-expert/SKILL.md +91 -0
  104. package/skills/performance-web-vitals/SKILL.md +337 -331
  105. package/skills/post-quantum-crypto-migrator/SKILL.md +57 -0
  106. package/skills/prd-architect/SKILL.md +206 -190
  107. package/skills/proactive-background-watcher/SKILL.md +68 -0
  108. package/skills/production-ready-hardener/PRODUCTION_READINESS_REPORT.md +67 -0
  109. package/skills/production-ready-hardener/SKILL.md +461 -468
  110. package/skills/production-ready-hardener/references/production_checklist.md +161 -161
  111. package/skills/production-ready-hardener/scripts/production_readiness_scanner.py +881 -875
  112. package/skills/project-context-mapper/SKILL.md +85 -0
  113. package/skills/pwa-offline-first-expert/SKILL.md +185 -0
  114. package/skills/python-programming-expert/SKILL.md +407 -270
  115. package/skills/rate-limit-abuse-prevention/SKILL.md +377 -0
  116. package/skills/realtime-collaboration-expert/SKILL.md +99 -45
  117. package/skills/rich-text-editor-expert/SKILL.md +177 -0
  118. package/skills/rust-programming-expert/SKILL.md +240 -234
  119. package/skills/saas-billing/SKILL.md +382 -376
  120. package/skills/saas-multi-tenant/SKILL.md +256 -236
  121. package/skills/saas-mvp-launcher/SKILL.md +30 -1
  122. package/skills/saas-transformer/SKILL.md +499 -445
  123. package/skills/saas-transformer/references/billing_integration_guide.md +401 -401
  124. package/skills/saas-transformer/references/feature_gating_patterns.md +137 -137
  125. package/skills/saas-transformer/references/saas_transformation_checklist.md +121 -121
  126. package/skills/saas-transformer/scripts/saas_transformation_scanner.py +39 -29
  127. package/skills/scalability-clean-code/SKILL.md +234 -228
  128. package/skills/search-engine-expert/SKILL.md +89 -0
  129. package/skills/secure-fuzz-testing/SKILL.md +7 -1
  130. package/skills/self-evolving-memory-graph/SKILL.md +91 -0
  131. package/skills/self-healing-cloud-orchestrator/SKILL.md +57 -0
  132. package/skills/senior-frontend/SKILL.md +85 -105
  133. package/skills/seo/SKILL.md +258 -224
  134. package/skills/session-context-loader/SKILL.md +83 -0
  135. package/skills/session-handoff-resume/SKILL.md +163 -157
  136. package/skills/{skill_baru → skill-baru}/SKILL.md +177 -146
  137. package/skills/solidjs-expert/SKILL.md +80 -0
  138. package/skills/spa-orchestrator/SKILL.md +306 -287
  139. package/skills/sse-websocket-streaming-expert/SKILL.md +93 -0
  140. package/skills/state-management-expert/SKILL.md +277 -271
  141. package/skills/supabase-migration/SKILL.md +47 -1
  142. package/skills/supabase-security-expert/SKILL.md +248 -242
  143. package/skills/svelte-sveltekit-expert/SKILL.md +91 -0
  144. package/skills/svg-animation-motion-expert/SKILL.md +115 -0
  145. package/skills/tailwind-expert/SKILL.md +139 -187
  146. package/skills/tanstack-query-expert/SKILL.md +204 -198
  147. package/skills/tauri-expert/SKILL.md +7 -1
  148. package/skills/token-saver/SKILL.md +118 -110
  149. package/skills/typescript-expert/SKILL.md +329 -278
  150. package/skills/ui-components-expert/SKILL.md +166 -63
  151. package/skills/ui-ux-pro-max/SKILL.md +221 -200
  152. package/skills/vector-db-rag-expert/SKILL.md +208 -0
  153. package/skills/vibe-code-gardener/SKILL.md +180 -172
  154. package/skills/visual-qa-vision-agent/SKILL.md +71 -0
  155. package/skills/voice-ai-realtime-agent/SKILL.md +202 -0
  156. package/skills/vue-frontend-expert/SKILL.md +132 -0
  157. package/skills/wasm-edge-computing-expert/SKILL.md +97 -0
  158. package/skills/web-3d-graphics-expert/SKILL.md +137 -0
  159. package/skills/web-game-engine-expert/SKILL.md +102 -0
  160. package/skills/web-scraper/SKILL.md +98 -146
  161. package/skills/website-design-cloner/SKILL.md +180 -0
  162. package/skills/webxr-ar-vr-expert/SKILL.md +123 -0
  163. package/skills/wordpress-headless-expert/SKILL.md +144 -0
  164. package/skills/zero-to-prod-orchestrator/SKILL.md +231 -180
  165. package/skills/zero-trust-secret-vault/SKILL.md +88 -0
  166. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -20
  167. package/CONTRIBUTING.md +0 -199
  168. package/SECURITY.md +0 -21
  169. package/banner.png +0 -0
  170. package/skills/senior-fullstack/SKILL.md +0 -167
  171. package/skills/senior-fullstack/references/architecture_patterns.md +0 -160
  172. package/skills/senior-fullstack/references/development_workflows.md +0 -222
  173. package/skills/senior-fullstack/references/tech_stack_guide.md +0 -190
  174. package/skills/senior-fullstack/scripts/code_quality_analyzer.py +0 -114
  175. package/skills/senior-fullstack/scripts/fullstack_scaffolder.py +0 -114
  176. package/skills/senior-fullstack/scripts/project_scaffolder.py +0 -114
  177. package/skills/seo-aeo-landing-page-writer/SKILL.md +0 -97
  178. package/skills/seo-geo/SKILL.md +0 -188
  179. package/skills/ui-ux-pro-max/scripts/__pycache__/core.cpython-310.pyc +0 -0
  180. package/skills/ui-ux-pro-max/scripts/__pycache__/core.cpython-312.pyc +0 -0
  181. package/skills/ui-ux-pro-max/scripts/__pycache__/design_system.cpython-310.pyc +0 -0
  182. package/skills/ui-ux-pro-max/scripts/__pycache__/design_system.cpython-312.pyc +0 -0
  183. package/skills/ui_ux_expert/SKILL.md +0 -114
@@ -1,315 +1,321 @@
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."
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
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.
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
+ ### Orchestration & Integration
17
+ Connects and orchestrates with relevant domain skills like `brainstorming`, `zero-to-prod-orchestrator`, and `project-context-mapper` to ensure cohesive execution.
18
+
19
+ ### Description
20
+ 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.
21
+
22
+ ### Trigger Conditions
23
+ - Writing E2E tests for web applications with Playwright.
24
+ - Writing unit or integration tests with Vitest.
25
+ - Setting up a full automated testing pipeline in GitHub Actions / GitLab CI.
26
+ - Testing React components in isolation with Playwright Component Testing.
27
+ - Mocking external services (APIs, databases) in tests.
28
+ - Setting up visual regression tests.
29
+
30
+ ### Playwright 1.49+Key Updates
31
+
32
+ #### New in 2026
33
+ - **`aria-snapshot`**: Assert the accessibility tree as a snapshot more semantic than DOM snapshots.
34
+ - **`page.addLocatorHandler()`**: Handle dynamic UI (modals, cookie banners) automatically.
35
+ - **WebSocket testing**: Built-in `page.expectWebSocketEvent()`.
36
+ - **Playwright MCP Server**: Expose a Playwright browser to AI agents via MCP tools.
37
+
38
+ #### Project Configuration
39
+ ```typescript
40
+ // playwright.config.ts
41
+ import { defineConfig, devices } from '@playwright/test';
42
+
43
+ export default defineConfig({
44
+ testDir: './tests/e2e',
45
+ fullyParallel: true,
46
+ forbidOnly: !!process.env.CI,
47
+ retries: process.env.CI ? 2 : 0,
48
+ workers: process.env.CI ? 4 : undefined,
49
+ reporter: [
50
+ ['html', { open: 'never' }],
51
+ ['junit', { outputFile: 'results.xml' }],
52
+ ],
53
+ use: {
54
+ baseURL: process.env.PLAYWRIGHT_BASE_URL ?? 'http://localhost:3000',
55
+ trace: 'on-first-retry',
56
+ screenshot: 'only-on-failure',
57
+ video: 'on-first-retry',
58
+ },
59
+ projects: [
60
+ // Setup: seed test DB
61
+ { name: 'setup', testMatch: /.*\.setup\.ts/ },
62
+ {
63
+ name: 'chromium',
64
+ use: { ...devices['Desktop Chrome'] },
65
+ dependencies: ['setup'],
66
+ },
67
+ {
68
+ name: 'mobile-chrome',
69
+ use: { ...devices['Pixel 7'] },
70
+ dependencies: ['setup'],
71
+ },
72
+ ],
73
+ webServer: {
74
+ command: 'npm run dev',
75
+ url: 'http://localhost:3000',
76
+ reuseExistingServer: !process.env.CI,
77
+ },
78
+ });
79
+ ```
80
+
81
+ #### Page Object Model (POM)
82
+ ```typescript
83
+ // tests/e2e/pages/LoginPage.ts
84
+ import { type Page, type Locator, expect } from '@playwright/test';
85
+
86
+ export class LoginPage {
87
+ readonly page: Page;
88
+ readonly emailInput: Locator;
89
+ readonly passwordInput: Locator;
90
+ readonly submitButton: Locator;
91
+
92
+ constructor(page: Page) {
93
+ this.page = page;
94
+ this.emailInput = page.getByLabel('Email');
95
+ this.passwordInput = page.getByLabel('Password');
96
+ this.submitButton = page.getByRole('button', { name: 'Sign in' });
97
+ }
98
+
99
+ async goto() {
100
+ await this.page.goto('/login');
101
+ }
102
+
103
+ async login(email: string, password: string) {
104
+ await this.emailInput.fill(email);
105
+ await this.passwordInput.fill(password);
106
+ await this.submitButton.click();
107
+ await this.page.waitForURL('/dashboard');
108
+ }
109
+ }
110
+ ```
111
+
112
+ #### API Mocking with `page.route()`
113
+ ```typescript
114
+ test('shows error when API fails', async ({ page }) => {
115
+ // Intercept and mock API response
116
+ await page.route('**/api/users', (route) => {
117
+ route.fulfill({
118
+ status: 500,
119
+ body: JSON.stringify({ error: 'Internal server error' }),
120
+ contentType: 'application/json',
121
+ });
122
+ });
123
+
124
+ await page.goto('/users');
125
+ await expect(page.getByRole('alert')).toContainText('Something went wrong');
126
+ });
127
+ ```
128
+
129
+ #### Accessibility Assertions (aria-snapshot)
130
+ ```typescript
131
+ test('navigation is accessible', async ({ page }) => {
132
+ await page.goto('/');
133
+
134
+ // Assert accessibility tree structure
135
+ await expect(page.locator('nav')).toMatchAriaSnapshot(`
136
+ - navigation:
137
+ - link "Home"
138
+ - link "Products"
139
+ - link "Pricing"
140
+ - link "Sign in"
141
+ `);
142
+ });
143
+ ```
144
+
145
+ #### Auth State Reuse (storageState)
146
+ ```typescript
147
+ // tests/e2e/auth.setup.ts
148
+ import { test as setup } from '@playwright/test';
149
+
150
+ setup('authenticate', async ({ page }) => {
151
+ await page.goto('/login');
152
+ await page.getByLabel('Email').fill('test@example.com');
153
+ await page.getByLabel('Password').fill('password');
154
+ await page.getByRole('button', { name: 'Sign in' }).click();
155
+ await page.waitForURL('/dashboard');
156
+
157
+ // Save session state for reuse in all tests
158
+ await page.context().storageState({ path: 'playwright/.auth/user.json' });
159
+ });
160
+
161
+ // tests/e2e/dashboard.spec.ts
162
+ import { test } from '@playwright/test';
163
+
164
+ test.use({ storageState: 'playwright/.auth/user.json' });
165
+
166
+ test('dashboard loads correctly', async ({ page }) => {
167
+ await page.goto('/dashboard');
168
+ // Already authenticated — no login needed
169
+ });
170
+ ```
171
+
172
+ ### Vitest 3 — Unit & Integration Testing
173
+
174
+ #### Configuration
175
+ ```typescript
176
+ // vitest.config.ts
177
+ import { defineConfig } from 'vitest/config';
178
+ import react from '@vitejs/plugin-react';
179
+
180
+ export default defineConfig({
181
+ plugins: [react()],
182
+ test: {
183
+ environment: 'jsdom',
184
+ globals: true,
185
+ setupFiles: ['./tests/setup.ts'],
186
+ coverage: {
187
+ provider: 'v8',
188
+ reporter: ['text', 'lcov', 'html'],
189
+ thresholds: { lines: 80, functions: 80 },
190
+ },
191
+ },
192
+ });
193
+ ```
194
+
195
+ #### React Component Testing
196
+ ```typescript
197
+ import { render, screen, userEvent } from '@testing-library/react';
198
+ import { describe, it, expect, vi } from 'vitest';
199
+ import { Counter } from './Counter';
200
+
201
+ describe('Counter', () => {
202
+ it('increments count on button click', async () => {
203
+ const user = userEvent.setup();
204
+ render(<Counter initialCount={0} />);
205
+
206
+ await user.click(screen.getByRole('button', { name: 'Increment' }));
207
+
208
+ expect(screen.getByText('Count: 1')).toBeInTheDocument();
209
+ });
210
+
211
+ it('calls onMaxReached when limit hit', async () => {
212
+ const onMaxReached = vi.fn();
213
+ const user = userEvent.setup();
214
+ render(<Counter initialCount={9} max={10} onMaxReached={onMaxReached} />);
215
+
216
+ await user.click(screen.getByRole('button', { name: 'Increment' }));
217
+
218
+ expect(onMaxReached).toHaveBeenCalledOnce();
219
+ });
220
+ });
221
+ ```
222
+
223
+ #### Server Action / API Route Testing
224
+ ```typescript
225
+ import { describe, it, expect, beforeEach } from 'vitest';
226
+ import { testClient } from 'hono/testing';
227
+ import { app } from '../src/server';
228
+ import { resetTestDb } from './helpers/db';
229
+
230
+ describe('POST /api/users', () => {
231
+ beforeEach(resetTestDb);
232
+
233
+ it('creates a new user', async () => {
234
+ const client = testClient(app);
235
+ const res = await client.api.users.$post({
236
+ json: { name: 'Alice', email: 'alice@example.com' },
237
+ });
238
+
239
+ expect(res.status).toBe(201);
240
+ const data = await res.json();
241
+ expect(data.email).toBe('alice@example.com');
242
+ });
243
+ });
244
+ ```
245
+
246
+ ### GitHub Actions CI Pipeline
247
+ ```yaml
248
+ # .github/workflows/test.yml
249
+ name: CI Tests
250
+
251
+ on: [push, pull_request]
252
+
253
+ jobs:
254
+ unit:
255
+ runs-on: ubuntu-latest
256
+ steps:
257
+ - uses: actions/checkout@v4
258
+ - uses: actions/setup-node@v4
259
+ with: { node-version: '22', cache: 'pnpm' }
260
+ - run: pnpm install --frozen-lockfile
261
+ - run: pnpm run typecheck
262
+ - run: pnpm run test:unit --coverage
263
+
264
+ e2e:
265
+ runs-on: ubuntu-latest
266
+ steps:
267
+ - uses: actions/checkout@v4
268
+ - uses: actions/setup-node@v4
269
+ with: { node-version: '22', cache: 'pnpm' }
270
+ - run: pnpm install --frozen-lockfile
271
+ - run: pnpm exec playwright install --with-deps chromium
272
+ - run: pnpm run test:e2e
273
+ - uses: actions/upload-artifact@v4
274
+ if: failure()
275
+ with:
276
+ name: playwright-report
277
+ path: playwright-report/
278
+ ```
279
+
280
+ ---
281
+
282
+ <a name="bahasa-indonesia"></a>
283
+ ## Bahasa Indonesia
284
+
285
+ ### Integrasi Orkestrasi
286
+ Terhubung dan mengorkestrasi skill domain yang relevan seperti `brainstorming`, `zero-to-prod-orchestrator`, dan `project-context-mapper` untuk memastikan eksekusi yang kohesif.
287
+
288
+ ### Deskripsi
289
+ 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.
290
+
291
+ ### Kondisi Pemicu
292
+ - Menulis E2E test untuk aplikasi web dengan Playwright.
293
+ - Menulis unit atau integration test dengan Vitest.
294
+ - Menyiapkan pipeline pengujian otomatis di GitHub Actions / GitLab CI.
295
+ - Menguji komponen React secara terisolasi.
296
+ - Mocking layanan eksternal (API, database) dalam test.
297
+ - Menyiapkan visual regression test.
298
+
299
+ ### Playwright 1.49+ Fitur Baru 2026
300
+ - **`aria-snapshot`**: Assert accessibility tree sebagai snapshot.
301
+ - **`page.addLocatorHandler()`**: Tangani UI dinamis (modal, cookie banner) secara otomatis.
302
+ - **WebSocket testing**: `page.expectWebSocketEvent()` bawaan.
303
+ - **Playwright MCP Server**: Ekspos browser Playwright ke agen AI via MCP.
304
+
305
+ ### Page Object Model (POM)
306
+ Enkapsulasi selektor dan tindakan halaman dalam kelas terpisah untuk mengurangi duplikasi dan meningkatkan keterbacaan test.
307
+
308
+ ### Mocking API dengan `page.route()`
309
+ Gunakan `page.route()` untuk mencegat permintaan jaringan dan mengembalikan respons palsu mengisolasi frontend dari backend dalam E2E test.
310
+
311
+ ### Aksesibilitas dengan aria-snapshot
312
+ Gunakan `toMatchAriaSnapshot()` untuk memvalidasi struktur aksesibilitas navigasi, form, dan komponen interaktif lebih semantis dari snapshot DOM biasa.
313
+
314
+ ### Auth State Reuse (storageState)
315
+ Gunakan `storageState` untuk menyimpan state sesi setelah login sekali dan menggunakannya kembali di semua test yang memerlukan autentikasi — menghemat waktu secara signifikan.
316
+
317
+ ### Vitest 3 — Unit & Integration Testing
318
+ Vitest 3 adalah test runner yang cepat berbasis Vite dengan kompatibilitas Jest penuh. Gunakan untuk unit test React component, server action, dan logika bisnis.
319
+
320
+ ### Pipeline CI GitHub Actions
321
+ Pisahkan job `unit` dan `e2e` untuk feedback paralel yang lebih cepat. Upload `playwright-report` sebagai artifact saat gagal untuk debugging.