@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.
- package/CLAUDE.md +85 -331
- package/README.md +4 -8
- package/dist/analyzer/page-analyzer.d.ts +11 -5
- package/dist/analyzer/page-analyzer.d.ts.map +1 -1
- package/dist/analyzer/page-analyzer.js +122 -35
- package/dist/analyzer/page-analyzer.js.map +1 -1
- package/dist/api/client.d.ts +2 -4
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/client.js +3 -17
- package/dist/api/client.js.map +1 -1
- package/dist/index.d.ts +0 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -4
- package/dist/index.js.map +1 -1
- package/dist/orchestrator/runner.d.ts +1 -2
- package/dist/orchestrator/runner.d.ts.map +1 -1
- package/dist/orchestrator/runner.js +7 -12
- package/dist/orchestrator/runner.js.map +1 -1
- package/dist/orchestrator/test-case-executor.d.ts.map +1 -1
- package/dist/orchestrator/test-case-executor.js +39 -9
- package/dist/orchestrator/test-case-executor.js.map +1 -1
- package/dist/orchestrator/types.d.ts +0 -15
- package/dist/orchestrator/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/orchestrator/decomposition.d.ts +0 -10
- package/dist/orchestrator/decomposition.d.ts.map +0 -1
- package/dist/orchestrator/decomposition.js +0 -658
- package/dist/orchestrator/decomposition.js.map +0 -1
- package/dist/orchestrator/direct-navigation.d.ts +0 -4
- package/dist/orchestrator/direct-navigation.d.ts.map +0 -1
- package/dist/orchestrator/direct-navigation.js +0 -47
- package/dist/orchestrator/direct-navigation.js.map +0 -1
- package/dist/orchestrator/discovery.d.ts +0 -10
- package/dist/orchestrator/discovery.d.ts.map +0 -1
- package/dist/orchestrator/discovery.js +0 -77
- package/dist/orchestrator/discovery.js.map +0 -1
- package/dist/orchestrator/expertise.d.ts +0 -5
- package/dist/orchestrator/expertise.d.ts.map +0 -1
- package/dist/orchestrator/expertise.js +0 -168
- package/dist/orchestrator/expertise.js.map +0 -1
- package/dist/orchestrator/orchestrator.d.ts +0 -5
- package/dist/orchestrator/orchestrator.d.ts.map +0 -1
- package/dist/orchestrator/orchestrator.js +0 -172
- package/dist/orchestrator/orchestrator.js.map +0 -1
- package/dist/orchestrator/page-capture.d.ts +0 -22
- package/dist/orchestrator/page-capture.d.ts.map +0 -1
- package/dist/orchestrator/page-capture.js +0 -112
- package/dist/orchestrator/page-capture.js.map +0 -1
- package/dist/orchestrator/test-execution.d.ts +0 -5
- package/dist/orchestrator/test-execution.d.ts.map +0 -1
- package/dist/orchestrator/test-execution.js +0 -254
- package/dist/orchestrator/test-execution.js.map +0 -1
package/CLAUDE.md
CHANGED
|
@@ -1,338 +1,92 @@
|
|
|
1
|
-
# Testomniac
|
|
2
|
-
|
|
3
|
-
Shared
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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
|
|
102
|
-
bun run
|
|
103
|
-
bun run
|
|
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
|
-
##
|
|
89
|
+
## Related Packages
|
|
330
90
|
|
|
331
|
-
-
|
|
332
|
-
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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,
|
|
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"}
|