@bugzy-ai/bugzy 1.7.0 → 1.9.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 (52) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +273 -273
  3. package/dist/cli/index.cjs +465 -15
  4. package/dist/cli/index.cjs.map +1 -1
  5. package/dist/cli/index.js +464 -14
  6. package/dist/cli/index.js.map +1 -1
  7. package/dist/index.cjs +460 -12
  8. package/dist/index.cjs.map +1 -1
  9. package/dist/index.js +460 -12
  10. package/dist/index.js.map +1 -1
  11. package/dist/subagents/index.cjs +392 -6
  12. package/dist/subagents/index.cjs.map +1 -1
  13. package/dist/subagents/index.js +392 -6
  14. package/dist/subagents/index.js.map +1 -1
  15. package/dist/subagents/metadata.cjs +27 -0
  16. package/dist/subagents/metadata.cjs.map +1 -1
  17. package/dist/subagents/metadata.js +27 -0
  18. package/dist/subagents/metadata.js.map +1 -1
  19. package/dist/tasks/index.cjs +30 -1
  20. package/dist/tasks/index.cjs.map +1 -1
  21. package/dist/tasks/index.js +30 -1
  22. package/dist/tasks/index.js.map +1 -1
  23. package/package.json +95 -95
  24. package/templates/init/.bugzy/runtime/knowledge-base.md +61 -61
  25. package/templates/init/.bugzy/runtime/knowledge-maintenance-guide.md +97 -97
  26. package/templates/init/.bugzy/runtime/project-context.md +35 -35
  27. package/templates/init/.bugzy/runtime/subagent-memory-guide.md +87 -87
  28. package/templates/init/.bugzy/runtime/templates/test-plan-template.md +50 -50
  29. package/templates/init/.bugzy/runtime/templates/test-result-schema.md +498 -498
  30. package/templates/init/.bugzy/runtime/test-execution-strategy.md +535 -535
  31. package/templates/init/.bugzy/runtime/testing-best-practices.md +724 -632
  32. package/templates/init/.env.testdata +18 -18
  33. package/templates/init/.gitignore-template +24 -24
  34. package/templates/init/AGENTS.md +155 -155
  35. package/templates/init/CLAUDE.md +157 -157
  36. package/templates/init/test-runs/README.md +45 -45
  37. package/templates/playwright/BasePage.template.ts +190 -190
  38. package/templates/playwright/auth.setup.template.ts +89 -89
  39. package/templates/playwright/dataGenerators.helper.template.ts +148 -148
  40. package/templates/playwright/dateUtils.helper.template.ts +96 -96
  41. package/templates/playwright/pages.fixture.template.ts +50 -50
  42. package/templates/playwright/playwright.config.template.ts +97 -97
  43. package/templates/playwright/reporters/bugzy-reporter.ts +454 -454
  44. package/dist/templates/init/.bugzy/runtime/knowledge-base.md +0 -61
  45. package/dist/templates/init/.bugzy/runtime/knowledge-maintenance-guide.md +0 -97
  46. package/dist/templates/init/.bugzy/runtime/project-context.md +0 -35
  47. package/dist/templates/init/.bugzy/runtime/subagent-memory-guide.md +0 -87
  48. package/dist/templates/init/.bugzy/runtime/templates/test-plan-template.md +0 -50
  49. package/dist/templates/init/.bugzy/runtime/templates/test-result-schema.md +0 -498
  50. package/dist/templates/init/.bugzy/runtime/test-execution-strategy.md +0 -535
  51. package/dist/templates/init/.bugzy/runtime/testing-best-practices.md +0 -632
  52. package/dist/templates/init/.gitignore-template +0 -25
