@sudobility/testomniac_runner_service 0.1.88 → 0.1.90
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/dist/analyzer/page-analyzer/index.d.ts.map +1 -1
- package/dist/analyzer/page-analyzer/index.js +50 -36
- package/dist/analyzer/page-analyzer/index.js.map +1 -1
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/client.js +18 -4
- package/dist/api/client.js.map +1 -1
- package/dist/browser/page-utils.d.ts +10 -0
- package/dist/browser/page-utils.d.ts.map +1 -1
- package/dist/browser/page-utils.js +74 -2
- package/dist/browser/page-utils.js.map +1 -1
- package/dist/crawler/url-normalizer.d.ts.map +1 -1
- package/dist/crawler/url-normalizer.js +5 -0
- package/dist/crawler/url-normalizer.js.map +1 -1
- package/dist/detectors/bug-detector.d.ts.map +1 -1
- package/dist/detectors/bug-detector.js +5 -2
- package/dist/detectors/bug-detector.js.map +1 -1
- package/dist/detectors/link-checker.d.ts.map +1 -1
- package/dist/detectors/link-checker.js +9 -0
- package/dist/detectors/link-checker.js.map +1 -1
- package/dist/detectors/rules/broken-link-rule.d.ts.map +1 -1
- package/dist/detectors/rules/broken-link-rule.js +5 -2
- package/dist/detectors/rules/broken-link-rule.js.map +1 -1
- package/dist/expertise/tester/core-checks.d.ts.map +1 -1
- package/dist/expertise/tester/core-checks.js +6 -0
- package/dist/expertise/tester/core-checks.js.map +1 -1
- package/dist/orchestrator/login-manager.d.ts.map +1 -1
- package/dist/orchestrator/login-manager.js +5 -1
- package/dist/orchestrator/login-manager.js.map +1 -1
- package/dist/orchestrator/runner.d.ts.map +1 -1
- package/dist/orchestrator/runner.js +82 -31
- package/dist/orchestrator/runner.js.map +1 -1
- package/dist/orchestrator/sso-handler.d.ts.map +1 -1
- package/dist/orchestrator/sso-handler.js +12 -1
- package/dist/orchestrator/sso-handler.js.map +1 -1
- package/dist/orchestrator/test-interaction-executor.d.ts +2 -2
- package/dist/orchestrator/test-interaction-executor.d.ts.map +1 -1
- package/dist/orchestrator/test-interaction-executor.js +24 -8
- package/dist/orchestrator/test-interaction-executor.js.map +1 -1
- package/dist/orchestrator/types.d.ts +1 -0
- package/dist/orchestrator/types.d.ts.map +1 -1
- package/dist/scanner/action-classifier.d.ts.map +1 -1
- package/dist/scanner/action-classifier.js +4 -0
- package/dist/scanner/action-classifier.js.map +1 -1
- package/dist/scanner/component-detector.d.ts.map +1 -1
- package/dist/scanner/component-detector.js +6 -1
- package/dist/scanner/component-detector.js.map +1 -1
- package/dist/scanner/login-detector.d.ts.map +1 -1
- package/dist/scanner/login-detector.js +4 -0
- package/dist/scanner/login-detector.js.map +1 -1
- package/dist/scanner/pattern-detector.d.ts.map +1 -1
- package/dist/scanner/pattern-detector.js +7 -1
- package/dist/scanner/pattern-detector.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/analyzer/page-analyzer/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,WAAW,EAQZ,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/analyzer/page-analyzer/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PlaywrightAction, ExpectationType, ExpectationSeverity, } from "@sudobility/testomniac_types";
|
|
2
2
|
import { buildReplaySelectorFromActionableItem, matchesActionableItemSelector, } from "../../browser/replay-selector";
|
|
3
|
-
import { computeHashes, computeActionableHash, sha256, normalizeHtml, } from "../../browser/page-utils";
|
|
3
|
+
import { computeHashes, computeActionableHash, sha256, normalizeHtml, htmlToMarkdown, } from "../../browser/page-utils";
|
|
4
4
|
import { getBody, getContentBody } from "../../scanner/html-decomposer";
|
|
5
5
|
import { createHash } from "node:crypto";
|
|
6
6
|
import { fillValuePlanner } from "../../planners/fill-value-planner";
|
|
@@ -260,6 +260,32 @@ export class PageAnalyzer {
|
|
|
260
260
|
return;
|
|
261
261
|
}
|
|
262
262
|
const normalizedContext = this.normalizeContext(context);
|
|
263
|
+
const isHover = this.isHoverOnly(testInteraction);
|
|
264
|
+
const currentPath = normalizedContext.currentPath.trim();
|
|
265
|
+
// For non-hover interactions: check cheap path/hash guards BEFORE the
|
|
266
|
+
// expensive ensureTargetPageState call so we can skip all the API work
|
|
267
|
+
// (scaffold resolution, hash computation, page-state creation) when the
|
|
268
|
+
// page has already been covered in this run.
|
|
269
|
+
if (!isHover) {
|
|
270
|
+
if (this.generatedPaths.has(currentPath)) {
|
|
271
|
+
logAnalyzer("generate:page-already-covered", {
|
|
272
|
+
sourceTitle: testInteraction.title,
|
|
273
|
+
currentTestInteractionId: normalizedContext.currentTestInteractionId,
|
|
274
|
+
currentPath,
|
|
275
|
+
});
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
const actionableHash = await computeActionableHash(normalizedContext.actionableItems);
|
|
279
|
+
if (this.generatedActionableHashes.has(actionableHash)) {
|
|
280
|
+
logAnalyzer("generate:actionable-items-already-covered", {
|
|
281
|
+
sourceTitle: testInteraction.title,
|
|
282
|
+
currentTestInteractionId: normalizedContext.currentTestInteractionId,
|
|
283
|
+
currentPath,
|
|
284
|
+
actionableHash,
|
|
285
|
+
});
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
263
289
|
const currentPageStateId = await this.ensureTargetPageState(normalizedContext);
|
|
264
290
|
const resolvedContext = {
|
|
265
291
|
...normalizedContext,
|
|
@@ -278,7 +304,7 @@ export class PageAnalyzer {
|
|
|
278
304
|
// Hover-only interactions have their own same-page-state handling inside
|
|
279
305
|
// generateHoverFollowUpCases (including click-follow-up reconciliation),
|
|
280
306
|
// so let them through to that dedicated path.
|
|
281
|
-
if (
|
|
307
|
+
if (isHover) {
|
|
282
308
|
logAnalyzer("generate:hover-only", {
|
|
283
309
|
sourceTitle: testInteraction.title,
|
|
284
310
|
currentTestInteractionId: resolvedContext.currentTestInteractionId,
|
|
@@ -300,34 +326,9 @@ export class PageAnalyzer {
|
|
|
300
326
|
});
|
|
301
327
|
return;
|
|
302
328
|
}
|
|
303
|
-
//
|
|
304
|
-
//
|
|
305
|
-
// previous runs on the same runner don't block re-discovery.
|
|
306
|
-
const currentPath = resolvedContext.currentPath.trim();
|
|
307
|
-
if (this.generatedPaths.has(currentPath)) {
|
|
308
|
-
logAnalyzer("generate:page-already-covered", {
|
|
309
|
-
sourceTitle: testInteraction.title,
|
|
310
|
-
currentTestInteractionId: resolvedContext.currentTestInteractionId,
|
|
311
|
-
currentPageStateId: resolvedContext.currentPageStateId,
|
|
312
|
-
currentPath,
|
|
313
|
-
});
|
|
314
|
-
return;
|
|
315
|
-
}
|
|
316
|
-
// Skip generation if a different path already produced the same set of
|
|
317
|
-
// interactive elements. For example /store/ and /store/all-items/ may
|
|
318
|
-
// resolve to the same product grid — generating hover/click tests for
|
|
319
|
-
// both is redundant.
|
|
329
|
+
// Re-check actionableHash (already passed the guard above, but we need
|
|
330
|
+
// to record it and the path now that we're committed to generation).
|
|
320
331
|
const actionableHash = await computeActionableHash(resolvedContext.actionableItems);
|
|
321
|
-
if (this.generatedActionableHashes.has(actionableHash)) {
|
|
322
|
-
logAnalyzer("generate:actionable-items-already-covered", {
|
|
323
|
-
sourceTitle: testInteraction.title,
|
|
324
|
-
currentTestInteractionId: resolvedContext.currentTestInteractionId,
|
|
325
|
-
currentPageStateId: resolvedContext.currentPageStateId,
|
|
326
|
-
currentPath,
|
|
327
|
-
actionableHash,
|
|
328
|
-
});
|
|
329
|
-
return;
|
|
330
|
-
}
|
|
331
332
|
this.generatedPaths.add(currentPath);
|
|
332
333
|
this.generatedActionableHashes.add(actionableHash);
|
|
333
334
|
// If a hover+click navigated to a new page, create a direct navigation
|
|
@@ -351,8 +352,12 @@ export class PageAnalyzer {
|
|
|
351
352
|
testSurfaceRunId: navSurfaceRun.id,
|
|
352
353
|
});
|
|
353
354
|
}
|
|
354
|
-
catch {
|
|
355
|
+
catch (err) {
|
|
355
356
|
// Run may already exist
|
|
357
|
+
logAnalyzer("create-interaction-run:skipped", {
|
|
358
|
+
reason: "may already exist",
|
|
359
|
+
error: err instanceof Error ? err.message : String(err),
|
|
360
|
+
});
|
|
356
361
|
}
|
|
357
362
|
}
|
|
358
363
|
logAnalyzer("generate:navigation-dependency-created", {
|
|
@@ -408,8 +413,6 @@ export class PageAnalyzer {
|
|
|
408
413
|
const isActive = testInteraction.isActive !== false;
|
|
409
414
|
if (!isGenerated || !isActive)
|
|
410
415
|
return false;
|
|
411
|
-
if (testInteraction.startingPageStateId !== context.currentPageStateId)
|
|
412
|
-
return false;
|
|
413
416
|
if ((testInteraction.dependencyTestInteractionId ?? null) !==
|
|
414
417
|
(params.dependencyTestInteractionId ?? null)) {
|
|
415
418
|
return false;
|
|
@@ -485,7 +488,11 @@ export class PageAnalyzer {
|
|
|
485
488
|
const url = new URL(href, "http://placeholder");
|
|
486
489
|
return url.pathname + url.search;
|
|
487
490
|
}
|
|
488
|
-
catch {
|
|
491
|
+
catch (err) {
|
|
492
|
+
logAnalyzer("extract-relative-path:failed", {
|
|
493
|
+
href,
|
|
494
|
+
error: err instanceof Error ? err.message : String(err),
|
|
495
|
+
});
|
|
489
496
|
return null;
|
|
490
497
|
}
|
|
491
498
|
}
|
|
@@ -708,7 +715,7 @@ export class PageAnalyzer {
|
|
|
708
715
|
pageId: context.pageId,
|
|
709
716
|
sizeClass: context.sizeClass,
|
|
710
717
|
hashes,
|
|
711
|
-
contentText: context.html.slice(0, 5000),
|
|
718
|
+
contentText: htmlToMarkdown(context.html).slice(0, 5000),
|
|
712
719
|
contentHtmlElementId: contentElement.id,
|
|
713
720
|
screenshotPath: context.screenshotPath,
|
|
714
721
|
});
|
|
@@ -724,8 +731,12 @@ export class PageAnalyzer {
|
|
|
724
731
|
patternsHash: "",
|
|
725
732
|
});
|
|
726
733
|
}
|
|
727
|
-
catch {
|
|
734
|
+
catch (err) {
|
|
728
735
|
// Best effort — decomposed hashes are optional
|
|
736
|
+
logAnalyzer("decomposed-hashes:failed", {
|
|
737
|
+
pageStateId: pageState.id,
|
|
738
|
+
error: err instanceof Error ? err.message : String(err),
|
|
739
|
+
});
|
|
729
740
|
}
|
|
730
741
|
}
|
|
731
742
|
context.events.onPageStateCreated({
|
|
@@ -2295,7 +2306,10 @@ export class PageAnalyzer {
|
|
|
2295
2306
|
const parsed = JSON.parse(rawOptions);
|
|
2296
2307
|
return Array.isArray(parsed) ? parsed.filter(Boolean) : [];
|
|
2297
2308
|
}
|
|
2298
|
-
catch {
|
|
2309
|
+
catch (err) {
|
|
2310
|
+
logAnalyzer("parse-select-options:json-fallback", {
|
|
2311
|
+
error: err instanceof Error ? err.message : String(err),
|
|
2312
|
+
});
|
|
2299
2313
|
return rawOptions
|
|
2300
2314
|
.split(",")
|
|
2301
2315
|
.map(value => value.trim())
|