@sudobility/testomniac_runner_service 0.1.39 → 0.1.40

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/CLAUDE.md +85 -331
  2. package/README.md +4 -8
  3. package/dist/analyzer/page-analyzer.d.ts +11 -5
  4. package/dist/analyzer/page-analyzer.d.ts.map +1 -1
  5. package/dist/analyzer/page-analyzer.js +122 -35
  6. package/dist/analyzer/page-analyzer.js.map +1 -1
  7. package/dist/api/client.d.ts +2 -4
  8. package/dist/api/client.d.ts.map +1 -1
  9. package/dist/api/client.js +3 -17
  10. package/dist/api/client.js.map +1 -1
  11. package/dist/index.d.ts +0 -4
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +0 -4
  14. package/dist/index.js.map +1 -1
  15. package/dist/orchestrator/runner.d.ts +1 -2
  16. package/dist/orchestrator/runner.d.ts.map +1 -1
  17. package/dist/orchestrator/runner.js +7 -12
  18. package/dist/orchestrator/runner.js.map +1 -1
  19. package/dist/orchestrator/test-case-executor.d.ts.map +1 -1
  20. package/dist/orchestrator/test-case-executor.js +39 -9
  21. package/dist/orchestrator/test-case-executor.js.map +1 -1
  22. package/dist/orchestrator/types.d.ts +0 -15
  23. package/dist/orchestrator/types.d.ts.map +1 -1
  24. package/package.json +1 -1
  25. package/dist/orchestrator/decomposition.d.ts +0 -10
  26. package/dist/orchestrator/decomposition.d.ts.map +0 -1
  27. package/dist/orchestrator/decomposition.js +0 -658
  28. package/dist/orchestrator/decomposition.js.map +0 -1
  29. package/dist/orchestrator/direct-navigation.d.ts +0 -4
  30. package/dist/orchestrator/direct-navigation.d.ts.map +0 -1
  31. package/dist/orchestrator/direct-navigation.js +0 -47
  32. package/dist/orchestrator/direct-navigation.js.map +0 -1
  33. package/dist/orchestrator/discovery.d.ts +0 -10
  34. package/dist/orchestrator/discovery.d.ts.map +0 -1
  35. package/dist/orchestrator/discovery.js +0 -77
  36. package/dist/orchestrator/discovery.js.map +0 -1
  37. package/dist/orchestrator/expertise.d.ts +0 -5
  38. package/dist/orchestrator/expertise.d.ts.map +0 -1
  39. package/dist/orchestrator/expertise.js +0 -168
  40. package/dist/orchestrator/expertise.js.map +0 -1
  41. package/dist/orchestrator/orchestrator.d.ts +0 -5
  42. package/dist/orchestrator/orchestrator.d.ts.map +0 -1
  43. package/dist/orchestrator/orchestrator.js +0 -172
  44. package/dist/orchestrator/orchestrator.js.map +0 -1
  45. package/dist/orchestrator/page-capture.d.ts +0 -22
  46. package/dist/orchestrator/page-capture.d.ts.map +0 -1
  47. package/dist/orchestrator/page-capture.js +0 -112
  48. package/dist/orchestrator/page-capture.js.map +0 -1
  49. package/dist/orchestrator/test-execution.d.ts +0 -5
  50. package/dist/orchestrator/test-execution.d.ts.map +0 -1
  51. package/dist/orchestrator/test-execution.js +0 -254
  52. package/dist/orchestrator/test-execution.js.map +0 -1