@@ -1,632 +0,0 @@
1
- # Testing Best Practices Reference
2
-
3
- ## Two-Phase Test Automation Workflow
4
-
5
- **Critical Distinction**: Separate test scenario discovery from automation implementation.
6
-
7
- ### Phase 1: Test Scenario Discovery (WHAT to test)
8
-
9
- **Goal**: Understand application behavior and identify what needs testing coverage.
10
-
11
- **Activities**:
12
- - Explore features and user workflows through manual interaction
13
- - Identify critical user paths and edge cases
14
- - Document test scenarios in human-readable format
15
- - Evaluate automation ROI for each scenario
16
- - Create manual test case documentation
17
-
18
- **Output**: Test plan with prioritized scenarios and automation decisions
19
-
20
- ### Phase 2: Automation Implementation (HOW to automate)
21
-
22
- **Goal**: Build robust test automation framework validated with working tests.
23
-
24
- **Activities**:
25
- - Technical exploration to identify correct selectors
26
- - Create Page Object infrastructure
27
- - Generate ONE smoke test to validate framework
28
- - Run and debug until test passes consistently
29
- - Scale to additional tests only after validation
30
-
31
- **Output**: Working test automation with validated Page Objects
32
-
33
- ### The "Test One First" Validation Loop
34
-
35
- **CRITICAL**: Always validate your framework with ONE working test before scaling.
36
-
37
- ```
38
- 1. Explore app for selectors (use Playwright MCP or codegen)
39
- 2. Create Page Objects with verified selectors
40
- 3. Write ONE critical path test (e.g., login)
41
- 4. Run the test: npx playwright test <test-file>
42
- 5. If fails → Debug and fix → Go to step 4
43
- 6. If passes → Run 3-5 more times to ensure stability
44
- 7. Once stable → Scale to additional tests
45
- ```
46
-
47
- **Why this matters**:
48
- - Catches framework issues early (config, setup, auth)
49
- - Validates selectors work in real application
50
- - Prevents generating 50 broken tests
51
- - Builds confidence in Page Object reliability
52
-
53
- **Example validation workflow**:
54
- ```bash
55
- # Generate ONE test first
56
- npx playwright test tests/specs/auth/login.spec.ts
57
-
58
- # Run multiple times to verify stability
59
- npx playwright test tests/specs/auth/login.spec.ts --repeat-each=5
60
-
61
- # Check for flakiness
62
- npx playwright test tests/specs/auth/login.spec.ts --workers=1
63
-
64
- # Once stable, generate more tests
65
- ```
66
-
67
- ## Page Object Model (POM) Architecture
68
-
69
- **Core Principle**: Separate locators, actions, and assertions into distinct layers to isolate UI changes from test logic.
70
-
71
- ### Page Object Structure
72
-
73
- ```typescript
74
- import { type Page, type Locator } from '@playwright/test';
75
-
76
- export class LoginPage {
77
- readonly page: Page;
78
-
79
- // Centralized selectors as readonly properties
80
- readonly emailInput: Locator;
81
- readonly passwordInput: Locator;
82
- readonly loginButton: Locator;
83
-
84
- constructor(page: Page) {
85
- this.page = page;
86
- this.emailInput = page.getByLabel('Email');
87
- this.passwordInput = page.getByLabel('Password');
88
- this.loginButton = page.getByRole('button', { name: 'Sign In' });
89
- }
90
-
91
- async navigate(): Promise<void> {
92
- await this.page.goto('/login');
93
- }
94
-
95
- async login(email: string, password: string): Promise<void> {
96
- await this.emailInput.fill(email);
97
- await this.passwordInput.fill(password);
98
- await this.loginButton.click();
99
- }
100
- }
101
- ```
102
-
103
- ### Key Rules for Page Objects
104
-
105
- - ✅ Define all locators as `readonly` properties
106
- - ✅ Initialize locators in constructor
107
- - ✅ Use method names that describe actions (login, fillEmail, clickSubmit)
108
- - ✅ Return data, never assert in page objects
109
- - ❌ Never put `expect()` assertions in page objects
110
- - ❌ Never use hardcoded waits (`waitForTimeout`)
111
-
112
- ## Selector Priority (Most to Least Resilient)
113
-
114
- 1. **Role-based**: `page.getByRole('button', { name: 'Submit' })` - Best for semantic HTML
115
- 2. **Label**: `page.getByLabel('Email')` - Perfect for form inputs
116
- 3. **Text**: `page.getByText('Welcome back')` - Good for headings/static content
117
- 4. **Placeholder**: `page.getByPlaceholder('Enter email')` - Inputs without labels
118
- 5. **Test ID**: `page.getByTestId('submit-btn')` - Stable but requires data-testid attributes
119
- 6. **CSS selectors**: `page.locator('.btn-primary')` - Avoid; breaks with styling changes
120
-
121
- ### When to Use Test IDs
122
-
123
- Add `data-testid` attributes for:
124
- - Critical user flows (checkout, login, signup)
125
- - Complex components (data tables, multi-step forms)
126
- - Elements where role-based selectors are ambiguous
127
-
128
- ```html
129
- <button data-testid="checkout-submit">Complete Purchase</button>
130
- ```
131
-
132
- ```typescript
133
- await page.getByTestId('checkout-submit').click();
134
- ```
135
-
136
- ## Playwright Codegen for Selector Discovery
137
-
138
- **Playwright's built-in codegen is faster and more reliable than manual selector creation.**
139
-
140
- ### Using Codegen
141
-
142
- ```bash
143
- # Start codegen from specific URL
144
- npx playwright codegen https://your-app.com
145
-
146
- # With authentication (loads saved state)
147
- npx playwright codegen --load-storage=tests/.auth/user.json https://your-app.com
148
-
149
- # Target specific browser
150
- npx playwright codegen --browser=chromium https://your-app.com
151
- ```
152
-
153
- **Workflow**:
154
- 1. Run codegen and interact with your application
155
- 2. Playwright generates test code with verified selectors
156
- 3. Copy generated selectors to your Page Objects
157
- 4. Refactor code to follow Page Object Model pattern
158
- 5. Extract reusable logic to fixtures and helpers
159
-
160
- ### Hybrid Approach: Codegen + AI Refactoring
161
-
162
- ```
163
- 1. Use Playwright codegen → Generates working test with selectors
164
- 2. Use AI (Claude) → Refactor to Page Objects, extract fixtures, add types
165
- 3. Best of both worlds: Reliability (codegen) + Intelligence (AI)
166
- ```
167
-
168
- **Example**:
169
- ```typescript
170
- // Raw codegen output
171
- await page.goto('https://example.com/');
172
- await page.getByLabel('Email').click();
173
- await page.getByLabel('Email').fill('test@example.com');
174
-
175
- // After AI refactoring into Page Object
176
- class LoginPage {
177
- readonly emailInput = this.page.getByLabel('Email');
178
-
179
- async fillEmail(email: string) {
180
- await this.emailInput.fill(email);
181
- }
182
- }
183
- ```
184
-
185
- ## Smoke Test Strategy
186
-
187
- **Smoke tests are a minimal suite of critical path tests that validate core functionality.**
188
-
189
- ### Characteristics
190
-
191
- - **Fast**: Target < 5 minutes total execution time
192
- - **Critical**: Cover must-work features (login, core user flows)
193
- - **Stable**: High reliability, minimal flakiness
194
- - **CI/CD**: Run on every commit/pull request
195
-
196
- ### Tagging Smoke Tests
197
-
198
- ```typescript
199
- // tests/specs/auth/login.spec.ts
200
- test('should login with valid credentials @smoke', async ({ page }) => {
201
- // Critical path test
202
- });
203
-
204
- test('should show error with invalid password', async ({ page }) => {
205
- // Not tagged - functional test only
206
- });
207
- ```
208
-
209
- ### Running Smoke Tests
210
-
211
- ```bash
212
- # Run only smoke tests
213
- npx playwright test --grep @smoke
214
-
215
- # In CI/CD pipeline
216
- npx playwright test --grep @smoke --workers=2
217
-
218
- # Smoke tests as gate for full suite
219
- npx playwright test --grep @smoke && npx playwright test
220
- ```
221
-
222
- ### Smoke Test Suite Example
223
-
224
- ```
225
- @smoke test coverage:
226
- ✓ Login with valid credentials
227
- ✓ Navigate to dashboard
228
- ✓ Create new item (core feature)
229
- ✓ View item details
230
- ✓ Logout
231
-
232
- Target: < 5 minutes, 100% pass rate
233
- ```
234
-
235
- ## Test Organization
236
-
237
- ### File Structure by Feature
238
-
239
- ```
240
- tests/
241
- ├── specs/ # Tests organized by feature
242
- │ ├── auth/
243
- │ │ └── login.spec.ts
244
- │ └── checkout/
245
- │ └── purchase-flow.spec.ts
246
- ├── pages/ # Page Object Models
247
- │ ├── LoginPage.ts
248
- │ └── CheckoutPage.ts
249
- ├── components/ # Reusable UI components
250
- ├── fixtures/ # Custom test fixtures
251
- ├── helpers/ # Utility functions
252
- └── setup/ # Global setup/teardown
253
- ```
254
-
255
- ### Test Structure with test.step()
256
-
257
- **REQUIRED**: All tests must use `test.step()` to organize actions into high-level logical phases. This enables:
258
- - Video navigation by step (users can jump to specific phases in test execution videos)
259
- - Clear test structure and intent
260
- - Granular error tracking (know exactly which phase failed)
261
- - Better debugging with step-level timing
262
-
263
- ```typescript
264
- test.describe('Purchase flow', () => {
265
- test.beforeEach(async ({ page }) => {
266
- // Common setup
267
- });
268
-
269
- test('should complete purchase with credit card', async ({ page }) => {
270
- const checkoutPage = new CheckoutPage(page);
271
-
272
- await test.step('Add item to cart', async () => {
273
- await checkoutPage.addItemToCart('Product A');
274
- await expect(checkoutPage.cartCount).toHaveText('1');
275
- });
276
-
277
- await test.step('Navigate to checkout', async () => {
278
- await checkoutPage.goToCheckout();
279
- await expect(page).toHaveURL('/checkout');
280
- });
281
-
282
- await test.step('Fill payment information', async () => {
283
- await checkoutPage.fillPaymentInfo({
284
- cardNumber: '4111111111111111',
285
- expiry: '12/25',
286
- cvv: '123'
287
- });
288
- });
289
-
290
- await test.step('Submit order', async () => {
291
- await checkoutPage.submitOrder();
292
- await expect(page).toHaveURL('/confirmation');
293
- });
294
-
295
- await test.step('Verify order confirmation', async () => {
296
- await expect(checkoutPage.confirmationMessage).toBeVisible();
297
- await expect(checkoutPage.orderNumber).toContain('ORD-');
298
- });
299
- });
300
- });
301
- ```
302
-
303
- **Step Granularity Guidelines**:
304
- - Target **3-7 steps per test** for optimal video navigation
305
- - Each step should represent a logical phase (e.g., "Login", "Navigate to settings", "Update profile")
306
- - Avoid micro-steps (e.g., "Click button", "Fill field") - group related actions
307
- - Step titles should be user-friendly and descriptive
308
-
309
- ## Video-Synchronized Test Steps
310
-
311
- **REQUIRED for all tests**: Use `test.step()` API to create video-navigable test execution.
312
-
313
- ### Why test.step() is Required
314
-
315
- Every test generates a video recording with `steps.json` file containing:
316
- - Step-by-step breakdown of test actions
317
- - Video timestamps for each step (in seconds from test start)
318
- - Step status (success/failed)
319
- - Step duration
320
-
321
- This enables users to:
322
- - Click on a step to jump to that point in the video
323
- - See exactly when and where a test failed
324
- - Navigate through test execution like a timeline
325
- - Debug issues by reviewing specific test phases
326
-
327
- ### test.step() Best Practices
328
-
329
- ```typescript
330
- import { test, expect } from '@playwright/test';
331
-
332
- test('user can update profile settings', async ({ page }) => {
333
- const settingsPage = new SettingsPage(page);
334
- const profilePage = new ProfilePage(page);
335
-
336
- await test.step('Navigate to settings page', async () => {
337
- await settingsPage.navigate();
338
- await expect(settingsPage.pageHeading).toBeVisible();
339
- });
340
-
341
- await test.step('Open profile section', async () => {
342
- await settingsPage.clickProfileTab();
343
- await expect(profilePage.nameInput).toBeVisible();
344
- });
345
-
346
- await test.step('Update profile information', async () => {
347
- await profilePage.updateName('John Doe');
348
- await profilePage.updateEmail('john@example.com');
349
- });
350
-
351
- await test.step('Save changes', async () => {
352
- await profilePage.clickSaveButton();
353
- await expect(profilePage.successMessage).toBeVisible();
354
- });
355
-
356
- await test.step('Verify changes persisted', async () => {
357
- await page.reload();
358
- await expect(profilePage.nameInput).toHaveValue('John Doe');
359
- await expect(profilePage.emailInput).toHaveValue('john@example.com');
360
- });
361
- });
362
- ```
363
-
364
- ### What Gets Recorded in steps.json
365
-
366
- ```json
367
- {
368
- "steps": [
369
- {
370
- "index": 1,
371
- "timestamp": "2025-11-17T09:26:22.335Z",
372
- "videoTimeSeconds": 0,
373
- "action": "Navigate to settings page",
374
- "status": "success",
375
- "description": "Navigate to settings page - completed successfully",
376
- "technicalDetails": "test.step",
377
- "duration": 1234
378
- },
379
- {
380
- "index": 2,
381
- "timestamp": "2025-11-17T09:26:23.569Z",
382
- "videoTimeSeconds": 1,
383
- "action": "Open profile section",
384
- "status": "success",
385
- "description": "Open profile section - completed successfully",
386
- "technicalDetails": "test.step",
387
- "duration": 856
388
- }
389
- ],
390
- "summary": {
391
- "totalSteps": 5,
392
- "successfulSteps": 5,
393
- "failedSteps": 0,
394
- "skippedSteps": 0
395
- }
396
- }
397
- ```
398
-
399
- ### Step Naming Conventions
400
-
401
- ✅ **Good step names** (user-friendly, high-level):
402
- - "Navigate to login page"
403
- - "Login with valid credentials"
404
- - "Add item to cart"
405
- - "Complete checkout process"
406
- - "Verify order confirmation"
407
-
408
- ❌ **Bad step names** (too technical, too granular):
409
- - "Click the login button"
410
- - "Fill email field"
411
- - "Wait for page load"
412
- - "Assert element visible"
413
- - "page.goto('/login')"
414
-
415
- ### Smoke Test Example with test.step()
416
-
417
- ```typescript
418
- // tests/specs/auth/login.spec.ts
419
- test('should login and navigate through all main pages @smoke', async ({ page }) => {
420
- const loginPage = new LoginPage(page);
421
- const dashboardPage = new DashboardPage(page);
422
-
423
- await test.step('Navigate to login page', async () => {
424
- await loginPage.navigate();
425
- await expect(loginPage.pageHeading).toBeVisible();
426
- });
427
-
428
- await test.step('Login with valid credentials', async () => {
429
- await loginPage.login(
430
- process.env.TEST_OWNER_EMAIL!,
431
- process.env.TEST_OWNER_PASSWORD!
432
- );
433
- await page.waitForURL(/.*\/dashboard/);
434
- });
435
-
436
- await test.step('Navigate to Overview page', async () => {
437
- await dashboardPage.navigateToOverview();
438
- await expect(dashboardPage.overviewNavLink).toBeVisible();
439
- });
440
-
441
- await test.step('Navigate to Settings page', async () => {
442
- await dashboardPage.navigateToSettings();
443
- await expect(dashboardPage.settingsNavLink).toBeVisible();
444
- });
445
-
446
- await test.step('Logout and verify redirect', async () => {
447
- await dashboardPage.logout();
448
- await page.waitForURL(/.*\/login/);
449
- await expect(loginPage.pageHeading).toBeVisible();
450
- });
451
- });
452
- ```
453
-
454
- ## Authentication & Session Management
455
-
456
- **Always authenticate once and reuse session state** across tests.
457
-
458
- ```typescript
459
- // tests/setup/auth.setup.ts
460
- import { test as setup } from '@playwright/test';
461
-
462
- const authFile = 'tests/.auth/user.json';
463
-
464
- setup('authenticate', async ({ page }) => {
465
- await page.goto('/login');
466
- await page.getByLabel('Email').fill(process.env.USER_EMAIL!);
467
- await page.getByLabel('Password').fill(process.env.USER_PASSWORD!);
468
- await page.getByRole('button', { name: 'Sign in' }).click();
469
-
470
- await page.waitForURL('/dashboard');
471
- await page.context().storageState({ path: authFile });
472
- });
473
- ```
474
-
475
- Configure in `playwright.config.ts`:
476
-
477
- ```typescript
478
- projects: [
479
- { name: 'setup', testMatch: /.*\.setup\.ts/ },
480
- {
481
- name: 'chromium',
482
- use: { storageState: 'tests/.auth/user.json' },
483
- dependencies: ['setup'],
484
- },
485
- ]
486
- ```
487
-
488
- ## Async Operations & Waiting
489
-
490
- ### Use Built-in Auto-waiting
491
-
492
- Playwright automatically waits for elements to be:
493
- - Visible
494
- - Enabled
495
- - Stable (not animating)
496
- - Ready to receive events
497
-
498
- ```typescript
499
- // ✅ GOOD: Auto-waiting
500
- await page.click('#submit');
501
- await expect(page.locator('.result')).toBeVisible();
502
-
503
- // ❌ BAD: Manual arbitrary wait
504
- await page.click('#submit');
505
- await page.waitForTimeout(3000);
506
- ```
507
-
508
- ### Explicit Waiting (when needed)
509
-
510
- ```typescript
511
- // Wait for element state
512
- await page.locator('.loading').waitFor({ state: 'hidden' });
513
-
514
- // Wait for URL change
515
- await page.waitForURL('**/dashboard');
516
-
517
- // Wait for network request
518
- const response = await page.waitForResponse(
519
- resp => resp.url().includes('/api/data') && resp.status() === 200
520
- );
521
- ```
522
-
523
- ## Common Anti-Patterns to Avoid
524
-
525
- | ❌ Anti-Pattern | ✅ Correct Approach |
526
- |----------------|-------------------|
527
- | `await page.waitForTimeout(3000)` | `await expect(element).toBeVisible()` |
528
- | `const el = await page.$('.btn')` | `await page.locator('.btn').click()` |
529
- | Tests depend on execution order | Each test is fully independent |
530
- | Assertions in Page Objects | Assertions only in test files |
531
- | `#app > div:nth-child(2) > button` | `page.getByRole('button', { name: 'Submit' })` |
532
- | `retries: 5` to mask flakiness | `retries: 2` + fix root cause |
533
-
534
- ## Debugging Workflow
535
-
536
- When a test fails:
537
-
538
- 1. **Reproduce locally**: `npx playwright test failing-test.spec.ts --headed`
539
- 2. **Enable trace**: `npx playwright test --trace on`
540
- 3. **View trace**: `npx playwright show-trace test-results/.../trace.zip`
541
- 4. **Identify failure**: Scrub timeline, check DOM snapshots
542
- 5. **Review network**: Look for failed API calls
543
- 6. **Check console**: JavaScript errors/warnings
544
- 7. **Fix selector**: Use inspector's locator picker
545
- 8. **Verify fix**: Run test 10 times to ensure stability
546
-
547
- ## API Testing for Speed
548
-
549
- **Use API calls for test setup** (10-20x faster than UI):
550
-
551
- ```typescript
552
- test('should display user dashboard', async ({ request, page }) => {
553
- // FAST: Create test data via API
554
- await request.post('/api/users', {
555
- data: { name: 'Test User', email: 'test@example.com' }
556
- });
557
-
558
- // UI: Test the actual user experience
559
- await page.goto('/dashboard');
560
- await expect(page.getByText('Test User')).toBeVisible();
561
- });
562
- ```
563
-
564
- ## Configuration Essentials
565
-
566
- ```typescript
567
- // playwright.config.ts
568
- export default defineConfig({
569
- testDir: './tests/specs',
570
- fullyParallel: true,
571
- retries: process.env.CI ? 2 : 0,
572
- workers: process.env.CI ? 1 : undefined,
573
-
574
- timeout: 30000,
575
- expect: { timeout: 5000 },
576
-
577
- use: {
578
- baseURL: process.env.BASE_URL,
579
- trace: 'on-first-retry',
580
- screenshot: 'only-on-failure',
581
- video: 'retain-on-failure',
582
- actionTimeout: 10000,
583
- },
584
- });
585
- ```
586
-
587
- ## Production-Ready Checklist
588
-
589
- **Configuration:**
590
- - [ ] Parallel execution enabled (`fullyParallel: true`)
591
- - [ ] Retry strategy configured (2 in CI, 0 locally)
592
- - [ ] Base URL from environment variables
593
- - [ ] Artifact capture optimized (`on-first-retry`)
594
-
595
- **Architecture:**
596
- - [ ] Page Object Model for all major pages
597
- - [ ] Component Objects for reusable UI elements
598
- - [ ] Custom fixtures for common setup
599
- - [ ] Tests organized by feature/user journey
600
-
601
- **Best Practices:**
602
- - [ ] No `waitForTimeout()` usage
603
- - [ ] Tests are independent (run in any order)
604
- - [ ] Assertions in test files, not Page Objects
605
- - [ ] Role-based selectors prioritized
606
- - [ ] No hardcoded credentials
607
- - [ ] Framework validated with ONE working test before scaling
608
- - [ ] Smoke tests tagged with @smoke for CI/CD
609
- - [ ] All tests use `test.step()` for video-navigable execution (3-7 steps per test)
610
-
611
- **Test Independence Validation:**
612
- - [ ] Each test can run in isolation: `npx playwright test <single-test>`
613
- - [ ] Tests pass in parallel: `npx playwright test --workers=4`
614
- - [ ] Tests pass in random order: `npx playwright test --shard=1/3` (run multiple shards)
615
- - [ ] No shared state between tests (each uses fixtures)
616
- - [ ] Tests cleanup after themselves (via fixtures or API)
617
-
618
- **CI/CD:**
619
- - [ ] Smoke tests run on every commit (`npx playwright test --grep @smoke`)
620
- - [ ] Full suite runs on pull requests
621
- - [ ] Artifacts uploaded (reports, traces)
622
- - [ ] Failure notifications configured
623
- - [ ] Test results published to PR comments
624
-
625
- ---
626
-
627
- **Remember**: The five critical pillars are:
628
- 1. **Two-Phase Approach** - Separate WHAT to test from HOW to automate
629
- 2. **Test One First** - Validate framework with ONE working test before scaling
630
- 3. **Page Object Model** - Isolate UI changes from test logic
631
- 4. **Role-based selectors** - Resist breakage with semantic HTML
632
- 5. **Authentication state reuse** - Maximize speed and reliability
@@ -1,25 +0,0 @@
1
- # Environment files (keep .env.testdata tracked, .env.example managed externally)
2
- .env
3
- .env.local
4
-
5
- # Logs and temporary files
6
- logs/
7
- tmp/
8
-
9
- # Playwright MCP cache
10
- .playwright-mcp/
11
-
12
- # Playwright test results
13
- test-results/
14
- playwright-report/
15
- playwright/.cache/
16
- tests/.auth/
17
-
18
- # Node modules if using any Node.js tooling
19
- node_modules/
20
- .DS_Store
21
-
22
- # Test result media files
23
- **/*.webm
24
- **/*.zip
25
- **/*.png