synapse-hub 0.0.0-stage → 2.0.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 (122) hide show
  1. package/.agents/agents/failure-analyst.md +47 -0
  2. package/.agents/agents/live-explorer.md +41 -0
  3. package/.agents/agents/orchestrator.md +43 -0
  4. package/.agents/agents/pom-crafter.md +81 -0
  5. package/.agents/agents/quality-gatekeeper.md +47 -0
  6. package/.agents/agents/test-runner.md +43 -0
  7. package/.agents/rules/context-engineering.md +88 -0
  8. package/.agents/rules/git-push-protocol.md +101 -0
  9. package/.agents/rules/graphify.md +14 -0
  10. package/.agents/rules/lessons-learned.md +23 -0
  11. package/.agents/rules/mandatory-playwright-live.md +29 -0
  12. package/.agents/rules/skill-precedence.md +42 -0
  13. package/.agents/rules/systematic-debugging.md +99 -0
  14. package/.agents/skills/agent-orchestration-multi-agent-optimize/SKILL.md +239 -0
  15. package/.agents/skills/antigravity-test-sentinel/SKILL.md +64 -0
  16. package/.agents/skills/api-network-mocking-interception/SKILL.md +142 -0
  17. package/.agents/skills/api-spec-to-e2e-matrix/SKILL.md +70 -0
  18. package/.agents/skills/architecture-decision-records/SKILL.md +441 -0
  19. package/.agents/skills/auth-session-and-cookie-manager/SKILL.md +72 -0
  20. package/.agents/skills/backend-load-and-stress-patterns/SKILL.md +214 -0
  21. package/.agents/skills/bats-testing-patterns/SKILL.md +100 -0
  22. package/.agents/skills/bats-testing-patterns/resources/implementation-playbook.md +614 -0
  23. package/.agents/skills/clean-pom-crafter/SKILL.md +75 -0
  24. package/.agents/skills/clean-pom-crafter/examples/standard_test_case.groovy +28 -0
  25. package/.agents/skills/clean-pom-crafter/references/pom_patterns.groovy +138 -0
  26. package/.agents/skills/code-refactoring-refactor-clean/SKILL.md +64 -0
  27. package/.agents/skills/code-refactoring-refactor-clean/resources/implementation-playbook.md +879 -0
  28. package/.agents/skills/db-state-verifier-and-seeder/SKILL.md +123 -0
  29. package/.agents/skills/e2e-testing-patterns/SKILL.md +103 -0
  30. package/.agents/skills/e2e-testing-patterns/resources/implementation-playbook.md +522 -0
  31. package/.agents/skills/failure-autopsy-and-healing/SKILL.md +54 -0
  32. package/.agents/skills/failure-autopsy-and-healing/references/healing_matrix.md +64 -0
  33. package/.agents/skills/failure-autopsy-and-healing/references/qa_investigation_protocol.md +56 -0
  34. package/.agents/skills/failure-autopsy-and-healing/scripts/triage_failures.sh +98 -0
  35. package/.agents/skills/file-and-report-validator/SKILL.md +90 -0
  36. package/.agents/skills/flaky-test-sentinel-and-quarantine/SKILL.md +114 -0
  37. package/.agents/skills/github-actions-templates/SKILL.md +334 -0
  38. package/.agents/skills/graphify-impact-analyzer/SKILL.md +78 -0
  39. package/.agents/skills/katalon-cli-runner/SKILL.md +76 -0
  40. package/.agents/skills/katalon-cli-runner/references/groovy-patterns.md +209 -0
  41. package/.agents/skills/katalon-cli-runner/references/katalon-api.md +155 -0
  42. package/.agents/skills/katalon-cli-runner/references/runner_commands.md +67 -0
  43. package/.agents/skills/lam-script-generator/SKILL.md +83 -0
  44. package/.agents/skills/playwright-live-interaction/SKILL.md +86 -0
  45. package/.agents/skills/playwright-live-interaction/references/advanced_superpowers.md +160 -0
  46. package/.agents/skills/playwright-live-interaction/references/compact_accessibility_snapshots.md +75 -0
  47. package/.agents/skills/playwright-live-interaction/references/recipes.md +388 -0
  48. package/.agents/skills/playwright-live-interaction/references/swarm_orchestration.md +134 -0
  49. package/.agents/skills/security-dast-sentinel/SKILL.md +176 -0
  50. package/.agents/skills/self-healing-locator/SKILL.md +73 -0
  51. package/.agents/skills/synthetic-test-data-generator/SKILL.md +135 -0
  52. package/.agents/skills/token-and-context-optimizer/SKILL.md +70 -0
  53. package/.agents/skills/visual-regression-sentinel/SKILL.md +62 -0
  54. package/.agents/skills/wcag-audit-patterns/SKILL.md +77 -0
  55. package/.agents/skills/wcag-audit-patterns/resources/implementation-playbook.md +541 -0
  56. package/.agents/skills/web-vitals-and-performance-profiler/SKILL.md +65 -0
  57. package/.agents/templates/completion_report.md +57 -0
  58. package/.agents/workflows/graphify.md +10 -0
  59. package/.agents/workflows/test-impact.md +15 -0
  60. package/.agents/workflows/verify.md +34 -0
  61. package/AGENTS.md +115 -0
  62. package/README.md +394 -2
  63. package/bin/agent-qa.js +90 -0
  64. package/package.json +59 -4
  65. package/skills_manifest.json +262 -0
  66. package/templates/PROJECT_AI_GUIDE_TEMPLATE.md +97 -0
  67. package/templates/PROJECT_STATE_TEMPLATE.md +20 -0
  68. package/tools/TOOLS_RUNBOOK.md +298 -0
  69. package/tools/agent_canary.py +501 -0
  70. package/tools/analyze_project.py +242 -0
  71. package/tools/api_drift_sentinel.py +208 -0
  72. package/tools/auto_heal.py +189 -0
  73. package/tools/browser_helpers.js +593 -0
  74. package/tools/bug_reporter.py +224 -0
  75. package/tools/cache_resolver.py +846 -0
  76. package/tools/check_env.py +288 -0
  77. package/tools/ci_healing_hook.py +128 -0
  78. package/tools/cli.py +402 -0
  79. package/tools/config_decoupler.py +253 -0
  80. package/tools/db_sandbox.py +341 -0
  81. package/tools/distill_log.py +152 -0
  82. package/tools/e2e_flow_prober.ps1 +65 -0
  83. package/tools/flaky_detector.py +222 -0
  84. package/tools/fuzz_payloads.py +197 -0
  85. package/tools/generate_allure_report.ps1 +30 -0
  86. package/tools/generate_api_matrix.py +193 -0
  87. package/tools/generate_tc_from_story.py +182 -0
  88. package/tools/generate_test_reports.ps1 +135 -0
  89. package/tools/git_pre_commit_guard.py +203 -0
  90. package/tools/heal_pr_automator.py +195 -0
  91. package/tools/heuristic_locator_matcher.py +202 -0
  92. package/tools/infer_linter.py +238 -0
  93. package/tools/lint_ai_docs.py +254 -0
  94. package/tools/lookup_tc.py +165 -0
  95. package/tools/lookup_xpath.py +167 -0
  96. package/tools/matrix_sharder.py +146 -0
  97. package/tools/mcp_excel_server.ps1 +251 -0
  98. package/tools/mcp_server.py +490 -0
  99. package/tools/micro_mutator.py +309 -0
  100. package/tools/network_mock_shield.py +170 -0
  101. package/tools/omni_emitter.py +500 -0
  102. package/tools/omni_parser.py +435 -0
  103. package/tools/omni_transpiler.py +168 -0
  104. package/tools/pinpoint_failure.py +88 -0
  105. package/tools/project_state.py +169 -0
  106. package/tools/repo_map.json +12 -0
  107. package/tools/repo_map.py +277 -0
  108. package/tools/repo_map.txt +7 -0
  109. package/tools/safety_firewall.py +245 -0
  110. package/tools/setup_project.py +265 -0
  111. package/tools/smart_visual_masker.py +134 -0
  112. package/tools/test_impact.py +321 -0
  113. package/tools/tms_sync_bridge.py +342 -0
  114. package/tools/trace_data_flow.py +240 -0
  115. package/tools/traffic_session_converter.py +256 -0
  116. package/tools/universal_ir.py +480 -0
  117. package/tools/validate_groovy_scripts.py +173 -0
  118. package/tools/verify_all.py +496 -0
  119. package/tools/verify_all.sh +4 -0
  120. package/tools/visual_diff_canvas.py +142 -0
  121. package/tools/visual_som_helper.py +418 -0
  122. package/tools/wcag_audit.py +214 -0