package/CLAUDE.md CHANGED
@@ -1,338 +1,92 @@
1
- # Testomniac Scanning Service
2
-
3
- Shared TypeScript library containing all core scanning business logic, browser abstraction, extractors, planners, detectors, AI analysis, test generation, scan orchestration, and API client for the Testomniac testing platform.
4
-
5
- **Package**: `@sudobility/testomniac_runner_service` v0.1.1 (published to npm, public)
6
-
7
- ## Tech Stack
8
-
9
- - **Language**: TypeScript (strict mode)
10
- - **Runtime**: Bun
11
- - **Package Manager**: Bun (do not use npm/yarn/pnpm for installing dependencies)
12
- - **Build**: TypeScript compiler (tsc) to `dist/`
13
- - **Test**: Vitest
14
- - **Module**: ES Module (ESM only)
15
-
16
- ## Project Structure
17
-
18
- ```
19
- src/
20
- ├── index.ts # Public API exports (all modules below)
21
- ├── adapter.ts # BrowserAdapter interface definition
22
- ├── api/
23
- │ └── client.ts # ApiClient — HTTP client for testomniac_api (55+ methods)
24
- ├── browser/
25
- │ ├── dom-snapshot.ts # buildDomSnapshot: two-pass DOM element discovery
26
- │ ├── page-utils.ts # normalizeHtml, computeHashes (async sha256: Node + browser)
27
- │ └── page-utils.test.ts
28
- ├── config/
29
- │ └── constants.ts # Timeouts, limits, URL patterns, error patterns
30
- ├── extractors/ # Modular element extraction system (11 files)
31
- │ ├── index.ts # extractActionableItems — registers extractors in priority order
32
- │ ├── types.ts # ItemExtractor, DomSnapshotEntry, ExtractorCandidate, ActionKind
33
- │ ├── helpers.ts # createCandidate, withResolvedSelector, uniqueBySelector
34
- │ ├── selectors.ts # classifyActionKind: navigate|select|fill|toggle|click
35
- │ ├── text-inputs.ts # <input>, <textarea>, role="textbox", contenteditable
36
- │ ├── selects.ts # <select>, role="combobox"
37
- │ ├── toggles.ts # checkbox, radio, role="switch"
38
- │ ├── product-actions.ts # E-commerce actions (cart, checkout, options)
39
- │ ├── buttons.ts # <button>, input[type="submit"]
40
- │ ├── clickables.ts # Remaining clickable elements (links, divs, etc.)
41
- │ └── form-extractor.ts # extractForms: discover form structures
42
- ├── planners/
43
- │ └── fill-value-planner.ts # RuleBasedFillValuePlanner: multi-signal form value heuristics
44
- ├── detectors/ # Page-level quality checks + bug/modal detection
45
- │ ├── index.ts # Re-exports all detectors
46
- ├── bug-detector.ts # Comprehensive bug detection (broken links, visual, content, media)
47
- │ ├── modal-handler.ts # Detect & dismiss Bootstrap, ARIA dialog, Fancybox, etc.
48
- │ ├── link-checker.ts # Broken link detection (HEAD requests, 4xx/5xx)
49
- │ ├── visual-checker.ts # Broken images, missing alt, duplicate IDs/headings, empty links
50
- │ ├── content-checker.ts # Placeholder text, error pages, invalid prices, short pages
51
- │ ├── functional-checker.ts # Console errors, network failures, error-after-click
52
- │ └── *.test.ts # Colocated tests
53
- ├── ai/ # AI analysis pipeline (GPT-4o)
54
- │ ├── analyzer.ts # runAiAnalysis: orchestrates persona use case input generation
55
- │ ├── persona-generator.ts # Generate 1-5 user personas from page content
56
- │ ├── use-case-generator.ts # Generate 2-8 use cases per persona
57
- │ ├── input-generator.ts # Generate realistic form inputs per use case
58
- │ └── token-tracker.ts # AI token usage tracking (reported to API)
59
- ├── generation/ # Test case generation (9 template files)
60
- │ ├── generator.ts # generateTestCases: orchestrator
61
- │ ├── suite-tagger.ts # Priority assignment (critical → low) by route keywords
62
- │ ├── render.ts # Render test template (navigate + assert visibility)
63
- │ ├── interaction.ts # Interaction test template (click/hover sequences)
64
- │ ├── form.ts # Form positive test template
65
- │ ├── form-negative.ts # Form negative/validation test template
66
- │ ├── password.ts # Password requirement test template
67
- │ ├── navigation.ts # Navigation flow test template
68
- │ └── e2e.ts # E2E multi-step path enumeration + template
69
- ├── orchestrator/ # Scan pipeline orchestration
70
- │ ├── types.ts # ScanConfig, ScanEventHandler, TestExecutor, ScanResult, ScanPhase
71
- │ ├── orchestrator.ts # runScan(adapter, config, api, eventHandler, testExecutor?)
72
- │ ├── mouse-scanning.ts # Phase 1a: navigate → extract → hover/click → detect → discover
73
- │ ├── ai-analysis.ts # Phase 1b: GPT-4o persona/use case/input generation
74
- │ ├── input-scanning.ts # Phase 1c: pairwise form filling with AI-generated values
75
- │ ├── test-generation.ts # Phase 3: JSON test case creation
76
- │ └── test-execution.ts # Phase 4: test execution via TestExecutor interface
77
- ├── scanner/ # Scanner utility modules
78
- │ ├── action-classifier.ts # normalizeHref, shouldExpectNavigation, getActionPriority
79
- │ ├── navigator.ts # Cross-page navigation tracking
80
- │ ├── action-queue.ts # In-memory action queue
81
- │ ├── state-manager.ts # Page state tracker
82
- │ ├── loop-guard.ts # Action dedup + caps (200/page, 5000 total)
83
- │ ├── phase-timer.ts # Per-phase duration tracking
84
- │ ├── component-detector.ts # Reusable UI component detection across pages
85
- │ ├── email-detector.ts # Email verification flow detection
86
- │ ├── scroll-scanner.ts # Lazy-loaded element discovery via scrolling
87
- │ ├── pairwise.ts # Pairwise combination generator
88
- │ ├── issue-detector.ts # detectDeadClick, detectErrorOnPage, detectConsoleErrors
89
- │ └── *.test.ts # Colocated tests
90
- ├── plugins/ # Plugin interface + registry
91
- │ ├── types.ts # Plugin, PluginContext, PluginResult, PluginIssue interfaces
92
- │ └── registry.ts # registerPlugin, getPlugin, getEnabledPlugins
93
- └── domain/
94
- ├── types.ts # Re-exports from @sudobility/testomniac_types
95
- └── url-ownership.ts # normalizeBaseUrl, getRegistrableDomain, emailMatchesUrlDomain
96
- ```
1
+ # Testomniac Runner Service
2
+
3
+ Shared execution and discovery library used by Testomniac runner clients.
4
+
5
+ ## Purpose
6
+
7
+ This package owns the active runtime architecture for:
8
+
9
+ - executing persisted test suites, cases, and case runs
10
+ - analyzing resulting browser states
11
+ - generating discovery-time follow-up coverage
12
+ - evaluating expertises and recording findings
13
+ - abstracting over the browser through `BrowserAdapter`
14
+ - abstracting over persistence through `ApiClient`
15
+
16
+ The legacy `runScan()` orchestration path has been removed. `runTestRun()` is
17
+ the runtime entry point.
18
+
19
+ ## Core Model
20
+
21
+ Persistent coverage:
22
+
23
+ - `test_suite_bundle`
24
+ - `test_suite`
25
+ - `test_case`
26
+ - `test_action`
27
+
28
+ Run records:
29
+
30
+ - `test_run`
31
+ - `test_suite_bundle_run`
32
+ - `test_suite_run`
33
+ - `test_case_run`
34
+ - `test_run_finding`
35
+
36
+ ## Execution Flow
37
+
38
+ 1. A client calls `runTestRun()`.
39
+ 2. The runner claims the `test_run`.
40
+ 3. It loads the active bundle run and iterates pending suite runs.
41
+ 4. For each suite run, it iterates pending case runs whose dependencies are
42
+ ready.
43
+ 5. `executeTestCase()` navigates, recreates dependency setup when needed,
44
+ executes actions, gathers runtime artifacts, and runs expertises.
45
+ 6. If the root run is a discovery run, `PageAnalyzer` creates or resolves the
46
+ target page state and generates follow-up cases and runs.
47
+ 7. The runner completes suite runs, bundle runs, and the root test run.
48
+
49
+ ## Discovery Rules
50
+
51
+ - Every actionable element starts with a hover test case.
52
+ - After hover:
53
+ - if no new actionable items appear, generate a dependent click test case
54
+ - if new actionable items appear, generate dependent hover test cases from
55
+ the hover target page state
56
+ - `PageAnalyzer` owns target-page-state creation and follow-up case generation.
57
+ - Expertises do not generate coverage.
58
+
59
+ ## Key Components
60
+
61
+ - [`src/adapter.ts`](src/adapter.ts): browser abstraction
62
+ - [`src/api/client.ts`](src/api/client.ts): scanner API client
63
+ - [`src/orchestrator/runner.ts`](src/orchestrator/runner.ts): `runTestRun()`
64
+ - [`src/orchestrator/test-case-executor.ts`](src/orchestrator/test-case-executor.ts):
65
+ single-case execution
66
+ - [`src/analyzer/page-analyzer.ts`](src/analyzer/page-analyzer.ts):
67
+ discovery-time target-state and follow-up coverage logic
68
+ - [`src/expertise`](src/expertise): expertise system
69
+ - [`src/extractors`](src/extractors): actionable-item extraction
70
+ - [`src/scanner/component-detector.ts`](src/scanner/component-detector.ts):
71
+ scaffold detection
72
+ - [`src/scanner/pattern-detector.ts`](src/scanner/pattern-detector.ts):
73
+ pattern detection
74
+
75
+ ## AI Boundary
76
+
77
+ `PageAnalyzer` is not the AI pipeline. Structural decomposition in the active
78
+ runtime is deterministic. Separate AI helpers exist under `src/ai`, but they
79
+ are not the discovery orchestrator.
97
80
 
