@sudobility/testomniac_runner_service 0.1.136 → 0.1.138
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/generators/content.d.ts +2 -1
- package/dist/analyzer/page-analyzer/generators/content.d.ts.map +1 -1
- package/dist/analyzer/page-analyzer/generators/content.js +32 -39
- package/dist/analyzer/page-analyzer/generators/content.js.map +1 -1
- package/dist/analyzer/page-analyzer/generators/dialogs.d.ts +2 -1
- package/dist/analyzer/page-analyzer/generators/dialogs.d.ts.map +1 -1
- package/dist/analyzer/page-analyzer/generators/dialogs.js +25 -37
- package/dist/analyzer/page-analyzer/generators/dialogs.js.map +1 -1
- package/dist/analyzer/page-analyzer/generators/e2e.d.ts +2 -1
- package/dist/analyzer/page-analyzer/generators/e2e.d.ts.map +1 -1
- package/dist/analyzer/page-analyzer/generators/e2e.js +30 -37
- package/dist/analyzer/page-analyzer/generators/e2e.js.map +1 -1
- package/dist/analyzer/page-analyzer/generators/forms.d.ts +2 -1
- package/dist/analyzer/page-analyzer/generators/forms.d.ts.map +1 -1
- package/dist/analyzer/page-analyzer/generators/forms.js +29 -45
- package/dist/analyzer/page-analyzer/generators/forms.js.map +1 -1
- package/dist/analyzer/page-analyzer/generators/keyboard-disclosure.d.ts +2 -1
- package/dist/analyzer/page-analyzer/generators/keyboard-disclosure.d.ts.map +1 -1
- package/dist/analyzer/page-analyzer/generators/keyboard-disclosure.js +25 -37
- package/dist/analyzer/page-analyzer/generators/keyboard-disclosure.js.map +1 -1
- package/dist/analyzer/page-analyzer/generators/render.d.ts +2 -1
- package/dist/analyzer/page-analyzer/generators/render.d.ts.map +1 -1
- package/dist/analyzer/page-analyzer/generators/render.js +26 -32
- package/dist/analyzer/page-analyzer/generators/render.js.map +1 -1
- package/dist/analyzer/page-analyzer/generators/scaffolds.d.ts +2 -1
- package/dist/analyzer/page-analyzer/generators/scaffolds.d.ts.map +1 -1
- package/dist/analyzer/page-analyzer/generators/scaffolds.js +27 -44
- package/dist/analyzer/page-analyzer/generators/scaffolds.js.map +1 -1
- package/dist/analyzer/page-analyzer/generators/semantic-journeys.d.ts +2 -1
- package/dist/analyzer/page-analyzer/generators/semantic-journeys.d.ts.map +1 -1
- package/dist/analyzer/page-analyzer/generators/semantic-journeys.js +25 -37
- package/dist/analyzer/page-analyzer/generators/semantic-journeys.js.map +1 -1
- package/dist/analyzer/page-analyzer/generators/variants.d.ts +2 -1
- package/dist/analyzer/page-analyzer/generators/variants.d.ts.map +1 -1
- package/dist/analyzer/page-analyzer/generators/variants.js +25 -37
- package/dist/analyzer/page-analyzer/generators/variants.js.map +1 -1
- package/dist/analyzer/page-analyzer/index.d.ts.map +1 -1
- package/dist/analyzer/page-analyzer/index.js +87 -83
- package/dist/analyzer/page-analyzer/index.js.map +1 -1
- package/dist/api/client.d.ts +4 -1
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/client.js +18 -0
- package/dist/api/client.js.map +1 -1
- package/dist/orchestrator/test-interaction-executor.js +18 -15
- package/dist/orchestrator/test-interaction-executor.js.map +1 -1
- package/package.json +3 -3
|
@@ -424,20 +424,43 @@ export class PageAnalyzer {
|
|
|
424
424
|
currentTestInteractionId: contextForFullPass.currentTestInteractionId,
|
|
425
425
|
currentPageStateId: contextForFullPass.currentPageStateId,
|
|
426
426
|
});
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
427
|
+
// Collect all standard generator outputs (they return data, no API calls)
|
|
428
|
+
const outputs = [];
|
|
429
|
+
outputs.push(await generateRenderTestInteractions(this, contextForFullPass));
|
|
430
|
+
outputs.push(await generateFormTestInteractions(this, contextForFullPass));
|
|
431
|
+
// Login test generation: calls API directly (dependency chains)
|
|
431
432
|
if (contextForFullPass.loginDetection?.isLoginPage) {
|
|
432
433
|
await generateLoginTestInteractions(this, contextForFullPass, contextForFullPass.loginDetection, contextForFullPass.loginConfig);
|
|
433
434
|
}
|
|
434
|
-
await generateSemanticJourneyTestInteractions(this, contextForFullPass);
|
|
435
|
-
await generateE2ETestInteractions(this, contextForFullPass);
|
|
436
|
-
await generateDialogLifecycleTestInteractions(this, contextForFullPass);
|
|
437
|
-
await generateScaffoldTestInteractions(this, contextForFullPass);
|
|
438
|
-
await generateContentTestInteractions(this, contextForFullPass);
|
|
439
|
-
await generateKeyboardAndDisclosureTestInteractions(this, contextForFullPass);
|
|
440
|
-
await generateVariantTestInteractions(this, contextForFullPass);
|
|
435
|
+
outputs.push(await generateSemanticJourneyTestInteractions(this, contextForFullPass));
|
|
436
|
+
outputs.push(await generateE2ETestInteractions(this, contextForFullPass));
|
|
437
|
+
outputs.push(await generateDialogLifecycleTestInteractions(this, contextForFullPass));
|
|
438
|
+
outputs.push(await generateScaffoldTestInteractions(this, contextForFullPass));
|
|
439
|
+
outputs.push(await generateContentTestInteractions(this, contextForFullPass));
|
|
440
|
+
outputs.push(await generateKeyboardAndDisclosureTestInteractions(this, contextForFullPass));
|
|
441
|
+
outputs.push(await generateVariantTestInteractions(this, contextForFullPass));
|
|
442
|
+
// Batch all collected generator outputs in one API call
|
|
443
|
+
const allCreates = outputs.flatMap(o => o.creates);
|
|
444
|
+
const allReconciles = outputs.flatMap(o => o.reconciles);
|
|
445
|
+
if (allCreates.length > 0 || allReconciles.length > 0) {
|
|
446
|
+
const batchResult = await contextForFullPass.api.generateAllSurfaceInteractions({
|
|
447
|
+
runnerId: contextForFullPass.runnerId,
|
|
448
|
+
testEnvironmentId: contextForFullPass.testEnvironmentId,
|
|
449
|
+
sizeClass: contextForFullPass.sizeClass,
|
|
450
|
+
testSurfaceBundleId: contextForFullPass.bundleRun.testSurfaceBundleId,
|
|
451
|
+
testSurfaceBundleRunId: contextForFullPass.bundleRun.id,
|
|
452
|
+
surfaces: allCreates,
|
|
453
|
+
reconcileOnly: allReconciles,
|
|
454
|
+
});
|
|
455
|
+
// Emit events for all created surfaces
|
|
456
|
+
for (const item of batchResult.results) {
|
|
457
|
+
contextForFullPass.events.onTestSurfaceCreated({
|
|
458
|
+
surfaceId: item.surface.id,
|
|
459
|
+
title: item.surface.title,
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
// Navigation calls API directly (no surface creation, no reconcile)
|
|
441
464
|
await generateNavigationTestInteractions(this, contextForFullPass);
|
|
442
465
|
}
|
|
443
466
|
async reconcileGeneratedSurfaceElements(context, params) {
|
|
@@ -705,19 +728,20 @@ export class PageAnalyzer {
|
|
|
705
728
|
.join("||");
|
|
706
729
|
}
|
|
707
730
|
async ensureTargetPageState(context) {
|
|
708
|
-
|
|
709
|
-
for (const item of context.actionableItems) {
|
|
710
|
-
if (!item.selector)
|
|
711
|
-
continue;
|
|
712
|
-
const scaffoldSelector = context.scaffoldSelectorByItemSelector[item.selector] ?? null;
|
|
713
|
-
if (!scaffoldSelector)
|
|
714
|
-
continue;
|
|
715
|
-
const scaffoldId = scaffoldIdsBySelector.get(scaffoldSelector);
|
|
716
|
-
if (scaffoldId) {
|
|
717
|
-
item.scaffoldId = scaffoldId;
|
|
718
|
-
}
|
|
719
|
-
}
|
|
731
|
+
// Fast path: page state already known — just link scaffolds
|
|
720
732
|
if (context.currentPageStateId > 0) {
|
|
733
|
+
const scaffoldIdsBySelector = await this.ensureScaffolds(context);
|
|
734
|
+
for (const item of context.actionableItems) {
|
|
735
|
+
if (!item.selector)
|
|
736
|
+
continue;
|
|
737
|
+
const scaffoldSelector = context.scaffoldSelectorByItemSelector[item.selector] ?? null;
|
|
738
|
+
if (!scaffoldSelector)
|
|
739
|
+
continue;
|
|
740
|
+
const scaffoldId = scaffoldIdsBySelector.get(scaffoldSelector);
|
|
741
|
+
if (scaffoldId) {
|
|
742
|
+
item.scaffoldId = scaffoldId;
|
|
743
|
+
}
|
|
744
|
+
}
|
|
721
745
|
if (scaffoldIdsBySelector.size > 0) {
|
|
722
746
|
await context.api.linkPageStateScaffolds(context.currentPageStateId, Array.from(new Set(scaffoldIdsBySelector.values())));
|
|
723
747
|
}
|
|
@@ -728,78 +752,58 @@ export class PageAnalyzer {
|
|
|
728
752
|
await this.ensureStoredForms(context.currentPageStateId, context);
|
|
729
753
|
return context.currentPageStateId;
|
|
730
754
|
}
|
|
755
|
+
// Combined endpoint: scaffolds + match + create in one round-trip
|
|
731
756
|
const hashes = await computeHashes(context.html, context.actionableItems);
|
|
732
|
-
|
|
733
|
-
if (existing) {
|
|
734
|
-
if (scaffoldIdsBySelector.size > 0) {
|
|
735
|
-
await context.api.linkPageStateScaffolds(existing.id, Array.from(new Set(scaffoldIdsBySelector.values())));
|
|
736
|
-
}
|
|
737
|
-
context.events.onPageStateCreated({
|
|
738
|
-
pageStateId: existing.id,
|
|
739
|
-
pageId: context.pageId,
|
|
740
|
-
});
|
|
741
|
-
await this.ensureStoredForms(existing.id, context);
|
|
742
|
-
return existing.id;
|
|
743
|
-
}
|
|
744
|
-
// Fallback: match by content minus scaffolds (e.g., cookie banner
|
|
745
|
-
// presence/absence should not create a different page state)
|
|
757
|
+
let fixedBodyHash;
|
|
746
758
|
if (context.scaffolds.length > 0) {
|
|
747
759
|
const body = getBody(context.html);
|
|
748
760
|
const { contentBody } = getContentBody(body, context.scaffolds);
|
|
749
|
-
|
|
750
|
-
const existingByContent = await context.api.findMatchingPageStateByContentBody(context.pageId, contentBodyHash, context.sizeClass);
|
|
751
|
-
if (existingByContent) {
|
|
752
|
-
if (scaffoldIdsBySelector.size > 0) {
|
|
753
|
-
await context.api.linkPageStateScaffolds(existingByContent.id, Array.from(new Set(scaffoldIdsBySelector.values())));
|
|
754
|
-
}
|
|
755
|
-
context.events.onPageStateCreated({
|
|
756
|
-
pageStateId: existingByContent.id,
|
|
757
|
-
pageId: context.pageId,
|
|
758
|
-
});
|
|
759
|
-
await this.ensureStoredForms(existingByContent.id, context);
|
|
760
|
-
return existingByContent.id;
|
|
761
|
-
}
|
|
761
|
+
fixedBodyHash = await sha256(normalizeHtml(contentBody));
|
|
762
762
|
}
|
|
763
|
-
const
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
763
|
+
const result = await context.api.ensurePageStateCombined({
|
|
764
|
+
pageId: context.pageId > 0 ? context.pageId : undefined,
|
|
765
|
+
relativePath: context.pageId === 0 ? context.currentPath : undefined,
|
|
766
|
+
runnerId: context.runnerId,
|
|
767
|
+
testEnvironmentId: context.testEnvironmentId,
|
|
768
768
|
sizeClass: context.sizeClass,
|
|
769
|
-
hashes,
|
|
770
|
-
contentText: htmlToMarkdown(context.html).slice(0, 5000),
|
|
771
|
-
contentHtmlElementId: contentElement.id,
|
|
772
769
|
screenshotPath: context.screenshotPath,
|
|
770
|
+
html: context.html,
|
|
771
|
+
contentText: htmlToMarkdown(context.html).slice(0, 5000),
|
|
772
|
+
hashes,
|
|
773
|
+
fixedBodyHash,
|
|
774
|
+
actionableItems: context.actionableItems,
|
|
775
|
+
scaffolds: context.scaffolds.map(scaffold => ({
|
|
776
|
+
type: scaffold.type,
|
|
777
|
+
html: scaffold.outerHtml,
|
|
778
|
+
hash: scaffold.hash,
|
|
779
|
+
selector: scaffold.selector,
|
|
780
|
+
})),
|
|
781
|
+
scaffoldSelectorByItemSelector: context.scaffoldSelectorByItemSelector,
|
|
773
782
|
});
|
|
774
|
-
//
|
|
775
|
-
if (context.
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
pageStateId: pageState.id,
|
|
790
|
-
error: err instanceof Error ? err.message : String(err),
|
|
791
|
-
});
|
|
783
|
+
// Part A: server resolved the page — update context
|
|
784
|
+
if (result.pageId && context.pageId === 0) {
|
|
785
|
+
context.pageId = result.pageId;
|
|
786
|
+
context.pageRequiresLogin = result.requiresLogin;
|
|
787
|
+
}
|
|
788
|
+
// Map scaffold IDs back to in-memory actionable items for generators
|
|
789
|
+
for (const item of context.actionableItems) {
|
|
790
|
+
if (!item.selector)
|
|
791
|
+
continue;
|
|
792
|
+
const scaffoldSelector = context.scaffoldSelectorByItemSelector[item.selector] ?? null;
|
|
793
|
+
if (!scaffoldSelector)
|
|
794
|
+
continue;
|
|
795
|
+
const scaffoldId = result.scaffoldIdsBySelector[scaffoldSelector];
|
|
796
|
+
if (scaffoldId) {
|
|
797
|
+
item.scaffoldId = scaffoldId;
|
|
792
798
|
}
|
|
793
799
|
}
|
|
800
|
+
// Scaffold screenshots are now updated server-side in ensure-page-state
|
|
794
801
|
context.events.onPageStateCreated({
|
|
795
|
-
pageStateId:
|
|
796
|
-
pageId: context.pageId,
|
|
802
|
+
pageStateId: result.pageStateId,
|
|
803
|
+
pageId: result.pageId ?? context.pageId,
|
|
797
804
|
});
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
}
|
|
801
|
-
await this.ensureStoredForms(pageState.id, context);
|
|
802
|
-
return pageState.id;
|
|
805
|
+
await this.ensureStoredForms(result.pageStateId, context);
|
|
806
|
+
return result.pageStateId;
|
|
803
807
|
}
|
|
804
808
|
async ensureScaffolds(context) {
|
|
805
809
|
const scaffoldIdsBySelector = new Map();
|