@@ -0,0 +1,522 @@
1
+ # E2E Testing Patterns Implementation Playbook
2
+
3
+ This file contains detailed patterns, checklists, and code samples referenced by the skill.
4
+
5
+ ## Core Concepts
6
+
7
+ ### 1. E2E Testing Fundamentals
8
+
9
+ **What to Test with E2E:**
10
+ - Critical user journeys (login, checkout, signup)
11
+ - Complex interactions (drag-and-drop, multi-step forms)
12
+ - Cross-browser compatibility
13
+ - Real API integration
14
+ - Authentication flows
15
+
16
+ **What NOT to Test with E2E:**
17
+ - Unit-level logic (use unit tests)
18
+ - API contracts (use integration tests)
19
+ - Edge cases (too slow)
20
+ - Internal implementation details
21
+
22
+ ### 2. Test Philosophy
23
+
24
+ **The Testing Pyramid:**
25
+ ```
26
+ /\
27
+ /E2E\ ← Few, focused on critical paths
28
+ /─────\
29
+ /Integr\ ← More, test component interactions
30
+ /────────\
31
+ /Unit Tests\ ← Many, fast, isolated
32
+ /────────────\
33
+ ```
34
+
35
+ **Best Practices:**
36
+ - Test user behavior, not implementation
37
+ - Keep tests independent
38
+ - Make tests deterministic
39
+ - Optimize for speed
40
+ - Use data-testid, not CSS selectors
41
+
42
+ ## Playwright Patterns
43
+
44
+ ### Setup and Configuration
45
+
46
+ ```typescript
47
+ // playwright.config.ts
48
+ import { defineConfig, devices } from '@playwright/test';
49
+
50
+ export default defineConfig({
51
+ testDir: './e2e',
52
+ timeout: 30000,
53
+ expect: {
54
+ timeout: 5000,
55
+ },
56
+ fullyParallel: true,
57
+ forbidOnly: !!process.env.CI,
58
+ retries: process.env.CI ? 2 : 0,
59
+ workers: process.env.CI ? 1 : undefined,
60
+ reporter: [
61
+ ['html'],
62
+ ['junit', { outputFile: 'results.xml' }],
63
+ ],
64
+ use: {
65
+ baseURL: 'http://localhost:3000',
66
+ trace: 'on-first-retry',
67
+ screenshot: 'only-on-failure',
68
+ video: 'retain-on-failure',
69
+ },
70
+ projects: [
71
+ { name: 'chromium', use: { ...devices['Desktop Chrome'] } },
72
+ { name: 'firefox', use: { ...devices['Desktop Firefox'] } },
73
+ { name: 'webkit', use: { ...devices['Desktop Safari'] } },
74
+ { name: 'mobile', use: { ...devices['iPhone 13'] } },
75
+ ],
76
+ });
77
+ ```
78
+
79
+ ### Pattern 1: Page Object Model
80
+
81
+ ```typescript
82
+ // pages/LoginPage.ts
83
+ import { Page, Locator } from '@playwright/test';
84
+
85
+ export class LoginPage {
86
+ readonly page: Page;
87
+ readonly emailInput: Locator;
88
+ readonly passwordInput: Locator;
89
+ readonly loginButton: Locator;
90
+ readonly errorMessage: Locator;
91
+
92
+ constructor(page: Page) {
93
+ this.page = page;
94
+ this.emailInput = page.getByLabel('Email');
95
+ this.passwordInput = page.getByLabel('Password');
96
+ this.loginButton = page.getByRole('button', { name: 'Login' });
97
+ this.errorMessage = page.getByRole('alert');
98
+ }
99
+
100
+ async goto() {
101
+ await this.page.goto('/login');
102
+ }
103
+
104
+ async login(email: string, password: string) {
105
+ await this.emailInput.fill(email);
106
+ await this.passwordInput.fill(password);
107
+ await this.loginButton.click();
108
+ }
109
+
110
+ async getErrorMessage(): Promise<string> {
111
+ return await this.errorMessage.textContent() ?? '';
112
+ }
113
+ }
114
+
115
+ // Test using Page Object
116
+ import { test, expect } from '@playwright/test';
117
+ import { LoginPage } from './pages/LoginPage';
118
+
119
+ test('successful login', async ({ page }) => {
120
+ const loginPage = new LoginPage(page);
121
+ await loginPage.goto();
122
+ await loginPage.login('user@example.com', process.env.TEST_PASSWORD || 'SecretAuth123!');
123
+
124
+ await expect(page).toHaveURL('/dashboard');
125
+ await expect(page.getByRole('heading', { name: 'Dashboard' }))
126
+ .toBeVisible();
127
+ });
128
+
129
+ test('failed login shows error', async ({ page }) => {
130
+ const loginPage = new LoginPage(page);
131
+ await loginPage.goto();
132
+ await loginPage.login('invalid@example.com', 'wrong');
133
+
134
+ const error = await loginPage.getErrorMessage();
135
+ expect(error).toContain('Invalid credentials');
136
+ });
137
+ ```
138
+
139
+ ### Pattern 2: Fixtures for Test Data
140
+
141
+ ```typescript
142
+ // fixtures/test-data.ts
143
+ import { test as base } from '@playwright/test';
144
+
145
+ type TestData = {
146
+ testUser: {
147
+ email: string;
148
+ password: string;
149
+ name: string;
150
+ };
151
+ adminUser: {
152
+ email: string;
153
+ password: string;
154
+ };
155
+ };
156
+
157
+ export const test = base.extend<TestData>({
158
+ testUser: async ({}, use) => {
159
+ const user = {
160
+ email: `test-${Date.now()}@example.com`,
161
+ password: process.env.TEST_USER_PASSWORD || 'DynamicTestPwd!123',
162
+ name: 'Test User',
163
+ };
164
+ // Setup: Create user in database
165
+ await createTestUser(user);
166
+ await use(user);
167
+ // Teardown: Clean up user
168
+ await deleteTestUser(user.email);
169
+ },
170
+
171
+ adminUser: async ({}, use) => {
172
+ await use({
173
+ email: 'admin@example.com',
174
+ password: process.env.ADMIN_PASSWORD!,
175
+ });
176
+ },
177
+ });
178
+
179
+ // Usage in tests
180
+ import { test } from './fixtures/test-data';
181
+
182
+ test('user can update profile', async ({ page, testUser }) => {
183
+ await page.goto('/login');
184
+ await page.getByLabel('Email').fill(testUser.email);
185
+ await page.getByLabel('Password').fill(testUser.password);
186
+ await page.getByRole('button', { name: 'Login' }).click();
187
+
188
+ await page.goto('/profile');
189
+ await page.getByLabel('Name').fill('Updated Name');
190
+ await page.getByRole('button', { name: 'Save' }).click();
191
+
192
+ await expect(page.getByText('Profile updated')).toBeVisible();
193
+ });
194
+ ```
195
+
196
+ ### Pattern 3: Waiting Strategies
197
+
198
+ ```typescript
199
+ // ❌ Bad: Fixed timeouts
200
+ await page.waitForTimeout(3000); // Flaky!
201
+
202
+ // ✅ Good: Wait for specific conditions
203
+ await page.waitForLoadState('networkidle');
204
+ await page.waitForURL('/dashboard');
205
+ await page.waitForSelector('[data-testid="user-profile"]');
206
+
207
+ // ✅ Better: Auto-waiting with assertions
208
+ await expect(page.getByText('Welcome')).toBeVisible();
209
+ await expect(page.getByRole('button', { name: 'Submit' }))
210
+ .toBeEnabled();
211
+
212
+ // Wait for API response
213
+ const responsePromise = page.waitForResponse(
214
+ response => response.url().includes('/api/users') && response.status() === 200
215
+ );
216
+ await page.getByRole('button', { name: 'Load Users' }).click();
217
+ const response = await responsePromise;
218
+ const data = await response.json();
219
+ expect(data.users).toHaveLength(10);
220
+
221
+ // Wait for multiple conditions
222
+ await Promise.all([
223
+ page.waitForURL('/success'),
224
+ page.waitForLoadState('networkidle'),
225
+ expect(page.getByText('Payment successful')).toBeVisible(),
226
+ ]);
227
+ ```
228
+
229
+ ### Pattern 4: Network Mocking and Interception
230
+
231
+ ```typescript
232
+ // Mock API responses
233
+ test('displays error when API fails', async ({ page }) => {
234
+ await page.route('**/api/users', route => {
235
+ route.fulfill({
236
+ status: 500,
237
+ contentType: 'application/json',
238
+ body: JSON.stringify({ error: 'Internal Server Error' }),
239
+ });
240
+ });
241
+
242
+ await page.goto('/users');
243
+ await expect(page.getByText('Failed to load users')).toBeVisible();
244
+ });
245
+
246
+ // Intercept and modify requests
247
+ test('can modify API request', async ({ page }) => {
248
+ await page.route('**/api/users', async route => {
249
+ const request = route.request();
250
+ const postData = JSON.parse(request.postData() || '{}');
251
+
252
+ // Modify request
253
+ postData.role = 'admin';
254
+
255
+ await route.continue({
256
+ postData: JSON.stringify(postData),
257
+ });
258
+ });
259
+
260
+ // Test continues...
261
+ });
262
+
263
+ // Mock third-party services
264
+ test('payment flow with mocked Stripe', async ({ page }) => {
265
+ await page.route('**/api/stripe/**', route => {
266
+ route.fulfill({
267
+ status: 200,
268
+ body: JSON.stringify({
269
+ id: 'mock_payment_id',
270
+ status: 'succeeded',
271
+ }),
272
+ });
273
+ });
274
+
275
+ // Test payment flow with mocked response
276
+ });
277
+ ```
278
+
279
+ ## Cypress Patterns
280
+
281
+ ### Setup and Configuration
282
+
283
+ ```typescript
284
+ // cypress.config.ts
285
+ import { defineConfig } from 'cypress';
286
+
287
+ export default defineConfig({
288
+ e2e: {
289
+ baseUrl: 'http://localhost:3000',
290
+ viewportWidth: 1280,
291
+ viewportHeight: 720,
292
+ video: false,
293
+ screenshotOnRunFailure: true,
294
+ defaultCommandTimeout: 10000,
295
+ requestTimeout: 10000,
296
+ setupNodeEvents(on, config) {
297
+ // Implement node event listeners
298
+ },
299
+ },
300
+ });
301
+ ```
302
+
303
+ ### Pattern 1: Custom Commands
304
+
305
+ ```typescript
306
+ // cypress/support/commands.ts
307
+ declare global {
308
+ namespace Cypress {
309
+ interface Chainable {
310
+ login(email: string, password: string): Chainable<void>;
311
+ createUser(userData: UserData): Chainable<User>;
312
+ dataCy(value: string): Chainable<JQuery<HTMLElement>>;
313
+ }
314
+ }
315
+ }
316
+
317
+ Cypress.Commands.add('login', (email: string, password: string) => {
318
+ cy.visit('/login');
319
+ cy.get('[data-testid="email"]').type(email);
320
+ cy.get('[data-testid="password"]').type(password);
321
+ cy.get('[data-testid="login-button"]').click();
322
+ cy.url().should('include', '/dashboard');
323
+ });
324
+
325
+ Cypress.Commands.add('createUser', (userData: UserData) => {
326
+ return cy.request('POST', '/api/users', userData)
327
+ .its('body');
328
+ });
329
+
330
+ Cypress.Commands.add('dataCy', (value: string) => {
331
+ return cy.get(`[data-cy="${value}"]`);
332
+ });
333
+
334
+ // Usage
335
+ cy.login('user@example.com', 'password');
336
+ cy.dataCy('submit-button').click();
337
+ ```
338
+
339
+ ### Pattern 2: Cypress Intercept
340
+
341
+ ```typescript
342
+ // Mock API calls
343
+ cy.intercept('GET', '/api/users', {
344
+ statusCode: 200,
345
+ body: [
346
+ { id: 1, name: 'John' },
347
+ { id: 2, name: 'Jane' },
348
+ ],
349
+ }).as('getUsers');
350
+
351
+ cy.visit('/users');
352
+ cy.wait('@getUsers');
353
+ cy.get('[data-testid="user-list"]').children().should('have.length', 2);
354
+
355
+ // Modify responses
356
+ cy.intercept('GET', '/api/users', (req) => {
357
+ req.reply((res) => {
358
+ // Modify response
359
+ res.body.users = res.body.users.slice(0, 5);
360
+ res.send();
361
+ });
362
+ });
363
+
364
+ // Simulate slow network
365
+ cy.intercept('GET', '/api/data', (req) => {
366
+ req.reply((res) => {
367
+ res.delay(3000); // 3 second delay
368
+ res.send();
369
+ });
370
+ });
371
+ ```
372
+
373
+ ## Advanced Patterns
374
+
375
+ ### Pattern 1: Visual Regression Testing
376
+
377
+ ```typescript
378
+ // With Playwright
379
+ import { test, expect } from '@playwright/test';
380
+
381
+ test('homepage looks correct', async ({ page }) => {
382
+ await page.goto('/');
383
+ await expect(page).toHaveScreenshot('homepage.png', {
384
+ fullPage: true,
385
+ maxDiffPixels: 100,
386
+ });
387
+ });
388
+
389
+ test('button in all states', async ({ page }) => {
390
+ await page.goto('/components');
391
+
392
+ const button = page.getByRole('button', { name: 'Submit' });
393
+
394
+ // Default state
395
+ await expect(button).toHaveScreenshot('button-default.png');
396
+
397
+ // Hover state
398
+ await button.hover();
399
+ await expect(button).toHaveScreenshot('button-hover.png');
400
+
401
+ // Disabled state
402
+ await button.evaluate(el => el.setAttribute('disabled', 'true'));
403
+ await expect(button).toHaveScreenshot('button-disabled.png');
404
+ });
405
+ ```
406
+
407
+ ### Pattern 2: Parallel Testing with Sharding
408
+
409
+ ```typescript
410
+ // playwright.config.ts
411
+ export default defineConfig({
412
+ projects: [
413
+ {
414
+ name: 'shard-1',
415
+ use: { ...devices['Desktop Chrome'] },
416
+ grepInvert: /@slow/,
417
+ shard: { current: 1, total: 4 },
418
+ },
419
+ {
420
+ name: 'shard-2',
421
+ use: { ...devices['Desktop Chrome'] },
422
+ shard: { current: 2, total: 4 },
423
+ },
424
+ // ... more shards
425
+ ],
426
+ });
427
+
428
+ // Run in CI
429
+ // npx playwright test --shard=1/4
430
+ // npx playwright test --shard=2/4
431
+ ```
432
+
433
+ ### Pattern 3: Accessibility Testing
434
+
435
+ ```typescript
436
+ // Install: npm install @axe-core/playwright
437
+ import { test, expect } from '@playwright/test';
438
+ import AxeBuilder from '@axe-core/playwright';
439
+
440
+ test('page should not have accessibility violations', async ({ page }) => {
441
+ await page.goto('/');
442
+
443
+ const accessibilityScanResults = await new AxeBuilder({ page })
444
+ .exclude('#third-party-widget')
445
+ .analyze();
446
+
447
+ expect(accessibilityScanResults.violations).toEqual([]);
448
+ });
449
+
450
+ test('form is accessible', async ({ page }) => {
451
+ await page.goto('/signup');
452
+
453
+ const results = await new AxeBuilder({ page })
454
+ .include('form')
455
+ .analyze();
456
+
457
+ expect(results.violations).toEqual([]);
458
+ });
459
+ ```
460
+
461
+ ## Best Practices
462
+
463
+ 1. **Use Data Attributes**: `data-testid` or `data-cy` for stable selectors
464
+ 2. **Avoid Brittle Selectors**: Don't rely on CSS classes or DOM structure
465
+ 3. **Test User Behavior**: Click, type, see - not implementation details
466
+ 4. **Keep Tests Independent**: Each test should run in isolation
467
+ 5. **Clean Up Test Data**: Create and destroy test data in each test
468
+ 6. **Use Page Objects**: Encapsulate page logic
469
+ 7. **Meaningful Assertions**: Check actual user-visible behavior
470
+ 8. **Optimize for Speed**: Mock when possible, parallel execution
471
+
472
+ ```typescript
473
+ // ❌ Bad selectors
474
+ cy.get('.btn.btn-primary.submit-button').click();
475
+ cy.get('div > form > div:nth-child(2) > input').type('text');
476
+
477
+ // ✅ Good selectors
478
+ cy.getByRole('button', { name: 'Submit' }).click();
479
+ cy.getByLabel('Email address').type('user@example.com');
480
+ cy.get('[data-testid="email-input"]').type('user@example.com');
481
+ ```
482
+
483
+ ## Common Pitfalls
484
+
485
+ - **Flaky Tests**: Use proper waits, not fixed timeouts
486
+ - **Slow Tests**: Mock external APIs, use parallel execution
487
+ - **Over-Testing**: Don't test every edge case with E2E
488
+ - **Coupled Tests**: Tests should not depend on each other
489
+ - **Poor Selectors**: Avoid CSS classes and nth-child
490
+ - **No Cleanup**: Clean up test data after each test
491
+ - **Testing Implementation**: Test user behavior, not internals
492
+
493
+ ## Debugging Failing Tests
494
+
495
+ ```typescript
496
+ // Playwright debugging
497
+ // 1. Run in headed mode
498
+ npx playwright test --headed
499
+
500
+ // 2. Run in debug mode
501
+ npx playwright test --debug
502
+
503
+ // 3. Use trace viewer
504
+ await page.screenshot({ path: 'screenshot.png' });
505
+ await page.video()?.saveAs('video.webm');
506
+
507
+ // 4. Add test.step for better reporting
508
+ test('checkout flow', async ({ page }) => {
509
+ await test.step('Add item to cart', async () => {
510
+ await page.goto('/products');
511
+ await page.getByRole('button', { name: 'Add to Cart' }).click();
512
+ });
513
+
514
+ await test.step('Proceed to checkout', async () => {
515
+ await page.goto('/cart');
516
+ await page.getByRole('button', { name: 'Checkout' }).click();
517
+ });
518
+ });
519
+
520
+ // 5. Inspect page state
521
+ await page.pause(); // Pauses execution, opens inspector
522
+ ```
@@ -0,0 +1,54 @@
1
+ ---
2
+ name: failure-autopsy-and-healing
3
+ description: >-
4
+ Automated failure triage, visual error autopsy from Screenshots/FAILED_*.png and Allure reports,
5
+ cross-platform JUnit XML parsing, and in-place Page Class code healing across automated test suites.
6
+ ---
7
+
8
+ # Failure Autopsy & Auto-Healing (Diagnostic & Self-Healing Engine)
9
+
10
+ Specialized skill for diagnosing batch test execution failures across automated test cases, performing visual autopsies via `Screenshots/FAILED_*.png`, parsing `JUnit_Report.xml`, and healing Page Classes (`Keywords/<namespace>/pages/*.groovy` or `pages/*.ts`) in place.
11
+
12
+ ---
13
+
14
+ ## 1. Five-Step Enterprise Autopsy Protocol
15
+
16
+ ```mermaid
17
+ flowchart LR
18
+ A["1. Detect FAILED TC"] --> B["2. Inspect Screenshots/FAILED_*.png"]
19
+ B --> C["3. Parse JUnit_Report.xml"]
20
+ C --> D["4. Heal Page Class in-place"]
21
+ D --> E["5. Re-run suite: 100% PASS"]
22
+ ```
23
+
24
+ 1. **Zero-Token Triage:** Pinpoint failed line and cause instantly (<50 tokens):
25
+ ```bash
26
+ python3 tools/pinpoint_failure.py
27
+ # or bash .agents/skills/failure-autopsy-and-healing/scripts/triage_failures.sh
28
+ ```
29
+ 2. **Visual Autopsy:** Inspect the latest error screenshot to immediately detect: disabled buttons, missing required fields, UI overlaps, or obscuring modal backdrops.
30
+ 3. **XML Parsing:** Extract stacktrace and exception messages from `Reports/<Timestamp>/JUnit_Report.xml` or Playwright test results.
31
+ 4. **In-Place Healing:** Update the corresponding Page Class in `Keywords/<project_namespace>/pages/` or `pages/`.
32
+ 5. **Regression Guard:** Verify 100% UTF-8 No BOM and re-run the targeted suite to confirm 100% Pass.
33
+
34
+ ---
35
+
36
+ ## 2. Dynamic Module & Page Class Mapping Architecture
37
+
38
+ | Functional Module Category | Target Page Class to Heal | Common Failure Vector | Recommended Auto-Heal Strategy |
39
+ | :--- | :--- | :--- | :--- |
40
+ | **Authentication & Session** | `LoginPage` | Stale session, cookie expiration | Switch to zero-second storage state / token injection |
41
+ | **System Admin & RBAC** | `UserAdminPage` | Role permission dialog overlay | Smart wait for dialog animation + backdrop dismissal |
42
+ | **Master Data & Catalogs** | `CategoryPage` | Table virtualization lazy-load | Scroll into view + waitForLoadState('networkidle') |
43
+ | **Workflows & Approvals** | `PlanningPage` | Button disabled state / slow API | Await formControl valid state before trigger click |
44
+ | **Data Tables & Search** | `DataManagementPage`| Dynamic table pagination index | Target semantic cell content or unique row testid |
45
+ | **Reporting & Exports** | `ReportPage` | Background worker generation lag | Poll download trigger with timeout rather than static wait |
46
+ | **API & Integrations** | `ApiTokenPage` | Bearer token header mismatch | Validate token generation response payload schema |
47
+
48
+ ---
49
+
50
+ ## 3. Reference Documentation
51
+
52
+ - [**Diagnostic & Healing Matrix (`healing_matrix.md`)**](references/healing_matrix.md): Concrete code prescriptions for disabled buttons, boundary overlaps, `ElementClickInterceptedException`, `StaleElementReferenceException`, and 4 flaky test root causes.
53
+ - [**Fast-Fix Triad & Runtime Helper (`tools/browser_helpers.js`)**](tools/browser_helpers.js): In-browser diagnosis engine via `window.__qa` (`audit`, `heal`, `clickSafe`, `hud`).
54
+ - **Automated Triage Script:** `python3 tools/pinpoint_failure.py` and `scripts/triage_failures.sh`.
@@ -0,0 +1,64 @@
1
+ # Enterprise Automation Failure Diagnostic & Healing Matrix
2
+
3
+ Reference documentation for the `failure-autopsy-and-healing` skill.
4
+
5
+ ---
6
+
7
+ ## 1. Diagnostic & Healing Matrix
8
+
9
+ | Visual / Exception Symptom | Root Cause | Groovy POM Healing Patch |
10
+ | :--- | :--- | :--- |
11
+ | **Save button `[ ✓ ]` disabled / dimmed** | Angular Reactive Form missed change detection or missing required field (`*`). | `WebElement el = findElement(By.cssSelector("input[formcontrolname='code']"))`<br>`jsSetInput(el, uniqueCode)` |
12
+ | **Alert: *"Phạm vi giữa các khu/cụm không hợp lệ"*** | OpenLayers polygon overlaps previously saved boundary data. | `Actions actions = new Actions(driver)`<br>`actions.moveToElement(viewport, -180, -80).click().perform()` |
13
+ | **`ElementClickInterceptedException`** | Modal overlay `.p-component-overlay` fading out but still blocking clicks. | `((JavascriptExecutor) driver).executeScript("arguments[0].click();", element)` |
14
+ | **Red Toast: *"Mã đã tồn tại"*** | Non-unique test data colliding with existing records. | `String code = BasePage.uniqueCode("CCN_")` |
15
+ | **`StaleElementReferenceException`** | Angular DOM re-rendered after API response, detaching element. | `for (int i = 0; i < 3; i++) { try { findElement(by).click(); break; } catch (StaleElementReferenceException e) { sleep(500) } }` |
16
+ | **`TimeoutException` (Waiting for table/button)** | Loading overlay `.p-blockui` or spinner `.p-progress-spinner` blocking UI. | `waitForElementNotVisible(By.cssSelector(".p-blockui, .p-progress-spinner"), 10)` |
17
+ | **PrimeNG Dropdown value not applied** | Clicked `p-dropdown` but overlay panel `.p-dropdown-panel` has not rendered. | `waitForElementVisible(By.cssSelector(".p-dropdown-panel"), 5)`<br>`findElement(By.xpath("//li[contains(., '" + text + "')]")).click()` |
18
+ | **Blank Screenshot** | Browser crashed before capturing UI (OOM or lost WebDriver session). | Inspect `console0.log`, kill zombie drivers (`pkill -f chromedriver`), restart session. |
19
+
20
+ ---
21
+
22
+ ## 2. Four Flaky Test Root Causes & Cures
23
+
24
+ | Flaky Root Cause | Symptom | Curing Strategy (Root Fix) |
25
+ |---|---|---|
26
+ | **1. Unstable Locator** | Random failures due to CSS refactoring or dynamic hashes | Enforce Master Priority Map: switch to `[formcontrolname]`, `[data-testid]`; forbid positional XPaths. |
27
+ | **2. Timing & Race Condition** | Fails under network latency; clicks before Angular finishes render | Replace all hard sleeps with Smart Wait: `waitForElementVisible`, wait for `.p-blockui` / `.p-progress-spinner` to hide. |
28
+ | **3. Test Data Conflict** | Fails on parallel or repeated runs due to duplicate codes | Enforce `BasePage.uniqueCode(prefix)` with epoch timestamps. |
29
+ | **4. Environment Dependency** | Fails due to expired session or stale browser cache | Use `LoginPage.ensureLoggedIn()` before every script. |
30
+
31
+ ---
32
+
33
+ ## 3. Fast-Fix Triad (Zero-Token Diagnostic & Targeted Healing Workflow)
34
+
35
+ To maximize fix speed and minimize token consumption without degrading test fidelity, follow this 3-step loop:
36
+
37
+ ### Step 1: Zero-Token Pinpoint (CLI Log Extraction)
38
+ Never read entire JUnit XML reports (>50KB). Extract failed test cases, exception reasons, and file line numbers in <50 tokens:
39
+ ```bash
40
+ python3 tools/pinpoint_failure.py Reports/<timestamp>/<suite>/JUnit_Report.xml
41
+ ```
42
+
43
+ ### Step 2: Instant Form & DOM Audit (Playwright MCP Recipe 15)
44
+ When a test fails because a button is disabled (e.g. Save `[ ✓ ]`), never guess which field is invalid. Execute Recipe 15 via `browser_run_code_unsafe` on the active live page:
45
+ ```javascript
46
+ () => {
47
+ const invalids = Array.from(document.querySelectorAll('form .ng-invalid, input.ng-invalid, p-dropdown.ng-invalid'));
48
+ return invalids.map(el => ({
49
+ tag: el.tagName,
50
+ name: el.getAttribute('name') || el.getAttribute('formcontrolname') || el.id,
51
+ classes: el.className
52
+ }));
53
+ }
54
+ ```
55
+ This instantly highlights missing required inputs, pattern mismatches, or invalid dropdowns.
56
+
57
+ ### Step 3: Targeted Single-TC Re-test (Zero Waste)
58
+ Never rerun an entire Test Suite to verify a 1-line locator or timing fix. Rerun only the targeted test case:
59
+ ```bash
60
+ # Via KRE CLI (License mode):
61
+ katalonc -noSplash -runMode=console -projectPath="." -retry=0 -testCasePath="Test Cases/TC-xxx" -browserType="Chrome (headless)"
62
+
63
+ # Or verify live flow in 2 seconds via Playwright MCP script.
64
+ ```
@@ -0,0 +1,56 @@
1
+ # QA Investigation & Root-Cause Analysis Protocol
2
+
3
+ *(Inherited from `fugazi/test-automation-skills-agents`)*
4
+
5
+ A file-backed, evidence-first investigation journal protocol for diagnosing failing and flaky automation test cases in enterprise automation projects.
6
+
7
+ ---
8
+
9
+ ## 1. Core Principles
10
+
11
+ 1. **Context Window is Volatile RAM; Filesystem is Persistent Disk:**
12
+ - Long triage sessions cause context drift. All goals, hypotheses, and evidence must be logged in markdown.
13
+ 2. **Discovered Classification, Not Presumed:**
14
+ - Never assume upfront whether a failure is a Flaky test, an AUT Defect, or a Test Infrastructure issue. The classification is a finding discovered through evidence.
15
+ 3. **No Guesswork / No Blind Fixes:**
16
+ - Every fix must address a proven root cause, not a symptom.
17
+
18
+ ---
19
+
20
+ ## 2. Four-Phase Investigation Cycle
21
+
22
+ ```mermaid
23
+ flowchart TD
24
+ P1["<b>Phase 1: Reproduction & Triage</b><br/>• Run single-TC isolated re-test<br/>• Classify: Intermittent (Flaky) vs Deterministic (Bug)"]
25
+ P2["<b>Phase 2: Evidence Collection</b><br/>• Extract CLI logs & stack trace<br/>• Inspect Screenshots/FAILED_*.png<br/>• Capture network & timing data"]
26
+ P3["<b>Phase 3: Hypothesis & Root Cause</b><br/>• Form testable hypothesis<br/>• Isolate: Timing vs Stale DOM vs AUT defect"]
27
+ P4["<b>Phase 4: Targeted Fix & Validation</b><br/>• Apply Clean POM Page Class fix<br/>• Validate 3x consecutive runs<br/>• Run verify_all.py DoD check"]
28
+
29
+ P1 --> P2 --> P3 --> P4
30
+ ```
31
+
32
+ ### Phase 1: Reproduction & Triage
33
+ - Run the failing test in isolation using the targeted single-TC runner.
34
+ - Determine failure pattern:
35
+ - **Deterministic Bug:** Fails 100% of the time with identical stack trace.
36
+ - **Intermittent Flaky:** Passes sometimes, fails under load/timing variations.
37
+ - **Environment Blocker:** Fails on 401/403 session expiration or network timeout.
38
+
39
+ ### Phase 2: Evidence Collection
40
+ - Collect ground-truth artifacts:
41
+ 1. CLI log excerpt around the failure point.
42
+ 2. Failure screenshot in `Screenshots/FAILED_<TestCaseId>_*.png`.
43
+ 3. Form audit state (e.g. disabled Save button, red validation borders).
44
+ 4. Redact any sensitive credentials or personal tokens.
45
+
46
+ ### Phase 3: Hypothesis Formulation
47
+ - Check the 4 most common failure archetypes:
48
+ - **Archetype A (PrimeNG Toast Collision):** Previous toast covers the button. Cure: `dismissToast()`.
49
+ - **Archetype B (Stale Element / Angular Re-render):** DOM re-created mid-click. Cure: Re-fetch locator with `BasePage.x()`.
50
+ - **Archetype C (Dialog Backdrop Overlay):** `cdk-overlay-backdrop` blocks click. Cure: Wait for backdrop fade-out.
51
+ - **Archetype D (Real AUT Defect):** Backend HTTP 500 or constraint violation. Cure: Log to `KNOWN_ISSUES.md`.
52
+
53
+ ### Phase 4: Targeted Fix & Validation
54
+ - Implement fix exclusively inside Page Classes in `Keywords/<namespace>/pages/` or `pages/` (never in `Scripts/`).
55
+ - Validate stability across multiple runs.
56
+ - Run `python3 tools/verify_all.py` to confirm zero regressions.