98
81
  ## Commands
99
82
 
100
83
  ```bash
101
- bun run build # Compile TypeScript to dist/ (tsc -p tsconfig.build.json)
102
- bun run dev # Watch mode (tsc --watch)
103
- bun run test # Run Vitest tests
104
- bun run test:watch # Vitest watch mode
105
- bun run typecheck # TypeScript check only (tsc --noEmit)
106
- bun run lint # ESLint
107
- bun run lint:fix # ESLint auto-fix
108
- bun run format # Prettier write
109
- bun run format:check # Prettier check
110
- bun run verify # typecheck + lint + test + build (run before publish)
111
- ```
112
-
113
- ## Main Entry Point: `runScan()`
114
-
115
- The orchestrator is the primary consumer API. Both `testomniac_runner` and `testomniac_extension` call it:
116
-
117
- ```typescript
118
- runScan(
119
- adapter: BrowserAdapter, // ChromeAdapter or PuppeteerAdapter
120
- config: ScanConfig, // runId, runnerId, baseUrl, phases, options
121
- api: ApiClient, // HTTP client for testomniac_api
122
- eventHandler: ScanEventHandler, // Progress callbacks
123
- testExecutor?: TestExecutor // Optional test runner (server-side only)
124
- ): Promise<ScanResult>
125
- ```
126
-
127
- ### ScanConfig
128
-
129
- ```typescript
130
- interface ScanConfig {
131
- runId: number;
132
- runnerId: number;
133
- baseUrl: string;
134
- phases: ScanPhase[]; // ["mouse_scanning", "ai_analysis", "input_scanning", ...]
135
- sizeClass?: string;
136
- openaiApiKey?: string;
137
- openaiModel?: string;
138
- testWorkerCount?: number;
139
- }
140
- ```
141
-
142
- ### ScanEventHandler
143
-
144
- Callback interface for progress reporting. Consumers implement this to bridge events to their UI (side panel messages for extension, Pino logging for scanner):
145
-
146
- ```typescript
147
- interface ScanEventHandler {
148
- onPageFound(page): void;
149
- onPageStateCreated(state): void;
150
- onActionCompleted(action): void;
151
- onIssueDetected(issue): void;
152
- onPhaseChanged(phase): void;
153
- onStatsUpdated(stats): void;
154
- onScreenshotCaptured(data): void;
155
- onScanComplete(summary): void;
156
- onError(error): void;
157
- }
158
- ```
159
-
160
- ### TestExecutor
161
-
162
- Optional interface for test execution. Only the server-side scanner provides this (via Puppeteer worker pool):
163
-
164
- ```typescript
165
- interface TestExecutor {
166
- executeTestCase(actions: TestAction[], screen: Screen): Promise<{ passed: boolean; error?: string; durationMs: number }>;
167
- }
168
- ```
169
-
170
- ## Scan Pipeline Phases
171
-
84
+ bun run typecheck
85
+ bun run test
86
+ bun run build
172
87
  ```
173
- Phase: mouse_scanning
174
- Navigate → buildDomSnapshot → extractActionableItems → hover/click each →
175
- bug detection → modal dismissal → discover pages → enqueue
176
- Output: pages, page_states, actionable_items, actions, issues
177
-
178
- Phase: ai_analysis
179
- Feed page content to GPT-4o → generate personas, use cases, input values
180
- Output: personas, use_cases, input_values
181
-
182
- Phase: input_scanning
183
- Fill forms with pairwise combinations of AI-generated values
184
- Output: form fill actions, new page_states
185
-
186
- Phase: test_generation
187
- Create JSON test cases: render, interaction, form, navigation, E2E
188
- Assign priority tags based on route keywords
189
- Output: test_cases with actions_json
190
-
191
- Phase: test_execution
192
- Delegate to TestExecutor interface for actual execution
193
- Output: test_runs (pass/fail), issues for failures
194
- ```
195
-
196
- ## BrowserAdapter Interface
197
-
198
- The core abstraction that allows the same scanning logic to work with both Puppeteer (server-side scanner) and Chrome DevTools Protocol (browser extension):
199
-
200
- ```typescript
201
- interface BrowserAdapter {
202
- goto(url, options?): Promise<void>
203
- waitForNavigation(options?): Promise<void>
204
- url(): Promise<string>
205
- content(): Promise<string>
206
- evaluate<T>(fn, ...args): Promise<T>
207
- waitForSelector(selector, options?): Promise<void>
208
- click(selector, options?): Promise<void>
209
- hover(selector, options?): Promise<void>
210
- type(selector, text): Promise<void>
211
- select(selector, value): Promise<void>
212
- pressKey(key): Promise<void>
213
- screenshot(options?): Promise<Uint8Array>
214
- setViewport(width, height): Promise<void>
215
- on(event, handler): void
216
- close(): Promise<void>
217
- }
218
- ```
219
-
220
- **Implementations**:
221
- - `ChromeAdapter` in `testomniac_extension/src/adapters/ChromeAdapter.ts` (CDP via chrome.debugger)
222
- - `PuppeteerAdapter` in `testomniac_runner/src/adapters/PuppeteerAdapter.ts` (Puppeteer page wrapper)
223
-
224
- ## ApiClient
225
-
226
- HTTP client for the `testomniac_api` scanner endpoints. Initialized via singleton factory:
227
-
228
- ```typescript
229
- const client = getApiClient(baseUrl, apiKey);
230
- ```
231
-
232
- **Method categories** (55+ methods):
233
- - **Run management**: `getPendingRun()`, `updateRunPhase()`, `updateRunStats()`, `updatePhaseDuration()`, `completeRun()`
234
- - **Page/state tracking**: `findOrCreatePage()`, `createPageState()`, `findMatchingPageState()`, `getPageState()`
235
- - **Actionable items**: `insertActionableItems()`, `getItemsByPageState()`
236
- - **Actions**: `createAction()`, `getNextOpenAction()`, `startAction()`, `completeAction()`, `getActionChain()`
237
- - **Personas/use cases**: `createPersona()`, `createUseCase()`, `createInputValue()`
238
- - **Forms/tests**: `insertForm()`, `insertTestCase()`, `createTestRun()`, `completeTestRun()`
239
- - **Issues**: `createIssue()`, `getIssuesByRun()`
240
- - **Other**: AI usage tracking, report emails, component saving, `getRunner()`
241
-
242
- All methods communicate via HTTP with `X-Scanner-Key` header authentication.
243
-
244
- ## Extractors
245
-
246
- The extraction system uses a two-pass approach in `dom-snapshot.ts`:
247
-
248
- **Pass 1**: Query comprehensive CSS selectors for interactive elements (inputs, buttons, links, ARIA roles, event handlers, tabindex, contenteditable)
249
-
250
- **Pass 2**: Find `cursor:pointer` elements missed by Pass 1 (framework-specific clickable divs, etc.)
251
-
252
- 6 extractors registered in priority order: textInputs, selects, toggles, productActions, buttons, clickables. Each returns candidates that are deduplicated and classified into action kinds: `navigate`, `select`, `fill`, `toggle`, `click`.
253
-
254
- ## Detectors
255
-
256
- ### Bug Detector
257
- Comprehensive bug detection combining broken link checking, visual analysis, content analysis, and media issues. Runs inline during mouse scanning.
258
-
259
- ### Modal Handler
260
- Detects and dismisses Bootstrap, Popup Maker, ARIA dialog, Fancybox modals. Uses close button, overlay click, or Escape key.
261
-
262
- ### Link Checker / Visual Checker / Content Checker / Functional Checker
263
- Individual page-level quality check modules. Pure functions that take HTML/text and return issue arrays.
264
-
265
- ## Fill Value Planner
266
-
267
- `RuleBasedFillValuePlanner` uses multi-signal heuristics for form field values:
268
- 1. HTML input type (email, password, tel, date, etc.)
269
- 2. HTML5 autocomplete attribute
270
- 3. Keyword matching on combined signals (name, id, placeholder, label) — English, Spanish, French, German
271
- 4. Default by tag
272
-
273
- ## Key Constants
274
-
275
- ```typescript
276
- SCAN_TIMEOUT_MS = 300_000 // 5 min total scan timeout
277
- ACTION_TIMEOUT_MS = 10_000 // 10 sec per action
278
- TEST_TIMEOUT_MS = 30_000 // 30 sec per test
279
- NETWORK_IDLE_TIMEOUT_MS = 5_000 // 5 sec network idle
280
- POST_ACTION_SETTLE_MS = 2_000 // 2 sec post-action settle
281
- HOVER_DELAY_MS = 500 // 500ms hover delay
282
- MAX_PAGE_LIMIT = 100 // Max pages per run
283
- MAX_E2E_PATHS = 20 // Max end-to-end test paths
284
- MAX_E2E_DEPTH = 6 // Max steps in E2E path
285
- SCREENSHOT_QUALITY = 72 // JPEG quality
286
- DEFAULT_WORKERS = 3 // Concurrent test workers
287
- ```
288
-
289
- ## Page State Hashing
290
-
291
- `computeHashes()` is **async** and uses universal SHA-256 (Node.js `crypto.createHash` when available, falls back to Web `crypto.subtle` for browser environments). Creates 4 hashes for deduplication:
292
- - **htmlHash**: SHA-256 of raw HTML
293
- - **normalizedHtmlHash**: SHA-256 of whitespace-normalized HTML
294
- - **textHash**: SHA-256 of visible text only
295
- - **actionableHash**: SHA-256 of sorted visible interactive items
296
-
297
- ## Dependencies
298
-
299
- **Peer (required)**:
300
- - `@sudobility/testomniac_types` ^0.0.21
301
-
302
- **Peer (optional)**:
303
- - `openai` >=6.0.0
304
- - `react` >=18.0.0
305
-
306
- **Dev**: TypeScript ~5.9.3, Vitest 4, ESLint 9, Prettier 3
307
-
308
- ## Related Projects (Testomniac Ecosystem)
309
-
310
- This library is the **shared foundation** consumed by both scanning clients:
311
-
312
- - **testomniac_runner** — Server-side Puppeteer worker. Thin wrapper that calls `runScan()` with `PuppeteerAdapter` and a `TestExecutor` backed by a worker pool. Provides auth, email, runner, and plugin implementations.
313
- - **testomniac_extension** — Chrome extension. Thin wrapper that calls `runScan()` with `ChromeAdapter`. Only runs `mouse_scanning` phase. Bridges events to side panel UI.
314
- - **testomniac_api** — REST API backend that `ApiClient` communicates with. Stores all scan data.
315
- - **testomniac_types** (`@sudobility/testomniac_types`) — Shared type definitions re-exported by this library.
316
-
317
- ## Coding Patterns
318
-
319
- - **`runScan()` is the single entry point**: Both consumers call `runScan()` with their adapter, config, and event handler. All scanning phases, extraction, detection, and orchestration are managed internally.
320
- - **Pure functions for detectors**: All detector modules export pure functions that take HTML/text and return issue arrays. No side effects, easy to test.
321
- - **Interface-driven browser abstraction**: `BrowserAdapter` is a plain TypeScript interface, not a class. Implementations in consumer packages.
322
- - **Singleton API client**: `getApiClient(baseUrl, apiKey)` returns a cached instance. Call once during initialization.
323
- - **Async `computeHashes`**: Uses a universal `sha256()` that auto-detects Node vs browser runtime. Callers must `await` it.
324
- - **Colocated tests**: Test files live next to source files (`*.test.ts` pattern). Run with `bun run test`.
325
- - **Hash-based dedup**: Page states are compared via 4-level hashing, not string equality.
326
- - **Constants, not config**: Timeouts, limits, and patterns are hardcoded constants. To change them, edit `config/constants.ts` and republish.
327
- - **Plugin interface is defined here, implementations live in consumers**: `Plugin`, `PluginContext`, `PluginResult` types and the registry are in this library. Actual plugin code (SEO, security, content, UI consistency) lives in `testomniac_runner`.
328
88
 
