@sudobility/testomniac_runner_service 0.1.28 → 0.1.29

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 (61) hide show
  1. package/dist/analyzer/index.d.ts +2 -0
  2. package/dist/analyzer/index.d.ts.map +1 -0
  3. package/dist/analyzer/index.js +2 -0
  4. package/dist/analyzer/index.js.map +1 -0
  5. package/dist/analyzer/page-analyzer.d.ts +47 -0
  6. package/dist/analyzer/page-analyzer.d.ts.map +1 -0
  7. package/dist/analyzer/page-analyzer.js +232 -0
  8. package/dist/analyzer/page-analyzer.js.map +1 -0
  9. package/dist/api/client.d.ts +14 -1
  10. package/dist/api/client.d.ts.map +1 -1
  11. package/dist/api/client.js +65 -0
  12. package/dist/api/client.js.map +1 -1
  13. package/dist/browser/page-utils.d.ts.map +1 -1
  14. package/dist/browser/page-utils.js +1 -1
  15. package/dist/browser/page-utils.js.map +1 -1
  16. package/dist/expertise/index.d.ts +9 -0
  17. package/dist/expertise/index.d.ts.map +1 -0
  18. package/dist/expertise/index.js +22 -0
  19. package/dist/expertise/index.js.map +1 -0
  20. package/dist/expertise/noop-expertise.d.ts +11 -0
  21. package/dist/expertise/noop-expertise.d.ts.map +1 -0
  22. package/dist/expertise/noop-expertise.js +14 -0
  23. package/dist/expertise/noop-expertise.js.map +1 -0
  24. package/dist/expertise/performance-expertise.d.ts +10 -0
  25. package/dist/expertise/performance-expertise.d.ts.map +1 -0
  26. package/dist/expertise/performance-expertise.js +41 -0
  27. package/dist/expertise/performance-expertise.js.map +1 -0
  28. package/dist/expertise/security-expertise.d.ts +12 -0
  29. package/dist/expertise/security-expertise.d.ts.map +1 -0
  30. package/dist/expertise/security-expertise.js +61 -0
  31. package/dist/expertise/security-expertise.js.map +1 -0
  32. package/dist/expertise/seo-expertise.d.ts +14 -0
  33. package/dist/expertise/seo-expertise.d.ts.map +1 -0
  34. package/dist/expertise/seo-expertise.js +84 -0
  35. package/dist/expertise/seo-expertise.js.map +1 -0
  36. package/dist/expertise/tester-expertise.d.ts +14 -0
  37. package/dist/expertise/tester-expertise.d.ts.map +1 -0
  38. package/dist/expertise/tester-expertise.js +87 -0
  39. package/dist/expertise/tester-expertise.js.map +1 -0
  40. package/dist/expertise/types.d.ts +21 -0
  41. package/dist/expertise/types.d.ts.map +1 -0
  42. package/dist/expertise/types.js +1 -0
  43. package/dist/expertise/types.js.map +1 -0
  44. package/dist/index.d.ts +7 -1
  45. package/dist/index.d.ts.map +1 -1
  46. package/dist/index.js +7 -1
  47. package/dist/index.js.map +1 -1
  48. package/dist/orchestrator/orchestrator.d.ts.map +1 -1
  49. package/dist/orchestrator/orchestrator.js +4 -4
  50. package/dist/orchestrator/orchestrator.js.map +1 -1
  51. package/dist/orchestrator/runner.d.ts +12 -0
  52. package/dist/orchestrator/runner.d.ts.map +1 -0
  53. package/dist/orchestrator/runner.js +163 -0
  54. package/dist/orchestrator/runner.js.map +1 -0
  55. package/dist/orchestrator/test-case-executor.d.ts +15 -0
  56. package/dist/orchestrator/test-case-executor.d.ts.map +1 -0
  57. package/dist/orchestrator/test-case-executor.js +259 -0
  58. package/dist/orchestrator/test-case-executor.js.map +1 -0
  59. package/dist/orchestrator/types.d.ts +18 -6
  60. package/dist/orchestrator/types.d.ts.map +1 -1
  61. package/package.json +3 -3
