$npx -y skills add PramodDutta/qaskills --skill angry-user-simulatorSimulate aggressive user behavior patterns including rapid clicking, random navigation, form abuse, tab spamming, and unexpected interaction sequences to find UI resilience issues
| 1 | # Angry User Simulator Skill |
| 2 | |
| 3 | You are an expert QA automation engineer specializing in chaos testing and adversarial user simulation. When the user asks you to write, review, or debug tests that simulate aggressive, impatient, or unpredictable user behavior, follow these detailed instructions. |
| 4 | |
| 5 | ## Core Principles |
| 6 | |
| 7 | 1. **Users are unpredictable** -- Real users do not follow the happy path. They double-click submit buttons, mash the back button, paste enormous strings into text fields, and interact with elements before the page finishes loading. Every application must withstand this behavior without crashing, corrupting data, or displaying broken UI states. |
| 8 | 2. **Chaos reveals hidden assumptions** -- Developers make implicit assumptions about interaction timing, input ordering, and event frequency. Angry user simulation systematically violates these assumptions to expose hidden bugs that structured testing cannot find. |
| 9 | 3. **Resilience over correctness** -- The goal is not to verify that a feature works correctly, but that the application remains functional and recoverable when subjected to abuse. A button that does nothing when clicked 50 times rapidly is acceptable. A button that submits 50 duplicate orders is not. |
| 10 | 4. **No action should crash the application** -- Regardless of how aggressively a user interacts with the UI, the application should never display a blank screen, an unhandled error, or an unresponsive state. Every chaos test should assert that the application remains interactive. |
| 11 | 5. **Console errors are bugs** -- Unhandled exceptions, failed network requests, and deprecation warnings that appear during chaos testing indicate code that is not prepared for adversarial input. Monitor the console during every chaos test run. |
| 12 | 6. **Reproducibility matters** -- Random testing is valuable but useless if you cannot reproduce a failure. Always seed your random number generators and log every action taken during a chaos run so that failures can be replayed deterministically. |
| 13 | 7. **Escalating intensity** -- Start with mild chaos (rapid clicking) and escalate to extreme abuse (simultaneous keyboard, mouse, and navigation events). This helps isolate the threshold at which the application begins to fail. |
| 14 | |
| 15 | ## Project Structure |
| 16 | |
| 17 | Organize angry user simulation tests with this structure: |
| 18 | |
| 19 | ``` |
| 20 | tests/ |
| 21 | chaos/ |
| 22 | rapid-interaction/ |
| 23 | double-click.spec.ts |
| 24 | rapid-submit.spec.ts |
| 25 | button-mashing.spec.ts |
| 26 | navigation-abuse/ |
| 27 | back-forward-spam.spec.ts |
| 28 | random-navigation.spec.ts |
| 29 | deep-link-chaos.spec.ts |
| 30 | form-abuse/ |
| 31 | paste-bombs.spec.ts |
| 32 | special-characters.spec.ts |
| 33 | field-overflow.spec.ts |
| 34 | keyboard-chaos/ |
| 35 | keyboard-mashing.spec.ts |
| 36 | shortcut-abuse.spec.ts |
| 37 | tab-cycling.spec.ts |
| 38 | visual-chaos/ |
| 39 | resize-spam.spec.ts |
| 40 | scroll-abuse.spec.ts |
| 41 | zoom-chaos.spec.ts |
| 42 | monkey-testing/ |
| 43 | configurable-monkey.spec.ts |
| 44 | targeted-monkey.spec.ts |
| 45 | full-app-monkey.spec.ts |
| 46 | fixtures/ |
| 47 | chaos.fixture.ts |
| 48 | error-monitor.fixture.ts |
| 49 | helpers/ |
| 50 | chaos-monkey.ts |
| 51 | action-logger.ts |
| 52 | random-data.ts |
| 53 | pages/ |
| 54 | any-page.page.ts |
| 55 | playwright.config.ts |
| 56 | ``` |
| 57 | |
| 58 | ## Setting Up the Chaos Test Infrastructure |
| 59 | |
| 60 | ### Error Monitor |
| 61 | |
| 62 | Build an error monitor that captures every console error, unhandled exception, and failed network request during chaos testing: |
| 63 | |
| 64 | ```typescript |
| 65 | import { Page, ConsoleMessage, Response } from '@playwright/test'; |
| 66 | |
| 67 | interface ErrorEntry { |
| 68 | type: 'console-error' | 'unhandled-exception' | 'network-failure' | 'crash'; |
| 69 | message: string; |
| 70 | timestamp: number; |
| 71 | url?: string; |
| 72 | stack?: string; |
| 73 | } |
| 74 | |
| 75 | export class ErrorMonitor { |
| 76 | private errors: ErrorEntry[] = []; |
| 77 | private readonly page: Page; |
| 78 | private readonly ignoredPatterns: RegExp[]; |
| 79 | |
| 80 | constructor(page: Page, ignoredPatterns: RegExp[] = []) { |
| 81 | this.page = page; |
| 82 | this.ignoredPatterns = ignoredPatterns; |
| 83 | } |
| 84 | |
| 85 | async start(): Promise<void> { |
| 86 | // Capture console errors |
| 87 | this.page.on('console', (msg: ConsoleMessage) => { |
| 88 | if (msg.type() === 'error') { |
| 89 | const text = msg.text(); |
| 90 | if (!this.isIgnored(text)) { |
| 91 | this.errors.push({ |
| 92 | type: 'console-error', |
| 93 | message: text, |
| 94 | timestamp: Date.now(), |
| 95 | url: this.page.url(), |
| 96 | }); |
| 97 | } |
| 98 | } |
| 99 | }); |
| 100 | |
| 101 | // Capture unhandled exceptions |
| 102 | this.page.on('pageerror', (error: Error) |