329
- ## Gotchas
89
+ ## Related Packages
330
90
 
331
- - **Published to npm**: This is a library, not an application. Changes require `bun run verify` + `npm publish`. Consumer packages must update their dependency version.
332
- - **No runtime dependencies**: All dependencies are peer or dev. Consumers must provide `@sudobility/testomniac_types` at minimum.
333
- - **`computeHashes` is async**: Uses `await sha256()` internally with universal Node + browser support. The extension shims `node:crypto` via `SubtleCrypto` at the Vite level, but `page-utils.ts` also has its own runtime detection.
334
- - **Constants are compile-time**: Changing a constant requires republishing. Consumer packages pick up changes only after updating their dependency.
335
- - **LoopGuard caps are per-instance**: Each scanner run creates its own `LoopGuard` instance. The 200/5000 limits apply per run, not globally.
336
- - **No logging**: This library does not import any logger. Consumers are responsible for logging around detector/scanner calls.
337
- - **Plugin types reference Puppeteer and OpenAI**: `PluginContext` in `plugins/types.ts` references `Page` from `puppeteer-core` and `OpenAI`. These are optional peer dependencies. The extension does not use plugins.
338
- - **`buildDomSnapshot` runs inside `page.evaluate()`**: The DOM snapshot code executes in the browser context. It cannot reference Node.js modules or closures from the calling scope.
91
+ - `testomniac_extension`: Chrome-hosted runner client
92
+ - `testomniac_api`: persistence and read APIs
package/README.md CHANGED
@@ -26,16 +26,12 @@ designed to support server-side runners as well.
26
26
  Browser runtime contract