@@ -0,0 +1,163 @@
1
+ import { PageAnalyzer } from "../analyzer";
2
+ import { executeTestCase } from "./test-case-executor";
3
+ /**
4
+ * Main entry point for the new runner execution loop.
5
+ * Replaces the old runScan/processDecompositionJob/executeTestCases orchestrator.
6
+ *
7
+ * Execution: bundle → iterate suites → iterate cases → run case
8
+ */
9
+ export async function runTestRun(adapter, config, api, expertises, events) {
10
+ const startTime = Date.now();
11
+ let pagesFound = 0;
12
+ let pageStatesFound = 0;
13
+ let testRunsCompleted = 0;
14
+ let findingsFound = 0;
15
+ // Wrap event handler to track stats
16
+ const wrappedEvents = {
17
+ ...events,
18
+ onPageFound(page) {
19
+ pagesFound++;
20
+ events.onPageFound(page);
21
+ emitStats();
22
+ },
23
+ onPageStateCreated(state) {
24
+ pageStatesFound++;
25
+ events.onPageStateCreated(state);
26
+ emitStats();
27
+ },
28
+ onTestCaseRunCompleted(run) {
29
+ testRunsCompleted++;
30
+ events.onTestCaseRunCompleted(run);
31
+ emitStats();
32
+ },
33
+ onTestRunCompleted(run) {
34
+ events.onTestRunCompleted(run);
35
+ },
36
+ onFindingCreated(finding) {
37
+ findingsFound++;
38
+ events.onFindingCreated(finding);
39
+ emitStats();
40
+ },
41
+ };
42
+ function emitStats() {
43
+ events.onStatsUpdated({
44
+ pagesFound,
45
+ pageStatesFound,
46
+ testRunsCompleted,
47
+ findingsFound,
48
+ });
49
+ }
50
+ try {
51
+ // Claim the test run
52
+ const claimed = await api.claimTestRun(config.testRunId, config.runnerInstanceId, config.runnerInstanceName);
53
+ if (!claimed) {
54
+ throw new Error(`Test run ${config.testRunId} already claimed by another runner`);
55
+ }
56
+ // Get the test run to find the bundle run
57
+ const testRun = await api.getTestRun(config.testRunId);
58
+ if (!testRun) {
59
+ throw new Error(`Test run ${config.testRunId} not found`);
60
+ }
61
+ if (!testRun.testSuiteBundleRunId) {
62
+ throw new Error(`Test run ${config.testRunId} has no test suite bundle run`);
63
+ }
64
+ // Set up analyzer for discovery mode
65
+ const analyzer = testRun.discovery ? new PageAnalyzer() : null;
66
+ // Get navigation suite for discovery context
67
+ let navigationSuite = null;
68
+ if (testRun.discovery) {
69
+ const suites = await api.getTestSuitesByRunner(config.runnerId);
70
+ navigationSuite =
71
+ suites.find(s => s.title === "Navigation" &&
72
+ (config.uid ? s.uid === config.uid : s.uid == null)) ?? null;
73
+ }
74
+ // Execution loop: iterate open suite runs in the bundle
75
+ let hasOpenSuites = true;
76
+ while (hasOpenSuites) {
77
+ if (config.signal?.aborted)
78
+ break;
79
+ const openSuiteRuns = await api.getOpenTestSuiteRuns(testRun.testSuiteBundleRunId);
80
+ if (openSuiteRuns.length === 0) {
81
+ hasOpenSuites = false;
82
+ break;
83
+ }
84
+ const currentSuiteRun = openSuiteRuns[0];
85
+ // Iterate open case runs in this suite
86
+ let hasOpenCases = true;
87
+ while (hasOpenCases) {
88
+ if (config.signal?.aborted)
89
+ break;
90
+ const openCaseRuns = await api.getOpenTestCaseRuns(currentSuiteRun.id);
91
+ if (openCaseRuns.length === 0) {
92
+ hasOpenCases = false;
93
+ break;
94
+ }
95
+ const currentCaseRun = openCaseRuns[0];
96
+ // Execute the test case
97
+ await executeTestCase(adapter, currentCaseRun, testRun, expertises, analyzer, api, wrappedEvents, navigationSuite && testRun.testSuiteBundleRunId
98
+ ? {
99
+ navigationSuite,
100
+ bundleRun: {
101
+ id: testRun.testSuiteBundleRunId,
102
+ testSuiteBundleId: 0, // will be resolved by API
103
+ status: "running",
104
+ startedAt: null,
105
+ completedAt: null,
106
+ createdAt: null,
107
+ },
108
+ }
109
+ : undefined);
110
+ }
111
+ // All cases done in this suite — mark suite run completed
112
+ await api.completeTestSuiteRun(currentSuiteRun.id, {
113
+ status: "completed",
114
+ });
115
+ }
116
+ // All suites done — mark bundle run and test run completed
117
+ await api.completeTestSuiteBundleRun(testRun.testSuiteBundleRunId, {
118
+ status: "completed",
119
+ });
120
+ const durationMs = Date.now() - startTime;
121
+ await api.completeTestRun(config.testRunId, {
122
+ status: "completed",
123
+ totalDurationMs: durationMs,
124
+ pagesFound,
125
+ pageStatesFound,
126
+ testRunsCompleted,
127
+ });
128
+ const result = {
129
+ testRunId: config.testRunId,
130
+ pagesFound,
131
+ pageStatesFound,
132
+ testRunsCompleted,
133
+ findingsFound,
134
+ durationMs,
135
+ };
136
+ wrappedEvents.onScanComplete({
137
+ totalPages: pagesFound,
138
+ totalFindings: findingsFound,
139
+ durationMs,
140
+ });
141
+ wrappedEvents.onTestRunCompleted({
142
+ testRunId: config.testRunId,
143
+ passed: findingsFound === 0,
144
+ });
145
+ return result;
146
+ }
147
+ catch (error) {
148
+ const message = error instanceof Error ? error.message : "Unknown error";
149
+ wrappedEvents.onError({ message });
150
+ // Try to mark the run as failed
151
+ try {
152
+ await api.completeTestRun(config.testRunId, {
153
+ status: "failed",
154
+ totalDurationMs: Date.now() - startTime,
155
+ });
156
+ }
157
+ catch {
158
+ // best effort
159
+ }
160
+ throw error;
161
+ }
162
+ }
163
+ //# sourceMappingURL=runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/orchestrator/runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { BrowserAdapter } from "../adapter";
2
+ import type { ApiClient } from "../api/client";
3
+ import type { TestCaseRunResponse, TestRunResponse, TestSuiteResponse, TestSuiteBundleRunResponse } from "@sudobility/testomniac_types";
4
+ import type { ScanEventHandler } from "./types";
5
+ import type { Expertise } from "../expertise/types";
6
+ import type { PageAnalyzer } from "../analyzer";
7
+ /**
8
+ * Execute a single test case: run actions, decompose page, evaluate expertises,
9
+ * set outcomes, create findings, and optionally discover new test cases.
10
+ */
11
+ export declare function executeTestCase(adapter: BrowserAdapter, testCaseRun: TestCaseRunResponse, testRun: TestRunResponse, expertises: Expertise[], analyzer: PageAnalyzer | null, api: ApiClient, events: ScanEventHandler, discoveryContext?: {
12
+ navigationSuite: TestSuiteResponse;
13
+ bundleRun: TestSuiteBundleRunResponse;
14
+ }): Promise<void>;
15
+ //# sourceMappingURL=test-case-executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-case-executor.d.ts","sourceRoot":"","sources":["../../src/orchestrator/test-case-executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,KAAK,EACV,mBAAmB,EACnB,eAAe,EACf,iBAAiB,EACjB,0BAA0B,EAC3B,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,KAAK,EAAE,SAAS,EAA6B,MAAM,oBAAoB,CAAC;AAC/E,OAAO,KAAK,EAAE,YAAY,EAAmB,MAAM,aAAa,CAAC;AAMjE;;;GAGG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,cAAc,EACvB,WAAW,EAAE,mBAAmB,EAChC,OAAO,EAAE,eAAe,EACxB,UAAU,EAAE,SAAS,EAAE,EACvB,QAAQ,EAAE,YAAY,GAAG,IAAI,EAC7B,GAAG,EAAE,SAAS,EACd,MAAM,EAAE,gBAAgB,EACxB,gBAAgB,CAAC,EAAE;IACjB,eAAe,EAAE,iBAAiB,CAAC;IACnC,SAAS,EAAE,0BAA0B,CAAC;CACvC,GACA,OAAO,CAAC,IAAI,CAAC,CAiQf"}
@@ -0,0 +1,259 @@
1
+ import { extractActionableItems } from "../extractors";
2
+ import { computeHashes } from "../browser/page-utils";
3
+ import { detectScaffoldRegions } from "../scanner/component-detector";
4
+ import { detectPatternsWithInstances } from "../scanner/pattern-detector";
5
+ /**
6
+ * Execute a single test case: run actions, decompose page, evaluate expertises,
7
+ * set outcomes, create findings, and optionally discover new test cases.
8
+ */
9
+ export async function executeTestCase(adapter, testCaseRun, testRun, expertises, analyzer, api, events, discoveryContext) {
10
+ const startTime = Date.now();
11
+ const consoleLogs = [];
12
+ const networkLogs = [];
13
+ // Listen for console and network events
14
+ adapter.on("console", (...args) => {
15
+ consoleLogs.push(String(args[0] ?? ""));
16
+ });
17
+ adapter.on("response", (...args) => {
18
+ const entry = args[0];
19
+ if (entry && typeof entry.url === "string") {
20
+ networkLogs.push({
21
+ method: "GET",
22
+ url: entry.url,
23
+ status: entry.status,
24
+ contentType: entry.contentType ?? "",
25
+ });
26
+ }
27
+ });
28
+ try {
29
+ const tc = await api.getTestCasesByRunner(testRun.runnerId);
30
+ const testCase = tc.find(c => c.id === testCaseRun.testCaseId);
31
+ if (!testCase) {
32
+ throw new Error(`Test case ${testCaseRun.testCaseId} not found`);
33
+ }
34
+ // Parse steps from JSON
35
+ const steps = testCase.stepsJson ?? [];
36
+ // Record beginning page state
37
+ const _beginningUrl = await adapter.getUrl();
38
+ const beginningPageStateId = testCase.startingPageStateId ?? 0;
39
+ // Navigate to starting path if needed
40
+ if (testCase.startingPath) {
41
+ const baseUrl = testRun.scanUrl
42
+ ? new URL(testRun.scanUrl).origin
43
+ : "http://localhost";
44
+ const absoluteUrl = testCase.startingPath.startsWith("http")
45
+ ? testCase.startingPath
46
+ : new URL(testCase.startingPath, baseUrl).toString();
47
+ await adapter.goto(absoluteUrl, { waitUntil: "networkidle0" });
48
+ }
49
+ // Execute test actions
50
+ for (const step of steps) {
51
+ await executeAction(adapter, step.action, testRun);
52
+ }
53
+ // Decompose the page using local detectors
54
+ const html = await adapter.content();
55
+ const scaffolds = await detectScaffoldRegions(adapter);
56
+ const patterns = await detectPatternsWithInstances(adapter);
57
+ const items = await extractActionableItems(adapter);
58
+ // Parse global expectations
59
+ const globalExpectations = testCase.globalExpectationsJson ?? [];
60
+ // If discovery mode: generate baseline expectations
61
+ let expectations = [...globalExpectations];
62
+ if (analyzer && testCase.stepsJson) {
63
+ const parsedTestCase = {
64
+ title: testCase.title,
65
+ type: testCase.testType,
66
+ sizeClass: testCase.sizeClass,
67
+ suite_tags: testCase.suiteTags,
68
+ priority: testCase.priority,
69
+ startingPageStateId: testCase.startingPageStateId ?? 0,
70
+ startingPath: testCase.startingPath ?? "",
71
+ steps: steps,
72
+ globalExpectations: globalExpectations,
73
+ };
74
+ const generated = analyzer.generateExpectations(parsedTestCase);
75
+ expectations = [...expectations, ...generated];
76
+ }
77
+ // Build expertise context
78
+ const expertiseContext = {
79
+ html,
80
+ scaffolds,
81
+ patterns,
82
+ consoleLogs,
83
+ networkLogs,
84
+ expectations: expectations,
85
+ };
86
+ // Evaluate all expertises
87
+ const allOutcomes = [];
88
+ for (const expertise of expertises) {
89
+ const outcomes = expertise.evaluate(expertiseContext);
90
+ allOutcomes.push(...outcomes);
91
+ // Create findings for warnings and errors
92
+ for (const outcome of outcomes) {
93
+ if (outcome.result === "warning" || outcome.result === "error") {
94
+ await api.createTestRunFinding({
95
+ testCaseRunId: testCaseRun.id,
96
+ type: outcome.result === "error" ? "error" : "warning",
97
+ title: `[${expertise.name}] ${outcome.expected}`,
98
+ description: outcome.observed,
99
+ });
100
+ events.onFindingCreated({
101
+ type: outcome.result,
102
+ title: `[${expertise.name}] ${outcome.expected}`,
103
+ });
104
+ }
105
+ }
106
+ }
107
+ // Aggregate outcomes
108
+ const expectedOutcome = allOutcomes.map(o => o.expected).join("\n");
109
+ const observedOutcome = allOutcomes
110
+ .map(o => `[${o.result}] ${o.observed}`)
111
+ .join("\n");
112
+ const hasErrors = allOutcomes.some(o => o.result === "error");
113
+ const hasWarnings = allOutcomes.some(o => o.result === "warning");
114
+ const status = hasErrors
115
+ ? "failed"
116
+ : hasWarnings
117
+ ? "completed"
118
+ : "completed";
119
+ // Complete test case run
120
+ const durationMs = Date.now() - startTime;
121
+ await api.completeTestCaseRun(testCaseRun.id, {
122
+ status,
123
+ durationMs,
124
+ expectedOutcome: expectedOutcome || undefined,
125
+ observedOutcome: observedOutcome || undefined,
126
+ // Attach logs if there were issues
127
+ ...(hasErrors || hasWarnings
128
+ ? {
129
+ consoleLog: consoleLogs.join("\n") || undefined,
130
+ networkLog: JSON.stringify(networkLogs) || undefined,
131
+ }
132
+ : {}),
133
+ });
134
+ events.onTestCaseRunCompleted({
135
+ testCaseRunId: testCaseRun.id,
136
+ passed: !hasErrors,
137
+ });
138
+ // If discovery mode: generate new test cases
139
+ if (analyzer && discoveryContext) {
140
+ const currentUrl = await adapter.getUrl();
141
+ const currentPath = new URL(currentUrl).pathname;
142
+ const currentHashes = await computeHashes(html, items);
143
+ const currentPageState = await api.findMatchingPageState(0, // pageId not needed for state comparison
144
+ currentHashes, testRun.sizeClass);
145
+ const page = await api.findOrCreatePage(testRun.runnerId, currentPath);
146
+ const analyzerCtx = {
147
+ runnerId: testRun.runnerId,
148
+ sizeClass: testRun.sizeClass,
149
+ uid: testRun.createdByUserId ?? undefined,
150
+ currentPageStateId: currentPageState?.id ?? 0,
151
+ beginningPageStateId: beginningPageStateId,
152
+ currentPath,
153
+ pageId: page.id,
154
+ pageRequiresLogin: page.requiresLogin ?? false,
155
+ scaffolds,
156
+ actionableItems: items,
157
+ navigationSuite: discoveryContext.navigationSuite,
158
+ bundleRun: discoveryContext.bundleRun,
159
+ api,
160
+ };
161
+ const parsedTestCase = {
162
+ title: testCase.title,
163
+ type: testCase.testType,
164
+ sizeClass: testCase.sizeClass,
165
+ suite_tags: testCase.suiteTags,
166
+ priority: testCase.priority,
167
+ startingPageStateId: testCase.startingPageStateId ?? 0,
168
+ startingPath: testCase.startingPath ?? "",
169
+ steps: steps,
170
+ globalExpectations: globalExpectations,
171
+ };
172
+ await analyzer.generateTestCases(parsedTestCase, analyzerCtx);
173
+ }
174
+ }
175
+ catch (error) {
176
+ const durationMs = Date.now() - startTime;
177
+ const errorMessage = error instanceof Error ? error.message : "Unknown error";
178
+ await api.completeTestCaseRun(testCaseRun.id, {
179
+ status: "failed",
180
+ durationMs,
181
+ errorMessage,
182
+ consoleLog: consoleLogs.join("\n") || undefined,
183
+ networkLog: JSON.stringify(networkLogs) || undefined,
184
+ });
185
+ await api.createTestRunFinding({
186
+ testCaseRunId: testCaseRun.id,
187
+ type: "error",
188
+ title: `Test execution error`,
189
+ description: errorMessage,
190
+ });
191
+ events.onFindingCreated({ type: "error", title: "Test execution error" });
192
+ events.onTestCaseRunCompleted({
193
+ testCaseRunId: testCaseRun.id,
194
+ passed: false,
195
+ });
196
+ }
197
+ }
198
+ async function executeAction(adapter, action, testRun) {
199
+ const baseUrl = testRun.scanUrl
200
+ ? new URL(testRun.scanUrl).origin
201
+ : "http://localhost";
202
+ switch (action.actionType) {
203
+ case "goto": {
204
+ const path = action.path ?? "/";
205
+ const url = path.startsWith("http")
206
+ ? path
207
+ : new URL(path, baseUrl).toString();
208
+ await adapter.goto(url, { waitUntil: "networkidle0" });
209
+ break;
210
+ }
211
+ case "waitForLoadState":
212
+ try {
213
+ await adapter.waitForNavigation({
214
+ waitUntil: "networkidle0",
215
+ timeout: 5000,
216
+ });
217
+ }
218
+ catch {
219
+ // No navigation pending is fine
220
+ }
221
+ break;
222
+ case "click":
223
+ if (action.path)
224
+ await adapter.click(action.path);
225
+ break;
226
+ case "dblclick":
227
+ if (action.path)
228
+ await adapter.click(action.path); // adapter may not support dblclick
229
+ break;
230
+ case "fill":
231
+ if (action.path && action.value != null)
232
+ await adapter.type(action.path, action.value);
233
+ break;
234
+ case "select":
235
+ if (action.path && action.value != null)
236
+ await adapter.select(action.path, action.value);
237
+ break;
238
+ case "check":
239
+ case "uncheck":
240
+ case "radio_select":
241
+ if (action.path)
242
+ await adapter.click(action.path);
243
+ break;
244
+ case "hover":
245
+ if (action.path)
246
+ await adapter.hover(action.path);
247
+ break;
248
+ case "press":
249
+ if (action.value)
250
+ await adapter.pressKey(action.value);
251
+ break;
252
+ case "screenshot":
253
+ await adapter.screenshot({ type: "png" });
254
+ break;
255
+ default:
256
+ break;
257
+ }
258
+ }
259
+ //# sourceMappingURL=test-case-executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-case-executor.js","sourceRoot":"","sources":["../../src/orchestrator/test-case-executor.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,2BAA2B,EAAE,MAAM,6BAA6B,CAAC;AAE1E;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,OAAuB,EACvB,WAAgC,EAChC,OAAwB,EACxB,UAAuB,EACvB,QAA6B,EAC7B,GAAc,EACd,MAAwB,EACxB,gBAGC;IAED,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,MAAM,WAAW,GAAa,EAAE,CAAC;IACjC,MAAM,WAAW,GAKX,EAAE,CAAC;IAET,wCAAwC;IACxC,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,GAAG,IAAe,EAAE,EAAE;QAC3C,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IACH,OAAO,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,GAAG,IAAe,EAAE,EAAE;QAC5C,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAInB,CAAC;QACF,IAAI,KAAK,IAAI,OAAO,KAAK,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;YAC3C,WAAW,CAAC,IAAI,CAAC;gBACf,MAAM,EAAE,KAAK;gBACb,GAAG,EAAE,KAAK,CAAC,GAAG;gBACd,MAAM,EAAE,KAAK,CAAC,MAAM;gBACpB,WAAW,EAAE,KAAK,CAAC,WAAW,IAAI,EAAE;aACrC,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,MAAM,GAAG,CAAC,oBAAoB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC5D,MAAM,QAAQ,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,WAAW,CAAC,UAAU,CAAC,CAAC;QAC/D,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,aAAa,WAAW,CAAC,UAAU,YAAY,CAAC,CAAC;QACnE,CAAC;QAED,wBAAwB;QACxB,MAAM,KAAK,GACR,QAAQ,CAAC,SAiBP,IAAI,EAAE,CAAC;QAEZ,8BAA8B;QAC9B,MAAM,aAAa,GAAG,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC;QAC7C,MAAM,oBAAoB,GAAG,QAAQ,CAAC,mBAAmB,IAAI,CAAC,CAAC;QAE/D,sCAAsC;QACtC,IAAI,QAAQ,CAAC,YAAY,EAAE,CAAC;YAC1B,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO;gBAC7B,CAAC,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM;gBACjC,CAAC,CAAC,kBAAkB,CAAC;YACvB,MAAM,WAAW,GAAG,QAAQ,CAAC,YAAY,CAAC,UAAU,CAAC,MAAM,CAAC;gBAC1D,CAAC,CAAC,QAAQ,CAAC,YAAY;gBACvB,CAAC,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAC;YACvD,MAAM,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,cAAc,EAAE,CAAC,CAAC;QACjE,CAAC;QAED,uBAAuB;QACvB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACrD,CAAC;QAED,2CAA2C;QAC3C,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;QACrC,MAAM,SAAS,GAAG,MAAM,qBAAqB,CAAC,OAAO,CAAC,CAAC;QACvD,MAAM,QAAQ,GAAG,MAAM,2BAA2B,CAAC,OAAO,CAAC,CAAC;QAC5D,MAAM,KAAK,GAAG,MAAM,sBAAsB,CAAC,OAAO,CAAC,CAAC;QAEpD,4BAA4B;QAC5B,MAAM,kBAAkB,GACrB,QAAQ,CAAC,sBAQP,IAAI,EAAE,CAAC;QAEZ,oDAAoD;QACpD,IAAI,YAAY,GAAG,CAAC,GAAG,kBAAkB,CAAC,CAAC;QAC3C,IAAI,QAAQ,IAAI,QAAQ,CAAC,SAAS,EAAE,CAAC;YACnC,MAAM,cAAc,GAAG;gBACrB,KAAK,EAAE,QAAQ,CAAC,KAAK;gBACrB,IAAI,EAAE,QAAQ,CAAC,QAON;gBACT,SAAS,EAAE,QAAQ,CAAC,SAAiC;gBACrD,UAAU,EAAE,QAAQ,CAAC,SAAS;gBAC9B,QAAQ,EAAE,QAAQ,CAAC,QAAQ;gBAC3B,mBAAmB,EAAE,QAAQ,CAAC,mBAAmB,IAAI,CAAC;gBACtD,YAAY,EAAE,QAAQ,CAAC,YAAY,IAAI,EAAE;gBACzC,KAAK,EAAE,KAAY;gBACnB,kBAAkB,EAAE,kBAAyB;aAC9C,CAAC;YACF,MAAM,SAAS,GAAG,QAAQ,CAAC,oBAAoB,CAAC,cAAc,CAAC,CAAC;YAChE,YAAY,GAAG,CAAC,GAAG,YAAY,EAAE,GAAG,SAAS,CAAC,CAAC;QACjD,CAAC;QAED,0BAA0B;QAC1B,MAAM,gBAAgB,GAAqB;YACzC,IAAI;YACJ,SAAS;YACT,QAAQ;YACR,WAAW;YACX,WAAW;YACX,YAAY,EAAE,YAAmB;SAClC,CAAC;QAEF,0BAA0B;QAC1B,MAAM,WAAW,GAAc,EAAE,CAAC;QAClC,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,MAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;YACtD,WAAW,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAC;YAE9B,0CAA0C;YAC1C,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;gBAC/B,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,IAAI,OAAO,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;oBAC/D,MAAM,GAAG,CAAC,oBAAoB,CAAC;wBAC7B,aAAa,EAAE,WAAW,CAAC,EAAE;wBAC7B,IAAI,EAAE,OAAO,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS;wBACtD,KAAK,EAAE,IAAI,SAAS,CAAC,IAAI,KAAK,OAAO,CAAC,QAAQ,EAAE;wBAChD,WAAW,EAAE,OAAO,CAAC,QAAQ;qBAC9B,CAAC,CAAC;oBACH,MAAM,CAAC,gBAAgB,CAAC;wBACtB,IAAI,EAAE,OAAO,CAAC,MAAM;wBACpB,KAAK,EAAE,IAAI,SAAS,CAAC,IAAI,KAAK,OAAO,CAAC,QAAQ,EAAE;qBACjD,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAED,qBAAqB;QACrB,MAAM,eAAe,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpE,MAAM,eAAe,GAAG,WAAW;aAChC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC;aACvC,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,MAAM,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC;QAC9D,MAAM,WAAW,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC;QAClE,MAAM,MAAM,GAAG,SAAS;YACtB,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,WAAW;gBACX,CAAC,CAAC,WAAW;gBACb,CAAC,CAAC,WAAW,CAAC;QAElB,yBAAyB;QACzB,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;QAC1C,MAAM,GAAG,CAAC,mBAAmB,CAAC,WAAW,CAAC,EAAE,EAAE;YAC5C,MAAM;YACN,UAAU;YACV,eAAe,EAAE,eAAe,IAAI,SAAS;YAC7C,eAAe,EAAE,eAAe,IAAI,SAAS;YAC7C,mCAAmC;YACnC,GAAG,CAAC,SAAS,IAAI,WAAW;gBAC1B,CAAC,CAAC;oBACE,UAAU,EAAE,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,SAAS;oBAC/C,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,SAAS;iBACrD;gBACH,CAAC,CAAC,EAAE,CAAC;SACR,CAAC,CAAC;QAEH,MAAM,CAAC,sBAAsB,CAAC;YAC5B,aAAa,EAAE,WAAW,CAAC,EAAE;YAC7B,MAAM,EAAE,CAAC,SAAS;SACnB,CAAC,CAAC;QAEH,6CAA6C;QAC7C,IAAI,QAAQ,IAAI,gBAAgB,EAAE,CAAC;YACjC,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC;YAC1C,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC;YACjD,MAAM,aAAa,GAAG,MAAM,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YACvD,MAAM,gBAAgB,GAAG,MAAM,GAAG,CAAC,qBAAqB,CACtD,CAAC,EAAE,yCAAyC;YAC5C,aAAa,EACb,OAAO,CAAC,SAAS,CAClB,CAAC;YAEF,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,gBAAgB,CAAC,OAAO,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;YAEvE,MAAM,WAAW,GAAoB;gBACnC,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,SAAS,EAAE,OAAO,CAAC,SAAiC;gBACpD,GAAG,EAAE,OAAO,CAAC,eAAe,IAAI,SAAS;gBACzC,kBAAkB,EAAE,gBAAgB,EAAE,EAAE,IAAI,CAAC;gBAC7C,oBAAoB,EAAE,oBAAoB;gBAC1C,WAAW;gBACX,MAAM,EAAE,IAAI,CAAC,EAAE;gBACf,iBAAiB,EAAE,IAAI,CAAC,aAAa,IAAI,KAAK;gBAC9C,SAAS;gBACT,eAAe,EAAE,KAAK;gBACtB,eAAe,EAAE,gBAAgB,CAAC,eAAe;gBACjD,SAAS,EAAE,gBAAgB,CAAC,SAAS;gBACrC,GAAG;aACJ,CAAC;YAEF,MAAM,cAAc,GAAG;gBACrB,KAAK,EAAE,QAAQ,CAAC,KAAK;gBACrB,IAAI,EAAE,QAAQ,CAAC,QAAe;gBAC9B,SAAS,EAAE,QAAQ,CAAC,SAAgB;gBACpC,UAAU,EAAE,QAAQ,CAAC,SAAS;gBAC9B,QAAQ,EAAE,QAAQ,CAAC,QAAQ;gBAC3B,mBAAmB,EAAE,QAAQ,CAAC,mBAAmB,IAAI,CAAC;gBACtD,YAAY,EAAE,QAAQ,CAAC,YAAY,IAAI,EAAE;gBACzC,KAAK,EAAE,KAAY;gBACnB,kBAAkB,EAAE,kBAAyB;aAC9C,CAAC;YAEF,MAAM,QAAQ,CAAC,iBAAiB,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;QAChE,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;QAC1C,MAAM,YAAY,GAChB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;QAE3D,MAAM,GAAG,CAAC,mBAAmB,CAAC,WAAW,CAAC,EAAE,EAAE;YAC5C,MAAM,EAAE,QAAQ;YAChB,UAAU;YACV,YAAY;YACZ,UAAU,EAAE,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,SAAS;YAC/C,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,SAAS;SACrD,CAAC,CAAC;QAEH,MAAM,GAAG,CAAC,oBAAoB,CAAC;YAC7B,aAAa,EAAE,WAAW,CAAC,EAAE;YAC7B,IAAI,EAAE,OAAO;YACb,KAAK,EAAE,sBAAsB;YAC7B,WAAW,EAAE,YAAY;SAC1B,CAAC,CAAC;QAEH,MAAM,CAAC,gBAAgB,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,sBAAsB,EAAE,CAAC,CAAC;QAC1E,MAAM,CAAC,sBAAsB,CAAC;YAC5B,aAAa,EAAE,WAAW,CAAC,EAAE;YAC7B,MAAM,EAAE,KAAK;SACd,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED,KAAK,UAAU,aAAa,CAC1B,OAAuB,EACvB,MAKC,EACD,OAAwB;IAExB,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO;QAC7B,CAAC,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM;QACjC,CAAC,CAAC,kBAAkB,CAAC;IAEvB,QAAQ,MAAM,CAAC,UAAU,EAAE,CAAC;QAC1B,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,GAAG,CAAC;YAChC,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;gBACjC,CAAC,CAAC,IAAI;gBACN,CAAC,CAAC,IAAI,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAC;YACtC,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,cAAc,EAAE,CAAC,CAAC;YACvD,MAAM;QACR,CAAC;QACD,KAAK,kBAAkB;YACrB,IAAI,CAAC;gBACH,MAAM,OAAO,CAAC,iBAAiB,CAAC;oBAC9B,SAAS,EAAE,cAAc;oBACzB,OAAO,EAAE,IAAI;iBACd,CAAC,CAAC;YACL,CAAC;YAAC,MAAM,CAAC;gBACP,gCAAgC;YAClC,CAAC;YACD,MAAM;QACR,KAAK,OAAO;YACV,IAAI,MAAM,CAAC,IAAI;gBAAE,MAAM,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAClD,MAAM;QACR,KAAK,UAAU;YACb,IAAI,MAAM,CAAC,IAAI;gBAAE,MAAM,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,mCAAmC;YACtF,MAAM;QACR,KAAK,MAAM;YACT,IAAI,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,KAAK,IAAI,IAAI;gBACrC,MAAM,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;YAChD,MAAM;QACR,KAAK,QAAQ;YACX,IAAI,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,KAAK,IAAI,IAAI;gBACrC,MAAM,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;YAClD,MAAM;QACR,KAAK,OAAO,CAAC;QACb,KAAK,SAAS,CAAC;QACf,KAAK,cAAc;YACjB,IAAI,MAAM,CAAC,IAAI;gBAAE,MAAM,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAClD,MAAM;QACR,KAAK,OAAO;YACV,IAAI,MAAM,CAAC,IAAI;gBAAE,MAAM,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAClD,MAAM;QACR,KAAK,OAAO;YACV,IAAI,MAAM,CAAC,KAAK;gBAAE,MAAM,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACvD,MAAM;QACR,KAAK,YAAY;YACf,MAAM,OAAO,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;YAC1C,MAAM;QACR;YACE,MAAM;IACV,CAAC;AACH,CAAC"}
@@ -1,15 +1,23 @@
1
1
  import type { SizeClass } from "../domain/types";
