@sudobility/testomniac_runner_service 0.1.69 → 0.1.71
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/hover-follow-up.d.ts.map +1 -1
- package/dist/analyzer/page-analyzer/generators/hover-follow-up.js +20 -9
- package/dist/analyzer/page-analyzer/generators/hover-follow-up.js.map +1 -1
- package/dist/analyzer/page-analyzer/generators/navigation.d.ts +1 -1
- package/dist/analyzer/page-analyzer/generators/navigation.d.ts.map +1 -1
- package/dist/analyzer/page-analyzer/generators/navigation.js +5 -6
- package/dist/analyzer/page-analyzer/generators/navigation.js.map +1 -1
- package/dist/analyzer/page-analyzer/index.d.ts +10 -0
- package/dist/analyzer/page-analyzer/index.d.ts.map +1 -1
- package/dist/analyzer/page-analyzer/index.js +193 -14
- package/dist/analyzer/page-analyzer/index.js.map +1 -1
- package/dist/api/client.d.ts +2 -1
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/client.js +11 -1
- package/dist/api/client.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/orchestrator/runner.d.ts.map +1 -1
- package/dist/orchestrator/runner.js +34 -11
- package/dist/orchestrator/runner.js.map +1 -1
- package/dist/orchestrator/test-interaction-executor.d.ts +1 -0
- package/dist/orchestrator/test-interaction-executor.d.ts.map +1 -1
- package/dist/orchestrator/test-interaction-executor.js +120 -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/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hover-follow-up.d.ts","sourceRoot":"","sources":["../../../../src/analyzer/page-analyzer/generators/hover-follow-up.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAEpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAEhD,wBAAsB,0BAA0B,CAC9C,QAAQ,EAAE,GAAG,EACb,eAAe,EAAE,eAAe,EAChC,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"hover-follow-up.d.ts","sourceRoot":"","sources":["../../../../src/analyzer/page-analyzer/generators/hover-follow-up.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAEpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAEhD,wBAAsB,0BAA0B,CAC9C,QAAQ,EAAE,GAAG,EACb,eAAe,EAAE,eAAe,EAChC,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,IAAI,CAAC,CA8Jf"}
|
|
@@ -45,13 +45,10 @@ export async function generateHoverFollowUpCases(analyzer, testInteraction, cont
|
|
|
45
45
|
});
|
|
46
46
|
if ((stayedOnSamePageState || revealedItems.length === 0) &&
|
|
47
47
|
stableHoveredItem) {
|
|
48
|
-
|
|
49
|
-
console.info("[PageAnalyzer][hover-follow-up] generating-click", {
|
|
48
|
+
console.info("[PageAnalyzer][hover-follow-up] inline-click-already-required", {
|
|
50
49
|
testInteractionId: context.currentTestInteractionId,
|
|
51
50
|
sourceTitle: testInteraction.title,
|
|
52
51
|
selector,
|
|
53
|
-
generatedKey: analyzer.getGeneratedKey(clickCase),
|
|
54
|
-
clickTitle: clickCase.title,
|
|
55
52
|
currentPageStateId: context.currentPageStateId,
|
|
56
53
|
beginningPageStateId: context.beginningPageStateId,
|
|
57
54
|
stayedOnSamePageState,
|
|
@@ -60,13 +57,27 @@ export async function generateHoverFollowUpCases(analyzer, testInteraction, cont
|
|
|
60
57
|
await analyzer.reconcileGeneratedSurfaceElements(context, {
|
|
61
58
|
surfaceId: context.currentTestSurfaceId,
|
|
62
59
|
surfaceTitle: "",
|
|
63
|
-
desiredKeys: [
|
|
60
|
+
desiredKeys: [],
|
|
64
61
|
dependencyTestInteractionId: context.currentTestInteractionId,
|
|
65
62
|
});
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
// Skip follow-up generation if this page path was already generated for in
|
|
66
|
+
// this run (the analyzer instance tracks covered paths per run)
|
|
67
|
+
const currentPath = context.currentPath.trim();
|
|
68
|
+
const pageAlreadyCovered = analyzer.hasGeneratedForPath(currentPath);
|
|
69
|
+
if (pageAlreadyCovered) {
|
|
70
|
+
console.info("[PageAnalyzer][hover-follow-up] page-already-covered", {
|
|
71
|
+
testInteractionId: context.currentTestInteractionId,
|
|
72
|
+
sourceTitle: testInteraction.title,
|
|
73
|
+
currentPath,
|
|
74
|
+
currentPageStateId: context.currentPageStateId,
|
|
75
|
+
});
|
|
76
|
+
await analyzer.reconcileGeneratedSurfaceElements(context, {
|
|
77
|
+
surfaceId: context.currentTestSurfaceId,
|
|
78
|
+
surfaceTitle: "",
|
|
79
|
+
desiredKeys: [],
|
|
80
|
+
dependencyTestInteractionId: context.currentTestInteractionId,
|
|
70
81
|
});
|
|
71
82
|
return;
|
|
72
83
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hover-follow-up.js","sourceRoot":"","sources":["../../../../src/analyzer/page-analyzer/generators/hover-follow-up.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"hover-follow-up.js","sourceRoot":"","sources":["../../../../src/analyzer/page-analyzer/generators/hover-follow-up.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,6BAA6B,EAAE,MAAM,kCAAkC,CAAC;AAGjF,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,QAAa,EACb,eAAgC,EAChC,OAAwB;IAExB,MAAM,QAAQ,GAAG,QAAQ,CAAC,kBAAkB,CAAC,eAAe,CAAC,CAAC;IAC9D,IAAI,CAAC,QAAQ,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE,CAAC;QAC7C,OAAO,CAAC,IAAI,CAAC,yCAAyC,EAAE;YACtD,MAAM,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,4BAA4B;YACrE,iBAAiB,EAAE,OAAO,CAAC,wBAAwB;YACnD,KAAK,EAAE,eAAe,CAAC,KAAK;YAC5B,QAAQ;YACR,kBAAkB,EAAE,OAAO,CAAC,kBAAkB;YAC9C,oBAAoB,EAAE,OAAO,CAAC,oBAAoB;YAClD,WAAW,EAAE,OAAO,CAAC,WAAW;SACjC,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IAED,MAAM,cAAc,GAClB,OAAO,CAAC,oBAAoB,GAAG,CAAC;QAC9B,CAAC,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,OAAO,CAAC,oBAAoB,CAAC;QACrE,CAAC,CAAC,EAAE,CAAC;IACT,MAAM,aAAa,GAAG,IAAI,GAAG,CAC3B,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CACtE,CAAC;IAEF,MAAM,aAAa,GAAG,QAAQ,CAAC,yBAAyB,CACtD,OAAO,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,IAAS,EAAE,EAAE;QAC3C,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,IAAI,CAAC;YAAE,OAAO,KAAK,CAAC;QACpD,MAAM,GAAG,GAAG,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACtC,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACjD,CAAC,CAAC,CACH,CAAC;IAEF,MAAM,WAAW,GACf,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAClC,6BAA6B,CAAC,QAAQ,EAAE,IAAI,CAAC,CAC9C,IAAI,IAAI,CAAC;IACZ,MAAM,YAAY,GAChB,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACzB,6BAA6B,CAAC,QAAQ,EAAE,IAAI,CAAC,CAC9C,IAAI,IAAI,CAAC;IACZ,MAAM,iBAAiB,GAAG,WAAW,IAAI,YAAY,CAAC;IACtD,MAAM,qBAAqB,GACzB,OAAO,CAAC,oBAAoB,GAAG,CAAC;QAChC,OAAO,CAAC,kBAAkB,KAAK,OAAO,CAAC,oBAAoB,CAAC;IAE9D,OAAO,CAAC,IAAI,CAAC,2CAA2C,EAAE;QACxD,iBAAiB,EAAE,OAAO,CAAC,wBAAwB;QACnD,KAAK,EAAE,eAAe,CAAC,KAAK;QAC5B,QAAQ;QACR,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,kBAAkB,EAAE,OAAO,CAAC,kBAAkB;QAC9C,oBAAoB,EAAE,OAAO,CAAC,oBAAoB;QAClD,qBAAqB;QACrB,mBAAmB,EAAE,cAAc,CAAC,MAAM;QAC1C,oBAAoB,EAAE,OAAO,CAAC,eAAe,CAAC,MAAM;QACpD,kBAAkB,EAAE,aAAa,CAAC,MAAM;QACxC,cAAc,EAAE,OAAO,CAAC,WAAW,CAAC;QACpC,eAAe,EAAE,OAAO,CAAC,YAAY,CAAC;QACtC,oBAAoB,EAAE,OAAO,CAAC,iBAAiB,CAAC;KACjD,CAAC,CAAC;IAEH,IACE,CAAC,qBAAqB,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,CAAC;QACrD,iBAAiB,EACjB,CAAC;QACD,OAAO,CAAC,IAAI,CACV,+DAA+D,EAC/D;YACE,iBAAiB,EAAE,OAAO,CAAC,wBAAwB;YACnD,WAAW,EAAE,eAAe,CAAC,KAAK;YAClC,QAAQ;YACR,kBAAkB,EAAE,OAAO,CAAC,kBAAkB;YAC9C,oBAAoB,EAAE,OAAO,CAAC,oBAAoB;YAClD,qBAAqB;YACrB,kBAAkB,EAAE,aAAa,CAAC,MAAM;SACzC,CACF,CAAC;QACF,MAAM,QAAQ,CAAC,iCAAiC,CAAC,OAAO,EAAE;YACxD,SAAS,EAAE,OAAO,CAAC,oBAAoB;YACvC,YAAY,EAAE,EAAE;YAChB,WAAW,EAAE,EAAE;YACf,2BAA2B,EAAE,OAAO,CAAC,wBAAwB;SAC9D,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IAED,2EAA2E;IAC3E,gEAAgE;IAChE,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;IAC/C,MAAM,kBAAkB,GAAG,QAAQ,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAC;IACrE,IAAI,kBAAkB,EAAE,CAAC;QACvB,OAAO,CAAC,IAAI,CAAC,sDAAsD,EAAE;YACnE,iBAAiB,EAAE,OAAO,CAAC,wBAAwB;YACnD,WAAW,EAAE,eAAe,CAAC,KAAK;YAClC,WAAW;YACX,kBAAkB,EAAE,OAAO,CAAC,kBAAkB;SAC/C,CAAC,CAAC;QACH,MAAM,QAAQ,CAAC,iCAAiC,CAAC,OAAO,EAAE;YACxD,SAAS,EAAE,OAAO,CAAC,oBAAoB;YACvC,YAAY,EAAE,EAAE;YAChB,WAAW,EAAE,EAAE;YACf,2BAA2B,EAAE,OAAO,CAAC,wBAAwB;SAC9D,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,6DAA6D,EAAE;QAC1E,iBAAiB,EAAE,OAAO,CAAC,wBAAwB;QACnD,WAAW,EAAE,eAAe,CAAC,KAAK;QAClC,QAAQ;QACR,kBAAkB,EAAE,OAAO,CAAC,kBAAkB;QAC9C,oBAAoB,EAAE,OAAO,CAAC,oBAAoB;QAClD,qBAAqB;QACrB,kBAAkB,EAAE,aAAa,CAAC,MAAM;QACxC,iBAAiB,EAAE,aAAa;aAC7B,GAAG,CAAC,CAAC,IAAS,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC;aACjC,MAAM,CAAC,OAAO,CAAC;aACf,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;KAChB,CAAC,CAAC;IAEH,MAAM,WAAW,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,IAAS,EAAE,EAAE,CAClD,QAAQ,CAAC,eAAe,CACtB,QAAQ,CAAC,yBAAyB,CAChC,IAAI,EACJ,OAAO,CAAC,WAAW,EACnB,OAAO,CAAC,SAAS,EACjB,OAAO,CAAC,GAAG,EACX,OAAO,CAAC,kBAAkB,EAC1B,OAAO,CAAC,wBAAwB,CACjC,CACF,CACF,CAAC;IACF,MAAM,QAAQ,CAAC,iCAAiC,CAAC,OAAO,EAAE;QACxD,SAAS,EAAE,OAAO,CAAC,oBAAoB;QACvC,YAAY,EAAE,EAAE;QAChB,WAAW;QACX,2BAA2B,EAAE,OAAO,CAAC,wBAAwB;KAC9D,CAAC,CAAC;IAEH,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;QACjC,MAAM,SAAS,GAAG,QAAQ,CAAC,yBAAyB,CAClD,IAAI,EACJ,OAAO,CAAC,WAAW,EACnB,OAAO,CAAC,SAAS,EACjB,OAAO,CAAC,GAAG,EACX,OAAO,CAAC,kBAAkB,EAC1B,OAAO,CAAC,wBAAwB,CACjC,CAAC;QACF,MAAM,EAAE,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAChD,OAAO,CAAC,QAAQ,EAChB,OAAO,CAAC,oBAAoB,EAC5B,SAAS,EACT,OAAO,CAAC,iBAAiB,CAC1B,CAAC;QACF,MAAM,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC;YACzC,iBAAiB,EAAE,EAAE,CAAC,EAAE;YACxB,gBAAgB,EAAE,OAAO,CAAC,mBAAmB,IAAI,SAAS;SAC3D,CAAC,CAAC;IACL,CAAC;AACH,CAAC"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { AnalyzerContext } from "../types";
|
|
2
|
-
export declare function generateNavigationTestInteractions(
|
|
2
|
+
export declare function generateNavigationTestInteractions(_analyzer: any, _context: AnalyzerContext): Promise<void>;
|
|
3
3
|
//# sourceMappingURL=navigation.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../../../../src/analyzer/page-analyzer/generators/navigation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAEhD,wBAAsB,kCAAkC,CACtD,
|
|
1
|
+
{"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../../../../src/analyzer/page-analyzer/generators/navigation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAEhD,wBAAsB,kCAAkC,CACtD,SAAS,EAAE,GAAG,EACd,QAAQ,EAAE,eAAe,GACxB,OAAO,CAAC,IAAI,CAAC,CAKf"}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
export async function generateNavigationTestInteractions(
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
});
|
|
1
|
+
export async function generateNavigationTestInteractions(_analyzer, _context) {
|
|
2
|
+
// Navigation surface is managed externally (scan bootstrap + auto-created
|
|
3
|
+
// navigations from hover-click discovery). Do not reconcile — reconciling
|
|
4
|
+
// with desiredKeys: [] would retire auto-created navigation interactions
|
|
5
|
+
// before the runner can execute them.
|
|
7
6
|
}
|
|
8
7
|
//# sourceMappingURL=navigation.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navigation.js","sourceRoot":"","sources":["../../../../src/analyzer/page-analyzer/generators/navigation.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,KAAK,UAAU,kCAAkC,CACtD,
|
|
1
|
+
{"version":3,"file":"navigation.js","sourceRoot":"","sources":["../../../../src/analyzer/page-analyzer/generators/navigation.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,KAAK,UAAU,kCAAkC,CACtD,SAAc,EACd,QAAyB;IAEzB,0EAA0E;IAC1E,0EAA0E;IAC1E,yEAAyE;IACzE,sCAAsC;AACxC,CAAC"}
|
|
@@ -4,16 +4,25 @@ export type { AnalyzerContext } from "./types";
|
|
|
4
4
|
type GeneratedTestInteraction = TestInteraction & {
|
|
5
5
|
generatedKey?: string;
|
|
6
6
|
};
|
|
7
|
+
type AppendActionResult = {
|
|
8
|
+
testInteraction: TestInteraction;
|
|
9
|
+
appended: boolean;
|
|
10
|
+
};
|
|
7
11
|
/**
|
|
8
12
|
* PageAnalyzer generates expectations and discovers new test elements
|
|
9
13
|
* during discovery mode.
|
|
10
14
|
*/
|
|
11
15
|
export declare class PageAnalyzer {
|
|
16
|
+
/** Paths for which full generation has already run in this test-run. */
|
|
17
|
+
private generatedPaths;
|
|
18
|
+
/** Check whether generation already happened for a given path in this run. */
|
|
19
|
+
hasGeneratedForPath(path: string): boolean;
|
|
12
20
|
/**
|
|
13
21
|
* Generate baseline expectations for a test element.
|
|
14
22
|
* Called BEFORE expertises evaluate.
|
|
15
23
|
*/
|
|
16
24
|
generateExpectations(testInteraction: TestInteraction): Expectation[];
|
|
25
|
+
maybeAppendActionToInteraction(testInteraction: TestInteraction, context: Pick<AnalyzerContext, "runnerId" | "testEnvironmentId" | "sizeClass" | "uid" | "currentTestInteractionId" | "currentTestSurfaceId" | "currentSurfaceRunId" | "beginningPageStateId" | "currentPath" | "actionableItems" | "api">): Promise<AppendActionResult>;
|
|
17
26
|
/**
|
|
18
27
|
* Generate new test elements for scaffolds and page content.
|
|
19
28
|
* Called AFTER expertises evaluate and the target page state is established.
|
|
@@ -35,6 +44,7 @@ export declare class PageAnalyzer {
|
|
|
35
44
|
private buildHoverTestInteraction;
|
|
36
45
|
private buildClickTestInteraction;
|
|
37
46
|
private isHoverOnly;
|
|
47
|
+
private isHoverBased;
|
|
38
48
|
private getPrimarySelector;
|
|
39
49
|
private getItemKey;
|
|
40
50
|
withGeneratedKey(testInteraction: GeneratedTestInteraction, ...parts: Array<string | number | null | undefined>): GeneratedTestInteraction;
|
|
@@ -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,7 @@
|
|
|
1
1
|
import { PlaywrightAction, ExpectationType, ExpectationSeverity, } from "@sudobility/testomniac_types";
|
|
2
|
-
import { buildReplaySelectorFromActionableItem } from "../../browser/replay-selector";
|
|
3
|
-
import { computeHashes } from "../../browser/page-utils";
|
|
2
|
+
import { buildReplaySelectorFromActionableItem, matchesActionableItemSelector, } from "../../browser/replay-selector";
|
|
3
|
+
import { computeHashes, sha256, normalizeHtml } from "../../browser/page-utils";
|
|
4
|
+
import { getBody, getContentBody } from "../../scanner/html-decomposer";
|
|
4
5
|
import { createHash } from "node:crypto";
|
|
5
6
|
import { fillValuePlanner } from "../../planners/fill-value-planner";
|
|
6
7
|
import { AUTH_URL_PATTERNS, SIGNUP_URL_PATTERNS } from "../../config/constants";
|
|
@@ -23,6 +24,12 @@ function logAnalyzer(step, details) {
|
|
|
23
24
|
* during discovery mode.
|
|
24
25
|
*/
|
|
25
26
|
export class PageAnalyzer {
|
|
27
|
+
/** Paths for which full generation has already run in this test-run. */
|
|
28
|
+
generatedPaths = new Set();
|
|
29
|
+
/** Check whether generation already happened for a given path in this run. */
|
|
30
|
+
hasGeneratedForPath(path) {
|
|
31
|
+
return this.generatedPaths.has(path);
|
|
32
|
+
}
|
|
26
33
|
/**
|
|
27
34
|
* Generate baseline expectations for a test element.
|
|
28
35
|
* Called BEFORE expertises evaluate.
|
|
@@ -58,6 +65,86 @@ export class PageAnalyzer {
|
|
|
58
65
|
}
|
|
59
66
|
return expectations;
|
|
60
67
|
}
|
|
68
|
+
async maybeAppendActionToInteraction(testInteraction, context) {
|
|
69
|
+
if (!this.isHoverOnly(testInteraction)) {
|
|
70
|
+
return { testInteraction, appended: false };
|
|
71
|
+
}
|
|
72
|
+
const selector = this.getPrimarySelector(testInteraction);
|
|
73
|
+
if (!selector) {
|
|
74
|
+
return { testInteraction, appended: false };
|
|
75
|
+
}
|
|
76
|
+
const beginningItems = context.beginningPageStateId > 0
|
|
77
|
+
? await context.api.getItemsByPageState(context.beginningPageStateId)
|
|
78
|
+
: [];
|
|
79
|
+
const beginningKeys = new Set(beginningItems.map(item => this.getItemKey(item)).filter(Boolean));
|
|
80
|
+
const revealedItems = this.selectRepresentativeItems(context.actionableItems.filter(item => {
|
|
81
|
+
if (!this.isMouseActionable(item))
|
|
82
|
+
return false;
|
|
83
|
+
const key = this.getItemKey(item);
|
|
84
|
+
return Boolean(key) && !beginningKeys.has(key);
|
|
85
|
+
}));
|
|
86
|
+
const currentHoveredItem = context.actionableItems.find(item => matchesActionableItemSelector(selector, item)) ?? null;
|
|
87
|
+
const stableHoveredItem = currentHoveredItem ??
|
|
88
|
+
beginningItems.find(item => matchesActionableItemSelector(selector, item)) ??
|
|
89
|
+
null;
|
|
90
|
+
logAnalyzer("generate:hover-inline-evaluated", {
|
|
91
|
+
sourceTitle: testInteraction.title,
|
|
92
|
+
currentTestInteractionId: context.currentTestInteractionId,
|
|
93
|
+
currentSurfaceRunId: context.currentSurfaceRunId ?? null,
|
|
94
|
+
selector,
|
|
95
|
+
beginningItemsCount: beginningItems.length,
|
|
96
|
+
actionableItemsCount: context.actionableItems.length,
|
|
97
|
+
revealedItemsCount: revealedItems.length,
|
|
98
|
+
hasCurrentHoveredItem: Boolean(currentHoveredItem),
|
|
99
|
+
hasStableHoveredItem: Boolean(stableHoveredItem),
|
|
100
|
+
});
|
|
101
|
+
if (!stableHoveredItem) {
|
|
102
|
+
return { testInteraction, appended: false };
|
|
103
|
+
}
|
|
104
|
+
// Prefer currentHoveredItem (ActionableItem); fall back to converting
|
|
105
|
+
// the ActionableItemResponse from beginning page state.
|
|
106
|
+
const fallback = stableHoveredItem;
|
|
107
|
+
const clickItem = currentHoveredItem ?? {
|
|
108
|
+
stableKey: fallback.stableKey ?? fallback.selector ?? "",
|
|
109
|
+
selector: fallback.selector ?? "",
|
|
110
|
+
tagName: fallback.tagName ?? "",
|
|
111
|
+
role: fallback.role ?? undefined,
|
|
112
|
+
inputType: undefined,
|
|
113
|
+
actionKind: fallback.actionKind ?? "click",
|
|
114
|
+
accessibleName: fallback.accessibleName ?? undefined,
|
|
115
|
+
textContent: undefined,
|
|
116
|
+
href: undefined,
|
|
117
|
+
disabled: fallback.disabled ?? false,
|
|
118
|
+
visible: fallback.visible ?? true,
|
|
119
|
+
attributes: (typeof fallback.attributesJson === "object" &&
|
|
120
|
+
fallback.attributesJson !== null
|
|
121
|
+
? fallback.attributesJson
|
|
122
|
+
: {}),
|
|
123
|
+
};
|
|
124
|
+
const clickStep = this.buildClickTestInteraction(clickItem, context.currentPath, context.sizeClass, context.uid, testInteraction.startingPageStateId, undefined).steps?.[0] ?? null;
|
|
125
|
+
if (!clickStep) {
|
|
126
|
+
return { testInteraction, appended: false };
|
|
127
|
+
}
|
|
128
|
+
const updatedInteraction = {
|
|
129
|
+
...testInteraction,
|
|
130
|
+
steps: [
|
|
131
|
+
...(Array.isArray(testInteraction.steps) ? testInteraction.steps : []),
|
|
132
|
+
clickStep,
|
|
133
|
+
],
|
|
134
|
+
};
|
|
135
|
+
await context.api.ensureTestInteraction(context.runnerId, context.currentTestSurfaceId, updatedInteraction, context.testEnvironmentId, context.currentTestInteractionId);
|
|
136
|
+
logAnalyzer("generate:hover-inline-click-appended", {
|
|
137
|
+
sourceTitle: testInteraction.title,
|
|
138
|
+
currentTestInteractionId: context.currentTestInteractionId,
|
|
139
|
+
currentSurfaceRunId: context.currentSurfaceRunId ?? null,
|
|
140
|
+
selector,
|
|
141
|
+
appendedActionType: clickStep.action.actionType,
|
|
142
|
+
});
|
|
143
|
+
return {
|
|
144
|
+
testInteraction: updatedInteraction,
|
|
145
|
+
appended: true,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
61
148
|
/**
|
|
62
149
|
* Generate new test elements for scaffolds and page content.
|
|
63
150
|
* Called AFTER expertises evaluate and the target page state is established.
|
|
@@ -103,21 +190,71 @@ export class PageAnalyzer {
|
|
|
103
190
|
await generateHoverFollowUpCases(this, testInteraction, resolvedContext);
|
|
104
191
|
return;
|
|
105
192
|
}
|
|
193
|
+
// Skip generation if we already generated tests for this path during this
|
|
194
|
+
// run. The check is scoped to the PageAnalyzer instance (one per run) so
|
|
195
|
+
// previous runs on the same runner don't block re-discovery.
|
|
196
|
+
const currentPath = resolvedContext.currentPath.trim();
|
|
197
|
+
if (this.generatedPaths.has(currentPath)) {
|
|
198
|
+
logAnalyzer("generate:page-already-covered", {
|
|
199
|
+
sourceTitle: testInteraction.title,
|
|
200
|
+
currentTestInteractionId: resolvedContext.currentTestInteractionId,
|
|
201
|
+
currentPageStateId: resolvedContext.currentPageStateId,
|
|
202
|
+
currentPath,
|
|
203
|
+
});
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
this.generatedPaths.add(currentPath);
|
|
207
|
+
// If a hover+click navigated to a new page, create a direct navigation
|
|
208
|
+
// interaction and use it as the dependency instead of the hover chain
|
|
209
|
+
let contextForFullPass = resolvedContext;
|
|
210
|
+
const normalizedStartingPath = (testInteraction.startingPath || "/").trim();
|
|
211
|
+
if (this.isHoverBased(testInteraction) &&
|
|
212
|
+
normalizedStartingPath !== currentPath) {
|
|
213
|
+
const navInteraction = this.buildNavigationTestInteraction(currentPath, resolvedContext.sizeClass, resolvedContext.uid, resolvedContext.currentPageStateId > 0
|
|
214
|
+
? resolvedContext.currentPageStateId
|
|
215
|
+
: undefined);
|
|
216
|
+
const navSurfaceId = resolvedContext.navigationSurface.id;
|
|
217
|
+
const saved = await resolvedContext.api.ensureTestInteraction(resolvedContext.runnerId, navSurfaceId, navInteraction, resolvedContext.testEnvironmentId);
|
|
218
|
+
// Also create a run for it so the runner can execute it
|
|
219
|
+
const surfaceRuns = await resolvedContext.api.getOpenTestSurfaceRuns(resolvedContext.bundleRun.id);
|
|
220
|
+
const navSurfaceRun = surfaceRuns.find(sr => sr.testSurfaceId === navSurfaceId);
|
|
221
|
+
if (navSurfaceRun) {
|
|
222
|
+
try {
|
|
223
|
+
await resolvedContext.api.createTestInteractionRun({
|
|
224
|
+
testInteractionId: saved.id,
|
|
225
|
+
testSurfaceRunId: navSurfaceRun.id,
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
catch {
|
|
229
|
+
// Run may already exist
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
logAnalyzer("generate:navigation-dependency-created", {
|
|
233
|
+
sourceTitle: testInteraction.title,
|
|
234
|
+
navigationInteractionId: saved.id,
|
|
235
|
+
navigationPath: currentPath,
|
|
236
|
+
originalDependencyId: resolvedContext.currentTestInteractionId,
|
|
237
|
+
});
|
|
238
|
+
contextForFullPass = {
|
|
239
|
+
...resolvedContext,
|
|
240
|
+
currentTestInteractionId: saved.id,
|
|
241
|
+
};
|
|
242
|
+
}
|
|
106
243
|
logAnalyzer("generate:full-pass", {
|
|
107
244
|
sourceTitle: testInteraction.title,
|
|
108
|
-
currentTestInteractionId:
|
|
109
|
-
currentPageStateId:
|
|
245
|
+
currentTestInteractionId: contextForFullPass.currentTestInteractionId,
|
|
246
|
+
currentPageStateId: contextForFullPass.currentPageStateId,
|
|
110
247
|
});
|
|
111
|
-
await generateRenderTestInteractions(this,
|
|
112
|
-
await generateFormTestInteractions(this,
|
|
113
|
-
await generateSemanticJourneyTestInteractions(this,
|
|
114
|
-
await generateE2ETestInteractions(this,
|
|
115
|
-
await generateDialogLifecycleTestInteractions(this,
|
|
116
|
-
await generateScaffoldTestInteractions(this,
|
|
117
|
-
await generateContentTestInteractions(this,
|
|
118
|
-
await generateKeyboardAndDisclosureTestInteractions(this,
|
|
119
|
-
await generateVariantTestInteractions(this,
|
|
120
|
-
await generateNavigationTestInteractions(this,
|
|
248
|
+
await generateRenderTestInteractions(this, contextForFullPass);
|
|
249
|
+
await generateFormTestInteractions(this, contextForFullPass);
|
|
250
|
+
await generateSemanticJourneyTestInteractions(this, contextForFullPass);
|
|
251
|
+
await generateE2ETestInteractions(this, contextForFullPass);
|
|
252
|
+
await generateDialogLifecycleTestInteractions(this, contextForFullPass);
|
|
253
|
+
await generateScaffoldTestInteractions(this, contextForFullPass);
|
|
254
|
+
await generateContentTestInteractions(this, contextForFullPass);
|
|
255
|
+
await generateKeyboardAndDisclosureTestInteractions(this, contextForFullPass);
|
|
256
|
+
await generateVariantTestInteractions(this, contextForFullPass);
|
|
257
|
+
await generateNavigationTestInteractions(this, contextForFullPass);
|
|
121
258
|
}
|
|
122
259
|
async reconcileGeneratedSurfaceElements(context, params) {
|
|
123
260
|
const surface = params.surfaceId != null
|
|
@@ -315,6 +452,13 @@ export class PageAnalyzer {
|
|
|
315
452
|
return (steps.length === 1 &&
|
|
316
453
|
steps[0]?.action?.actionType === PlaywrightAction.Hover);
|
|
317
454
|
}
|
|
455
|
+
isHoverBased(testInteraction) {
|
|
456
|
+
const steps = Array.isArray(testInteraction.steps)
|
|
457
|
+
? testInteraction.steps
|
|
458
|
+
: [];
|
|
459
|
+
return (steps.length > 0 &&
|
|
460
|
+
steps[0]?.action?.actionType === PlaywrightAction.Hover);
|
|
461
|
+
}
|
|
318
462
|
getPrimarySelector(testInteraction) {
|
|
319
463
|
const steps = Array.isArray(testInteraction.steps)
|
|
320
464
|
? testInteraction.steps
|
|
@@ -407,6 +551,25 @@ export class PageAnalyzer {
|
|
|
407
551
|
await this.ensureStoredForms(existing.id, context);
|
|
408
552
|
return existing.id;
|
|
409
553
|
}
|
|
554
|
+
// Fallback: match by content minus scaffolds (e.g., cookie banner
|
|
555
|
+
// presence/absence should not create a different page state)
|
|
556
|
+
if (context.scaffolds.length > 0) {
|
|
557
|
+
const body = getBody(context.html);
|
|
558
|
+
const { contentBody } = getContentBody(body, context.scaffolds);
|
|
559
|
+
const contentBodyHash = await sha256(normalizeHtml(contentBody));
|
|
560
|
+
const existingByContent = await context.api.findMatchingPageStateByContentBody(context.pageId, contentBodyHash, context.sizeClass);
|
|
561
|
+
if (existingByContent) {
|
|
562
|
+
if (scaffoldIdsBySelector.size > 0) {
|
|
563
|
+
await context.api.linkPageStateScaffolds(existingByContent.id, Array.from(new Set(scaffoldIdsBySelector.values())));
|
|
564
|
+
}
|
|
565
|
+
context.events.onPageStateCreated({
|
|
566
|
+
pageStateId: existingByContent.id,
|
|
567
|
+
pageId: context.pageId,
|
|
568
|
+
});
|
|
569
|
+
await this.ensureStoredForms(existingByContent.id, context);
|
|
570
|
+
return existingByContent.id;
|
|
571
|
+
}
|
|
572
|
+
}
|
|
410
573
|
const contentHash = createHash("sha256").update(context.html).digest("hex");
|
|
411
574
|
const contentElement = await context.api.findOrCreateHtmlElement(context.html, contentHash);
|
|
412
575
|
await context.api.insertActionableItems(contentElement.id, context.actionableItems);
|
|
@@ -417,6 +580,22 @@ export class PageAnalyzer {
|
|
|
417
580
|
contentText: context.html.slice(0, 5000),
|
|
418
581
|
contentHtmlElementId: contentElement.id,
|
|
419
582
|
});
|
|
583
|
+
// Store content-body hash (HTML minus scaffolds) for fallback matching
|
|
584
|
+
if (context.scaffolds.length > 0) {
|
|
585
|
+
const body = getBody(context.html);
|
|
586
|
+
const { contentBody } = getContentBody(body, context.scaffolds);
|
|
587
|
+
const contentBodyHash = await sha256(normalizeHtml(contentBody));
|
|
588
|
+
try {
|
|
589
|
+
await context.api.updatePageStateDecomposedHashes(pageState.id, {
|
|
590
|
+
fixedBodyHash: contentBodyHash,
|
|
591
|
+
scaffoldsHash: "",
|
|
592
|
+
patternsHash: "",
|
|
593
|
+
});
|
|
594
|
+
}
|
|
595
|
+
catch {
|
|
596
|
+
// Best effort — decomposed hashes are optional
|
|
597
|
+
}
|
|
598
|
+
}
|
|
420
599
|
context.events.onPageStateCreated({
|
|
421
600
|
pageStateId: pageState.id,
|
|
422
601
|
pageId: context.pageId,
|