{"_id":"@anthropic-desktop/playwright-desktop-actions","_rev":"3-513665f4e3563a2e99fa06b87bc09bab","name":"@anthropic-desktop/playwright-desktop-actions","dist-tags":{"latest":"0.1.2"},"versions":{"0.1.0":{"name":"@anthropic-desktop/playwright-desktop-actions","version":"0.1.0","keywords":["playwright","desktop","automation","okta","fastpass","windows","native-auth"],"license":"Apache-2.0","_id":"@anthropic-desktop/playwright-desktop-actions@0.1.0","maintainers":[{"name":"desktoptest","email":"maddipatihemanthkumar@gmail.com"}],"homepage":"https://github.com/anthropic-desktop/playwright-desktop-actions#readme","bugs":{"url":"https://github.com/anthropic-desktop/playwright-desktop-actions/issues"},"os":["win32"],"dist":{"shasum":"a270606f926a88e5bdef5a1c03009543149f4be0","tarball":"https://registry.npmjs.org/@anthropic-desktop/playwright-desktop-actions/-/playwright-desktop-actions-0.1.0.tgz","fileCount":92,"integrity":"sha512-MAg6Rgm9pH93OudtWgdZo0Ia2+xXuT+mHj3R6OSfa6IgUw0bhs183oGp0XWncIFVriM1HP+DoZK2pOhm9U1J5g==","signatures":[{"sig":"MEYCIQDPV5ZeTVwt8R3BEYLw7V5lSiH4YZJLnzWwjVvaOb6i4QIhAJS6jEys5HrVuQx0vVdOue0F6k4nc/U/qK1I7A/agm8z","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":204327},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js","require":"./dist/index.js"},"./config":{"types":"./dist/config/ConfigManager.d.ts","default":"./dist/config/ConfigManager.js","require":"./dist/config/ConfigManager.js"}},"gitHead":"5ebc8eddee6888b9ba9dd30cd423a8133a3a17b7","scripts":{"build":"tsc -p tsconfig.build.json","clean":"node -e \"const fs=require('fs');fs.rmSync('dist',{recursive:true,force:true})\"","watch":"tsc -p tsconfig.build.json --watch","prepack":"npm run build","prepare":"npm run build","prepublishOnly":"npm run clean && npm run build"},"_npmUser":{"name":"desktoptest","email":"maddipatihemanthkumar@gmail.com"},"repository":{"url":"git+https://github.com/anthropic-desktop/playwright-desktop-actions.git","type":"git"},"_npmVersion":"11.9.0","description":"Desktop automation agent for Playwright — handles Okta Verify FastPass and other native auth flows","directories":{},"_nodeVersion":"24.14.0","dependencies":{"typescript":"^5.3.0"},"_hasShrinkwrap":false,"devDependencies":{"@types/node":">=18"},"peerDependencies":{"playwright":">=1.40.0","playwright-core":">=1.40.0"},"peerDependenciesMeta":{"playwright":{"optional":true},"playwright-core":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/playwright-desktop-actions_0.1.0_1774298222441_0.7210620793007889","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@anthropic-desktop/playwright-desktop-actions","version":"0.1.1","keywords":["playwright","desktop","automation","okta","fastpass","windows","native-auth"],"license":"Apache-2.0","_id":"@anthropic-desktop/playwright-desktop-actions@0.1.1","maintainers":[{"name":"desktoptest","email":"maddipatihemanthkumar@gmail.com"}],"homepage":"https://github.com/anthropic-desktop/playwright-desktop-actions#readme","bugs":{"url":"https://github.com/anthropic-desktop/playwright-desktop-actions/issues"},"os":["win32"],"dist":{"shasum":"d030441ed747d4c31249ad13e1a030b746297403","tarball":"https://registry.npmjs.org/@anthropic-desktop/playwright-desktop-actions/-/playwright-desktop-actions-0.1.1.tgz","fileCount":91,"integrity":"sha512-/HgipK+sJW0jCmrnjpNw+mUWdrDDcwDoeRiJnzLWbahTGTR/1H0Ls+VTlaWYZ1AKIWWYDGtw+mmF55sp04rN3g==","signatures":[{"sig":"MEQCIBgJASIxO6HFaf4CFa2d5ehsREuaZlAa8wOTQbEWMamJAiBComdHyJpJvS36G7H/1zjdbj5bOQtClE1xrv5Tn8804A==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":194198},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js","require":"./dist/index.js"},"./config":{"types":"./dist/config/ConfigManager.d.ts","default":"./dist/config/ConfigManager.js","require":"./dist/config/ConfigManager.js"}},"gitHead":"28ddfa82cd0f2aadd2dcbdef24ac473ec067ca56","scripts":{"build":"tsc -p tsconfig.build.json","clean":"node -e \"const fs=require('fs');fs.rmSync('dist',{recursive:true,force:true})\"","watch":"tsc -p tsconfig.build.json --watch","prepack":"npm run build","prepublishOnly":"npm run clean && npm run build"},"_npmUser":{"name":"desktoptest","email":"maddipatihemanthkumar@gmail.com"},"repository":{"url":"git+https://github.com/anthropic-desktop/playwright-desktop-actions.git","type":"git"},"_npmVersion":"11.9.0","description":"Desktop automation agent for Playwright — handles Okta Verify FastPass and other native auth flows","directories":{},"_nodeVersion":"24.14.0","dependencies":{},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.3.0","@types/node":">=18"},"peerDependencies":{"playwright":">=1.40.0-0","playwright-core":">=1.40.0-0"},"peerDependenciesMeta":{"playwright":{"optional":true},"playwright-core":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/playwright-desktop-actions_0.1.1_1776669515145_0.5875458745227768","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@anthropic-desktop/playwright-desktop-actions","version":"0.1.2","description":"Desktop automation agent for Playwright — handles Okta Verify FastPass and other native auth flows","main":"dist/index.js","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","require":"./dist/index.js","default":"./dist/index.js"},"./config":{"types":"./dist/config/ConfigManager.d.ts","require":"./dist/config/ConfigManager.js","default":"./dist/config/ConfigManager.js"}},"license":"Apache-2.0","repository":{"type":"git","url":"git+https://github.com/Hemanth-7026/playwright.git","directory":"packages/desktop-agent"},"keywords":["playwright","desktop","automation","okta","fastpass","windows","native-auth"],"scripts":{"build":"tsc -p tsconfig.build.json","watch":"tsc -p tsconfig.build.json --watch","clean":"node -e \"const fs=require('fs');fs.rmSync('dist',{recursive:true,force:true})\"","prepublishOnly":"npm run clean && npm run build","prepack":"npm run build"},"dependencies":{},"devDependencies":{"@types/node":">=18","typescript":"^5.3.0"},"peerDependencies":{"playwright":">=1.40.0-0","playwright-core":">=1.40.0-0"},"peerDependenciesMeta":{"playwright":{"optional":true},"playwright-core":{"optional":true}},"engines":{"node":">=18"},"os":["win32"],"gitHead":"bfed0f5dd8a02af545fae45c1baa220ac98e9cee","_id":"@anthropic-desktop/playwright-desktop-actions@0.1.2","bugs":{"url":"https://github.com/Hemanth-7026/playwright/issues"},"homepage":"https://github.com/Hemanth-7026/playwright#readme","_nodeVersion":"24.14.0","_npmVersion":"11.9.0","dist":{"integrity":"sha512-/uzHx95cZPNlw+n95E5LpRYF/TJpMM4mG9Tv7l0lwZNc4IYzqtSydIt8ZU+3xiYMkv5mEYxvP6/QJuFcI3PPcg==","shasum":"79278e04716a1bdcee23a67bdfc503e69af95404","tarball":"https://registry.npmjs.org/@anthropic-desktop/playwright-desktop-actions/-/playwright-desktop-actions-0.1.2.tgz","fileCount":91,"unpackedSize":204241,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDJB+9eUnU9RLXWKWeQ876fh90VAbs4bpexam2DCn9fMwIgGqOBQ2+TMXBiE2jvvNBy714EqR8AG4qsu4HT4GWzIW0="}]},"_npmUser":{"name":"desktoptest","email":"maddipatihemanthkumar@gmail.com"},"directories":{},"maintainers":[{"name":"desktoptest","email":"maddipatihemanthkumar@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/playwright-desktop-actions_0.1.2_1776699223883_0.4695935322888942"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-23T20:37:02.364Z","modified":"2026-04-20T15:33:44.134Z","0.1.0":"2026-03-23T20:37:02.587Z","0.1.1":"2026-04-20T07:18:35.336Z","0.1.2":"2026-04-20T15:33:44.023Z"},"bugs":{"url":"https://github.com/Hemanth-7026/playwright/issues"},"license":"Apache-2.0","homepage":"https://github.com/Hemanth-7026/playwright#readme","keywords":["playwright","desktop","automation","okta","fastpass","windows","native-auth"],"repository":{"type":"git","url":"git+https://github.com/Hemanth-7026/playwright.git","directory":"packages/desktop-agent"},"description":"Desktop automation agent for Playwright — handles Okta Verify FastPass and other native auth flows","maintainers":[{"name":"desktoptest","email":"maddipatihemanthkumar@gmail.com"}],"readme":"# @playwright/desktop-agent\n\nA highly flexible, scalable, and resilient desktop automation module that integrates with Playwright to automatically handle Okta Verify FastPass approval (and other native auth flows) in the background on Windows.\n\n---\n\n## Architecture\n\n```\n┌─────────────────────────────────────────────────────────┐\n│                   Playwright Test Code                  │\n│         await authHandler.handleFastPass()              │\n└──────────────────────┬──────────────────────────────────┘\n                       │\n┌──────────────────────▼──────────────────────────────────┐\n│              Integration Layer                          │\n│  PlaywrightAuthHandler  (promise-based, blocks caller)  │\n└──────────────────────┬──────────────────────────────────┘\n                       │\n┌──────────────────────▼──────────────────────────────────┐\n│               Desktop Agent (core)                      │\n│  Polling loop · retry/fallback · listener management    │\n├─────────┬───────────┬───────────┬───────────────────────┤\n│Detection│  Action   │  Window   │     Environment       │\n│ Engine  │  Engine   │  Manager  │      Manager          │\n├─────────┴───────────┴───────────┴───────────────────────┤\n│         Strategy & Handler Registries (plugin)          │\n├─────────────────────────────────────────────────────────┤\n│  Config Manager  │  Logger  │  Retry Manager            │\n└─────────────────────────────────────────────────────────┘\n```\n\n### Layer Responsibilities\n\n| Layer | Files | Purpose |\n|-------|-------|---------|\n| **Integration** | `integration/PlaywrightAuthHandler.ts` | Promise-based API for Playwright tests |\n| **Agent** | `agent/DesktopAgent.ts`, `agent/AgentService.ts` | Background polling loop, lifecycle, auto-start |\n| **Detection** | `detection/DetectionEngine.ts`, `detection/StrategyRegistry.ts`, `detection/strategies/*` | Multi-strategy prompt detection with fallback |\n| **Action** | `action/ActionEngine.ts`, `action/HandlerRegistry.ts`, `action/handlers/*` | Multi-handler approval execution with fallback |\n| **Window** | `window/WindowScanner.ts`, `window/WindowManager.ts` | Win32 window enumeration, focus, move, restore |\n| **Environment** | `environment/EnvironmentManager.ts` | OS version, screen resolution, user profile |\n| **Retry** | `retry/RetryManager.ts` | Configurable retries with fixed/linear/exponential backoff + jitter |\n| **Config** | `config/ConfigManager.ts` | Layered config: defaults → external JSON → runtime overrides |\n| **Logging** | `logging/Logger.ts` | Structured logging with component tags |\n\n---\n\n## Folder Structure\n\n```\npackages/desktop-agent/\n├── package.json\n├── tsconfig.json\n├── config/\n│   └── default.config.json         # External config (editable without code changes)\n└── src/\n    ├── index.ts                     # Public API barrel export\n    ├── types.ts                     # All interfaces and type definitions\n    ├── agent/\n    │   ├── DesktopAgent.ts          # Core background agent\n    │   └── AgentService.ts          # Windows Task Scheduler auto-start\n    ├── config/\n    │   └── ConfigManager.ts         # Layered configuration\n    ├── logging/\n    │   └── Logger.ts                # Structured logging\n    ├── environment/\n    │   └── EnvironmentManager.ts    # OS / display detection\n    ├── detection/\n    │   ├── DetectionEngine.ts       # Strategy orchestrator\n    │   ├── StrategyRegistry.ts      # Plugin registry for strategies\n    │   ├── fuzzyMatch.ts            # Fuzzy string matching util\n    │   └── strategies/\n    │       ├── WindowTitleStrategy.ts\n    │       ├── ProcessMonitorStrategy.ts\n    │       └── AccessibilityStrategy.ts\n    ├── action/\n    │   ├── ActionEngine.ts          # Handler orchestrator\n    │   ├── HandlerRegistry.ts       # Plugin registry for handlers\n    │   └── handlers/\n    │       ├── KeyboardApprovalHandler.ts\n    │       └── ClickApprovalHandler.ts\n    ├── window/\n    │   ├── WindowScanner.ts         # Win32 window enumeration\n    │   └── WindowManager.ts         # Window focus / move / restore\n    ├── retry/\n    │   └── RetryManager.ts          # Retry with backoff\n    └── integration/\n        └── PlaywrightAuthHandler.ts # Playwright-facing API\n```\n\n---\n\n## Quick Start\n\n### Basic Playwright Usage\n\n```typescript\nimport { test, expect } from '@playwright/test';\nimport { createAuthHandler } from '@playwright/desktop-agent';\n\nconst authHandler = createAuthHandler();\n\ntest('login with Okta FastPass', async ({ page }) => {\n  await page.goto('https://myapp.example.com/login');\n\n  // Click the SSO / Okta login button\n  await page.click('button:has-text(\"Sign in with Okta\")');\n\n  // Block until FastPass approval completes (or times out)\n  await authHandler.handleFastPass();\n\n  // Page is now authenticated\n  await expect(page.locator('.dashboard')).toBeVisible();\n});\n\ntest.afterAll(async () => {\n  await authHandler.dispose();\n});\n```\n\n### Custom Configuration\n\n```typescript\nconst authHandler = createAuthHandler({\n  config: {\n    approvalTimeoutMs: 60_000,\n    pollIntervalMs: 250,\n    logLevel: 'debug',\n    patterns: {\n      windowTitles: ['Okta Verify', 'My Custom Auth Prompt'],\n      processNames: ['OktaVerify', 'MyAuthApp'],\n      windowClassNames: [],\n      fuzzyThreshold: 0.5,\n    },\n  },\n});\n```\n\n### External Config File (no code changes)\n\n```typescript\nconst authHandler = createAuthHandler({\n  config: {\n    externalConfigPath: './okta-agent.config.json',\n  },\n});\n```\n\nEdit `okta-agent.config.json` to change patterns, timeouts, and behavior\nwithout touching any code.\n\nBrowser-hosted protocol prompts such as `Open Okta Verify?` are handled as part\nof the normal FastPass detection flow through the built-in matching patterns.\n\n### Persistent Background Agent\n\n```typescript\nimport { DesktopAgent, AgentService } from '@playwright/desktop-agent';\nimport { Logger } from '@playwright/desktop-agent';\n\n// Run the agent as a long-lived process\nconst agent = new DesktopAgent();\nawait agent.start();\n\n// Install auto-start on login (one-time setup)\nconst service = new AgentService(agent.logger);\nawait service.install('./run-agent.js');\n\n// Agent now polls in the background\n// Stop with: await agent.stop();\n```\n\n### Manual Popup Validation\n\nThe package includes a reproducible popup simulation and approval check:\n\n```powershell\nSet-Location C:\\Users\\maddi\\source\\repos\\playwright\\packages\\desktop-agent\nnpm run build\nnpm run test:vscode-popup\n```\n\nThis starts a Windows Forms dialog titled `Open VS Code?` and verifies that\nthe package detects it and approves it using the popup API.\n\n---\n\n## Adding a New Detection Strategy (Without Changing Core Logic)\n\nTo demonstrate the plugin architecture, here's how to add a **toast notification** detection strategy:\n\n```typescript\nimport {\n  DesktopAgent,\n  createAuthHandler,\n} from '@playwright/desktop-agent';\nimport type {\n  DetectionStrategy,\n  DetectionResult,\n  EnvironmentInfo,\n} from '@playwright/desktop-agent';\n\n/**\n * Detects Okta Verify toast notifications via Windows Action Center.\n * (Example custom strategy — add without modifying any core files.)\n */\nclass ToastNotificationStrategy implements DetectionStrategy {\n  readonly name = 'ToastNotification';\n  readonly priority = 15; // Between WindowTitle (10) and ProcessMonitor (20)\n\n  async isAvailable(env: EnvironmentInfo): Promise<boolean> {\n    // Only available on Windows 10+\n    return process.platform === 'win32' && parseInt(env.osBuild) >= 10240;\n  }\n\n  async detect(env: EnvironmentInfo): Promise<DetectionResult> {\n    // ... your custom toast detection logic here ...\n    // For example, query the WinRT notification API via PowerShell\n    return {\n      detected: false,\n      strategyName: this.name,\n      confidence: 0,\n      timestamp: Date.now(),\n    };\n  }\n}\n\n// Register the custom strategy — no core code modified\nconst auth = createAuthHandler();\n(auth as any).agent.strategies.register(new ToastNotificationStrategy());\n\n// Use as normal\nawait auth.handleFastPass();\n```\n\nThe `StrategyRegistry` and `HandlerRegistry` accept any object implementing\nthe `DetectionStrategy` or `ActionHandler` interface. Core logic never needs\nto change.\n\n---\n\n## How the System Handles Environment Differences\n\n### 1. Environment Abstraction\n\nThe `EnvironmentManager` detects at runtime:\n- **OS version & build** — strategies can check `isAvailable()` and skip themselves\n  on unsupported Windows versions\n- **Screen resolution** — `WindowManager` computes off-screen coordinates dynamically\n  from `EnvironmentInfo.primaryScreen`, never using hardcoded pixel values\n- **User profile path** — used for locating per-user config and log files\n- **Multi-monitor** — all screens are enumerated; the primary screen is used\n  for off-screen positioning by default\n\n### 2. Config-Driven Detection\n\nWindow titles, process names, and class names are stored in the external\nconfig file and matched via fuzzy matching. When Okta ships a version that\nchanges the window title from \"Okta Verify\" to \"Okta Verify - FastPass v2\",\nyou update the config file — no code change, no recompile:\n\n```json\n{\n  \"patterns\": {\n    \"windowTitles\": [\n      \"Okta Verify\",\n      \"Okta Verify - FastPass v2\"\n    ],\n    \"fuzzyThreshold\": 0.55\n  }\n}\n```\n\nLowering `fuzzyThreshold` makes matching more tolerant of minor text\ndifferences across versions.\n\n### 3. Strategy Fallback Chain\n\nIf window title matching fails (e.g., a UI redesign), the Detection Engine\nautomatically falls through to:\n1. `ProcessMonitorStrategy` — detects the OktaVerify process (less precise\n   but version-independent)\n2. `AccessibilityStrategy` — uses UI Automation tree traversal (resilient\n   to visual changes, reads semantic element names)\n\nEach strategy reports a **confidence score**, so the engine can prefer\nhigh-confidence matches while still accepting lower-confidence fallbacks.\n\n### 4. Action Handler Fallback\n\nSimilarly, if `KeyboardApprovalHandler` (SendKeys Enter) fails — perhaps\nthe dialog layout changed and focus lands on the wrong button —\n`ClickApprovalHandler` uses UI Automation to find and invoke the approval\nbutton by its accessible name, independent of visual layout.\n\n### 5. Display-Adaptive Window Management\n\nThe `WindowManager` never uses hardcoded screen coordinates. It:\n- Queries `EnvironmentInfo.primaryScreen.width` to compute off-screen placement\n- Saves and restores original window bounds regardless of resolution\n- Handles minimized windows by restoring them before interaction\n\n### 6. Version Awareness\n\nThe `ProcessMonitorStrategy` reports the process name which can include\nversion suffixes. The config-driven fuzzy matching adapts automatically.\nFor deeper version detection, a custom strategy can read the Okta Verify\nexecutable's file version via PowerShell:\n\n```powershell\n(Get-Item \"C:\\...\\OktaVerify.exe\").VersionInfo.FileVersion\n```\n\nAnd adjust its detection behavior dynamically.\n\n---\n\n## Resilience Features\n\n| Feature | Implementation |\n|---------|---------------|\n| **Retry with backoff** | `RetryManager` — fixed, linear, or exponential backoff with jitter |\n| **Fallback chain** | Strategies/handlers tried in priority order; first success wins |\n| **Graceful degradation** | If all automated handlers fail, logs state for manual intervention |\n| **Hot-reload config** | `ConfigManager.reload()` re-reads external JSON without restart |\n| **Fault isolation** | Each strategy/handler runs in its own try/catch; one failure doesn't stop others |\n| **Structured logging** | Every detection attempt, success, failure, and unknown state is logged with timestamps and component tags |\n| **Auto-start** | `AgentService` installs a Windows Task Scheduler entry for login trigger |\n\n---\n\n## API Reference\n\n### `createAuthHandler(options?): AuthHandler`\n\nFactory function. Returns a `PlaywrightAuthHandler` ready for use.\n\n### `AuthHandler.handleFastPass(options?): Promise<void>`\n\nBlocks until FastPass approval completes. Throws on timeout.\n\n### `AuthHandler.status(): AgentStatus`\n\nReturns current agent state: uptime, last detection/action, registered plugins.\n\n### `AuthHandler.dispose(): Promise<void>`\n\nShuts down the agent and releases all resources.\n\n### `DesktopAgent`\n\nFull-featured agent with `start()`, `stop()`, `waitForApproval()`, direct\naccess to strategy/handler registries, and config hot-reload.\n\n### `StrategyRegistry.register(strategy: DetectionStrategy): void`\n\nAdd a custom detection strategy at runtime.\n\n### `HandlerRegistry.register(handler: ActionHandler): void`\n\nAdd a custom action handler at runtime.\n","readmeFilename":"README.md"}