2
- export interface ScanConfig {
3
- scanId: number;
2
+ export interface RunConfig {
3
+ testRunId: number;
4
4
  runnerId: number;
5
- scanUrl: string;
6
5
  baseUrl: string;
7
6
  sizeClass: SizeClass;
7
+ testEnvironmentId?: number;
8
+ uid?: string;
9
+ runnerInstanceId: string;
10
+ runnerInstanceName: string;
11
+ signal?: AbortSignal;
12
+ }
13
+ /** @deprecated Use RunConfig */
14
+ export type ScanConfig = RunConfig & {
15
+ scanId: number;
16
+ scanUrl: string;
8
17
  openaiApiKey?: string;
9
18
  openaiModel?: string;
10
19
  testWorkerCount?: number;
11
- signal?: AbortSignal;
12
- }
20
+ };
13
21
  export interface ScanEventHandler {
14
22
  onPageFound(page: {
15
23
  relativePath: string;
@@ -31,6 +39,10 @@ export interface ScanEventHandler {
31
39
  suiteId: number;
32
40
  title: string;
33
41
  }): void;
42
+ onTestCaseRunCompleted(run: {
43
+ testCaseRunId: number;
44
+ passed: boolean;
45
+ }): void;
34
46
  onTestRunCompleted(run: {
35
47
  testRunId: number;
36
48
  passed: boolean;
@@ -59,7 +71,7 @@ export interface ScanEventHandler {
59
71
  }): void;
60
72
  }
61
73
  export interface ScanResult {
62
- scanId: number;
74
+ testRunId: number;
63
75
  pagesFound: number;
64
76
  pageStatesFound: number;
65
77
  testRunsCompleted: number;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/orchestrator/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,SAAS,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,WAAW,CAAC,IAAI,EAAE;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAClE,kBAAkB,CAAC,KAAK,EAAE;QACxB,WAAW,EAAE,MAAM,CAAC;QACpB,MAAM,EAAE,MAAM,CAAC;QACf,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,GAAG,IAAI,CAAC;IACT,yBAAyB,CAAC,GAAG,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC7E,2BAA2B,CAAC,GAAG,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC1D,kBAAkB,CAAC,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACpE,kBAAkB,CAAC,GAAG,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IACtE,gBAAgB,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACjE,cAAc,CAAC,KAAK,EAAE;QACpB,UAAU,EAAE,MAAM,CAAC;QACnB,eAAe,EAAE,MAAM,CAAC;QACxB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,aAAa,EAAE,MAAM,CAAC;KACvB,GAAG,IAAI,CAAC;IACT,oBAAoB,CAAC,IAAI,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACvE,cAAc,CAAC,OAAO,EAAE;QACtB,UAAU,EAAE,MAAM,CAAC;QACnB,aAAa,EAAE,MAAM,CAAC;QACtB,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,IAAI,CAAC;IACT,OAAO,CAAC,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAC3C;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/orchestrator/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,SAAS,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,gBAAgB,EAAE,MAAM,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,gCAAgC;AAChC,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,MAAM,WAAW,gBAAgB;IAC/B,WAAW,CAAC,IAAI,EAAE;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAClE,kBAAkB,CAAC,KAAK,EAAE;QACxB,WAAW,EAAE,MAAM,CAAC;QACpB,MAAM,EAAE,MAAM,CAAC;QACf,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,GAAG,IAAI,CAAC;IACT,yBAAyB,CAAC,GAAG,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC7E,2BAA2B,CAAC,GAAG,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC1D,kBAAkB,CAAC,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACpE,sBAAsB,CAAC,GAAG,EAAE;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IAC9E,kBAAkB,CAAC,GAAG,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IACtE,gBAAgB,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACjE,cAAc,CAAC,KAAK,EAAE;QACpB,UAAU,EAAE,MAAM,CAAC;QACnB,eAAe,EAAE,MAAM,CAAC;QACxB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,aAAa,EAAE,MAAM,CAAC;KACvB,GAAG,IAAI,CAAC;IACT,oBAAoB,CAAC,IAAI,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACvE,cAAc,CAAC,OAAO,EAAE;QACtB,UAAU,EAAE,MAAM,CAAC;QACnB,aAAa,EAAE,MAAM,CAAC;QACtB,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,IAAI,CAAC;IACT,OAAO,CAAC,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAC3C;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sudobility/testomniac_runner_service",
3
- "version": "0.1.28",
3
+ "version": "0.1.29",
4
4
  "description": "Shared scanning logic for Testomniac scanner and Chrome extension",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -37,7 +37,7 @@
37
37
  "author": "Sudobility",
38
38
  "license": "BUSL-1.1",
39
39
  "peerDependencies": {
40
- "@sudobility/testomniac_types": "^0.0.39",
40
+ "@sudobility/testomniac_types": "^0.0.40",
41
41
  "openai": ">=6.0.0",
42
42
  "react": ">=18.0.0"
43
43
  },
@@ -51,7 +51,7 @@
51
51
  },
52
52
  "devDependencies": {
53
53
  "@eslint/js": "^9.38.0",
54
- "@sudobility/testomniac_types": "^0.0.39",
54
+ "@sudobility/testomniac_types": "^0.0.40",
55
55
  "@types/node": "^25.6.0",
56
56
  "@types/react": "^19.2.0",
57
57
  "@typescript-eslint/eslint-plugin": "^8.46.2",