27
27
  - [src/index.ts](/Users/johnhuang/projects/testomniac_runner_service/src/index.ts)
28
28
  Package exports
29
- - [src/orchestrator/orchestrator.ts](/Users/johnhuang/projects/testomniac_runner_service/src/orchestrator/orchestrator.ts)
30
- Legacy discovery-oriented scan loop exported as `runScan`
31
29
  - [src/orchestrator/runner.ts](/Users/johnhuang/projects/testomniac_runner_service/src/orchestrator/runner.ts)
32
30
  Suite/bundle execution loop exported as `runTestRun`
33
- - [src/orchestrator/decomposition.ts](/Users/johnhuang/projects/testomniac_runner_service/src/orchestrator/decomposition.ts)
34
- Generates coverage from captured page states
35
- - [src/orchestrator/test-execution.ts](/Users/johnhuang/projects/testomniac_runner_service/src/orchestrator/test-execution.ts)
36
- Executes generated test cases and captures newly reached states
37
31
  - [src/orchestrator/test-case-executor.ts](/Users/johnhuang/projects/testomniac_runner_service/src/orchestrator/test-case-executor.ts)
38
32
  Executes a single persisted test case in the newer runner
33
+ - [src/analyzer/page-analyzer.ts](/Users/johnhuang/projects/testomniac_runner_service/src/analyzer/page-analyzer.ts)
34
+ Owns discovery-time target page state creation and follow-up case generation
39
35
 
40
36
  ## Coverage Model
41
37
 
@@ -44,8 +40,8 @@ The package creates coverage in two complementary ways:
44
40
  1. Direct navigation coverage
45
41
  Every discovered same-origin path gets a navigation case
46
42
  2. Stateful interaction coverage
47
- Captured page states are decomposed into actionable interactions, forms,
48
- scaffold-driven flows, and page-content flows
43
+ `PageAnalyzer` uses observed target page states to generate actionable
44
+ interaction coverage, scaffold-driven flows, and page-content flows
49
45
 
50
46
  As test actions execute, newly reached states are captured and turned into more
51
47
  coverage.
@@ -5,6 +5,10 @@ export interface AnalyzerContext {
5
5
  runnerId: number;
6
6
  sizeClass: SizeClass;
7
7
  uid?: string;
8
+ currentTestCaseId: number;
9
+ currentTestSuiteId: number;
10
+ currentSuiteRunId: number | null;
11
+ html: string;
8
12
  currentPageStateId: number;
9
13
  beginningPageStateId: number;
10
14
  currentPath: string;
@@ -28,13 +32,10 @@ export declare class PageAnalyzer {
28
32
  generateExpectations(testCase: TestCase): Expectation[];
29
33
  /**
30
34
  * Generate new test cases for scaffolds and page content.
31
- * Called AFTER expertises evaluate and test case run results are set.
32
- *
33
- * Also performs mouse-over fixup: if a hover had no visible effect,
34
- * adds a click action.
35
+ * Called AFTER expertises evaluate and the target page state is established.
35
36
  */
36
37
  generateTestCases(testCase: TestCase, context: AnalyzerContext): Promise<void>;
37
- private mouseOverFixup;
38
+ private generateHoverFollowUpCases;
38
39
  private generateNavigationTestCases;
39
40
  private generateScaffoldTestCases;
40
41
  private generateContentTestCases;
@@ -43,5 +44,10 @@ export declare class PageAnalyzer {
43
44
  private extractRelativePath;
44
45
  private buildNavigationTestCase;
45
46
  private buildHoverTestCase;
47
+ private buildClickTestCase;
48
+ private isHoverOnly;
49
+ private getPrimarySelector;
50
+ private getItemKey;
51
+ private ensureTargetPageState;
46
52
  }
47
53
  //# sourceMappingURL=page-analyzer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"page-analyzer.d.ts","sourceRoot":"","sources":["../../src/analyzer/page-analyzer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,QAAQ,EACR,WAAW,EACX,cAAc,EACd,SAAS,EACT,iBAAiB,EACjB,0BAA0B,EAE3B,MAAM,8BAA8B,CAAC;AAMtC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAE5E,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,SAAS,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,kBAAkB,EAAE,MAAM,CAAC;IAC3B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,iBAAiB,EAAE,OAAO,CAAC;IAC3B,SAAS,EAAE,sBAAsB,EAAE,CAAC;IACpC,eAAe,EAAE,cAAc,EAAE,CAAC;IAClC,eAAe,EAAE,iBAAiB,CAAC;IACnC,SAAS,EAAE,0BAA0B,CAAC;IACtC,GAAG,EAAE,SAAS,CAAC;CAChB;AAED;;;GAGG;AACH,qBAAa,YAAY;IACvB;;;OAGG;IACH,oBAAoB,CAAC,QAAQ,EAAE,QAAQ,GAAG,WAAW,EAAE;IAiCvD;;;;;;OAMG;IACG,iBAAiB,CACrB,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,IAAI,CAAC;YAqBF,cAAc;YA2Bd,2BAA2B;YA0C3B,yBAAyB;YA4CzB,wBAAwB;YAgDxB,cAAc;IAY5B,OAAO,CAAC,iBAAiB;IAQzB,OAAO,CAAC,mBAAmB;IAS3B,OAAO,CAAC,uBAAuB;IA+B/B,OAAO,CAAC,kBAAkB;CA+B3B"}
1
+ {"version":3,"file":"page-analyzer.d.ts","sourceRoot":"","sources":["../../src/analyzer/page-analyzer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,QAAQ,EACR,WAAW,EACX,cAAc,EACd,SAAS,EACT,iBAAiB,EACjB,0BAA0B,EAG3B,MAAM,8BAA8B,CAAC;AAOtC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAG5E,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,SAAS,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,iBAAiB,EAAE,MAAM,CAAC;IAC1B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,kBAAkB,EAAE,MAAM,CAAC;IAC3B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,iBAAiB,EAAE,OAAO,CAAC;IAC3B,SAAS,EAAE,sBAAsB,EAAE,CAAC;IACpC,eAAe,EAAE,cAAc,EAAE,CAAC;IAClC,eAAe,EAAE,iBAAiB,CAAC;IACnC,SAAS,EAAE,0BAA0B,CAAC;IACtC,GAAG,EAAE,SAAS,CAAC;CAChB;AAED;;;GAGG;AACH,qBAAa,YAAY;IACvB;;;OAGG;IACH,oBAAoB,CAAC,QAAQ,EAAE,QAAQ,GAAG,WAAW,EAAE;IAiCvD;;;OAGG;IACG,iBAAiB,CACrB,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,IAAI,CAAC;YAsBF,0BAA0B;YAkE1B,2BAA2B;YA+C3B,yBAAyB;YA6CzB,wBAAwB;YAiDxB,cAAc;IAkB5B,OAAO,CAAC,iBAAiB;IAQzB,OAAO,CAAC,mBAAmB;IAS3B,OAAO,CAAC,uBAAuB;IAgC/B,OAAO,CAAC,kBAAkB;IAoC1B,OAAO,CAAC,kBAAkB;IAoC1B,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,kBAAkB;IAK1B,OAAO,CAAC,UAAU;YAUJ,qBAAqB;CAqCpC"}